diff --git a/Makefile b/Makefile index a94a243..b7f0b1a 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ PROGRAM=crash # Supported targets: X86 ALPHA PPC IA64 PPC64 SPARC64 # TARGET and GDB_CONF_FLAGS will be configured automatically by configure # -TARGET= -GDB_CONF_FLAGS= +TARGET=SW_64 +GDB_CONF_FLAGS=--host=sw_64-sunway-linux-gnu --build=sw_64-sunway-linux-gnu --with-guile=no --with-python --with-expat ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) ifeq (${ARCH}, ppc64) @@ -35,10 +35,10 @@ endif # # GDB, GDB_FILES, GDB_OFILES and GDB_PATCH_FILES will be configured automatically by configure # -GDB= -GDB_FILES= -GDB_OFILES= -GDB_PATCH_FILES= +GDB=gdb-10.2 +GDB_FILES=${GDB_10.2_FILES} +GDB_OFILES=${GDB_10.2_OFILES} +GDB_PATCH_FILES=gdb-10.2.patch # # Default installation directory @@ -65,7 +65,7 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \ kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \ printk.c \ alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \ - arm.c arm64.c mips.c mips64.c riscv64.c sparc64.c \ + arm.c arm64.c mips.c mips64.c riscv64.c sparc64.c sw_64.c\ extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \ lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\ lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \ @@ -85,7 +85,7 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \ build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \ printk.o \ alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \ - arm.o arm64.o mips.o mips64.o riscv64.o sparc64.o \ + arm.o arm64.o mips.o mips64.o riscv64.o sparc64.o sw_64.o\ extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \ lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \ lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o \ @@ -190,7 +190,7 @@ GDB_10.2_OFILES=${GDB}/gdb/symtab.o crash_target.o # # GDB_FLAGS is passed up from the gdb Makefile. # -GDB_FLAGS= +GDB_FLAGS=-DGDB_10_2 # # WARNING_OPTIONS and WARNING_ERROR are both applied on a per-file basis. @@ -199,15 +199,15 @@ GDB_FLAGS= # usefulness is also dependent upon the processor's compiler -- your mileage # may vary. # -#WARNING_OPTIONS=-Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security +WARNING_OPTIONS=-Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security #WARNING_ERROR=-Werror # TARGET_CFLAGS will be configured automatically by configure -TARGET_CFLAGS= +TARGET_CFLAGS=-O2 -D_SW64_ -DSCORE CRASH_CFLAGS=-g -D${TARGET} ${TARGET_CFLAGS} ${GDB_FLAGS} ${CFLAGS} -GPL_FILES= +GPL_FILES=COPYING3 TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \ ${EXTENSION_SOURCE_FILES} ${MEMORY_DRIVER_FILES} CSCOPE_FILES=${SOURCE_FILES} @@ -415,6 +415,9 @@ x86.o: ${GENERIC_HFILES} ${REDHAT_HFILES} x86.c alpha.o: ${GENERIC_HFILES} alpha.c ${CC} -c ${CRASH_CFLAGS} alpha.c ${WARNING_OPTIONS} ${WARNING_ERROR} +sw_64.o: ${GENERIC_HFILES} sw_64.c + ${CC} -c ${CRASH_CFLAGS} sw_64.c ${WARNING_OPTIONS} ${WARNING_ERROR} + ppc.o: ${GENERIC_HFILES} ppc.c ${CC} -c ${CRASH_CFLAGS} ppc.c ${WARNING_OPTIONS} ${WARNING_ERROR} diff --git a/configure.c b/configure.c index 08b52be..ea6a418 100644 --- a/configure.c +++ b/configure.c @@ -108,6 +108,7 @@ void add_extra_lib(char *); #undef SPARC64 #undef MIPS64 #undef RISCV64 +#undef SW_64 #define UNKNOWN 0 #define X86 1 @@ -124,6 +125,7 @@ void add_extra_lib(char *); #define SPARC64 12 #define MIPS64 13 #define RISCV64 14 +#define SW_64 15 #define TARGET_X86 "TARGET=X86" #define TARGET_ALPHA "TARGET=ALPHA" @@ -139,6 +141,7 @@ void add_extra_lib(char *); #define TARGET_MIPS64 "TARGET=MIPS64" #define TARGET_SPARC64 "TARGET=SPARC64" #define TARGET_RISCV64 "TARGET=RISCV64" +#define TARGET_SW_64 "TARGET=SW_64" #define TARGET_CFLAGS_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64" #define TARGET_CFLAGS_ALPHA "TARGET_CFLAGS=" @@ -163,6 +166,7 @@ void add_extra_lib(char *); #define TARGET_CFLAGS_SPARC64 "TARGET_CFLAGS=" #define TARGET_CFLAGS_RISCV64 "TARGET_CFLAGS=" #define TARGET_CFLAGS_RISCV64_ON_X86_64 "TARGET_CFLAGS=" +#define TARGET_CFLAGS_SW_64 "TARGET_CFLAGS=-O2 -D_SW64_ -DSCORE" #define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS=" #define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux" @@ -174,6 +178,7 @@ void add_extra_lib(char *); #define GDB_TARGET_MIPS_ON_X86 "GDB_CONF_FLAGS=--target=mipsel-elf-linux" #define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32 CXXFLAGS=-m32" #define GDB_TARGET_RISCV64_ON_X86_64 "GDB_CONF_FLAGS=--target=riscv64-unknown-linux-gnu" +#define GDB_TARGET_SW_64 "GDB_CONF_FLAGS=--host=sw_64-sunway-linux-gnu --build=sw_64-sunway-linux-gnu --with-guile=no --with-python --with-expat" /* * The original plan was to allow the use of a particular version @@ -373,6 +378,9 @@ get_current_configuration(struct supported_gdb_version *sp) #ifdef __alpha__ target_data.target = ALPHA; #endif +#ifdef __sw_64__ + target_data.target = SW_64; +#endif #ifdef __i386__ target_data.target = X86; #endif @@ -650,6 +658,9 @@ show_configuration(void) case ALPHA: printf("TARGET: ALPHA\n"); break; + case SW_64: + printf("TARGET: SW_64\n"); + break; case PPC: printf("TARGET: PPC\n"); break; @@ -733,6 +744,11 @@ build_configure(struct supported_gdb_version *sp) target = TARGET_ALPHA; target_CFLAGS = TARGET_CFLAGS_ALPHA; break; + case SW_64: + target = TARGET_SW_64; + target_CFLAGS = TARGET_CFLAGS_SW_64; + gdb_conf_flags = GDB_TARGET_SW_64; + break; case PPC: target = TARGET_PPC; if (target_data.host == PPC64) { @@ -1627,6 +1643,8 @@ set_initial_target(struct supported_gdb_version *sp) target_data.initial_gdb_target = X86; else if (strncmp(buf, "ALPHA", strlen("ALPHA")) == 0) target_data.initial_gdb_target = ALPHA; + else if (strncmp(buf, "SW_64", strlen("SW_64")) == 0) + target_data.initial_gdb_target = SW_64; else if (strncmp(buf, "PPC64", strlen("PPC64")) == 0) target_data.initial_gdb_target = PPC64; else if (strncmp(buf, "PPC", strlen("PPC")) == 0) @@ -1658,6 +1676,7 @@ target_to_name(int target) { case X86: return("X86"); case ALPHA: return("ALPHA"); + case SW_64: return("SW_64"); case PPC: return("PPC"); case IA64: return("IA64"); case S390: return("S390"); @@ -1690,6 +1709,10 @@ name_to_target(char *name) return ALPHA; else if (strncmp(name, "alpha", strlen("alpha")) == 0) return ALPHA; + else if (strncmp(name, "SW_64", strlen("SW_64")) == 0) + return SW_64; + else if (strncmp(name, "sw_64", strlen("sw_64")) == 0) + return SW_64; else if (strncmp(name, "PPC64", strlen("PPC64")) == 0) return PPC64; else if (strncmp(name, "ppc64", strlen("ppc64")) == 0) diff --git a/defs.h b/defs.h index 788f63a..d5a0951 100644 --- a/defs.h +++ b/defs.h @@ -76,10 +76,13 @@ #if !defined(X86) && !defined(X86_64) && !defined(ALPHA) && !defined(PPC) && \ !defined(IA64) && !defined(PPC64) && !defined(S390) && !defined(S390X) && \ !defined(ARM) && !defined(ARM64) && !defined(MIPS) && !defined(MIPS64) && \ - !defined(RISCV64) && !defined(SPARC64) + !defined(RISCV64) && !defined(SPARC64) && !defined(SW_64) #ifdef __alpha__ #define ALPHA #endif +#ifdef __sw_64__ +#define SW_64 +#endif #ifdef __i386__ #define X86 #endif @@ -132,6 +135,9 @@ #ifdef ALPHA #define NR_CPUS (64) #endif +#ifdef SW_64 +#define NR_CPUS (512) +#endif #ifdef PPC #define NR_CPUS (32) #endif @@ -4044,6 +4050,98 @@ typedef signed int s32; #endif /* ALPHA */ +#ifdef SW_64 +#define _64BIT_ +#define MACHINE_TYPE "SW_64" + +#define PAGEBASE(X) (((unsigned long)(X)) & (unsigned long)machdep->pagemask) + +#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) +#define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +#define VMALLOC_END (0xfffff80000000000) +#define IS_VMALLOC_ADDR(X) ((ulong)(X) >= vt->vmalloc_start && (ulong)(X) <= VMALLOC_END) +#define KSEG_BASE (0xfff0000000000000) +#define _PFN_MASK (0xFFFFFFFFF0000000) +#define PFN_SHIFT 28 +#define VMALLOC_START (0xfffff00000000000) +#define MIN_SYMBOL_VALUE (KSEG_BASE) + +#define PGDIR_SHIFT (PAGESHIFT() + 3*(PAGESHIFT()-3)) +#define PUD_SHIFT (PAGESHIFT() + 2*(PAGESHIFT()-3)) +#define PMD_SHIFT (PAGESHIFT() + 1*(PAGESHIFT()-3)) +#define PTRS_PER_PAGE (1024) + +#define PTRS_PER_PGD (1UL << (PAGESHIFT()-3)) + +/* + * OSF/1 PAL-code-imposed page table bits + */ +#define _PAGE_VALID 0x0001 +#define _PAGE_FOR 0x0002 /* used for page protection (fault on read) */ +#define _PAGE_FOW 0x0004 /* used for page protection (fault on write) */ +#define _PAGE_FOE 0x0008 /* used for page protection (fault on exec) */ +#define _PAGE_ASM 0x0010 +#define _PAGE_KRE 0x0100 /* xxx - see below on the "accessed" bit */ +#define _PAGE_URE 0x0200 /* xxx */ +#define _PAGE_KWE 0x1000 /* used to do the dirty bit in software */ +#define _PAGE_UWE 0x2000 /* used to do the dirty bit in software */ + +/* .. and these are ours ... */ +#define _PAGE_DIRTY 0x20000 +#define _PAGE_ACCESSED 0x40000 + +#define SWP_TYPE(entry) (((entry) >> 32) & 0xff) +#define SWP_OFFSET(entry) ((entry) >> 40) +#define __swp_type(entry) SWP_TYPE(entry) +#define __swp_offset(entry) SWP_OFFSET(entry) + +#define TIF_SIGPENDING (2) + +struct sw64_pt_regs { + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long r16; + unsigned long r17; + unsigned long r18; + unsigned long r19; + unsigned long r20; + unsigned long r21; + unsigned long r22; + unsigned long r23; + unsigned long r24; + unsigned long r25; + unsigned long r26; + unsigned long r27; + unsigned long r28; + unsigned long gp; + unsigned long usp; + unsigned long pc; + unsigned long ps; +}; + +struct machine_specific { + struct sw64_pt_regs *panic_task_regs; +}; + +#ifdef roundup +#undef roundup +#endif +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif /* SW_64 */ #ifdef PPC #define _32BIT_ #define MACHINE_TYPE "PPC" @@ -4723,6 +4821,10 @@ struct machine_specific { #define MAX_HEXADDR_STRLEN (16) #define UVADDR_PRLEN (11) #endif +#ifdef SW_64 +#define MAX_HEXADDR_STRLEN (16) +#define UVADDR_PRLEN (11) +#endif #ifdef PPC #define MAX_HEXADDR_STRLEN (8) #define UVADDR_PRLEN (8) @@ -4962,6 +5064,12 @@ static inline unsigned int __const_hweight8(unsigned long w) #define SA_SHIRQ 0x40000000 #endif +#ifdef SW_64 +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x40000000 +#endif + #ifdef PPC #define SA_PROBE SA_ONESHOT #define SA_SAMPLE_RANDOM SA_RESTART @@ -5358,6 +5466,9 @@ void dump_build_data(void); #ifdef ALPHA #define machdep_init(X) alpha_init(X) #endif +#ifdef SW_64 +#define machdep_init(X) sw64_init(X) +#endif #ifdef PPC #define machdep_init(X) ppc_init(X) #endif @@ -5849,6 +5960,9 @@ void display_help_screen(char *); #ifdef ALPHA #define dump_machdep_table(X) alpha_dump_machdep_table(X) #endif +#ifdef SW_64 +#define dump_machdep_table(X) sw64_dump_machdep_table(X) +#endif #ifdef PPC #define dump_machdep_table(X) ppc_dump_machdep_table(X) #endif @@ -6307,6 +6421,18 @@ void alpha_dump_machdep_table(ulong); (task_to_context(X)->processor == 0)) #endif +/* + * sw_64.c + */ +#ifdef SW_64 +void sw64_init(int); +void sw64_dump_machdep_table(ulong); +#define display_idt_table() \ + error(FATAL, "-d option is not applicable to alpha architecture\n") + +#define HWRESET_TASK(X) ((machdep->flags & HWRESET) && is_task_active(X)) +#endif + /* * x86.c */ diff --git a/diskdump.c b/diskdump.c index 0fe46f4..71dcc6d 100644 --- a/diskdump.c +++ b/diskdump.c @@ -29,6 +29,7 @@ #include "vmcore.h" #define BITMAP_SECT_LEN 4096 +#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) struct diskdump_data { char *filename; @@ -198,7 +199,7 @@ resize_note_pointers: * within this file, resize the arrays accordingly. */ if (machine_type("X86_64") || machine_type("X86") || - machine_type("ARM64")) { + machine_type("ARM64") || machine_type("SW_64")) { if ((dd->nt_prstatus_percpu = realloc(dd->nt_prstatus_percpu, dd->num_prstatus_notes * sizeof(void *))) == NULL) error(FATAL, @@ -309,6 +310,80 @@ dump_is_partial(const struct disk_dump_header *header) divideup(divideup(dd->max_mapnr, 8), dd->block_size) * 2; } +int set_disp_mode(int fd,int option) +{ + int err; + struct termios term; + if(tcgetattr(fd,&term)==-1){ + perror("Cannot get the attribution of the terminal"); + return 1; + } + if(option) + term.c_lflag|=ECHOFLAGS; + else + term.c_lflag &=~ECHOFLAGS; + err=tcsetattr(fd,TCSAFLUSH,&term); + if(err==-1 && err==EINTR){ + perror("Cannot set the attribution of the terminal"); + return 1; + } + return 0; +} + +int _try_decrypt(int fd, char *file) +{ + int ret; + FILE * fp; + char cmd[1024]; + char password[1024]; + char header[8]; + if (lseek(fd, 0, SEEK_SET) == -1) { + if (CRASHDEBUG(1)) + error(INFO, "diskdump / compressed kdump: cannot lseek dump header\n"); + return -1; + } + if (read(fd, header, 8) < 8) { + if (CRASHDEBUG(1)) + error(INFO, "diskdump / compressed kdump: cannot read dump header\n"); + return -1; + } + if(strncmp("Salted__", &header, 8) != 0){ + if (lseek(fd, 0, SEEK_SET) == -1) { + if (CRASHDEBUG(1)) + error(INFO, "diskdump / compressed kdump: cannot lseek dump header\n"); + return -1; + } + return fd; + } + close(fd); + printf("enter des-ede3-cbc decryption password:\n"); + memset(password, 0, 1024); + set_disp_mode(STDIN_FILENO,0); + scanf("%s", &password); + set_disp_mode(STDIN_FILENO,1); + + printf("decrypting...\n"); + memset(cmd, 0, 1024); + sprintf(cmd, + "openssl enc -d -des3 -salt -k %s -iter 2 -pbkdf2 -in %s -out /tmp/tmp.raw\n", + password, file); + fp = popen(cmd, "r"); + ret = pclose(fp); + if(ret != 0){ + error(INFO, "exec openssl error. %s\n", + strerror(errno)); + return -1; + } + printf("decrypt finish.\n"); + + fd = open("/tmp/tmp.raw", O_RDONLY); + if (fd < 0) { + error(INFO, "diskdump / compressed kdump: unable to open dump file %s\n", file); + return -1; + } + return fd; +} + static int open_dump_file(char *file) { @@ -323,6 +398,10 @@ open_dump_file(char *file) if (KDUMP_SPLIT()) dd = calloc(1, sizeof(*dd)); + fd = _try_decrypt(fd, file); + if(fd == -1) + return FALSE; + dd->dfd = fd; return TRUE; } @@ -683,6 +762,9 @@ restart: else if (STRNEQ(header->utsname.machine, "riscv64") && machine_type_mismatch(file, "RISCV64", NULL, 0)) goto err; + else if (STRNEQ(header->utsname.machine, "sw_64") && + machine_type_mismatch(file, "SW_64", NULL, 0)) + goto err; if (header->block_size != block_size) { block_size = header->block_size; @@ -702,7 +784,8 @@ restart: DISKDUMP_VALID() ? "diskdump" : "compressed kdump", header->nr_cpus); if (!machine_type("S390") && !machine_type("S390X") && - !machine_type("X86") && !machine_type("X86_64")) { + !machine_type("X86") && !machine_type("X86_64") && + !machine_type("SW_64")) { if (DISKDUMP_VALID()) goto err; } @@ -825,6 +908,8 @@ restart: dd->machine_type = EM_ARM; else if (machine_type("MIPS") || machine_type("MIPS64")) dd->machine_type = EM_MIPS; + else if (machine_type("ALPHA")) + dd->machine_type = EM_ALPHA; else if (machine_type("X86")) dd->machine_type = EM_386; else if (machine_type("X86_64")) @@ -843,6 +928,8 @@ restart: dd->machine_type = EM_SPARCV9; else if (machine_type("RISCV64")) dd->machine_type = EM_RISCV; + else if (machine_type("SW_64")) + dd->machine_type = EM_SW_64; else { error(INFO, "%s: unsupported machine type: %s\n", DISKDUMP_VALID() ? "diskdump" : "compressed kdump", @@ -1628,6 +1715,12 @@ get_diskdump_regs_sparc64(struct bt_info *bt, ulong *eip, ulong *esp) machdep->get_stack_frame(bt, eip, esp); } +static void +get_diskdump_regs_sw64(struct bt_info *bt, ulong *eip, ulong *esp) +{ + machdep->get_stack_frame(bt, eip, esp); +} + /* * Send the request to the proper architecture hander. */ @@ -1686,6 +1779,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp) get_diskdump_regs_riscv64(bt, eip, esp); break; + case EM_SW_64: + get_diskdump_regs_sw64(bt, eip, esp); + break; + default: error(FATAL, "%s: unsupported machine type: %s\n", DISKDUMP_VALID() ? "diskdump" : "compressed kdump", @@ -1833,7 +1930,7 @@ dump_note_offsets(FILE *fp) if (machine_type("X86_64") || machine_type("S390X") || machine_type("ARM64") || machine_type("PPC64") || machine_type("SPARC64") || machine_type("MIPS64") || - machine_type("RISCV64")) { + machine_type("RISCV64") || machine_type("SW_64")) { note64 = (void *)dd->notes_buf + tot; len = sizeof(Elf64_Nhdr); if (STRNEQ((char *)note64 + len, "QEMU")) @@ -2590,6 +2687,64 @@ diskdump_display_regs(int cpu, FILE *ofp) UINT(user_regs + sizeof(ulong) * 34)); } + if (machine_type("SW_64")) { + note64 = dd->nt_prstatus_percpu[cpu]; + len = sizeof(Elf64_Nhdr); + len = roundup(len + note64->n_namesz, 4); + len = roundup(len + note64->n_descsz, 4); + if (!valid_note_address((unsigned char *)note64 + len)) { + error(INFO, "invalid NT_PRSTATUS note for cpu %d\n", cpu); + return; + } + user_regs = (char *)note64 + len - SIZE(elf_prstatus) + OFFSET(elf_prstatus_pr_reg); + fprintf(ofp, + " v0: %016lx t0: %016lx t1: %016lx\n" + " t2: %016lx t3: %016lx t4: %016lx\n" + " t5: %016lx t6: %016lx t7: %016lx\n" + " r9: %016lx r10: %016lx r11: %016lx\n" + " r12: %016lx r13: %016lx r14: %016lx\n" + " r15: %016lx r16: %016lx r17: %016lx\n" + " r18: %016lx a3: %016lx a4: %016lx\n" + " a5: %016lx t8: %016lx t9: %016lx\n" + " t10: %016lx t11: %016lx ra: %016lx\n" + " pv: %016lx at: %016lx gp: %016lx\n" + " usp: %016lx pc: %016lx unique: %016lx\n", + ULONG(user_regs + sizeof(ulong) * 0), + ULONG(user_regs + sizeof(ulong) * 1), + ULONG(user_regs + sizeof(ulong) * 2), + ULONG(user_regs + sizeof(ulong) * 3), + ULONG(user_regs + sizeof(ulong) * 4), + ULONG(user_regs + sizeof(ulong) * 5), + ULONG(user_regs + sizeof(ulong) * 6), + ULONG(user_regs + sizeof(ulong) * 7), + ULONG(user_regs + sizeof(ulong) * 8), + ULONG(user_regs + sizeof(ulong) * 9), + ULONG(user_regs + sizeof(ulong) * 10), + ULONG(user_regs + sizeof(ulong) * 11), + ULONG(user_regs + sizeof(ulong) * 12), + ULONG(user_regs + sizeof(ulong) * 13), + ULONG(user_regs + sizeof(ulong) * 14), + ULONG(user_regs + sizeof(ulong) * 15), + ULONG(user_regs + sizeof(ulong) * 16), + ULONG(user_regs + sizeof(ulong) * 17), + ULONG(user_regs + sizeof(ulong) * 18), + ULONG(user_regs + sizeof(ulong) * 19), + ULONG(user_regs + sizeof(ulong) * 20), + ULONG(user_regs + sizeof(ulong) * 21), + ULONG(user_regs + sizeof(ulong) * 22), + ULONG(user_regs + sizeof(ulong) * 23), + ULONG(user_regs + sizeof(ulong) * 24), + ULONG(user_regs + sizeof(ulong) * 25), + ULONG(user_regs + sizeof(ulong) * 26), + ULONG(user_regs + sizeof(ulong) * 27), + ULONG(user_regs + sizeof(ulong) * 28), + ULONG(user_regs + sizeof(ulong) * 29), + ULONG(user_regs + sizeof(ulong) * 30), + ULONG(user_regs + sizeof(ulong) * 31), + ULONG(user_regs + sizeof(ulong) * 32) + ); + } + if (machine_type("X86")) { note32 = dd->nt_prstatus_percpu[cpu]; len = sizeof(Elf32_Nhdr); @@ -2641,7 +2796,7 @@ dump_registers_for_compressed_kdump(void) !(machine_type("X86") || machine_type("X86_64") || machine_type("ARM64") || machine_type("PPC64") || machine_type("MIPS") || machine_type("MIPS64") || - machine_type("RISCV64"))) + machine_type("RISCV64") || machine_type("SW_64"))) error(FATAL, "-r option not supported for this dumpfile\n"); if (machine_type("ARM64") && (kt->cpus != dd->num_prstatus_notes)) diff --git a/extensions/Makefile b/extensions/Makefile index a608073..af3a593 100644 --- a/extensions/Makefile +++ b/extensions/Makefile @@ -30,7 +30,10 @@ all: link_defs $(CONTRIB_SO) link_defs: @rm -f defs.h - @ln ../defs.h + @ln ../defs.h defs.h + +defs.h: + @ln ../defs.h defs.h $(CONTRIB_SO): %.so: %.c defs.h @if [ -f $*.mk ]; then \ diff --git a/gdb-10.2.patch b/gdb-10.2.patch index d81030d..bf62a2b 100644 --- a/gdb-10.2.patch +++ b/gdb-10.2.patch @@ -1,3026 +1,99460 @@ - -# When this file is updated in an existing source tree, it gets re-applied -# during the next build using "patch -N --fuzz=0", which ignores patches -# that have already been applied. However, if a gdb file has been modified -# multiple times, the subsequent patching may fail to recognize that a -# given patch has been previously applied, and will attempt to re-apply it. -# To prevent any unintended consequences, this file also acts as a -# shell script that can restore any gdb file to its original state prior -# to all subsequent patch applications. - -tar xvzmf gdb-10.2.tar.gz \ - gdb-10.2/gdb/symtab.c \ - gdb-10.2/gdb/printcmd.c \ - gdb-10.2/gdb/symfile.c \ - gdb-10.2/gdb/Makefile.in \ - gdb-10.2/gdb/dwarf2/read.c \ - gdb-10.2/gdb/ada-lang.c - -exit 0 - ---- gdb-10.2/Makefile.in.orig -+++ gdb-10.2/Makefile.in -@@ -340,6 +340,9 @@ AR_FOR_BUILD = @AR_FOR_BUILD@ - AS_FOR_BUILD = @AS_FOR_BUILD@ - CC_FOR_BUILD = @CC_FOR_BUILD@ - CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ -+ifeq (${CRASH_TARGET}, PPC64) -+CFLAGS_FOR_BUILD += -m64 -fPIC -+endif - CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@ - CXX_FOR_BUILD = @CXX_FOR_BUILD@ - DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@ -@@ -406,6 +409,9 @@ GNATBIND = @GNATBIND@ - GNATMAKE = @GNATMAKE@ - - CFLAGS = @CFLAGS@ -+ifeq (${CRASH_TARGET}, PPC64) -+CFLAGS += -m64 -fPIC -+endif - LDFLAGS = @LDFLAGS@ - LIBCFLAGS = $(CFLAGS) - CXXFLAGS = @CXXFLAGS@ ---- gdb-10.2/gdb/Makefile.in.orig -+++ gdb-10.2/gdb/Makefile.in -@@ -571,7 +571,7 @@ CONFIG_DEP_SUBDIR = $(addsuffix /$(DEPDIR),$(CONFIG_SRC_SUBDIR)) - # It is also possible that you will need to add -I/usr/include/sys if - # your system doesn't have fcntl.h in /usr/include (which is where it - # should be according to Posix). --DEFS = @DEFS@ -+DEFS = -DCRASH_MERGE @DEFS@ - GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/config \ - -DLOCALEDIR="\"$(localedir)\"" $(DEFS) - -@@ -1135,6 +1135,7 @@ COMMON_SFILES = \ - symmisc.c \ - symtab.c \ - target.c \ -+ ../../crash_target.c \ - target-connection.c \ - target-dcache.c \ - target-descriptions.c \ -@@ -1564,7 +1565,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ - $(SUBDIR_TARGET_OBS) \ - $(SUBDIR_GCC_COMPILE_OBS) - --SUBDIRS = doc @subdirs@ data-directory -+SUBDIRS = build_no_subdirs - CLEANDIRS = $(SUBDIRS) - - # List of subdirectories in the build tree that must exist. -@@ -1606,8 +1607,8 @@ generated_files = \ - # Flags needed to compile Python code - PYTHON_CFLAGS = @PYTHON_CFLAGS@ +diff -Nuar gdb-10.2/bfd/archures.c gdb-10.2/bfd/archures.c +--- gdb-10.2/bfd/archures.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/archures.c 2025-04-16 17:06:51.902086800 +0800 +@@ -308,6 +308,9 @@ + .#define bfd_mach_alpha_ev4 0x10 + .#define bfd_mach_alpha_ev5 0x20 + .#define bfd_mach_alpha_ev6 0x30 ++. bfd_arch_sw_64, {* Sw_64 *} ++.#define bfd_mach_sw_64_sw6a 0x32 ++.#define bfd_mach_sw_64_sw6b 0x33 + . bfd_arch_arm, {* Advanced Risc Machines ARM. *} + .#define bfd_mach_arm_unknown 0 + .#define bfd_mach_arm_2 1 +@@ -611,6 +614,7 @@ --all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb -- @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do -+all: gdb$(EXEEXT) gdb-gdb.py gdb-gdb.gdb -+ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do + extern const bfd_arch_info_type bfd_aarch64_arch; + extern const bfd_arch_info_type bfd_alpha_arch; ++extern const bfd_arch_info_type bfd_sw_64_arch; + extern const bfd_arch_info_type bfd_arc_arch; + extern const bfd_arch_info_type bfd_arm_arch; + extern const bfd_arch_info_type bfd_avr_arch; +@@ -700,6 +704,7 @@ + #else + &bfd_aarch64_arch, + &bfd_alpha_arch, ++ &bfd_sw_64_arch, + &bfd_arc_arch, + &bfd_arm_arch, + &bfd_avr_arch, +diff -Nuar gdb-10.2/bfd/bfd-in2.h gdb-10.2/bfd/bfd-in2.h +--- gdb-10.2/bfd/bfd-in2.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/bfd-in2.h 2025-04-16 17:06:51.902086800 +0800 +@@ -1708,6 +1708,9 @@ + #define bfd_mach_alpha_ev4 0x10 + #define bfd_mach_alpha_ev5 0x20 + #define bfd_mach_alpha_ev6 0x30 ++ bfd_arch_sw_64, /* Sw_64 */ ++#define bfd_mach_sw_64_sw6a 0x32 ++#define bfd_mach_sw_64_sw6b 0x33 + bfd_arch_arm, /* Advanced Risc Machines ARM. */ + #define bfd_mach_arm_unknown 0 + #define bfd_mach_arm_2 1 +@@ -2326,6 +2329,10 @@ + displacement is used on the Alpha. */ + BFD_RELOC_32_PCREL_S2, + BFD_RELOC_16_PCREL_S2, ++#ifndef XWB20200308 ++ BFD_RELOC_20_PCREL_S2, ++ BFD_RELOC_24_PCREL_S2, ++#endif + BFD_RELOC_23_PCREL_S2, - # Rule for compiling .c files in the top-level gdb directory. - # The order-only dependencies ensure that we create the build subdirectories. -@@ -1864,9 +1865,10 @@ libgdb.a: $(LIBGDB_OBS) - # Removing the old gdb first works better if it is running, at least on SunOS. - gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS) - $(SILENCE) rm -f gdb$(EXEEXT) -+ @(cd ../..; make --no-print-directory GDB_FLAGS=-DGDB_10_2 library) - $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ -- -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \ -- $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) -+ -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \ -+ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs) - ifneq ($(CODESIGN_CERT),) - $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT) - endif -@@ -2530,9 +2532,9 @@ ifeq ($(DEPMODE),depmode=gcc3) - # into place if the compile succeeds. We need this because gcc does - # not atomically write the dependency output file. - override COMPILE.post = -c -o $@ -MT $@ -MMD -MP \ -- -MF $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo --override POSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo \ -- $(@D)/$(DEPDIR)/$(basename $(@F)).Po -+ -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo -+override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo \ -+ $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Po - else - override COMPILE.pre = source='$<' object='$@' libtool=no \ - DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \ ---- gdb-10.2/gdb/cli/cli-cmds.c.orig -+++ gdb-10.2/gdb/cli/cli-cmds.c -@@ -435,6 +435,11 @@ complete_command (const char *arg, int from_tty) - } - } + /* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of +@@ -2547,6 +2554,99 @@ + BFD_RELOC_ALPHA_TPREL_LO16, + BFD_RELOC_ALPHA_TPREL16, -+#ifdef CRASH_MERGE -+static int crash_from_tty = 0; -+extern "C" void untrusted_file(FILE *, char *); -+#endif ++/* Sw_64 ECOFF and ELF relocations. Some of these treat the symbol or ++"addend" in some special way. ++For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when ++writing; when reading, it will be the absolute section symbol. The ++addend is the displacement in bytes of the "lda" instruction from ++the "ldah" instruction (which is at the address of this reloc). */ ++ BFD_RELOC_SW_64_GPDISP_HI16, + - int - is_complete_command (struct cmd_list_element *c) - { -@@ -654,8 +659,32 @@ find_and_open_script (const char *script_file, int search_path) - close (fd); - errno = save_errno; - } -- else -- opened.emplace (gdb_file_up (result), std::move (full_path)); -+#ifdef CRASH_MERGE -+ /* -+ * Only allow trusted versions of .gdbinit files to be -+ * sourced during session initialization. -+ */ -+ if (crash_from_tty == -1) ++/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as ++with GPDISP_HI16 relocs. The addend is ignored when writing the ++relocations out, and is filled in with the file's GP value on ++reading, for convenience. */ ++ BFD_RELOC_SW_64_GPDISP_LO16, ++/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 ++relocation except that there is no accompanying GPDISP_LO16 ++relocation. */ ++ BFD_RELOC_SW_64_GPDISP, ++/*> The Sw_64 LITERAL/LITUSE relocs are produced by a symbol reference; ++> the assembler turns it into a LDQ instruction to load the address of ++> the symbol, and then fills in a register in the real instruction. ++> ++> The LITERAL reloc, at the LDQ instruction, refers to the .lita ++> section symbol. The addend is ignored when writing, but is filled ++> in with the file's GP value on reading, for convenience, as with the ++> GPDISP_LO16 reloc. ++> ++> The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. ++> It should refer to the symbol to be referenced, as with 16_GOTOFF, ++> but it generates output not based on the position within the .got ++> section, but relative to the GP value chosen for the file during the ++> final link stage. ++> ++> The LITUSE reloc, on the instruction using the loaded address, gives ++> information to the linker that it might be able to use to optimize ++> away some literal section references. The symbol is ignored (read ++> as the absolute section symbol), and the "addend" indicates the type ++> of instruction using the register: ++> 1 - "memory" fmt insn ++> 2 - byte-manipulation (byte offset reg) ++> 3 - jsr (target of branch) */ ++ BFD_RELOC_SW_64_LITERAL, ++ BFD_RELOC_SW_64_ELF_LITERAL, ++ BFD_RELOC_SW_64_LITUSE, ++/* The HINT relocation indicates a value that should be filled into the ++"hint" field of a jmp/jsr/ret instruction, for possible branch- ++prediction logic which may be provided on some processors. */ ++ BFD_RELOC_SW_64_HINT, ++ ++/* The LINKAGE relocation outputs a linkage pair in the object file, ++which is filled by the linker. */ ++ BFD_RELOC_SW_64_LINKAGE, ++ ++/* The CODEADDR relocation outputs a STO_CA in the object file, ++which is filled by the linker. */ ++ BFD_RELOC_SW_64_CODEADDR, ++/* The GPREL_HI/LO relocations together form a 32-bit offset from the ++GP register. */ ++ BFD_RELOC_SW_64_GPREL_HI16, ++ BFD_RELOC_SW_64_GPREL_LO16, ++ ++/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must ++share a common GP, and the target address is adjusted forSTO_SW_64_STD_GPLOAD. */ ++ BFD_RELOC_SW_64_BRSGP, ++ ++/* The NOP relocation outputs a NOP if the longword displacementbetween two procedure entry points is < 2^21. */ ++ BFD_RELOC_SW_64_NOP, ++/* The BSR relocation outputs a BSR if the longword displacement ++between two procedure entry points is < 2^21. */ ++ BFD_RELOC_SW_64_BSR, ++ ++/* The LDA relocation outputs a LDA if the longword displacement ++between two procedure entry points is < 2^16. */ ++ BFD_RELOC_SW_64_LDA, ++ ++/* The BOH relocation outputs a BSR if the longword displacement ++between two procedure entry points is < 2^21, or else a hint. */ ++ BFD_RELOC_SW_64_BOH, ++ ++/* Sw_64 thread-local storage relocations. */ ++ BFD_RELOC_SW_64_TLSGD, ++ BFD_RELOC_SW_64_TLSLDM, ++ BFD_RELOC_SW_64_DTPMOD64, ++ BFD_RELOC_SW_64_GOTDTPREL16, ++ BFD_RELOC_SW_64_DTPREL64, ++ BFD_RELOC_SW_64_DTPREL_HI16, ++ BFD_RELOC_SW_64_DTPREL_LO16, ++ BFD_RELOC_SW_64_DTPREL16, ++ BFD_RELOC_SW_64_GOTTPREL16, ++ BFD_RELOC_SW_64_TPREL64, ++ BFD_RELOC_SW_64_TPREL_HI16, ++ BFD_RELOC_SW_64_TPREL_LO16, ++ BFD_RELOC_SW_64_TPREL16, ++ + /* The MIPS jump instruction. */ + BFD_RELOC_MIPS_JMP, + BFD_RELOC_MICROMIPS_JMP, +diff -Nuar gdb-10.2/bfd/coff-sw_64.c gdb-10.2/bfd/coff-sw_64.c +--- gdb-10.2/bfd/coff-sw_64.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/coff-sw_64.c 2025-04-16 17:06:51.902086800 +0800 +@@ -0,0 +1,2467 @@ ++/* BFD back-end for SW_64 Extended-Coff files. ++ Copyright (C) 1993-2019 Free Software Foundation, Inc. ++ Modified from coff-mips.c by Steve Chamberlain and ++ Ian Lance Taylor . ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdlink.h" ++#include "libbfd.h" ++#include "coff/internal.h" ++#include "coff/sym.h" ++#include "coff/symconst.h" ++#include "coff/ecoff.h" ++#include "coff/sw_64.h" ++#include "aout/ar.h" ++#include "libcoff.h" ++#include "libecoff.h" ++ ++/* Prototypes for static functions. */ ++ ++ ++ ++/* ECOFF has COFF sections, but the debugging information is stored in ++ a completely different format. ECOFF targets use some of the ++ swapping routines from coffswap.h, and some of the generic COFF ++ routines in coffgen.c, but, unlike the real COFF targets, do not ++ use coffcode.h itself. ++ ++ Get the generic COFF swapping routines, except for the reloc, ++ symbol, and lineno ones. Give them ecoff names. Define some ++ accessor macros for the large sizes used for Sw_64 ECOFF. */ ++ ++#define GET_FILEHDR_SYMPTR H_GET_64 ++#define PUT_FILEHDR_SYMPTR H_PUT_64 ++#define GET_AOUTHDR_TSIZE H_GET_64 ++#define PUT_AOUTHDR_TSIZE H_PUT_64 ++#define GET_AOUTHDR_DSIZE H_GET_64 ++#define PUT_AOUTHDR_DSIZE H_PUT_64 ++#define GET_AOUTHDR_BSIZE H_GET_64 ++#define PUT_AOUTHDR_BSIZE H_PUT_64 ++#define GET_AOUTHDR_ENTRY H_GET_64 ++#define PUT_AOUTHDR_ENTRY H_PUT_64 ++#define GET_AOUTHDR_TEXT_START H_GET_64 ++#define PUT_AOUTHDR_TEXT_START H_PUT_64 ++#define GET_AOUTHDR_DATA_START H_GET_64 ++#define PUT_AOUTHDR_DATA_START H_PUT_64 ++#define GET_SCNHDR_PADDR H_GET_64 ++#define PUT_SCNHDR_PADDR H_PUT_64 ++#define GET_SCNHDR_VADDR H_GET_64 ++#define PUT_SCNHDR_VADDR H_PUT_64 ++#define GET_SCNHDR_SIZE H_GET_64 ++#define PUT_SCNHDR_SIZE H_PUT_64 ++#define GET_SCNHDR_SCNPTR H_GET_64 ++#define PUT_SCNHDR_SCNPTR H_PUT_64 ++#define GET_SCNHDR_RELPTR H_GET_64 ++#define PUT_SCNHDR_RELPTR H_PUT_64 ++#define GET_SCNHDR_LNNOPTR H_GET_64 ++#define PUT_SCNHDR_LNNOPTR H_PUT_64 ++ ++#define SW_64ECOFF ++ ++#define NO_COFF_RELOCS ++#define NO_COFF_SYMBOLS ++#define NO_COFF_LINENOS ++#define coff_swap_filehdr_in sw_64_ecoff_swap_filehdr_in ++#define coff_swap_filehdr_out sw_64_ecoff_swap_filehdr_out ++#define coff_swap_aouthdr_in sw_64_ecoff_swap_aouthdr_in ++#define coff_swap_aouthdr_out sw_64_ecoff_swap_aouthdr_out ++#define coff_swap_scnhdr_in sw_64_ecoff_swap_scnhdr_in ++#define coff_swap_scnhdr_out sw_64_ecoff_swap_scnhdr_out ++#include "coffswap.h" ++ ++/* Get the ECOFF swapping routines. */ ++#define ECOFF_64 ++#include "ecoffswap.h" ++ ++/* How to process the various reloc types. */ ++ ++static bfd_reloc_status_type ++reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, ++ arelent *reloc ATTRIBUTE_UNUSED, ++ asymbol *sym ATTRIBUTE_UNUSED, ++ void * data ATTRIBUTE_UNUSED, ++ asection *sec ATTRIBUTE_UNUSED, ++ bfd *output_bfd ATTRIBUTE_UNUSED, ++ char **error_message ATTRIBUTE_UNUSED) ++{ ++ return bfd_reloc_ok; ++} ++ ++/* In case we're on a 32-bit machine, construct a 64-bit "-1" value ++ from smaller values. Start with zero, widen, *then* decrement. */ ++#define MINUS_ONE (((bfd_vma)0) - 1) ++ ++static reloc_howto_type sw_64_howto_table[] = ++{ ++ /* Reloc type 0 is ignored by itself. However, it appears after a ++ GPDISP reloc to identify the location where the low order 16 bits ++ of the gp register are loaded. */ ++ HOWTO (SW_64_R_IGNORE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ reloc_nil, /* special_function */ ++ "IGNORE", /* name */ ++ TRUE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A 32 bit reference to a symbol. */ ++ HOWTO (SW_64_R_REFLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "REFLONG", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 64 bit reference to a symbol. */ ++ HOWTO (SW_64_R_REFQUAD, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "REFQUAD", /* name */ ++ TRUE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 32 bit GP relative offset. This is just like REFLONG except ++ that when the value is used the value of the gp register will be ++ added in. */ ++ HOWTO (SW_64_R_GPREL32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "GPREL32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Used for an instruction that refers to memory off the GP ++ register. The offset is 16 bits of the 32 bit instruction. This ++ reloc always seems to be against the .lita section. */ ++ HOWTO (SW_64_R_LITERAL, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "LITERAL", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* This reloc only appears immediately following a LITERAL reloc. ++ It identifies a use of the literal. It seems that the linker can ++ use this to eliminate a portion of the .lita section. The symbol ++ index is special: 1 means the literal address is in the base ++ register of a memory format instruction; 2 means the literal ++ address is in the byte offset register of a byte-manipulation ++ instruction; 3 means the literal address is in the target ++ register of a jsr instruction. This does not actually do any ++ relocation. */ ++ HOWTO (SW_64_R_LITUSE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ reloc_nil, /* special_function */ ++ "LITUSE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Load the gp register. This is always used for a ldah instruction ++ which loads the upper 16 bits of the gp register. The next reloc ++ will be an IGNORE reloc which identifies the location of the lda ++ instruction which loads the lower 16 bits. The symbol index of ++ the GPDISP instruction appears to actually be the number of bytes ++ between the ldah and lda instructions. This gives two different ++ ways to determine where the lda instruction is; I don't know why ++ both are used. The value to use for the relocation is the ++ difference between the GP value and the current location; the ++ load will always be done against a register holding the current ++ address. */ ++ HOWTO (SW_64_R_GPDISP, /* type */ ++ 16, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ reloc_nil, /* special_function */ ++ "GPDISP", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A 21 bit branch. The native assembler generates these for ++ branches within the text segment, and also fills in the PC ++ relative offset in the instruction. */ ++ HOWTO (SW_64_R_BRADDR, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 21, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "BRADDR", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x1fffff, /* src_mask */ ++ 0x1fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A hint for a jump to a register. */ ++ HOWTO (SW_64_R_HINT, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 14, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "HINT", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x3fff, /* src_mask */ ++ 0x3fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* 16 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "SREL16", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* 32 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "SREL32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 64 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL64, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "SREL64", /* name */ ++ TRUE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Push a value on the reloc evaluation stack. */ ++ HOWTO (SW_64_R_OP_PUSH, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "OP_PUSH", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Store the value from the stack at the given address. Store it in ++ a bitfield of size r_size starting at bit position r_offset. */ ++ HOWTO (SW_64_R_OP_STORE, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "OP_STORE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Subtract the reloc address from the value on the top of the ++ relocation stack. */ ++ HOWTO (SW_64_R_OP_PSUB, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "OP_PSUB", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Shift the value on the top of the relocation stack right by the ++ given value. */ ++ HOWTO (SW_64_R_OP_PRSHIFT, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "OP_PRSHIFT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Adjust the GP value for a new range in the object file. */ ++ HOWTO (SW_64_R_GPVALUE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ 0, /* special_function */ ++ "GPVALUE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE) /* pcrel_offset */ ++}; ++ ++/* Recognize an Sw_64 ECOFF file. */ ++ ++static const bfd_target * ++sw_64_ecoff_object_p (bfd *abfd) ++{ ++ static const bfd_target *ret; ++ ++ ret = coff_object_p (abfd); ++ ++ if (ret != NULL) + { -+ struct stat statbuf; -+ FILE *stream = result; -+ int _fd = fileno (stream); -+ if (fstat (_fd, &statbuf) < 0) -+ { -+ perror_with_name (full_path.get()); -+ fclose (stream); -+ return opened; -+ } -+ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH)) -+ { -+ untrusted_file(NULL, full_path.get()); -+ fclose (stream); -+ return opened; -+ } ++ asection *sec; ++ ++ /* Sw_64 ECOFF has a .pdata section. The lnnoptr field of the ++ .pdata section is the number of entries it contains. Each ++ entry takes up 8 bytes. The number of entries is required ++ since the section is aligned to a 16 byte boundary. When we ++ link .pdata sections together, we do not want to include the ++ alignment bytes. We handle this on input by faking the size ++ of the .pdata section to remove the unwanted alignment bytes. ++ On output we will set the lnnoptr field and force the ++ alignment. */ ++ sec = bfd_get_section_by_name (abfd, _PDATA); ++ if (sec != (asection *) NULL) ++ { ++ bfd_size_type size; ++ ++ size = sec->line_filepos * 8; ++ BFD_ASSERT (size == sec->size ++ || size + 8 == sec->size); ++ if (! bfd_set_section_size (sec, size)) ++ return NULL; ++ } + } -+#endif -+ opened.emplace (gdb_file_up (result), std::move (full_path)); + - - return opened; - } -@@ -719,7 +748,11 @@ source_script_with_search (const char *file, int from_tty, int search_path) - If the source command was invoked interactively, throw an - error. Otherwise (e.g. if it was invoked by a script), - just emit a warning, rather than cause an error. */ -+#ifdef CRASH_MERGE -+ if (from_tty > 0) -+#else - if (from_tty) -+#endif - perror_with_name (file); - else - { -@@ -743,7 +776,14 @@ source_script_with_search (const char *file, int from_tty, int search_path) - void - source_script (const char *file, int from_tty) - { -+#ifdef CRASH_MERGE -+ crash_from_tty = from_tty; -+#endif - source_script_with_search (file, from_tty, 0); -+#ifdef CRASH_MERGE -+ crash_from_tty = 0; -+#endif ++ return ret; ++} + - } - - static void ---- gdb-10.2/gdb/defs.h.orig -+++ gdb-10.2/gdb/defs.h -@@ -629,4 +629,7 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what); - - #include "utils.h" - -+#ifdef CRASH_MERGE -+extern "C" int gdb_main_entry(int, char **); -+#endif - #endif /* #ifndef DEFS_H */ ---- gdb-10.2/gdb/dwarf2/read.c.orig -+++ gdb-10.2/gdb/dwarf2/read.c -@@ -3015,7 +3015,11 @@ read_gdb_index_from_buffer (const char *filename, - indices. */ - if (version < 4) - { -+#ifdef CRASH_MERGE -+ static int warning_printed = 1; -+#else - static int warning_printed = 0; -+#endif - if (!warning_printed) - { - warning (_("Skipping obsolete .gdb_index section in %s."), -@@ -3034,7 +3038,11 @@ read_gdb_index_from_buffer (const char *filename, - "set use-deprecated-index-sections on". */ - if (version < 6 && !deprecated_ok) - { -+#ifdef CRASH_MERGE -+ static int warning_printed = 1; -+#else - static int warning_printed = 0; -+#endif - if (!warning_printed) - { - warning (_("\ ---- gdb-10.2/gdb/main.c.orig -+++ gdb-10.2/gdb/main.c -@@ -392,6 +392,14 @@ start_event_loop () - return; - } - -+#ifdef CRASH_MERGE -+extern "C" void update_gdb_hooks(void); -+extern "C" void main_loop(void); -+extern "C" unsigned long crash_get_kaslr_offset(void); -+extern "C" int console(const char *, ...); -+void crash_target_init (void); -+#endif ++/* See whether the magic number matches. */ + - /* Call command_loop. */ - - /* Prevent inlining this function for the benefit of GDB's selftests -@@ -925,7 +933,11 @@ captured_main_1 (struct captured_main_args *context) - } - } - -+#ifdef CRASH_MERGE -+ save_original_signals_state (1); -+#else - save_original_signals_state (quiet); -+#endif - - /* Try to set up an alternate signal stack for SIGSEGV handlers. */ - gdb::alternate_signal_stack signal_stack; -@@ -999,7 +1011,7 @@ captured_main_1 (struct captured_main_args *context) - { - print_gdb_version (gdb_stdout, false); - wrap_here (""); -- printf_filtered ("\n"); -+ printf_filtered ("\n\n"); - exit (0); - } - -@@ -1038,6 +1050,10 @@ captured_main_1 (struct captured_main_args *context) - look at things by now. Initialize the default interpreter. */ - set_top_level_interpreter (interpreter_p); - -+#ifdef CRASH_MERGE -+ update_gdb_hooks(); -+#endif ++static bfd_boolean ++sw_64_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, ++ void * filehdr) ++{ ++ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; + - /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets - GDB retain the old MI1 interpreter startup behavior. Output the - copyright message after the interpreter is installed when it is -@@ -1066,7 +1082,11 @@ captured_main_1 (struct captured_main_args *context) - if (!system_gdbinit.empty () && !inhibit_gdbinit) - { - for (const std::string &file : system_gdbinit) -+#ifdef CRASH_MERGE -+ ret = catch_command_errors (source_script, file.c_str (), -1); -+#else - ret = catch_command_errors (source_script, file.c_str (), 0); -+#endif - } - - /* Read and execute $HOME/.gdbinit file, if it exists. This is done -@@ -1075,7 +1095,11 @@ captured_main_1 (struct captured_main_args *context) - debugging or what directory you are in. */ - - if (!home_gdbinit.empty () && !inhibit_gdbinit && !inhibit_home_gdbinit) -+#ifdef CRASH_MERGE -+ ret = catch_command_errors (source_script, home_gdbinit.c_str (), -1); -+#else - ret = catch_command_errors (source_script, home_gdbinit.c_str (), 0); -+#endif - - /* Process '-ix' and '-iex' options early. */ - for (i = 0; i < cmdarg_vec.size (); i++) -@@ -1121,7 +1145,11 @@ captured_main_1 (struct captured_main_args *context) - !batch_flag); - if (ret != 0) - ret = catch_command_errors (symbol_file_add_main_adapter, -+#ifdef CRASH_MERGE -+ symarg, 0); -+#else - symarg, !batch_flag); -+#endif - } - else - { -@@ -1191,7 +1219,11 @@ captured_main_1 (struct captured_main_args *context) - { - auto_load_local_gdbinit_loaded = 1; - -+#ifdef CRASH_MERGE -+ ret = catch_command_errors (source_script, local_gdbinit.c_str (), -1); -+#else - ret = catch_command_errors (source_script, local_gdbinit.c_str (), 0); ++ if (! SW_64_ECOFF_BADMAG (*internal_f)) ++ return TRUE; ++ ++ if (SW_64_ECOFF_COMPRESSEDMAG (*internal_f)) ++ _bfd_error_handler ++ (_("%pB: cannot handle compressed Sw_64 binaries; " ++ "use compiler flags, or objZ, to generate uncompressed binaries"), ++ abfd); ++ ++ return FALSE; ++} ++ ++/* This is a hook called by coff_real_object_p to create any backend ++ specific information. */ ++ ++static void * ++sw_64_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) ++{ ++ void * ecoff; ++ ++ ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr); ++ ++ if (ecoff != NULL) ++ { ++ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; ++ ++ /* Set additional BFD flags according to the object type from the ++ machine specific file header flags. */ ++ switch (internal_f->f_flags & F_SW_64_OBJECT_TYPE_MASK) ++ { ++ case F_SW_64_SHARABLE: ++ abfd->flags |= DYNAMIC; ++ break; ++ case F_SW_64_CALL_SHARED: ++ /* Always executable if using shared libraries as the run time ++ loader might resolve undefined references. */ ++ abfd->flags |= (DYNAMIC | EXEC_P); ++ break; ++ } ++ } ++ return ecoff; ++} ++ ++/* Reloc handling. */ ++ ++/* Swap a reloc in. */ ++ ++static void ++sw_64_ecoff_swap_reloc_in (bfd *abfd, ++ void * ext_ptr, ++ struct internal_reloc *intern) ++{ ++ const RELOC *ext = (RELOC *) ext_ptr; ++ ++ intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr); ++ intern->r_symndx = H_GET_32 (abfd, ext->r_symndx); ++ ++ BFD_ASSERT (bfd_header_little_endian (abfd)); ++ ++ intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) ++ >> RELOC_BITS0_TYPE_SH_LITTLE); ++ intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; ++ intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) ++ >> RELOC_BITS1_OFFSET_SH_LITTLE); ++ /* Ignored the reserved bits. */ ++ intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) ++ >> RELOC_BITS3_SIZE_SH_LITTLE); ++ ++ if (intern->r_type == SW_64_R_LITUSE ++ || intern->r_type == SW_64_R_GPDISP) ++ { ++ /* Handle the LITUSE and GPDISP relocs specially. Its symndx ++ value is not actually a symbol index, but is instead a ++ special code. We put the code in the r_size field, and ++ clobber the symndx. */ ++ if (intern->r_size != 0) ++ abort (); ++ intern->r_size = intern->r_symndx; ++ intern->r_symndx = RELOC_SECTION_NONE; ++ } ++ else if (intern->r_type == SW_64_R_IGNORE) ++ { ++ /* The IGNORE reloc generally follows a GPDISP reloc, and is ++ against the .lita section. The section is irrelevant. */ ++ if (! intern->r_extern && ++ intern->r_symndx == RELOC_SECTION_ABS) ++ abort (); ++ if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA) ++ intern->r_symndx = RELOC_SECTION_ABS; ++ } ++} ++ ++/* Swap a reloc out. */ ++ ++static void ++sw_64_ecoff_swap_reloc_out (bfd *abfd, ++ const struct internal_reloc *intern, ++ void * dst) ++{ ++ RELOC *ext = (RELOC *) dst; ++ long symndx; ++ unsigned char size; ++ ++ /* Undo the hackery done in swap_reloc_in. */ ++ if (intern->r_type == SW_64_R_LITUSE ++ || intern->r_type == SW_64_R_GPDISP) ++ { ++ symndx = intern->r_size; ++ size = 0; ++ } ++ else if (intern->r_type == SW_64_R_IGNORE ++ && ! intern->r_extern ++ && intern->r_symndx == RELOC_SECTION_ABS) ++ { ++ symndx = RELOC_SECTION_LITA; ++ size = intern->r_size; ++ } ++ else ++ { ++ symndx = intern->r_symndx; ++ size = intern->r_size; ++ } ++ ++ /* XXX FIXME: The maximum symndx value used to be 14 but this ++ fails with object files produced by DEC's C++ compiler. ++ Where does the value 14 (or 15) come from anyway ? */ ++ BFD_ASSERT (intern->r_extern ++ || (intern->r_symndx >= 0 && intern->r_symndx <= 15)); ++ ++ H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr); ++ H_PUT_32 (abfd, symndx, ext->r_symndx); ++ ++ BFD_ASSERT (bfd_header_little_endian (abfd)); ++ ++ ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE) ++ & RELOC_BITS0_TYPE_LITTLE); ++ ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) ++ | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) ++ & RELOC_BITS1_OFFSET_LITTLE)); ++ ext->r_bits[2] = 0; ++ ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE) ++ & RELOC_BITS3_SIZE_LITTLE); ++} ++ ++/* Finish canonicalizing a reloc. Part of this is generic to all ++ ECOFF targets, and that part is in ecoff.c. The rest is done in ++ this backend routine. It must fill in the howto field. */ ++ ++static void ++sw_64_adjust_reloc_in (bfd *abfd, ++ const struct internal_reloc *intern, ++ arelent *rptr) ++{ ++ if (intern->r_type > SW_64_R_GPVALUE) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), ++ abfd, intern->r_type); ++ bfd_set_error (bfd_error_bad_value); ++ rptr->addend = 0; ++ rptr->howto = NULL; ++ return; ++ } ++ ++ switch (intern->r_type) ++ { ++ case SW_64_R_BRADDR: ++ case SW_64_R_SREL16: ++ case SW_64_R_SREL32: ++ case SW_64_R_SREL64: ++ /* This relocs appear to be fully resolved when they are against ++ internal symbols. Against external symbols, BRADDR at least ++ appears to be resolved against the next instruction. */ ++ if (! intern->r_extern) ++ rptr->addend = 0; ++ else ++ rptr->addend = - (intern->r_vaddr + 4); ++ break; ++ ++ case SW_64_R_GPREL32: ++ case SW_64_R_LITERAL: ++ /* Copy the gp value for this object file into the addend, to ++ ensure that we are not confused by the linker. */ ++ if (! intern->r_extern) ++ rptr->addend += ecoff_data (abfd)->gp; ++ break; ++ ++ case SW_64_R_LITUSE: ++ case SW_64_R_GPDISP: ++ /* The LITUSE and GPDISP relocs do not use a symbol, or an ++ addend, but they do use a special code. Put this code in the ++ addend field. */ ++ rptr->addend = intern->r_size; ++ break; ++ ++ case SW_64_R_OP_STORE: ++ /* The STORE reloc needs the size and offset fields. We store ++ them in the addend. */ ++ BFD_ASSERT (intern->r_offset <= 256); ++ rptr->addend = (intern->r_offset << 8) + intern->r_size; ++ break; ++ ++ case SW_64_R_OP_PUSH: ++ case SW_64_R_OP_PSUB: ++ case SW_64_R_OP_PRSHIFT: ++ /* The PUSH, PSUB and PRSHIFT relocs do not actually use an ++ address. I believe that the address supplied is really an ++ addend. */ ++ rptr->addend = intern->r_vaddr; ++ break; ++ ++ case SW_64_R_GPVALUE: ++ /* Set the addend field to the new GP value. */ ++ rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp; ++ break; ++ ++ case SW_64_R_IGNORE: ++ /* If the type is SW_64_R_IGNORE, make sure this is a reference ++ to the absolute section so that the reloc is ignored. For ++ some reason the address of this reloc type is not adjusted by ++ the section vma. We record the gp value for this object file ++ here, for convenience when doing the GPDISP relocation. */ ++ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; ++ rptr->address = intern->r_vaddr; ++ rptr->addend = ecoff_data (abfd)->gp; ++ break; ++ ++ default: ++ break; ++ } ++ ++ rptr->howto = &sw_64_howto_table[intern->r_type]; ++} ++ ++/* When writing out a reloc we need to pull some values back out of ++ the addend field into the reloc. This is roughly the reverse of ++ sw_64_adjust_reloc_in, except that there are several changes we do ++ not need to undo. */ ++ ++static void ++sw_64_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, ++ const arelent *rel, ++ struct internal_reloc *intern) ++{ ++ switch (intern->r_type) ++ { ++ case SW_64_R_LITUSE: ++ case SW_64_R_GPDISP: ++ intern->r_size = rel->addend; ++ break; ++ ++ case SW_64_R_OP_STORE: ++ intern->r_size = rel->addend & 0xff; ++ intern->r_offset = (rel->addend >> 8) & 0xff; ++ break; ++ ++ case SW_64_R_OP_PUSH: ++ case SW_64_R_OP_PSUB: ++ case SW_64_R_OP_PRSHIFT: ++ intern->r_vaddr = rel->addend; ++ break; ++ ++ case SW_64_R_IGNORE: ++ intern->r_vaddr = rel->address; ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/* The size of the stack for the relocation evaluator. */ ++#define RELOC_STACKSIZE (10) ++ ++/* Sw_64 ECOFF relocs have a built in expression evaluator as well as ++ other interdependencies. Rather than use a bunch of special ++ functions and global variables, we use a single routine to do all ++ the relocation for a section. I haven't yet worked out how the ++ assembler is going to handle this. */ ++ ++static bfd_byte * ++sw_64_ecoff_get_relocated_section_contents (bfd *abfd, ++ struct bfd_link_info *link_info, ++ struct bfd_link_order *link_order, ++ bfd_byte *data, ++ bfd_boolean relocatable, ++ asymbol **symbols) ++{ ++ bfd *input_bfd = link_order->u.indirect.section->owner; ++ asection *input_section = link_order->u.indirect.section; ++ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); ++ arelent **reloc_vector = NULL; ++ long reloc_count; ++ bfd *output_bfd = relocatable ? abfd : (bfd *) NULL; ++ bfd_vma gp; ++ bfd_size_type sz; ++ bfd_boolean gp_undefined; ++ bfd_vma stack[RELOC_STACKSIZE]; ++ int tos = 0; ++ ++ if (reloc_size < 0) ++ goto error_return; ++ reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); ++ if (reloc_vector == NULL && reloc_size != 0) ++ goto error_return; ++ ++ sz = input_section->rawsize ? input_section->rawsize : input_section->size; ++ if (! bfd_get_section_contents (input_bfd, input_section, data, 0, sz)) ++ goto error_return; ++ ++ reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, ++ reloc_vector, symbols); ++ if (reloc_count < 0) ++ goto error_return; ++ if (reloc_count == 0) ++ goto successful_return; ++ ++ /* Get the GP value for the output BFD. */ ++ gp_undefined = FALSE; ++ gp = _bfd_get_gp_value (abfd); ++ if (gp == 0) ++ { ++ if (relocatable) ++ { ++ asection *sec; ++ bfd_vma lo; ++ ++ /* Make up a value. */ ++ lo = (bfd_vma) -1; ++ for (sec = abfd->sections; sec != NULL; sec = sec->next) ++ { ++ if (sec->vma < lo ++ && (strcmp (sec->name, ".sbss") == 0 ++ || strcmp (sec->name, ".sdata") == 0 ++ || strcmp (sec->name, ".lit4") == 0 ++ || strcmp (sec->name, ".lit8") == 0 ++ || strcmp (sec->name, ".lita") == 0)) ++ lo = sec->vma; ++ } ++ gp = lo + 0x8000; ++ _bfd_set_gp_value (abfd, gp); ++ } ++ else ++ { ++ struct bfd_link_hash_entry *h; ++ ++ h = bfd_link_hash_lookup (link_info->hash, "_gp", FALSE, FALSE, ++ TRUE); ++ if (h == (struct bfd_link_hash_entry *) NULL ++ || h->type != bfd_link_hash_defined) ++ gp_undefined = TRUE; ++ else ++ { ++ gp = (h->u.def.value ++ + h->u.def.section->output_section->vma ++ + h->u.def.section->output_offset); ++ _bfd_set_gp_value (abfd, gp); ++ } ++ } ++ } ++ ++ for (; *reloc_vector != (arelent *) NULL; reloc_vector++) ++ { ++ arelent *rel; ++ bfd_reloc_status_type r; ++ char *err; ++ ++ rel = *reloc_vector; ++ r = bfd_reloc_ok; ++ switch (rel->howto->type) ++ { ++ case SW_64_R_IGNORE: ++ rel->address += input_section->output_offset; ++ break; ++ ++ case SW_64_R_REFLONG: ++ case SW_64_R_REFQUAD: ++ case SW_64_R_BRADDR: ++ case SW_64_R_HINT: ++ case SW_64_R_SREL16: ++ case SW_64_R_SREL32: ++ case SW_64_R_SREL64: ++ if (relocatable ++ && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) ++ { ++ rel->address += input_section->output_offset; ++ break; ++ } ++ r = bfd_perform_relocation (input_bfd, rel, data, input_section, ++ output_bfd, &err); ++ break; ++ ++ case SW_64_R_GPREL32: ++ /* This relocation is used in a switch table. It is a 32 ++ bit offset from the current GP value. We must adjust it ++ by the different between the original GP value and the ++ current GP value. The original GP value is stored in the ++ addend. We adjust the addend and let ++ bfd_perform_relocation finish the job. */ ++ rel->addend -= gp; ++ r = bfd_perform_relocation (input_bfd, rel, data, input_section, ++ output_bfd, &err); ++ if (r == bfd_reloc_ok && gp_undefined) ++ { ++ r = bfd_reloc_dangerous; ++ err = (char *) _("GP relative relocation used when GP not defined"); ++ } ++ break; ++ ++ case SW_64_R_LITERAL: ++ /* This is a reference to a literal value, generally ++ (always?) in the .lita section. This is a 16 bit GP ++ relative relocation. Sometimes the subsequent reloc is a ++ LITUSE reloc, which indicates how this reloc is used. ++ This sometimes permits rewriting the two instructions ++ referred to by the LITERAL and the LITUSE into different ++ instructions which do not refer to .lita. This can save ++ a memory reference, and permits removing a value from ++ .lita thus saving GP relative space. ++ ++ We do not these optimizations. To do them we would need ++ to arrange to link the .lita section first, so that by ++ the time we got here we would know the final values to ++ use. This would not be particularly difficult, but it is ++ not currently implemented. */ ++ ++ { ++ unsigned long insn; ++ ++ /* I believe that the LITERAL reloc will only apply to a ++ ldq or ldl instruction, so check my assumption. */ ++ insn = bfd_get_32 (input_bfd, data + rel->address); ++ BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 ++ || ((insn >> 26) & 0x3f) == 0x28); ++ ++ rel->addend -= gp; ++ r = bfd_perform_relocation (input_bfd, rel, data, input_section, ++ output_bfd, &err); ++ if (r == bfd_reloc_ok && gp_undefined) ++ { ++ r = bfd_reloc_dangerous; ++ err = ++ (char *) _("GP relative relocation used when GP not defined"); ++ } ++ } ++ break; ++ ++ case SW_64_R_LITUSE: ++ /* See SW_64_R_LITERAL above for the uses of this reloc. It ++ does not cause anything to happen, itself. */ ++ rel->address += input_section->output_offset; ++ break; ++ ++ case SW_64_R_GPDISP: ++ /* This marks the ldah of an ldah/lda pair which loads the ++ gp register with the difference of the gp value and the ++ current location. The second of the pair is r_size bytes ++ ahead; it used to be marked with an SW_64_R_IGNORE reloc, ++ but that no longer happens in OSF/1 3.2. */ ++ { ++ unsigned long insn1, insn2; ++ bfd_vma addend; ++ ++ /* Get the two instructions. */ ++ insn1 = bfd_get_32 (input_bfd, data + rel->address); ++ insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend); ++ ++ BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ ++ BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ ++ ++ /* Get the existing addend. We must account for the sign ++ extension done by lda and ldah. */ ++ addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); ++ if (insn1 & 0x8000) ++ { ++ addend -= 0x80000000; ++ addend -= 0x80000000; ++ } ++ if (insn2 & 0x8000) ++ addend -= 0x10000; ++ ++ /* The existing addend includes the different between the ++ gp of the input BFD and the address in the input BFD. ++ Subtract this out. */ ++ addend -= (ecoff_data (input_bfd)->gp ++ - (input_section->vma + rel->address)); ++ ++ /* Now add in the final gp value, and subtract out the ++ final address. */ ++ addend += (gp ++ - (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->address)); ++ ++ /* Change the instructions, accounting for the sign ++ extension, and write them out. */ ++ if (addend & 0x8000) ++ addend += 0x10000; ++ insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); ++ insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); ++ ++ bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address); ++ bfd_put_32 (input_bfd, (bfd_vma) insn2, ++ data + rel->address + rel->addend); ++ ++ rel->address += input_section->output_offset; ++ } ++ break; ++ ++ case SW_64_R_OP_PUSH: ++ /* Push a value on the reloc evaluation stack. */ ++ { ++ asymbol *symbol; ++ bfd_vma relocation; ++ ++ if (relocatable) ++ { ++ rel->address += input_section->output_offset; ++ break; ++ } ++ ++ /* Figure out the relocation of this symbol. */ ++ symbol = *rel->sym_ptr_ptr; ++ ++ if (bfd_is_und_section (symbol->section)) ++ r = bfd_reloc_undefined; ++ ++ if (bfd_is_com_section (symbol->section)) ++ relocation = 0; ++ else ++ relocation = symbol->value; ++ relocation += symbol->section->output_section->vma; ++ relocation += symbol->section->output_offset; ++ relocation += rel->addend; ++ ++ if (tos >= RELOC_STACKSIZE) ++ abort (); ++ ++ stack[tos++] = relocation; ++ } ++ break; ++ ++ case SW_64_R_OP_STORE: ++ /* Store a value from the reloc stack into a bitfield. */ ++ { ++ bfd_vma val; ++ int offset, size; ++ ++ if (relocatable) ++ { ++ rel->address += input_section->output_offset; ++ break; ++ } ++ ++ if (tos == 0) ++ abort (); ++ ++ /* The offset and size for this reloc are encoded into the ++ addend field by sw_64_adjust_reloc_in. */ ++ offset = (rel->addend >> 8) & 0xff; ++ size = rel->addend & 0xff; ++ ++ val = bfd_get_64 (abfd, data + rel->address); ++ val &=~ (((1 << size) - 1) << offset); ++ val |= (stack[--tos] & ((1 << size) - 1)) << offset; ++ bfd_put_64 (abfd, val, data + rel->address); ++ } ++ break; ++ ++ case SW_64_R_OP_PSUB: ++ /* Subtract a value from the top of the stack. */ ++ { ++ asymbol *symbol; ++ bfd_vma relocation; ++ ++ if (relocatable) ++ { ++ rel->address += input_section->output_offset; ++ break; ++ } ++ ++ /* Figure out the relocation of this symbol. */ ++ symbol = *rel->sym_ptr_ptr; ++ ++ if (bfd_is_und_section (symbol->section)) ++ r = bfd_reloc_undefined; ++ ++ if (bfd_is_com_section (symbol->section)) ++ relocation = 0; ++ else ++ relocation = symbol->value; ++ relocation += symbol->section->output_section->vma; ++ relocation += symbol->section->output_offset; ++ relocation += rel->addend; ++ ++ if (tos == 0) ++ abort (); ++ ++ stack[tos - 1] -= relocation; ++ } ++ break; ++ ++ case SW_64_R_OP_PRSHIFT: ++ /* Shift the value on the top of the stack. */ ++ { ++ asymbol *symbol; ++ bfd_vma relocation; ++ ++ if (relocatable) ++ { ++ rel->address += input_section->output_offset; ++ break; ++ } ++ ++ /* Figure out the relocation of this symbol. */ ++ symbol = *rel->sym_ptr_ptr; ++ ++ if (bfd_is_und_section (symbol->section)) ++ r = bfd_reloc_undefined; ++ ++ if (bfd_is_com_section (symbol->section)) ++ relocation = 0; ++ else ++ relocation = symbol->value; ++ relocation += symbol->section->output_section->vma; ++ relocation += symbol->section->output_offset; ++ relocation += rel->addend; ++ ++ if (tos == 0) ++ abort (); ++ ++ stack[tos - 1] >>= relocation; ++ } ++ break; ++ ++ case SW_64_R_GPVALUE: ++ /* I really don't know if this does the right thing. */ ++ gp = rel->addend; ++ gp_undefined = FALSE; ++ break; ++ ++ default: ++ abort (); ++ } ++ ++ if (relocatable) ++ { ++ asection *os = input_section->output_section; ++ ++ /* A partial link, so keep the relocs. */ ++ os->orelocation[os->reloc_count] = rel; ++ os->reloc_count++; ++ } ++ ++ if (r != bfd_reloc_ok) ++ { ++ switch (r) ++ { ++ case bfd_reloc_undefined: ++ (*link_info->callbacks->undefined_symbol) ++ (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), ++ input_bfd, input_section, rel->address, TRUE); ++ break; ++ case bfd_reloc_dangerous: ++ (*link_info->callbacks->reloc_dangerous) ++ (link_info, err, input_bfd, input_section, rel->address); ++ break; ++ case bfd_reloc_overflow: ++ (*link_info->callbacks->reloc_overflow) ++ (link_info, NULL, bfd_asymbol_name (*rel->sym_ptr_ptr), ++ rel->howto->name, rel->addend, input_bfd, ++ input_section, rel->address); ++ break; ++ case bfd_reloc_outofrange: ++ default: ++ abort (); ++ break; ++ } ++ } ++ } ++ ++ if (tos != 0) ++ abort (); ++ ++ successful_return: ++ if (reloc_vector != NULL) ++ free (reloc_vector); ++ return data; ++ ++ error_return: ++ if (reloc_vector != NULL) ++ free (reloc_vector); ++ return NULL; ++} ++ ++/* Get the howto structure for a generic reloc type. */ ++ ++static reloc_howto_type * ++sw_64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ bfd_reloc_code_real_type code) ++{ ++ int sw_64_type; ++ ++ switch (code) ++ { ++ case BFD_RELOC_32: ++ sw_64_type = SW_64_R_REFLONG; ++ break; ++ case BFD_RELOC_64: ++ case BFD_RELOC_CTOR: ++ sw_64_type = SW_64_R_REFQUAD; ++ break; ++ case BFD_RELOC_GPREL32: ++ sw_64_type = SW_64_R_GPREL32; ++ break; ++ case BFD_RELOC_SW_64_LITERAL: ++ sw_64_type = SW_64_R_LITERAL; ++ break; ++ case BFD_RELOC_SW_64_LITUSE: ++ sw_64_type = SW_64_R_LITUSE; ++ break; ++ case BFD_RELOC_SW_64_GPDISP_HI16: ++ sw_64_type = SW_64_R_GPDISP; ++ break; ++ case BFD_RELOC_SW_64_GPDISP_LO16: ++ sw_64_type = SW_64_R_IGNORE; ++ break; ++#ifndef XWB20200308 ++ case BFD_RELOC_20_PCREL_S2: ++ sw_64_type = SW_64_R_BR18ADDR; ++ break; ++ case BFD_RELOC_24_PCREL_S2: ++ sw_64_type = SW_64_R_BR22ADDR; ++ break; +#endif - } - } - -@@ -1242,6 +1274,16 @@ captured_main (void *data) - - captured_main_1 (context); - -+#ifdef CRASH_MERGE -+ /* Relocate the vmlinux. */ -+ objfile_rebase (symfile_objfile, crash_get_kaslr_offset()); ++ case BFD_RELOC_23_PCREL_S2: ++ sw_64_type = SW_64_R_BRADDR; ++ break; ++ case BFD_RELOC_SW_64_HINT: ++ sw_64_type = SW_64_R_HINT; ++ break; ++ case BFD_RELOC_16_PCREL: ++ sw_64_type = SW_64_R_SREL16; ++ break; ++ case BFD_RELOC_32_PCREL: ++ sw_64_type = SW_64_R_SREL32; ++ break; ++ case BFD_RELOC_64_PCREL: ++ sw_64_type = SW_64_R_SREL64; ++ break; ++ default: ++ return (reloc_howto_type *) NULL; ++ } ++ ++ return &sw_64_howto_table[sw_64_type]; ++} ++ ++static reloc_howto_type * ++sw_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ const char *r_name) ++{ ++ unsigned int i; ++ ++ for (i = 0; ++ i < sizeof (sw_64_howto_table) / sizeof (sw_64_howto_table[0]); ++ i++) ++ if (sw_64_howto_table[i].name != NULL ++ && strcasecmp (sw_64_howto_table[i].name, r_name) == 0) ++ return &sw_64_howto_table[i]; ++ ++ return NULL; ++} ++ ++/* A helper routine for sw_64_relocate_section which converts an ++ external reloc when generating relocatable output. Returns the ++ relocation amount. */ ++ ++static bfd_vma ++sw_64_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info, ++ bfd *input_bfd, ++ struct external_reloc *ext_rel, ++ struct ecoff_link_hash_entry *h) ++{ ++ unsigned long r_symndx; ++ bfd_vma relocation; ++ ++ BFD_ASSERT (bfd_link_relocatable (info)); ++ ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ { ++ asection *hsec; ++ const char *name; ++ ++ /* This symbol is defined in the output. Convert the reloc from ++ being against the symbol to being against the section. */ ++ ++ /* Clear the r_extern bit. */ ++ ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE; ++ ++ /* Compute a new r_symndx value. */ ++ hsec = h->root.u.def.section; ++ name = bfd_section_name (hsec->output_section); ++ ++ r_symndx = (unsigned long) -1; ++ switch (name[1]) ++ { ++ case 'A': ++ if (strcmp (name, "*ABS*") == 0) ++ r_symndx = RELOC_SECTION_ABS; ++ break; ++ case 'b': ++ if (strcmp (name, ".bss") == 0) ++ r_symndx = RELOC_SECTION_BSS; ++ break; ++ case 'd': ++ if (strcmp (name, ".data") == 0) ++ r_symndx = RELOC_SECTION_DATA; ++ break; ++ case 'f': ++ if (strcmp (name, ".fini") == 0) ++ r_symndx = RELOC_SECTION_FINI; ++ break; ++ case 'i': ++ if (strcmp (name, ".init") == 0) ++ r_symndx = RELOC_SECTION_INIT; ++ break; ++ case 'l': ++ if (strcmp (name, ".lita") == 0) ++ r_symndx = RELOC_SECTION_LITA; ++ else if (strcmp (name, ".lit8") == 0) ++ r_symndx = RELOC_SECTION_LIT8; ++ else if (strcmp (name, ".lit4") == 0) ++ r_symndx = RELOC_SECTION_LIT4; ++ break; ++ case 'p': ++ if (strcmp (name, ".pdata") == 0) ++ r_symndx = RELOC_SECTION_PDATA; ++ break; ++ case 'r': ++ if (strcmp (name, ".rdata") == 0) ++ r_symndx = RELOC_SECTION_RDATA; ++ else if (strcmp (name, ".rconst") == 0) ++ r_symndx = RELOC_SECTION_RCONST; ++ break; ++ case 's': ++ if (strcmp (name, ".sdata") == 0) ++ r_symndx = RELOC_SECTION_SDATA; ++ else if (strcmp (name, ".sbss") == 0) ++ r_symndx = RELOC_SECTION_SBSS; ++ break; ++ case 't': ++ if (strcmp (name, ".text") == 0) ++ r_symndx = RELOC_SECTION_TEXT; ++ break; ++ case 'x': ++ if (strcmp (name, ".xdata") == 0) ++ r_symndx = RELOC_SECTION_XDATA; ++ break; ++ } ++ ++ if (r_symndx == (unsigned long) -1) ++ abort (); ++ ++ /* Add the section VMA and the symbol value. */ ++ relocation = (h->root.u.def.value ++ + hsec->output_section->vma ++ + hsec->output_offset); ++ } ++ else ++ { ++ /* Change the symndx value to the right one for ++ the output BFD. */ ++ r_symndx = h->indx; ++ if (r_symndx == (unsigned long) -1) ++ { ++ /* Caller must give an error. */ ++ r_symndx = 0; ++ } ++ relocation = 0; ++ } ++ ++ /* Write out the new r_symndx value. */ ++ H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx); ++ ++ return relocation; ++} ++ ++/* Relocate a section while linking an Sw_64 ECOFF file. This is ++ quite similar to get_relocated_section_contents. Perhaps they ++ could be combined somehow. */ ++ ++static bfd_boolean ++sw_64_relocate_section (bfd *output_bfd, ++ struct bfd_link_info *info, ++ bfd *input_bfd, ++ asection *input_section, ++ bfd_byte *contents, ++ void * external_relocs) ++{ ++ asection **symndx_to_section, *lita_sec; ++ struct ecoff_link_hash_entry **sym_hashes; ++ bfd_vma gp; ++ bfd_boolean gp_undefined; ++ bfd_vma stack[RELOC_STACKSIZE]; ++ int tos = 0; ++ struct external_reloc *ext_rel; ++ struct external_reloc *ext_rel_end; ++ bfd_size_type amt; ++ ++ /* We keep a table mapping the symndx found in an internal reloc to ++ the appropriate section. This is faster than looking up the ++ section by name each time. */ ++ symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; ++ if (symndx_to_section == (asection **) NULL) ++ { ++ amt = NUM_RELOC_SECTIONS * sizeof (asection *); ++ symndx_to_section = (asection **) bfd_alloc (input_bfd, amt); ++ if (!symndx_to_section) ++ return FALSE; ++ ++ symndx_to_section[RELOC_SECTION_NONE] = NULL; ++ symndx_to_section[RELOC_SECTION_TEXT] = ++ bfd_get_section_by_name (input_bfd, ".text"); ++ symndx_to_section[RELOC_SECTION_RDATA] = ++ bfd_get_section_by_name (input_bfd, ".rdata"); ++ symndx_to_section[RELOC_SECTION_DATA] = ++ bfd_get_section_by_name (input_bfd, ".data"); ++ symndx_to_section[RELOC_SECTION_SDATA] = ++ bfd_get_section_by_name (input_bfd, ".sdata"); ++ symndx_to_section[RELOC_SECTION_SBSS] = ++ bfd_get_section_by_name (input_bfd, ".sbss"); ++ symndx_to_section[RELOC_SECTION_BSS] = ++ bfd_get_section_by_name (input_bfd, ".bss"); ++ symndx_to_section[RELOC_SECTION_INIT] = ++ bfd_get_section_by_name (input_bfd, ".init"); ++ symndx_to_section[RELOC_SECTION_LIT8] = ++ bfd_get_section_by_name (input_bfd, ".lit8"); ++ symndx_to_section[RELOC_SECTION_LIT4] = ++ bfd_get_section_by_name (input_bfd, ".lit4"); ++ symndx_to_section[RELOC_SECTION_XDATA] = ++ bfd_get_section_by_name (input_bfd, ".xdata"); ++ symndx_to_section[RELOC_SECTION_PDATA] = ++ bfd_get_section_by_name (input_bfd, ".pdata"); ++ symndx_to_section[RELOC_SECTION_FINI] = ++ bfd_get_section_by_name (input_bfd, ".fini"); ++ symndx_to_section[RELOC_SECTION_LITA] = ++ bfd_get_section_by_name (input_bfd, ".lita"); ++ symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr; ++ symndx_to_section[RELOC_SECTION_RCONST] = ++ bfd_get_section_by_name (input_bfd, ".rconst"); ++ ++ ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; ++ } ++ ++ sym_hashes = ecoff_data (input_bfd)->sym_hashes; ++ ++ /* On the Sw_64, the .lita section must be addressable by the global ++ pointer. To support large programs, we need to allow multiple ++ global pointers. This works as long as each input .lita section ++ is <64KB big. This implies that when producing relocatable ++ output, the .lita section is limited to 64KB. . */ ++ ++ lita_sec = symndx_to_section[RELOC_SECTION_LITA]; ++ gp = _bfd_get_gp_value (output_bfd); ++ if (! bfd_link_relocatable (info) && lita_sec != NULL) ++ { ++ struct ecoff_section_tdata *lita_sec_data; ++ ++ /* Make sure we have a section data structure to which we can ++ hang on to the gp value we pick for the section. */ ++ lita_sec_data = ecoff_section_data (input_bfd, lita_sec); ++ if (lita_sec_data == NULL) ++ { ++ amt = sizeof (struct ecoff_section_tdata); ++ lita_sec_data = ((struct ecoff_section_tdata *) ++ bfd_zalloc (input_bfd, amt)); ++ lita_sec->used_by_bfd = lita_sec_data; ++ } ++ ++ if (lita_sec_data->gp != 0) ++ { ++ /* If we already assigned a gp to this section, we better ++ stick with that value. */ ++ gp = lita_sec_data->gp; ++ } ++ else ++ { ++ bfd_vma lita_vma; ++ bfd_size_type lita_size; ++ ++ lita_vma = lita_sec->output_offset + lita_sec->output_section->vma; ++ lita_size = lita_sec->size; ++ ++ if (gp == 0 ++ || lita_vma < gp - 0x8000 ++ || lita_vma + lita_size >= gp + 0x8000) ++ { ++ /* Either gp hasn't been set at all or the current gp ++ cannot address this .lita section. In both cases we ++ reset the gp to point into the "middle" of the ++ current input .lita section. */ ++ if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning) ++ { ++ (*info->callbacks->warning) (info, ++ _("using multiple gp values"), ++ (char *) NULL, output_bfd, ++ (asection *) NULL, (bfd_vma) 0); ++ ecoff_data (output_bfd)->issued_multiple_gp_warning = TRUE; ++ } ++ if (lita_vma < gp - 0x8000) ++ gp = lita_vma + lita_size - 0x8000; ++ else ++ gp = lita_vma + 0x8000; ++ ++ } ++ ++ lita_sec_data->gp = gp; ++ } ++ ++ _bfd_set_gp_value (output_bfd, gp); ++ } ++ ++ gp_undefined = (gp == 0); ++ ++ BFD_ASSERT (bfd_header_little_endian (output_bfd)); ++ BFD_ASSERT (bfd_header_little_endian (input_bfd)); ++ ++ ext_rel = (struct external_reloc *) external_relocs; ++ ext_rel_end = ext_rel + input_section->reloc_count; ++ for (; ext_rel < ext_rel_end; ext_rel++) ++ { ++ bfd_vma r_vaddr; ++ unsigned long r_symndx; ++ int r_type; ++ int r_extern; ++ int r_offset; ++ int r_size; ++ bfd_boolean relocatep; ++ bfd_boolean adjust_addrp; ++ bfd_boolean gp_usedp; ++ bfd_vma addend; ++ ++ r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr); ++ r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx); ++ ++ r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) ++ >> RELOC_BITS0_TYPE_SH_LITTLE); ++ r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; ++ r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) ++ >> RELOC_BITS1_OFFSET_SH_LITTLE); ++ /* Ignored the reserved bits. */ ++ r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) ++ >> RELOC_BITS3_SIZE_SH_LITTLE); ++ ++ relocatep = FALSE; ++ adjust_addrp = TRUE; ++ gp_usedp = FALSE; ++ addend = 0; ++ ++ switch (r_type) ++ { ++ case SW_64_R_GPRELHIGH: ++ _bfd_error_handler (_("%pB: %s unsupported"), ++ input_bfd, "SW_64_R_GPRELHIGH"); ++ bfd_set_error (bfd_error_bad_value); ++ continue; ++ ++ case SW_64_R_GPRELLOW: ++ _bfd_error_handler (_("%pB: %s unsupported"), ++ input_bfd, "SW_64_R_GPRELLOW"); ++ bfd_set_error (bfd_error_bad_value); ++ continue; ++ ++ default: ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), ++ input_bfd, (int) r_type); ++ bfd_set_error (bfd_error_bad_value); ++ continue; ++ ++ case SW_64_R_IGNORE: ++ /* This reloc appears after a GPDISP reloc. On earlier ++ versions of OSF/1, It marked the position of the second ++ instruction to be altered by the GPDISP reloc, but it is ++ not otherwise used for anything. For some reason, the ++ address of the relocation does not appear to include the ++ section VMA, unlike the other relocation types. */ ++ if (bfd_link_relocatable (info)) ++ H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr, ++ ext_rel->r_vaddr); ++ adjust_addrp = FALSE; ++ break; ++ ++ case SW_64_R_REFLONG: ++ case SW_64_R_REFQUAD: ++ case SW_64_R_HINT: ++ relocatep = TRUE; ++ break; ++ ++ case SW_64_R_BRADDR: ++ case SW_64_R_SREL16: ++ case SW_64_R_SREL32: ++ case SW_64_R_SREL64: ++ if (r_extern) ++ addend += - (r_vaddr + 4); ++ relocatep = TRUE; ++ break; ++ ++ case SW_64_R_GPREL32: ++ /* This relocation is used in a switch table. It is a 32 ++ bit offset from the current GP value. We must adjust it ++ by the different between the original GP value and the ++ current GP value. */ ++ relocatep = TRUE; ++ addend = ecoff_data (input_bfd)->gp - gp; ++ gp_usedp = TRUE; ++ break; ++ ++ case SW_64_R_LITERAL: ++ /* This is a reference to a literal value, generally ++ (always?) in the .lita section. This is a 16 bit GP ++ relative relocation. Sometimes the subsequent reloc is a ++ LITUSE reloc, which indicates how this reloc is used. ++ This sometimes permits rewriting the two instructions ++ referred to by the LITERAL and the LITUSE into different ++ instructions which do not refer to .lita. This can save ++ a memory reference, and permits removing a value from ++ .lita thus saving GP relative space. ++ ++ We do not these optimizations. To do them we would need ++ to arrange to link the .lita section first, so that by ++ the time we got here we would know the final values to ++ use. This would not be particularly difficult, but it is ++ not currently implemented. */ ++ ++ /* I believe that the LITERAL reloc will only apply to a ldq ++ or ldl instruction, so check my assumption. */ ++ { ++ unsigned long insn; ++ ++ insn = bfd_get_32 (input_bfd, ++ contents + r_vaddr - input_section->vma); ++ BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 ++ || ((insn >> 26) & 0x3f) == 0x28); ++ } ++ ++ relocatep = TRUE; ++ addend = ecoff_data (input_bfd)->gp - gp; ++ gp_usedp = TRUE; ++ break; ++ ++ case SW_64_R_LITUSE: ++ /* See SW_64_R_LITERAL above for the uses of this reloc. It ++ does not cause anything to happen, itself. */ ++ break; ++ ++ case SW_64_R_GPDISP: ++ /* This marks the ldah of an ldah/lda pair which loads the ++ gp register with the difference of the gp value and the ++ current location. The second of the pair is r_symndx ++ bytes ahead. It used to be marked with an SW_64_R_IGNORE ++ reloc, but OSF/1 3.2 no longer does that. */ ++ { ++ unsigned long insn1, insn2; ++ ++ /* Get the two instructions. */ ++ insn1 = bfd_get_32 (input_bfd, ++ contents + r_vaddr - input_section->vma); ++ insn2 = bfd_get_32 (input_bfd, ++ (contents ++ + r_vaddr ++ - input_section->vma ++ + r_symndx)); ++ ++ BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ ++ BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ ++ ++ /* Get the existing addend. We must account for the sign ++ extension done by lda and ldah. */ ++ addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); ++ if (insn1 & 0x8000) ++ { ++ /* This is addend -= 0x100000000 without causing an ++ integer overflow on a 32 bit host. */ ++ addend -= 0x80000000; ++ addend -= 0x80000000; ++ } ++ if (insn2 & 0x8000) ++ addend -= 0x10000; ++ ++ /* The existing addend includes the difference between the ++ gp of the input BFD and the address in the input BFD. ++ We want to change this to the difference between the ++ final GP and the final address. */ ++ addend += (gp ++ - ecoff_data (input_bfd)->gp ++ + input_section->vma ++ - (input_section->output_section->vma ++ + input_section->output_offset)); ++ ++ /* Change the instructions, accounting for the sign ++ extension, and write them out. */ ++ if (addend & 0x8000) ++ addend += 0x10000; ++ insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); ++ insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); ++ ++ bfd_put_32 (input_bfd, (bfd_vma) insn1, ++ contents + r_vaddr - input_section->vma); ++ bfd_put_32 (input_bfd, (bfd_vma) insn2, ++ contents + r_vaddr - input_section->vma + r_symndx); ++ ++ gp_usedp = TRUE; ++ } ++ break; ++ ++ case SW_64_R_OP_PUSH: ++ case SW_64_R_OP_PSUB: ++ case SW_64_R_OP_PRSHIFT: ++ /* Manipulate values on the reloc evaluation stack. The ++ r_vaddr field is not an address in input_section, it is ++ the current value (including any addend) of the object ++ being used. */ ++ if (! r_extern) ++ { ++ asection *s; ++ ++ s = symndx_to_section[r_symndx]; ++ if (s == (asection *) NULL) ++ abort (); ++ addend = s->output_section->vma + s->output_offset - s->vma; ++ } ++ else ++ { ++ struct ecoff_link_hash_entry *h; ++ ++ h = sym_hashes[r_symndx]; ++ if (h == (struct ecoff_link_hash_entry *) NULL) ++ abort (); ++ ++ if (! bfd_link_relocatable (info)) ++ { ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ addend = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ else ++ { ++ /* Note that we pass the address as 0, since we ++ do not have a meaningful number for the ++ location within the section that is being ++ relocated. */ ++ (*info->callbacks->undefined_symbol) ++ (info, h->root.root.string, input_bfd, ++ input_section, (bfd_vma) 0, TRUE); ++ addend = 0; ++ } ++ } ++ else ++ { ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak ++ && h->indx == -1) ++ { ++ /* This symbol is not being written out. Pass ++ the address as 0, as with undefined_symbol, ++ above. */ ++ (*info->callbacks->unattached_reloc) ++ (info, h->root.root.string, ++ input_bfd, input_section, (bfd_vma) 0); ++ } ++ ++ addend = sw_64_convert_external_reloc (output_bfd, info, ++ input_bfd, ++ ext_rel, h); ++ } ++ } ++ ++ addend += r_vaddr; ++ ++ if (bfd_link_relocatable (info)) ++ { ++ /* Adjust r_vaddr by the addend. */ ++ H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr); ++ } ++ else ++ { ++ switch (r_type) ++ { ++ case SW_64_R_OP_PUSH: ++ if (tos >= RELOC_STACKSIZE) ++ abort (); ++ stack[tos++] = addend; ++ break; ++ ++ case SW_64_R_OP_PSUB: ++ if (tos == 0) ++ abort (); ++ stack[tos - 1] -= addend; ++ break; ++ ++ case SW_64_R_OP_PRSHIFT: ++ if (tos == 0) ++ abort (); ++ stack[tos - 1] >>= addend; ++ break; ++ } ++ } ++ ++ adjust_addrp = FALSE; ++ break; ++ ++ case SW_64_R_OP_STORE: ++ /* Store a value from the reloc stack into a bitfield. If ++ we are generating relocatable output, all we do is ++ adjust the address of the reloc. */ ++ if (! bfd_link_relocatable (info)) ++ { ++ bfd_vma mask; ++ bfd_vma val; ++ ++ if (tos == 0) ++ abort (); ++ ++ /* Get the relocation mask. The separate steps and the ++ casts to bfd_vma are attempts to avoid a bug in the ++ Sw_64 OSF 1.3 C compiler. See reloc.c for more ++ details. */ ++ mask = 1; ++ mask <<= (bfd_vma) r_size; ++ mask -= 1; ++ ++ /* FIXME: I don't know what kind of overflow checking, ++ if any, should be done here. */ ++ val = bfd_get_64 (input_bfd, ++ contents + r_vaddr - input_section->vma); ++ val &=~ mask << (bfd_vma) r_offset; ++ val |= (stack[--tos] & mask) << (bfd_vma) r_offset; ++ bfd_put_64 (input_bfd, val, ++ contents + r_vaddr - input_section->vma); ++ } ++ break; ++ ++ case SW_64_R_GPVALUE: ++ /* I really don't know if this does the right thing. */ ++ gp = ecoff_data (input_bfd)->gp + r_symndx; ++ gp_undefined = FALSE; ++ break; ++ } ++ ++ if (relocatep) ++ { ++ reloc_howto_type *howto; ++ struct ecoff_link_hash_entry *h = NULL; ++ asection *s = NULL; ++ bfd_vma relocation; ++ bfd_reloc_status_type r; ++ ++ /* Perform a relocation. */ ++ ++ howto = &sw_64_howto_table[r_type]; ++ ++ if (r_extern) ++ { ++ h = sym_hashes[r_symndx]; ++ /* If h is NULL, that means that there is a reloc ++ against an external symbol which we thought was just ++ a debugging symbol. This should not happen. */ ++ if (h == (struct ecoff_link_hash_entry *) NULL) ++ abort (); ++ } ++ else ++ { ++ if (r_symndx >= NUM_RELOC_SECTIONS) ++ s = NULL; ++ else ++ s = symndx_to_section[r_symndx]; ++ ++ if (s == (asection *) NULL) ++ abort (); ++ } ++ ++ if (bfd_link_relocatable (info)) ++ { ++ /* We are generating relocatable output, and must ++ convert the existing reloc. */ ++ if (r_extern) ++ { ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak ++ && h->indx == -1) ++ { ++ /* This symbol is not being written out. */ ++ (*info->callbacks->unattached_reloc) ++ (info, h->root.root.string, input_bfd, ++ input_section, r_vaddr - input_section->vma); ++ } ++ ++ relocation = sw_64_convert_external_reloc (output_bfd, ++ info, ++ input_bfd, ++ ext_rel, ++ h); ++ } ++ else ++ { ++ /* This is a relocation against a section. Adjust ++ the value by the amount the section moved. */ ++ relocation = (s->output_section->vma ++ + s->output_offset ++ - s->vma); ++ } ++ ++ /* If this is PC relative, the existing object file ++ appears to already have the reloc worked out. We ++ must subtract out the old value and add in the new ++ one. */ ++ if (howto->pc_relative) ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset ++ - input_section->vma); ++ ++ /* Put in any addend. */ ++ relocation += addend; ++ ++ /* Adjust the contents. */ ++ r = _bfd_relocate_contents (howto, input_bfd, relocation, ++ (contents ++ + r_vaddr ++ - input_section->vma)); ++ } ++ else ++ { ++ /* We are producing a final executable. */ ++ if (r_extern) ++ { ++ /* This is a reloc against a symbol. */ ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ { ++ asection *hsec; ++ ++ hsec = h->root.u.def.section; ++ relocation = (h->root.u.def.value ++ + hsec->output_section->vma ++ + hsec->output_offset); ++ } ++ else ++ { ++ (*info->callbacks->undefined_symbol) ++ (info, h->root.root.string, input_bfd, input_section, ++ r_vaddr - input_section->vma, TRUE); ++ relocation = 0; ++ } ++ } ++ else ++ { ++ /* This is a reloc against a section. */ ++ relocation = (s->output_section->vma ++ + s->output_offset ++ - s->vma); ++ ++ /* Adjust a PC relative relocation by removing the ++ reference to the original source section. */ ++ if (howto->pc_relative) ++ relocation += input_section->vma; ++ } ++ ++ r = _bfd_final_link_relocate (howto, ++ input_bfd, ++ input_section, ++ contents, ++ r_vaddr - input_section->vma, ++ relocation, ++ addend); ++ } ++ ++ if (r != bfd_reloc_ok) ++ { ++ switch (r) ++ { ++ default: ++ case bfd_reloc_outofrange: ++ abort (); ++ case bfd_reloc_overflow: ++ { ++ const char *name; ++ ++ if (r_extern) ++ name = sym_hashes[r_symndx]->root.root.string; ++ else ++ name = bfd_section_name (symndx_to_section[r_symndx]); ++ (*info->callbacks->reloc_overflow) ++ (info, NULL, name, sw_64_howto_table[r_type].name, ++ (bfd_vma) 0, input_bfd, input_section, ++ r_vaddr - input_section->vma); ++ } ++ break; ++ } ++ } ++ } ++ ++ if (bfd_link_relocatable (info) && adjust_addrp) ++ { ++ /* Change the address of the relocation. */ ++ H_PUT_64 (input_bfd, ++ (input_section->output_section->vma ++ + input_section->output_offset ++ - input_section->vma ++ + r_vaddr), ++ ext_rel->r_vaddr); ++ } ++ ++ if (gp_usedp && gp_undefined) ++ { ++ (*info->callbacks->reloc_dangerous) ++ (info, _("GP relative relocation used when GP not defined"), ++ input_bfd, input_section, r_vaddr - input_section->vma); ++ /* Only give the error once per link. */ ++ gp = 4; ++ _bfd_set_gp_value (output_bfd, gp); ++ gp_undefined = FALSE; ++ } ++ } ++ ++ if (tos != 0) ++ abort (); ++ ++ return TRUE; ++} ++ ++/* Do final adjustments to the filehdr and the aouthdr. This routine ++ sets the dynamic bits in the file header. */ ++ ++static bfd_boolean ++sw_64_adjust_headers (bfd *abfd, ++ struct internal_filehdr *fhdr, ++ struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED) ++{ ++ if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P)) ++ fhdr->f_flags |= F_SW_64_CALL_SHARED; ++ else if ((abfd->flags & DYNAMIC) != 0) ++ fhdr->f_flags |= F_SW_64_SHARABLE; ++ return TRUE; ++} ++ ++/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital ++ introduced archive packing, in which the elements in an archive are ++ optionally compressed using a simple dictionary scheme. We know ++ how to read such archives, but we don't write them. */ ++ ++#define sw_64_ecoff_slurp_armap _bfd_ecoff_slurp_armap ++#define sw_64_ecoff_slurp_extended_name_table \ ++ _bfd_ecoff_slurp_extended_name_table ++#define sw_64_ecoff_construct_extended_name_table \ ++ _bfd_ecoff_construct_extended_name_table ++#define sw_64_ecoff_truncate_arname _bfd_ecoff_truncate_arname ++#define sw_64_ecoff_write_armap _bfd_ecoff_write_armap ++#define sw_64_ecoff_write_ar_hdr _bfd_generic_write_ar_hdr ++#define sw_64_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt ++#define sw_64_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp ++ ++/* A compressed file uses this instead of ARFMAG. */ ++ ++#define ARFZMAG "Z\012" ++ ++/* Read an archive header. This is like the standard routine, but it ++ also accepts ARFZMAG. */ ++ ++static void * ++sw_64_ecoff_read_ar_hdr (bfd *abfd) ++{ ++ struct areltdata *ret; ++ struct ar_hdr *h; ++ ++ ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); ++ if (ret == NULL) ++ return NULL; ++ ++ h = (struct ar_hdr *) ret->arch_header; ++ if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0) ++ { ++ bfd_byte ab[8]; ++ ++ /* This is a compressed file. We must set the size correctly. ++ The size is the eight bytes after the dummy file header. */ ++ if (bfd_seek (abfd, (file_ptr) FILHSZ, SEEK_CUR) != 0 ++ || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8 ++ || bfd_seek (abfd, (file_ptr) (- (FILHSZ + 8)), SEEK_CUR) != 0) ++ return NULL; ++ ++ ret->parsed_size = H_GET_64 (abfd, ab); ++ } ++ ++ return ret; ++} ++ ++/* Get an archive element at a specified file position. This is where ++ we uncompress the archive element if necessary. */ ++ ++static bfd * ++sw_64_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos) ++{ ++ bfd *nbfd = NULL; ++ struct areltdata *tdata; ++ struct ar_hdr *hdr; ++ bfd_byte ab[8]; ++ bfd_size_type size; ++ bfd_byte *buf, *p; ++ struct bfd_in_memory *bim; ++ ++ buf = NULL; ++ nbfd = _bfd_get_elt_at_filepos (archive, filepos); ++ if (nbfd == NULL) ++ goto error_return; ++ ++ if ((nbfd->flags & BFD_IN_MEMORY) != 0) ++ { ++ /* We have already expanded this BFD. */ ++ return nbfd; ++ } ++ ++ tdata = (struct areltdata *) nbfd->arelt_data; ++ hdr = (struct ar_hdr *) tdata->arch_header; ++ if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0) ++ return nbfd; ++ ++ /* We must uncompress this element. We do this by copying it into a ++ memory buffer, and making bfd_bread and bfd_seek use that buffer. ++ This can use a lot of memory, but it's simpler than getting a ++ temporary file, making that work with the file descriptor caching ++ code, and making sure that it is deleted at all appropriate ++ times. It can be changed if it ever becomes important. */ ++ ++ /* The compressed file starts with a dummy ECOFF file header. */ ++ if (bfd_seek (nbfd, (file_ptr) FILHSZ, SEEK_SET) != 0) ++ goto error_return; ++ ++ /* The next eight bytes are the real file size. */ ++ if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8) ++ goto error_return; ++ size = H_GET_64 (nbfd, ab); ++ ++ if (size != 0) ++ { ++ bfd_size_type left; ++ bfd_byte dict[4096]; ++ unsigned int h; ++ bfd_byte b; ++ ++ buf = (bfd_byte *) bfd_malloc (size); ++ if (buf == NULL) ++ goto error_return; ++ p = buf; ++ ++ left = size; ++ ++ /* I don't know what the next eight bytes are for. */ ++ if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8) ++ goto error_return; ++ ++ /* This is the uncompression algorithm. It's a simple ++ dictionary based scheme in which each character is predicted ++ by a hash of the previous three characters. A control byte ++ indicates whether the character is predicted or whether it ++ appears in the input stream; each control byte manages the ++ next eight bytes in the output stream. */ ++ memset (dict, 0, sizeof dict); ++ h = 0; ++ while (bfd_bread (&b, (bfd_size_type) 1, nbfd) == 1) ++ { ++ unsigned int i; ++ ++ for (i = 0; i < 8; i++, b >>= 1) ++ { ++ bfd_byte n; ++ ++ if ((b & 1) == 0) ++ n = dict[h]; ++ else ++ { ++ if (! bfd_bread (&n, (bfd_size_type) 1, nbfd)) ++ goto error_return; ++ dict[h] = n; ++ } ++ ++ *p++ = n; ++ ++ --left; ++ if (left == 0) ++ break; ++ ++ h <<= 4; ++ h ^= n; ++ h &= sizeof dict - 1; ++ } ++ ++ if (left == 0) ++ break; ++ } ++ } ++ ++ /* Now the uncompressed file contents are in buf. */ ++ bim = ((struct bfd_in_memory *) ++ bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory))); ++ if (bim == NULL) ++ goto error_return; ++ bim->size = size; ++ bim->buffer = buf; ++ ++ nbfd->mtime_set = TRUE; ++ nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10); ++ ++ nbfd->flags |= BFD_IN_MEMORY; ++ nbfd->iostream = bim; ++ nbfd->iovec = &_bfd_memory_iovec; ++ nbfd->origin = 0; ++ BFD_ASSERT (! nbfd->cacheable); ++ ++ return nbfd; ++ ++ error_return: ++ if (buf != NULL) ++ free (buf); ++ if (nbfd != NULL) ++ bfd_close (nbfd); ++ return NULL; ++} ++ ++/* Open the next archived file. */ ++ ++static bfd * ++sw_64_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file) ++{ ++ ufile_ptr filestart; ++ ++ if (last_file == NULL) ++ filestart = bfd_ardata (archive)->first_file_filepos; ++ else ++ { ++ struct areltdata *t; ++ struct ar_hdr *h; ++ bfd_size_type size; ++ ++ /* We can't use arelt_size here, because that uses parsed_size, ++ which is the uncompressed size. We need the compressed size. */ ++ t = (struct areltdata *) last_file->arelt_data; ++ h = (struct ar_hdr *) t->arch_header; ++ size = strtol (h->ar_size, (char **) NULL, 10); ++ ++ /* Pad to an even boundary... ++ Note that last_file->origin can be odd in the case of ++ BSD-4.4-style element with a long odd size. */ ++ filestart = last_file->proxy_origin + size; ++ filestart += filestart % 2; ++ if (filestart < last_file->proxy_origin) ++ { ++ /* Prevent looping. See PR19256. */ ++ bfd_set_error (bfd_error_malformed_archive); ++ return NULL; ++ } ++ } ++ ++ return sw_64_ecoff_get_elt_at_filepos (archive, filestart); ++} ++ ++/* Open the archive file given an index into the armap. */ ++ ++static bfd * ++sw_64_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index) ++{ ++ carsym *entry; ++ ++ entry = bfd_ardata (abfd)->symdefs + sym_index; ++ return sw_64_ecoff_get_elt_at_filepos (abfd, entry->file_offset); ++} ++ ++static void ++sw_64_ecoff_swap_coff_aux_in (bfd *abfd ATTRIBUTE_UNUSED, ++ void *ext1 ATTRIBUTE_UNUSED, ++ int type ATTRIBUTE_UNUSED, ++ int in_class ATTRIBUTE_UNUSED, ++ int indx ATTRIBUTE_UNUSED, ++ int numaux ATTRIBUTE_UNUSED, ++ void *in1 ATTRIBUTE_UNUSED) ++{ ++} ++ ++static void ++sw_64_ecoff_swap_coff_sym_in (bfd *abfd ATTRIBUTE_UNUSED, ++ void *ext1 ATTRIBUTE_UNUSED, ++ void *in1 ATTRIBUTE_UNUSED) ++{ ++} ++ ++static void ++sw_64_ecoff_swap_coff_lineno_in (bfd *abfd ATTRIBUTE_UNUSED, ++ void *ext1 ATTRIBUTE_UNUSED, ++ void *in1 ATTRIBUTE_UNUSED) ++{ ++} ++ ++static unsigned int ++sw_64_ecoff_swap_coff_aux_out (bfd *abfd ATTRIBUTE_UNUSED, ++ void *inp ATTRIBUTE_UNUSED, ++ int type ATTRIBUTE_UNUSED, ++ int in_class ATTRIBUTE_UNUSED, ++ int indx ATTRIBUTE_UNUSED, ++ int numaux ATTRIBUTE_UNUSED, ++ void *extp ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++static unsigned int ++sw_64_ecoff_swap_coff_sym_out (bfd *abfd ATTRIBUTE_UNUSED, ++ void *inp ATTRIBUTE_UNUSED, ++ void *extp ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++static unsigned int ++sw_64_ecoff_swap_coff_lineno_out (bfd *abfd ATTRIBUTE_UNUSED, ++ void *inp ATTRIBUTE_UNUSED, ++ void *extp ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++static unsigned int ++sw_64_ecoff_swap_coff_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, ++ void *inp ATTRIBUTE_UNUSED, ++ void *extp ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++/* This is the ECOFF backend structure. The backend field of the ++ target vector points to this. */ ++ ++static const struct ecoff_backend_data sw_64_ecoff_backend_data = ++{ ++ /* COFF backend structure. */ ++ { ++ sw_64_ecoff_swap_coff_aux_in, sw_64_ecoff_swap_coff_sym_in, ++ sw_64_ecoff_swap_coff_lineno_in, sw_64_ecoff_swap_coff_aux_out, ++ sw_64_ecoff_swap_coff_sym_out, sw_64_ecoff_swap_coff_lineno_out, ++ sw_64_ecoff_swap_coff_reloc_out, ++ sw_64_ecoff_swap_filehdr_out, sw_64_ecoff_swap_aouthdr_out, ++ sw_64_ecoff_swap_scnhdr_out, ++ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, ++ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768, ++ sw_64_ecoff_swap_filehdr_in, sw_64_ecoff_swap_aouthdr_in, ++ sw_64_ecoff_swap_scnhdr_in, NULL, ++ sw_64_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, ++ sw_64_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, ++ _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL ++ }, ++ /* Supported architecture. */ ++ bfd_arch_sw_64, ++ /* Initial portion of armap string. */ ++ "________64", ++ /* The page boundary used to align sections in a demand-paged ++ executable file. E.g., 0x1000. */ ++ 0x2000, ++ /* TRUE if the .rdata section is part of the text segment, as on the ++ Sw_64. FALSE if .rdata is part of the data segment, as on the ++ MIPS. */ ++ TRUE, ++ /* Bitsize of constructor entries. */ ++ 64, ++ /* Reloc to use for constructor entries. */ ++ &sw_64_howto_table[SW_64_R_REFQUAD], ++ { ++ /* Symbol table magic number. */ ++ magicSym2, ++ /* Alignment of debugging information. E.g., 4. */ ++ 8, ++ /* Sizes of external symbolic information. */ ++ sizeof (struct hdr_ext), ++ sizeof (struct dnr_ext), ++ sizeof (struct pdr_ext), ++ sizeof (struct sym_ext), ++ sizeof (struct opt_ext), ++ sizeof (struct fdr_ext), ++ sizeof (struct rfd_ext), ++ sizeof (struct ext_ext), ++ /* Functions to swap in external symbolic data. */ ++ ecoff_swap_hdr_in, ++ ecoff_swap_dnr_in, ++ ecoff_swap_pdr_in, ++ ecoff_swap_sym_in, ++ ecoff_swap_opt_in, ++ ecoff_swap_fdr_in, ++ ecoff_swap_rfd_in, ++ ecoff_swap_ext_in, ++ _bfd_ecoff_swap_tir_in, ++ _bfd_ecoff_swap_rndx_in, ++ /* Functions to swap out external symbolic data. */ ++ ecoff_swap_hdr_out, ++ ecoff_swap_dnr_out, ++ ecoff_swap_pdr_out, ++ ecoff_swap_sym_out, ++ ecoff_swap_opt_out, ++ ecoff_swap_fdr_out, ++ ecoff_swap_rfd_out, ++ ecoff_swap_ext_out, ++ _bfd_ecoff_swap_tir_out, ++ _bfd_ecoff_swap_rndx_out, ++ /* Function to read in symbolic data. */ ++ _bfd_ecoff_slurp_symbolic_info ++ }, ++ /* External reloc size. */ ++ RELSZ, ++ /* Reloc swapping functions. */ ++ sw_64_ecoff_swap_reloc_in, ++ sw_64_ecoff_swap_reloc_out, ++ /* Backend reloc tweaking. */ ++ sw_64_adjust_reloc_in, ++ sw_64_adjust_reloc_out, ++ /* Relocate section contents while linking. */ ++ sw_64_relocate_section, ++ /* Do final adjustments to filehdr and aouthdr. */ ++ sw_64_adjust_headers, ++ /* Read an element from an archive at a given file position. */ ++ sw_64_ecoff_get_elt_at_filepos ++}; ++ ++/* Looking up a reloc type is Sw_64 specific. */ ++#define _bfd_ecoff_bfd_reloc_type_lookup sw_64_bfd_reloc_type_lookup ++#define _bfd_ecoff_bfd_reloc_name_lookup \ ++ sw_64_bfd_reloc_name_lookup ++ ++/* So is getting relocated section contents. */ ++#define _bfd_ecoff_bfd_get_relocated_section_contents \ ++ sw_64_ecoff_get_relocated_section_contents ++ ++/* Handling file windows is generic. */ ++#define _bfd_ecoff_get_section_contents_in_window \ ++ _bfd_generic_get_section_contents_in_window ++ ++/* Input section flag lookup is generic. */ ++#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags ++ ++/* Relaxing sections is generic. */ ++#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section ++#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections ++#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections ++#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section ++#define _bfd_ecoff_bfd_group_name bfd_generic_group_name ++#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group ++#define _bfd_ecoff_section_already_linked \ ++ _bfd_coff_section_already_linked ++#define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol ++#define _bfd_ecoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol ++#define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop ++#define _bfd_ecoff_bfd_link_check_relocs _bfd_generic_link_check_relocs ++ ++/* Installing internal relocations in a section is also generic. */ ++#define _bfd_ecoff_set_reloc _bfd_generic_set_reloc ++ ++const bfd_target sw_64_ecoff_le_vec = ++{ ++ "ecoff-littlesw_64", /* name */ ++ bfd_target_ecoff_flavour, ++ BFD_ENDIAN_LITTLE, /* data byte order is little */ ++ BFD_ENDIAN_LITTLE, /* header byte order is little */ ++ ++ (HAS_RELOC | EXEC_P /* object flags */ ++ | HAS_LINENO | HAS_DEBUG ++ | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), ++ ++ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), ++ 0, /* leading underscore */ ++ ' ', /* ar_pad_char */ ++ 15, /* ar_max_namelen */ ++ 0, /* match priority. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ ++ ++ { /* bfd_check_format */ ++ _bfd_dummy_target, ++ sw_64_ecoff_object_p, ++ bfd_generic_archive_p, ++ _bfd_dummy_target ++ }, ++ { /* bfd_set_format */ ++ _bfd_bool_bfd_false_error, ++ _bfd_ecoff_mkobject, ++ _bfd_generic_mkarchive, ++ _bfd_bool_bfd_false_error ++ }, ++ { /* bfd_write_contents */ ++ _bfd_bool_bfd_false_error, ++ _bfd_ecoff_write_object_contents, ++ _bfd_write_archive_contents, ++ _bfd_bool_bfd_false_error ++ }, ++ ++ BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), ++ BFD_JUMP_TABLE_COPY (_bfd_ecoff), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (sw_64_ecoff), ++ BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), ++ BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), ++ BFD_JUMP_TABLE_WRITE (_bfd_ecoff), ++ BFD_JUMP_TABLE_LINK (_bfd_ecoff), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ &sw_64_ecoff_backend_data ++}; +diff -Nuar gdb-10.2/bfd/coffswap.h gdb-10.2/bfd/coffswap.h +--- gdb-10.2/bfd/coffswap.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/coffswap.h 2025-04-16 17:06:51.902086800 +0800 +@@ -653,6 +653,13 @@ + aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask); + aouthdr_int->fprmask = H_GET_32 (abfd, aouthdr_ext->fprmask); + #endif ++ ++#ifdef SW_64ECOFF ++ aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start); ++ aouthdr_int->gp_value = H_GET_64 (abfd, aouthdr_ext->gp_value); ++ aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask); ++ aouthdr_int->fprmask = H_GET_32 (abfd, aouthdr_ext->fprmask); ++#endif + } + + static unsigned int +diff -Nuar gdb-10.2/bfd/config.bfd gdb-10.2/bfd/config.bfd +--- gdb-10.2/bfd/config.bfd 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/config.bfd 2025-04-16 17:06:51.902086800 +0800 +@@ -166,6 +166,7 @@ + case "${targ_cpu}" in + aarch64*) targ_archs="bfd_aarch64_arch bfd_arm_arch";; + alpha*) targ_archs=bfd_alpha_arch ;; ++sw_64*) targ_archs=bfd_sw_64_arch ;; + am33_2.0*) targ_archs=bfd_mn10300_arch ;; + arc*) targ_archs=bfd_arc_arch ;; + arm*) targ_archs=bfd_arm_arch ;; +@@ -300,6 +301,40 @@ + targ_defvec=alpha_ecoff_le_vec + want64=true + ;; ++ sw_64*-*-freebsd* | sw_64*-*-kfreebsd*-gnu) ++ targ_defvec=sw_64_elf64_fbsd_vec ++ targ_selvecs="sw_64_elf64_vec sw_64_ecoff_le_vec" ++ want64=true ++ # FreeBSD <= 4.0 supports only the old nonstandard way of ABI labelling. ++ case "${targ}" in ++ sw_64*-*-freebsd3* | sw_64*-*-freebsd4 | sw_64*-*-freebsd4.0*) ++ targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;; ++ esac ++ ;; ++ sw_64*-*-netbsd* | sw_64*-*-openbsd*) ++ targ_defvec=sw_64_elf64_vec ++ targ_selvecs=sw_64_ecoff_le_vec ++ want64=true ++ ;; ++ sw_64*-*-linux*ecoff*) ++ targ_defvec=sw_64_ecoff_le_vec ++ targ_selvecs=sw_64_elf64_vec ++ want64=true ++ ;; ++ sw_64*-*-linux-* | sw_64*-*-elf*) ++ targ_defvec=sw_64_elf64_vec ++ targ_selvecs=sw_64_ecoff_le_vec ++ want64=true ++ ;; ++ sw_64*-*-*vms*) ++ targ_defvec=sw_64_vms_vec ++ targ_selvecs=sw_64_vms_lib_txt_vec ++ want64=true ++ ;; ++ sw_64*-*-*) ++ targ_defvec=sw_64_ecoff_le_vec ++ want64=true ++ ;; + ia64*-*-freebsd* | ia64*-*-netbsd* | ia64*-*-linux-* | ia64*-*-elf* | ia64*-*-kfreebsd*-gnu) + targ_defvec=ia64_elf64_le_vec + targ_selvecs="ia64_elf64_be_vec ia64_pei_vec" +diff -Nuar gdb-10.2/bfd/configure gdb-10.2/bfd/configure +--- gdb-10.2/bfd/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/configure 2025-04-16 17:06:51.912086800 +0800 +@@ -14748,6 +14748,10 @@ + alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; + alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; + alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;; ++ sw_64_ecoff_le_vec) tb="$tb coff-sw_64.lo ecoff.lo $ecoff"; target_size=64 ;; ++ sw_64_elf64_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; ++ sw_64_elf64_fbsd_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; ++ sw_64_vms_vec) tb="$tb vms-sw_64.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; + am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; + aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;; + aout64_vec) tb="$tb demo64.lo aout64.lo"; target_size=64 ;; +@@ -15161,6 +15165,19 @@ + alpha*-*-*) + COREFILE=osf-core.lo + ;; ++ sw_64*-*-freebsd* | sw_64*-*-kfreebsd*-gnu | sw_64*-*-*vms*) ++ COREFILE='' ++ ;; ++ sw_64*-*-linux-*) ++ COREFILE=trad-core.lo ++ TRAD_HEADER='"hosts/sw_64linux.h"' ++ ;; ++ sw_64*-*-netbsd* | sw_64*-*-openbsd*) ++ COREFILE=netbsd-core.lo ++ ;; ++ sw_64*-*-*) ++ COREFILE=osf-core.lo ++ ;; + arm-*-freebsd* | arm-*-kfreebsd*-gnu) + COREFILE='' ;; + arm*-*-netbsd* | arm-*-openbsd*) +diff -Nuar gdb-10.2/bfd/configure.ac gdb-10.2/bfd/configure.ac +--- gdb-10.2/bfd/configure.ac 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/configure.ac 2025-04-16 17:06:51.912086800 +0800 +@@ -454,6 +454,11 @@ + alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; + alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; + alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;; ++ sw_64_ecoff_le_vec) tb="$tb coff-sw_64.lo ecoff.lo $ecoff"; target_size=64 ;; ++ sw_64_elf64_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; ++ sw_64_elf64_fbsd_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; ++ sw_64_vms_vec) tb="$tb vms-sw_64.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; ++ sw_64_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;; + am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; + aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;; + aout64_vec) tb="$tb demo64.lo aout64.lo"; target_size=64 ;; +@@ -852,6 +857,19 @@ + alpha*-*-*) + COREFILE=osf-core.lo + ;; ++ sw_64*-*-freebsd* | sw_64*-*-kfreebsd*-gnu | sw_64*-*-*vms*) ++ COREFILE='' ++ ;; ++ sw_64*-*-linux-*) ++ COREFILE=trad-core.lo ++ TRAD_HEADER='"hosts/sw_64linux.h"' ++ ;; ++ sw_64*-*-netbsd* | sw_64*-*-openbsd*) ++ COREFILE=netbsd-core.lo ++ ;; ++ sw_64*-*-*) ++ COREFILE=osf-core.lo ++ ;; + arm-*-freebsd* | arm-*-kfreebsd*-gnu) + COREFILE='' ;; + arm*-*-netbsd* | arm-*-openbsd*) +diff -Nuar gdb-10.2/bfd/configure.com gdb-10.2/bfd/configure.com +--- gdb-10.2/bfd/configure.com 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/configure.com 2025-04-16 17:06:51.912086800 +0800 +@@ -26,9 +26,10 @@ + $ arch=F$GETSYI("ARCH_NAME") + $ arch=F$EDIT(arch,"LOWERCASE") + $if arch .eqs. "alpha" then target = "alpha" ++$if arch .eqs. "sw_64" then target = "sw_64" + $if arch .eqs. "ia64" then target = "ia64" + $! +-$if (arch .eqs. "alpha") .or. (arch .eqs. "ia64") ++$if (arch .eqs. "alpha") .or. (arch .eqs. "sw_64") .or. (arch .eqs. "ia64") + $then + $! + $ write sys$output "Configuring BFD for ''target' target" +@@ -335,6 +336,15 @@ + $ FILES="cpu-alpha,vms,vms-hdr,vms-gsd,vms-tir,vms-misc," + $EOD + $ endif ++$ if ARCH.eqs."sw_64" ++$ then ++$ create build.com ++$DECK ++$ DEFS="""SELECT_VECS=&sw_64_vms_vec"","+- ++ """SELECT_ARCHITECTURES=&bfd_sw_64_arch""" ++$ FILES="cpu-sw_64,vms,vms-hdr,vms-gsd,vms-tir,vms-misc," ++$EOD ++$ endif + $ if ARCH.eqs."ia64" + $ then + $ create build.com +diff -Nuar gdb-10.2/bfd/cpu-sw_64.c gdb-10.2/bfd/cpu-sw_64.c +--- gdb-10.2/bfd/cpu-sw_64.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/cpu-sw_64.c 2025-04-16 17:06:51.912086800 +0800 +@@ -0,0 +1,53 @@ ++/* BFD support for the SW_64 architecture. ++ Copyright (C) 1992-2019 Free Software Foundation, Inc. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "libbfd.h" ++ ++#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \ ++ { \ ++ BITS_WORD, /* Bits in a word. */ \ ++ BITS_ADDR, /* Bits in an address. */ \ ++ 8, /* Bits in a byte. */ \ ++ bfd_arch_sw_64, \ ++ NUMBER, \ ++ "sw_64", \ ++ PRINT, \ ++ 3, /* Section alignment power. */ \ ++ DEFAULT, \ ++ bfd_default_compatible, \ ++ bfd_default_scan, \ ++ bfd_arch_default_fill, \ ++ NEXT, \ ++ 0 /* Maximum offset of a reloc from the start of an insn. */ \ ++ } ++ ++#define NN(index) (&arch_info_struct[index]) ++ ++/* These exist only so that we can reasonably disassemble PALcode. */ ++static const bfd_arch_info_type arch_info_struct[] = ++{ ++ N (64, 64, bfd_mach_sw_64_sw6a, "sw_64:sw6a", FALSE, NN(1)), ++ N (64, 64, bfd_mach_sw_64_sw6b, "sw_64:sw6b", FALSE, 0), ++}; ++ ++const bfd_arch_info_type bfd_sw_64_arch = ++ N (64, 64, 0, "sw_64", TRUE, NN(0)); +diff -Nuar gdb-10.2/bfd/ecoff.c gdb-10.2/bfd/ecoff.c +--- gdb-10.2/bfd/ecoff.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/ecoff.c 2025-04-16 17:06:51.912086800 +0800 +@@ -233,6 +233,10 @@ + arch = bfd_arch_alpha; + mach = 0; + break; ++ case SW_64_MAGIC: ++ arch = bfd_arch_sw_64; ++ mach = 0; ++ break; + + default: + arch = bfd_arch_obscure; +@@ -287,6 +291,9 @@ + case bfd_arch_alpha: + return ALPHA_MAGIC; + ++ case bfd_arch_sw_64: ++ return SW_64_MAGIC; ++ + default: + abort (); + return 0; +diff -Nuar gdb-10.2/bfd/elf64-sw_64.c gdb-10.2/bfd/elf64-sw_64.c +--- gdb-10.2/bfd/elf64-sw_64.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/elf64-sw_64.c 2025-04-16 17:06:51.922086800 +0800 +@@ -0,0 +1,5575 @@ ++/* Sw_64 specific support for 64-bit ELF ++ Copyright (C) 1996-2020 Free Software Foundation, Inc. ++ Contributed by Richard Henderson . ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++ ++/* We need a published ABI spec for this. Until one comes out, don't ++ assume this'll remain unchanged forever. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "libbfd.h" ++#include "elf-bfd.h" ++#include "ecoff-bfd.h" ++ ++#include "elf/sw_64.h" ++ ++#define SW_64ECOFF ++ ++#define NO_COFF_RELOCS ++#define NO_COFF_SYMBOLS ++#define NO_COFF_LINENOS ++ ++/* Get the ECOFF swapping routines. Needed for the debug information. */ ++#include "coff/internal.h" ++#include "coff/sym.h" ++#include "coff/symconst.h" ++#include "coff/ecoff.h" ++#include "coff/sw_64.h" ++#include "aout/ar.h" ++#include "libcoff.h" ++#include "libecoff.h" ++#define ECOFF_64 ++#include "ecoffswap.h" ++ ++ ++/* Instruction data for plt generation and relaxation. */ ++ ++#define OP_LDA 0x08U ++#define OP_LDAH 0x09U ++#define OP_LDQ 0x29U ++#define OP_BR 0x30U ++#define OP_BSR 0x34U ++ ++#define INSN_LDA (OP_LDA << 26) ++#define INSN_LDAH (OP_LDAH << 26) ++#define INSN_LDQ (OP_LDQ << 26) ++#define INSN_BR (OP_BR << 26) ++ ++#define INSN_ADDQ 0x40000400 ++#define INSN_RDUNIQ 0x0000009e ++#define INSN_SUBQ 0x40000520 ++#define INSN_S4SUBQ 0x40000560 ++#define INSN_UNOP 0x2ffe0000 ++ ++#define INSN_JSR 0x68004000 ++#define INSN_JMP 0x68000000 ++#define INSN_JSR_MASK 0xfc00c000 ++ ++#define INSN_A(I,A) (I | ((unsigned) A << 21)) ++#define INSN_AB(I,A,B) (INSN_A (I, A) | (B << 16)) ++#define INSN_ABC(I,A,B,C) (INSN_A (I, A) | (B << 16) | C) ++#define INSN_ABO(I,A,B,O) (INSN_A (I, A) | (B << 16) | ((O) & 0xffff)) ++#define INSN_AD(I,A,D) (INSN_A (I, A) | (((D) >> 2) & 0x1fffff)) ++ ++/* PLT/GOT Stuff */ ++ ++/* Set by ld emulation. Putting this into the link_info or hash structure ++ is simply working too hard. */ ++#ifdef USE_SECUREPLT ++bfd_boolean elf64_sw_64_use_secureplt = TRUE; ++#else ++bfd_boolean elf64_sw_64_use_secureplt = FALSE; ++#endif ++ ++#define OLD_PLT_HEADER_SIZE 32 ++#define OLD_PLT_ENTRY_SIZE 12 ++#define NEW_PLT_HEADER_SIZE 36 ++#define NEW_PLT_ENTRY_SIZE 4 ++ ++#define PLT_HEADER_SIZE \ ++ (elf64_sw_64_use_secureplt ? NEW_PLT_HEADER_SIZE : OLD_PLT_HEADER_SIZE) ++#define PLT_ENTRY_SIZE \ ++ (elf64_sw_64_use_secureplt ? NEW_PLT_ENTRY_SIZE : OLD_PLT_ENTRY_SIZE) ++ ++#define MAX_GOT_SIZE (64*1024) ++ ++#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so" ++ ++ ++/* Used to implement multiple .got subsections. */ ++struct sw_64_elf_got_entry ++{ ++ struct sw_64_elf_got_entry *next; ++ ++ /* Which .got subsection? */ ++ bfd *gotobj; ++ ++ /* The addend in effect for this entry. */ ++ bfd_vma addend; ++ ++ /* The .got offset for this entry. */ ++ int got_offset; ++ ++ /* The .plt offset for this entry. */ ++ int plt_offset; ++ ++ /* How many references to this entry? */ ++ int use_count; ++ ++ /* The relocation type of this entry. */ ++ unsigned char reloc_type; ++ ++ /* How a LITERAL is used. */ ++ unsigned char flags; ++ ++ /* Have we initialized the dynamic relocation for this entry? */ ++ unsigned char reloc_done; ++ ++ /* Have we adjusted this entry for SEC_MERGE? */ ++ unsigned char reloc_xlated; ++}; ++ ++struct sw_64_elf_reloc_entry ++{ ++ struct sw_64_elf_reloc_entry *next; ++ ++ /* Which .reloc section? */ ++ asection *srel; ++ ++ /* Which section this relocation is against? */ ++ asection *sec; ++ ++ /* How many did we find? */ ++ unsigned long count; ++ ++ /* What kind of relocation? */ ++ unsigned int rtype; ++}; ++ ++struct sw_64_elf_link_hash_entry ++{ ++ struct elf_link_hash_entry root; ++ ++ /* External symbol information. */ ++ EXTR esym; ++ ++ /* Cumulative flags for all the .got entries. */ ++ int flags; ++ ++ /* Contexts in which a literal was referenced. */ ++#define SW_64_ELF_LINK_HASH_LU_ADDR 0x01 ++#define SW_64_ELF_LINK_HASH_LU_MEM 0x02 ++#define SW_64_ELF_LINK_HASH_LU_BYTE 0x04 ++#define SW_64_ELF_LINK_HASH_LU_JSR 0x08 ++#define SW_64_ELF_LINK_HASH_LU_TLSGD 0x10 ++#define SW_64_ELF_LINK_HASH_LU_TLSLDM 0x20 ++#define SW_64_ELF_LINK_HASH_LU_JSRDIRECT 0x40 ++#define SW_64_ELF_LINK_HASH_LU_PLT 0x38 ++#define SW_64_ELF_LINK_HASH_TLS_IE 0x80 ++ ++ /* Used to implement multiple .got subsections. */ ++ struct sw_64_elf_got_entry *got_entries; ++ ++ /* Used to count non-got, non-plt relocations for delayed sizing ++ of relocation sections. */ ++ struct sw_64_elf_reloc_entry *reloc_entries; ++}; ++ ++/* Sw_64 ELF linker hash table. */ ++ ++struct sw_64_elf_link_hash_table ++{ ++ struct elf_link_hash_table root; ++ ++ /* The head of a list of .got subsections linked through ++ sw_64_elf_tdata(abfd)->got_link_next. */ ++ bfd *got_list; ++ ++ /* The most recent relax pass that we've seen. The GOTs ++ should be regenerated if this doesn't match. */ ++ int relax_trip; ++}; ++ ++/* Look up an entry in a Sw_64 ELF linker hash table. */ ++ ++#define sw_64_elf_link_hash_lookup(table, string, create, copy, follow) \ ++ ((struct sw_64_elf_link_hash_entry *) \ ++ elf_link_hash_lookup (&(table)->root, (string), (create), \ ++ (copy), (follow))) ++ ++/* Traverse a Sw_64 ELF linker hash table. */ ++ ++#define sw_64_elf_link_hash_traverse(table, func, info) \ ++ (elf_link_hash_traverse \ ++ (&(table)->root, \ ++ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ ++ (info))) ++ ++/* Get the Sw_64 ELF linker hash table from a link_info structure. */ ++ ++#define sw_64_elf_hash_table(p) \ ++ ((is_elf_hash_table ((p)->hash) \ ++ && elf_hash_table_id (elf_hash_table (p)) == SW_64_ELF_DATA) \ ++ ? (struct sw_64_elf_link_hash_table *) (p)->hash : NULL) ++ ++/* Get the object's symbols as our own entry type. */ ++ ++#define sw_64_elf_sym_hashes(abfd) \ ++ ((struct sw_64_elf_link_hash_entry **)elf_sym_hashes(abfd)) ++ ++/* Should we do dynamic things to this symbol? This differs from the ++ generic version in that we never need to consider function pointer ++ equality wrt PLT entries -- we don't create a PLT entry if a symbol's ++ address is ever taken. */ ++ ++static inline bfd_boolean ++sw_64_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, ++ struct bfd_link_info *info) ++{ ++ return _bfd_elf_dynamic_symbol_p (h, info, 0); ++} ++ ++/* Create an entry in a Sw_64 ELF linker hash table. */ ++ ++static struct bfd_hash_entry * ++elf64_sw_64_link_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct sw_64_elf_link_hash_entry *ret = ++ (struct sw_64_elf_link_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == (struct sw_64_elf_link_hash_entry *) NULL) ++ ret = ((struct sw_64_elf_link_hash_entry *) ++ bfd_hash_allocate (table, ++ sizeof (struct sw_64_elf_link_hash_entry))); ++ if (ret == (struct sw_64_elf_link_hash_entry *) NULL) ++ return (struct bfd_hash_entry *) ret; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = ((struct sw_64_elf_link_hash_entry *) ++ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, ++ table, string)); ++ if (ret != (struct sw_64_elf_link_hash_entry *) NULL) ++ { ++ /* Set local fields. */ ++ memset (&ret->esym, 0, sizeof (EXTR)); ++ /* We use -2 as a marker to indicate that the information has ++ not been set. -1 means there is no associated ifd. */ ++ ret->esym.ifd = -2; ++ ret->flags = 0; ++ ret->got_entries = NULL; ++ ret->reloc_entries = NULL; ++ } ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++/* Create a Sw_64 ELF linker hash table. */ ++ ++static struct bfd_link_hash_table * ++elf64_sw_64_bfd_link_hash_table_create (bfd *abfd) ++{ ++ struct sw_64_elf_link_hash_table *ret; ++ size_t amt = sizeof (struct sw_64_elf_link_hash_table); ++ ++ ret = (struct sw_64_elf_link_hash_table *) bfd_zmalloc (amt); ++ if (ret == (struct sw_64_elf_link_hash_table *) NULL) ++ return NULL; ++ ++ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, ++ elf64_sw_64_link_hash_newfunc, ++ sizeof (struct sw_64_elf_link_hash_entry), ++ SW_64_ELF_DATA)) ++ { ++ free (ret); ++ return NULL; ++ } ++ ++ return &ret->root.root; ++} ++ ++/* Sw_64 ELF follows MIPS ELF in using a special find_nearest_line ++ routine in order to handle the ECOFF debugging information. */ ++ ++struct sw_64_elf_find_line ++{ ++ struct ecoff_debug_info d; ++ struct ecoff_find_line i; ++}; ++ ++/* We have some private fields hanging off of the elf_tdata structure. */ ++ ++struct sw_64_elf_obj_tdata ++{ ++ struct elf_obj_tdata root; ++ ++ /* For every input file, these are the got entries for that object's ++ local symbols. */ ++ struct sw_64_elf_got_entry ** local_got_entries; ++ ++ /* For every input file, this is the object that owns the got that ++ this input file uses. */ ++ bfd *gotobj; ++ ++ /* For every got, this is a linked list through the objects using this got */ ++ bfd *in_got_link_next; ++ ++ /* For every got, this is a link to the next got subsegment. */ ++ bfd *got_link_next; ++ ++ /* For every got, this is the section. */ ++ asection *got; ++ ++ /* For every got, this is it's total number of words. */ ++ int total_got_size; ++ ++ /* For every got, this is the sum of the number of words required ++ to hold all of the member object's local got. */ ++ int local_got_size; ++ ++ /* Used by elf64_sw_64_find_nearest_line entry point. */ ++ struct sw_64_elf_find_line *find_line_info; ++ ++}; ++ ++#define sw_64_elf_tdata(abfd) \ ++ ((struct sw_64_elf_obj_tdata *) (abfd)->tdata.any) ++ ++#define is_sw_64_elf(bfd) \ ++ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ ++ && elf_tdata (bfd) != NULL \ ++ && elf_object_id (bfd) == SW_64_ELF_DATA) ++ ++static bfd_boolean ++elf64_sw_64_mkobject (bfd *abfd) ++{ ++ return bfd_elf_allocate_object (abfd, sizeof (struct sw_64_elf_obj_tdata), ++ SW_64_ELF_DATA); ++} ++ ++static bfd_boolean ++elf64_sw_64_object_p (bfd *abfd) ++{ ++ /* Set the right machine number for an Sw_64 ELF file. */ ++ return bfd_default_set_arch_mach (abfd, bfd_arch_sw_64, 0); ++} ++ ++/* A relocation function which doesn't do anything. */ ++ ++static bfd_reloc_status_type ++elf64_sw_64_reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc, ++ asymbol *sym ATTRIBUTE_UNUSED, ++ void * data ATTRIBUTE_UNUSED, asection *sec, ++ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) ++{ ++ if (output_bfd) ++ reloc->address += sec->output_offset; ++ return bfd_reloc_ok; ++} ++ ++/* A relocation function used for an unsupported reloc. */ ++ ++static bfd_reloc_status_type ++elf64_sw_64_reloc_bad (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc, ++ asymbol *sym ATTRIBUTE_UNUSED, ++ void * data ATTRIBUTE_UNUSED, asection *sec, ++ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) ++{ ++ if (output_bfd) ++ reloc->address += sec->output_offset; ++ return bfd_reloc_notsupported; ++} ++ ++/* Do the work of the GPDISP relocation. */ ++ ++static bfd_reloc_status_type ++elf64_sw_64_do_reloc_gpdisp (bfd *abfd, bfd_vma gpdisp, bfd_byte *p_ldah, ++ bfd_byte *p_lda) ++{ ++ bfd_reloc_status_type ret = bfd_reloc_ok; ++ bfd_vma addend; ++ unsigned long i_ldah, i_lda; ++ ++ i_ldah = bfd_get_32 (abfd, p_ldah); ++ i_lda = bfd_get_32 (abfd, p_lda); ++ ++ /* Complain if the instructions are not correct. */ ++#ifndef XWB20200308 ++ if (((i_ldah >> 26) & 0x3f) != 0x3f ++ || ((i_lda >> 26) & 0x3f) != 0x3e) ++#else ++ if (((i_ldah >> 26) & 0x3f) != 0x09 ++ || ((i_lda >> 26) & 0x3f) != 0x08) ++#endif ++ ret = bfd_reloc_dangerous; ++ ++ /* Extract the user-supplied offset, mirroring the sign extensions ++ that the instructions perform. */ ++ addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff); ++ addend = (addend ^ 0x80008000) - 0x80008000; ++ ++ gpdisp += addend; ++ ++ if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000 ++ || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000) ++ ret = bfd_reloc_overflow; ++ ++ /* compensate for the sign extension again. */ ++ i_ldah = ((i_ldah & 0xffff0000) ++ | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff)); ++ i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff); ++ ++ bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah); ++ bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda); ++ ++ return ret; ++} ++ ++/* The special function for the GPDISP reloc. */ ++ ++static bfd_reloc_status_type ++elf64_sw_64_reloc_gpdisp (bfd *abfd, arelent *reloc_entry, ++ asymbol *sym ATTRIBUTE_UNUSED, void * data, ++ asection *input_section, bfd *output_bfd, ++ char **err_msg) ++{ ++ bfd_reloc_status_type ret; ++ bfd_vma gp, relocation; ++ bfd_vma high_address; ++ bfd_byte *p_ldah, *p_lda; ++ ++ /* Don't do anything if we're not doing a final link. */ ++ if (output_bfd) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ high_address = bfd_get_section_limit (abfd, input_section); ++ if (reloc_entry->address > high_address ++ || reloc_entry->address + reloc_entry->addend > high_address) ++ return bfd_reloc_outofrange; ++ ++ /* The gp used in the portion of the output object to which this ++ input object belongs is cached on the input bfd. */ ++ gp = _bfd_get_gp_value (abfd); ++ ++ relocation = (input_section->output_section->vma ++ + input_section->output_offset ++ + reloc_entry->address); ++ ++ p_ldah = (bfd_byte *) data + reloc_entry->address; ++ p_lda = p_ldah + reloc_entry->addend; ++ ++ ret = elf64_sw_64_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda); ++ ++ /* Complain if the instructions are not correct. */ ++ if (ret == bfd_reloc_dangerous) ++ *err_msg = _("GPDISP relocation did not find ldah and lda instructions"); ++ ++ return ret; ++} ++ ++/* In case we're on a 32-bit machine, construct a 64-bit "-1" value ++ from smaller values. Start with zero, widen, *then* decrement. */ ++#define MINUS_ONE (((bfd_vma)0) - 1) ++ ++ ++#define SKIP_HOWTO(N) \ ++ HOWTO(N, 0, 0, 0, 0, 0, complain_overflow_dont, elf64_sw_64_reloc_bad, 0, 0, 0, 0, 0) ++ ++static reloc_howto_type elf64_sw_64_howto_table[] = ++{ ++ HOWTO (R_SW_64_NONE, /* type */ ++ 0, /* rightshift */ ++ 3, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ elf64_sw_64_reloc_nil, /* special_function */ ++ "NONE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A 32 bit reference to a symbol. */ ++ HOWTO (R_SW_64_REFLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "REFLONG", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 64 bit reference to a symbol. */ ++ HOWTO (R_SW_64_REFQUAD, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "REFQUAD", /* name */ ++ FALSE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 32 bit GP relative offset. This is just like REFLONG except ++ that when the value is used the value of the gp register will be ++ added in. */ ++ HOWTO (R_SW_64_GPREL32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GPREL32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Used for an instruction that refers to memory off the GP register. */ ++ HOWTO (R_SW_64_LITERAL, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "ELF_LITERAL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* This reloc only appears immediately following an ELF_LITERAL reloc. ++ It identifies a use of the literal. The symbol index is special: ++ 1 means the literal address is in the base register of a memory ++ format instruction; 2 means the literal address is in the byte ++ offset register of a byte-manipulation instruction; 3 means the ++ literal address is in the target register of a jsr instruction. ++ This does not actually do any relocation. */ ++ HOWTO (R_SW_64_LITUSE, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ elf64_sw_64_reloc_nil, /* special_function */ ++ "LITUSE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Load the gp register. This is always used for a ldah instruction ++ which loads the upper 16 bits of the gp register. The symbol ++ index of the GPDISP instruction is an offset in bytes to the lda ++ instruction that loads the lower 16 bits. The value to use for ++ the relocation is the difference between the GP value and the ++ current location; the load will always be done against a register ++ holding the current address. ++ ++ NOTE: Unlike ECOFF, partial in-place relocation is not done. If ++ any offset is present in the instructions, it is an offset from ++ the register to the ldah instruction. This lets us avoid any ++ stupid hackery like inventing a gp value to do partial relocation ++ against. Also unlike ECOFF, we do the whole relocation off of ++ the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd, ++ space consuming bit, that, since all the information was present ++ in the GPDISP_HI16 reloc. */ ++ HOWTO (R_SW_64_GPDISP, /* type */ ++ 16, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ elf64_sw_64_reloc_gpdisp, /* special_function */ ++ "GPDISP", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A 21 bit branch. */ ++ HOWTO (R_SW_64_BRADDR, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 21, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "BRADDR", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x1fffff, /* src_mask */ ++ 0x1fffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A hint for a jump to a register. */ ++#ifndef XWB20200308 ++ HOWTO (R_SW_64_HINT, /* type */ ++ 2, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "HINT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++#else ++ HOWTO (R_SW_64_HINT, /* type */ ++ 2, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 14, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "HINT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x3fff, /* src_mask */ ++ 0x3fff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++#endif ++ ++ /* 16 bit PC relative offset. */ ++ HOWTO (R_SW_64_SREL16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "SREL16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* 32 bit PC relative offset. */ ++ HOWTO (R_SW_64_SREL32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "SREL32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A 64 bit PC relative offset. */ ++ HOWTO (R_SW_64_SREL64, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "SREL64", /* name */ ++ FALSE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* Skip 12 - 16; deprecated ECOFF relocs. */ ++ SKIP_HOWTO (12), ++ SKIP_HOWTO (13), ++ SKIP_HOWTO (14), ++ SKIP_HOWTO (15), ++ SKIP_HOWTO (16), ++ ++ /* The high 16 bits of the displacement from GP to the target. */ ++ HOWTO (R_SW_64_GPRELHIGH, ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GPRELHIGH", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* The low 16 bits of the displacement from GP to the target. */ ++ HOWTO (R_SW_64_GPRELLOW, ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GPRELLOW", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 16-bit displacement from the GP to the target. */ ++ HOWTO (R_SW_64_GPREL16, ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GPREL16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Skip 20 - 23; deprecated ECOFF relocs. */ ++ SKIP_HOWTO (20), ++ SKIP_HOWTO (21), ++ SKIP_HOWTO (22), ++ SKIP_HOWTO (23), ++ ++ /* Misc ELF relocations. */ ++ ++ /* A dynamic relocation to copy the target into our .dynbss section. */ ++ /* Not generated, as all Sw_64 objects use PIC, so it is not needed. It ++ is present because every other ELF has one, but should not be used ++ because .dynbss is an ugly thing. */ ++ HOWTO (R_SW_64_COPY, ++ 0, ++ 0, ++ 0, ++ FALSE, ++ 0, ++ complain_overflow_dont, ++ bfd_elf_generic_reloc, ++ "COPY", ++ FALSE, ++ 0, ++ 0, ++ TRUE), ++ ++ /* A dynamic relocation for a .got entry. */ ++ HOWTO (R_SW_64_GLOB_DAT, ++ 0, ++ 0, ++ 0, ++ FALSE, ++ 0, ++ complain_overflow_dont, ++ bfd_elf_generic_reloc, ++ "GLOB_DAT", ++ FALSE, ++ 0, ++ 0, ++ TRUE), ++ ++ /* A dynamic relocation for a .plt entry. */ ++ HOWTO (R_SW_64_JMP_SLOT, ++ 0, ++ 0, ++ 0, ++ FALSE, ++ 0, ++ complain_overflow_dont, ++ bfd_elf_generic_reloc, ++ "JMP_SLOT", ++ FALSE, ++ 0, ++ 0, ++ TRUE), ++ ++ /* A dynamic relocation to add the base of the DSO to a 64-bit field. */ ++ HOWTO (R_SW_64_RELATIVE, ++ 0, ++ 0, ++ 0, ++ FALSE, ++ 0, ++ complain_overflow_dont, ++ bfd_elf_generic_reloc, ++ "RELATIVE", ++ FALSE, ++ 0, ++ 0, ++ TRUE), ++ ++ /* A 21 bit branch that adjusts for gp loads. */ ++ HOWTO (R_SW_64_BRSGP, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 21, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "BRSGP", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x1fffff, /* src_mask */ ++ 0x1fffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* Creates a tls_index for the symbol in the got. */ ++ HOWTO (R_SW_64_TLSGD, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TLSGD", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Creates a tls_index for the (current) module in the got. */ ++ HOWTO (R_SW_64_TLSLDM, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TLSLDM", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A dynamic relocation for a DTP module entry. */ ++ HOWTO (R_SW_64_DTPMOD64, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "DTPMOD64", /* name */ ++ FALSE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Creates a 64-bit offset in the got for the displacement ++ from DTP to the target. */ ++ HOWTO (R_SW_64_GOTDTPREL, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GOTDTPREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A dynamic relocation for a displacement from DTP to the target. */ ++ HOWTO (R_SW_64_DTPREL64, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "DTPREL64", /* name */ ++ FALSE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* The high 16 bits of the displacement from DTP to the target. */ ++ HOWTO (R_SW_64_DTPRELHI, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "DTPRELHI", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* The low 16 bits of the displacement from DTP to the target. */ ++ HOWTO (R_SW_64_DTPRELLO, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "DTPRELLO", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 16-bit displacement from DTP to the target. */ ++ HOWTO (R_SW_64_DTPREL16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "DTPREL16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Creates a 64-bit offset in the got for the displacement ++ from TP to the target. */ ++ HOWTO (R_SW_64_GOTTPREL, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "GOTTPREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A dynamic relocation for a displacement from TP to the target. */ ++ HOWTO (R_SW_64_TPREL64, /* type */ ++ 0, /* rightshift */ ++ 4, /* size (0 = byte, 1 = short, 2 = long) */ ++ 64, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TPREL64", /* name */ ++ FALSE, /* partial_inplace */ ++ MINUS_ONE, /* src_mask */ ++ MINUS_ONE, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* The high 16 bits of the displacement from TP to the target. */ ++ HOWTO (R_SW_64_TPRELHI, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TPRELHI", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* The low 16 bits of the displacement from TP to the target. */ ++ HOWTO (R_SW_64_TPRELLO, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TPRELLO", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 16-bit displacement from TP to the target. */ ++ HOWTO (R_SW_64_TPREL16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "TPREL16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++}; ++ ++/* A mapping from BFD reloc types to Sw_64 ELF reloc types. */ ++ ++struct elf_reloc_map ++{ ++ bfd_reloc_code_real_type bfd_reloc_val; ++ int elf_reloc_val; ++}; ++ ++static const struct elf_reloc_map elf64_sw_64_reloc_map[] = ++{ ++ {BFD_RELOC_NONE, R_SW_64_NONE}, ++ {BFD_RELOC_32, R_SW_64_REFLONG}, ++ {BFD_RELOC_64, R_SW_64_REFQUAD}, ++ {BFD_RELOC_CTOR, R_SW_64_REFQUAD}, ++ {BFD_RELOC_GPREL32, R_SW_64_GPREL32}, ++ {BFD_RELOC_SW_64_ELF_LITERAL, R_SW_64_LITERAL}, ++ {BFD_RELOC_SW_64_LITUSE, R_SW_64_LITUSE}, ++ {BFD_RELOC_SW_64_GPDISP, R_SW_64_GPDISP}, ++ {BFD_RELOC_23_PCREL_S2, R_SW_64_BRADDR}, ++ {BFD_RELOC_SW_64_HINT, R_SW_64_HINT}, ++ {BFD_RELOC_16_PCREL, R_SW_64_SREL16}, ++ {BFD_RELOC_32_PCREL, R_SW_64_SREL32}, ++ {BFD_RELOC_64_PCREL, R_SW_64_SREL64}, ++#ifndef XWB20200308 ++ {BFD_RELOC_20_PCREL_S2, R_SW_64_BR18ADDR}, ++ {BFD_RELOC_24_PCREL_S2, R_SW_64_BR22ADDR}, ++#endif ++ {BFD_RELOC_SW_64_GPREL_HI16, R_SW_64_GPRELHIGH}, ++ {BFD_RELOC_SW_64_GPREL_LO16, R_SW_64_GPRELLOW}, ++ {BFD_RELOC_GPREL16, R_SW_64_GPREL16}, ++ {BFD_RELOC_SW_64_BRSGP, R_SW_64_BRSGP}, ++ {BFD_RELOC_SW_64_TLSGD, R_SW_64_TLSGD}, ++ {BFD_RELOC_SW_64_TLSLDM, R_SW_64_TLSLDM}, ++ {BFD_RELOC_SW_64_DTPMOD64, R_SW_64_DTPMOD64}, ++ {BFD_RELOC_SW_64_GOTDTPREL16, R_SW_64_GOTDTPREL}, ++ {BFD_RELOC_SW_64_DTPREL64, R_SW_64_DTPREL64}, ++ {BFD_RELOC_SW_64_DTPREL_HI16, R_SW_64_DTPRELHI}, ++ {BFD_RELOC_SW_64_DTPREL_LO16, R_SW_64_DTPRELLO}, ++ {BFD_RELOC_SW_64_DTPREL16, R_SW_64_DTPREL16}, ++ {BFD_RELOC_SW_64_GOTTPREL16, R_SW_64_GOTTPREL}, ++ {BFD_RELOC_SW_64_TPREL64, R_SW_64_TPREL64}, ++ {BFD_RELOC_SW_64_TPREL_HI16, R_SW_64_TPRELHI}, ++ {BFD_RELOC_SW_64_TPREL_LO16, R_SW_64_TPRELLO}, ++ {BFD_RELOC_SW_64_TPREL16, R_SW_64_TPREL16}, ++}; ++ ++/* Given a BFD reloc type, return a HOWTO structure. */ ++ ++static reloc_howto_type * ++elf64_sw_64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ bfd_reloc_code_real_type code) ++{ ++ const struct elf_reloc_map *i, *e; ++ i = e = elf64_sw_64_reloc_map; ++ e += sizeof (elf64_sw_64_reloc_map) / sizeof (struct elf_reloc_map); ++ for (; i != e; ++i) ++ { ++ if (i->bfd_reloc_val == code) ++ return &elf64_sw_64_howto_table[i->elf_reloc_val]; ++ } ++ return 0; ++} ++ ++static reloc_howto_type * ++elf64_sw_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ const char *r_name) ++{ ++ unsigned int i; ++ ++ for (i = 0; ++ i < (sizeof (elf64_sw_64_howto_table) ++ / sizeof (elf64_sw_64_howto_table[0])); ++ i++) ++ if (elf64_sw_64_howto_table[i].name != NULL ++ && strcasecmp (elf64_sw_64_howto_table[i].name, r_name) == 0) ++ return &elf64_sw_64_howto_table[i]; ++ ++ return NULL; ++} ++ ++/* Given an Sw_64 ELF reloc type, fill in an arelent structure. */ ++ ++static bfd_boolean ++elf64_sw_64_info_to_howto (bfd *abfd, arelent *cache_ptr, ++ Elf_Internal_Rela *dst) ++{ ++ unsigned r_type = ELF64_R_TYPE(dst->r_info); ++ ++ if (r_type >= R_SW_64_max) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), ++ abfd, r_type); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ cache_ptr->howto = &elf64_sw_64_howto_table[r_type]; ++ return TRUE; ++} ++ ++/* These two relocations create a two-word entry in the got. */ ++#define sw_64_got_entry_size(r_type) \ ++ (r_type == R_SW_64_TLSGD || r_type == R_SW_64_TLSLDM ? 16 : 8) ++ ++/* This is PT_TLS segment p_vaddr. */ ++#define sw_64_get_dtprel_base(info) \ ++ (elf_hash_table (info)->tls_sec->vma) ++ ++/* Main program TLS (whose template starts at PT_TLS p_vaddr) ++ is assigned offset round(16, PT_TLS p_align). */ ++#define sw_64_get_tprel_base(info) \ ++ (elf_hash_table (info)->tls_sec->vma \ ++ - align_power ((bfd_vma) 16, \ ++ elf_hash_table (info)->tls_sec->alignment_power)) ++ ++/* Handle an Sw_64 specific section when reading an object file. This ++ is called when bfd_section_from_shdr finds a section with an unknown ++ type. */ ++ ++static bfd_boolean ++elf64_sw_64_section_from_shdr (bfd *abfd, ++ Elf_Internal_Shdr *hdr, ++ const char *name, ++ int shindex) ++{ ++ asection *newsect; ++ ++ /* There ought to be a place to keep ELF backend specific flags, but ++ at the moment there isn't one. We just keep track of the ++ sections by their name, instead. Fortunately, the ABI gives ++ suggested names for all the MIPS specific sections, so we will ++ probably get away with this. */ ++ switch (hdr->sh_type) ++ { ++ case SHT_SW_64_DEBUG: ++ if (strcmp (name, ".mdebug") != 0) ++ return FALSE; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) ++ return FALSE; ++ newsect = hdr->bfd_section; ++ ++ if (hdr->sh_type == SHT_SW_64_DEBUG) ++ { ++ if (!bfd_set_section_flags (newsect, ++ bfd_section_flags (newsect) | SEC_DEBUGGING)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Convert Sw_64 specific section flags to bfd internal section flags. */ ++ ++static bfd_boolean ++elf64_sw_64_section_flags (const Elf_Internal_Shdr *hdr) ++{ ++ if (hdr->sh_flags & SHF_SW_64_GPREL) ++ hdr->bfd_section->flags |= SEC_SMALL_DATA; ++ ++ return TRUE; ++} ++ ++/* Set the correct type for an Sw_64 ELF section. We do this by the ++ section name, which is a hack, but ought to work. */ ++ ++static bfd_boolean ++elf64_sw_64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec) ++{ ++ register const char *name; ++ ++ name = bfd_section_name (sec); ++ ++ if (strcmp (name, ".mdebug") == 0) ++ { ++ hdr->sh_type = SHT_SW_64_DEBUG; ++ /* In a shared object on Irix 5.3, the .mdebug section has an ++ entsize of 0. FIXME: Does this matter? */ ++ if ((abfd->flags & DYNAMIC) != 0 ) ++ hdr->sh_entsize = 0; ++ else ++ hdr->sh_entsize = 1; ++ } ++ else if ((sec->flags & SEC_SMALL_DATA) ++ || strcmp (name, ".sdata") == 0 ++ || strcmp (name, ".sbss") == 0 ++ || strcmp (name, ".lit4") == 0 ++ || strcmp (name, ".lit8") == 0) ++ hdr->sh_flags |= SHF_SW_64_GPREL; ++ ++ return TRUE; ++} ++ ++/* Hook called by the linker routine which adds symbols from an object ++ file. We use it to put .comm items in .sbss, and not .bss. */ ++ ++static bfd_boolean ++elf64_sw_64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, ++ Elf_Internal_Sym *sym, ++ const char **namep ATTRIBUTE_UNUSED, ++ flagword *flagsp ATTRIBUTE_UNUSED, ++ asection **secp, bfd_vma *valp) ++{ ++ if (sym->st_shndx == SHN_COMMON ++ && !bfd_link_relocatable (info) ++ && sym->st_size <= elf_gp_size (abfd)) ++ { ++ /* Common symbols less than or equal to -G nn bytes are ++ automatically put into .sbss. */ ++ ++ asection *scomm = bfd_get_section_by_name (abfd, ".scommon"); ++ ++ if (scomm == NULL) ++ { ++ scomm = bfd_make_section_with_flags (abfd, ".scommon", ++ (SEC_ALLOC ++ | SEC_IS_COMMON ++ | SEC_SMALL_DATA ++ | SEC_LINKER_CREATED)); ++ if (scomm == NULL) ++ return FALSE; ++ } ++ ++ *secp = scomm; ++ *valp = sym->st_size; ++ } ++ ++ return TRUE; ++} ++ ++/* Create the .got section. */ ++ ++static bfd_boolean ++elf64_sw_64_create_got_section (bfd *abfd, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED) ++{ ++ flagword flags; ++ asection *s; ++ ++ if (! is_sw_64_elf (abfd)) ++ return FALSE; ++ ++ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ++ | SEC_LINKER_CREATED); ++ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, 3)) ++ return FALSE; ++ ++ sw_64_elf_tdata (abfd)->got = s; ++ ++ /* Make sure the object's gotobj is set to itself so that we default ++ to every object with its own .got. We'll merge .gots later once ++ we've collected each object's info. */ ++ sw_64_elf_tdata (abfd)->gotobj = abfd; ++ ++ return TRUE; ++} ++ ++/* Create all the dynamic sections. */ ++ ++static bfd_boolean ++elf64_sw_64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) ++{ ++ asection *s; ++ flagword flags; ++ struct elf_link_hash_entry *h; ++ ++ if (! is_sw_64_elf (abfd)) ++ return FALSE; ++ ++ /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */ ++ ++ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY ++ | SEC_LINKER_CREATED ++ | (elf64_sw_64_use_secureplt ? SEC_READONLY : 0)); ++ s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags); ++ elf_hash_table (info)->splt = s; ++ if (s == NULL || ! bfd_set_section_alignment (s, 4)) ++ return FALSE; ++ ++ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the ++ .plt section. */ ++ h = _bfd_elf_define_linkage_sym (abfd, info, s, ++ "_PROCEDURE_LINKAGE_TABLE_"); ++ elf_hash_table (info)->hplt = h; ++ if (h == NULL) ++ return FALSE; ++ ++ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ++ | SEC_LINKER_CREATED | SEC_READONLY); ++ s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags); ++ elf_hash_table (info)->srelplt = s; ++ if (s == NULL || ! bfd_set_section_alignment (s, 3)) ++ return FALSE; ++ ++ if (elf64_sw_64_use_secureplt) ++ { ++ flags = SEC_ALLOC | SEC_LINKER_CREATED; ++ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); ++ elf_hash_table (info)->sgotplt = s; ++ if (s == NULL || ! bfd_set_section_alignment (s, 3)) ++ return FALSE; ++ } ++ ++ /* We may or may not have created a .got section for this object, but ++ we definitely havn't done the rest of the work. */ ++ ++ if (sw_64_elf_tdata(abfd)->gotobj == NULL) ++ { ++ if (!elf64_sw_64_create_got_section (abfd, info)) ++ return FALSE; ++ } ++ ++ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ++ | SEC_LINKER_CREATED | SEC_READONLY); ++ s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags); ++ elf_hash_table (info)->srelgot = s; ++ if (s == NULL ++ || !bfd_set_section_alignment (s, 3)) ++ return FALSE; ++ ++ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the ++ dynobj's .got section. We don't do this in the linker script ++ because we don't want to define the symbol if we are not creating ++ a global offset table. */ ++ h = _bfd_elf_define_linkage_sym (abfd, info, sw_64_elf_tdata(abfd)->got, ++ "_GLOBAL_OFFSET_TABLE_"); ++ elf_hash_table (info)->hgot = h; ++ if (h == NULL) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++/* Read ECOFF debugging information from a .mdebug section into a ++ ecoff_debug_info structure. */ ++ ++static bfd_boolean ++elf64_sw_64_read_ecoff_info (bfd *abfd, asection *section, ++ struct ecoff_debug_info *debug) ++{ ++ HDRR *symhdr; ++ const struct ecoff_debug_swap *swap; ++ char *ext_hdr = NULL; ++ ++ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; ++ memset (debug, 0, sizeof (*debug)); ++ ++ ext_hdr = (char *) bfd_malloc (swap->external_hdr_size); ++ if (ext_hdr == NULL && swap->external_hdr_size != 0) ++ goto error_return; ++ ++ if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, ++ swap->external_hdr_size)) ++ goto error_return; ++ ++ symhdr = &debug->symbolic_header; ++ (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); ++ ++ /* The symbolic header contains absolute file offsets and sizes to ++ read. */ ++#define READ(ptr, offset, count, size, type) \ ++ do \ ++ { \ ++ size_t amt; \ ++ debug->ptr = NULL; \ ++ if (symhdr->count == 0) \ ++ break; \ ++ if (_bfd_mul_overflow (size, symhdr->count, &amt)) \ ++ { \ ++ bfd_set_error (bfd_error_file_too_big); \ ++ goto error_return; \ ++ } \ ++ if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0) \ ++ goto error_return; \ ++ debug->ptr = (type) _bfd_malloc_and_read (abfd, amt, amt); \ ++ if (debug->ptr == NULL) \ ++ goto error_return; \ ++ } while (0) ++ ++ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); ++ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); ++ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *); ++ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *); ++ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *); ++ READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), ++ union aux_ext *); ++ READ (ss, cbSsOffset, issMax, sizeof (char), char *); ++ READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); ++ READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *); ++ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *); ++ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *); ++#undef READ ++ ++ debug->fdr = NULL; ++ ++ return TRUE; ++ ++ error_return: ++ free (ext_hdr); ++ free (debug->line); ++ free (debug->external_dnr); ++ free (debug->external_pdr); ++ free (debug->external_sym); ++ free (debug->external_opt); ++ free (debug->external_aux); ++ free (debug->ss); ++ free (debug->ssext); ++ free (debug->external_fdr); ++ free (debug->external_rfd); ++ free (debug->external_ext); ++ return FALSE; ++} ++ ++/* Sw_64 ELF local labels start with '$'. */ ++ ++static bfd_boolean ++elf64_sw_64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name) ++{ ++ return name[0] == '$'; ++} ++ ++static bfd_boolean ++elf64_sw_64_find_nearest_line (bfd *abfd, asymbol **symbols, ++ asection *section, bfd_vma offset, ++ const char **filename_ptr, ++ const char **functionname_ptr, ++ unsigned int *line_ptr, ++ unsigned int *discriminator_ptr) ++{ ++ asection *msec; ++ ++ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset, ++ filename_ptr, functionname_ptr, ++ line_ptr, discriminator_ptr, ++ dwarf_debug_sections, ++ &elf_tdata (abfd)->dwarf2_find_line_info) ++ == 1) ++ return TRUE; ++ ++ msec = bfd_get_section_by_name (abfd, ".mdebug"); ++ if (msec != NULL) ++ { ++ flagword origflags; ++ struct sw_64_elf_find_line *fi; ++ const struct ecoff_debug_swap * const swap = ++ get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; ++ ++ /* If we are called during a link, sw_64_elf_final_link may have ++ cleared the SEC_HAS_CONTENTS field. We force it back on here ++ if appropriate (which it normally will be). */ ++ origflags = msec->flags; ++ if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) ++ msec->flags |= SEC_HAS_CONTENTS; ++ ++ fi = sw_64_elf_tdata (abfd)->find_line_info; ++ if (fi == NULL) ++ { ++ bfd_size_type external_fdr_size; ++ char *fraw_src; ++ char *fraw_end; ++ struct fdr *fdr_ptr; ++ bfd_size_type amt = sizeof (struct sw_64_elf_find_line); ++ ++ fi = (struct sw_64_elf_find_line *) bfd_zalloc (abfd, amt); ++ if (fi == NULL) ++ { ++ msec->flags = origflags; ++ return FALSE; ++ } ++ ++ if (!elf64_sw_64_read_ecoff_info (abfd, msec, &fi->d)) ++ { ++ msec->flags = origflags; ++ return FALSE; ++ } ++ ++ /* Swap in the FDR information. */ ++ amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr); ++ fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt); ++ if (fi->d.fdr == NULL) ++ { ++ msec->flags = origflags; ++ return FALSE; ++ } ++ external_fdr_size = swap->external_fdr_size; ++ fdr_ptr = fi->d.fdr; ++ fraw_src = (char *) fi->d.external_fdr; ++ fraw_end = (fraw_src ++ + fi->d.symbolic_header.ifdMax * external_fdr_size); ++ for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) ++ (*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr); ++ ++ sw_64_elf_tdata (abfd)->find_line_info = fi; ++ ++ /* Note that we don't bother to ever free this information. ++ find_nearest_line is either called all the time, as in ++ objdump -l, so the information should be saved, or it is ++ rarely called, as in ld error messages, so the memory ++ wasted is unimportant. Still, it would probably be a ++ good idea for free_cached_info to throw it away. */ ++ } ++ ++ if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, ++ &fi->i, filename_ptr, functionname_ptr, ++ line_ptr)) ++ { ++ msec->flags = origflags; ++ return TRUE; ++ } ++ ++ msec->flags = origflags; ++ } ++ ++ /* Fall back on the generic ELF find_nearest_line routine. */ ++ ++ return _bfd_elf_find_nearest_line (abfd, symbols, section, offset, ++ filename_ptr, functionname_ptr, ++ line_ptr, discriminator_ptr); ++} ++ ++/* Structure used to pass information to sw_64_elf_output_extsym. */ ++ ++struct extsym_info ++{ ++ bfd *abfd; ++ struct bfd_link_info *info; ++ struct ecoff_debug_info *debug; ++ const struct ecoff_debug_swap *swap; ++ bfd_boolean failed; ++}; ++ ++static bfd_boolean ++elf64_sw_64_output_extsym (struct sw_64_elf_link_hash_entry *h, void * data) ++{ ++ struct extsym_info *einfo = (struct extsym_info *) data; ++ bfd_boolean strip; ++ asection *sec, *output_section; ++ ++ if (h->root.indx == -2) ++ strip = FALSE; ++ else if ((h->root.def_dynamic ++ || h->root.ref_dynamic ++ || h->root.root.type == bfd_link_hash_new) ++ && !h->root.def_regular ++ && !h->root.ref_regular) ++ strip = TRUE; ++ else if (einfo->info->strip == strip_all ++ || (einfo->info->strip == strip_some ++ && bfd_hash_lookup (einfo->info->keep_hash, ++ h->root.root.root.string, ++ FALSE, FALSE) == NULL)) ++ strip = TRUE; ++ else ++ strip = FALSE; ++ ++ if (strip) ++ return TRUE; ++ ++ if (h->esym.ifd == -2) ++ { ++ h->esym.jmptbl = 0; ++ h->esym.cobol_main = 0; ++ h->esym.weakext = 0; ++ h->esym.reserved = 0; ++ h->esym.ifd = ifdNil; ++ h->esym.asym.value = 0; ++ h->esym.asym.st = stGlobal; ++ ++ if (h->root.root.type != bfd_link_hash_defined ++ && h->root.root.type != bfd_link_hash_defweak) ++ h->esym.asym.sc = scAbs; ++ else ++ { ++ const char *name; ++ ++ sec = h->root.root.u.def.section; ++ output_section = sec->output_section; ++ ++ /* When making a shared library and symbol h is the one from ++ the another shared library, OUTPUT_SECTION may be null. */ ++ if (output_section == NULL) ++ h->esym.asym.sc = scUndefined; ++ else ++ { ++ name = bfd_section_name (output_section); ++ ++ if (strcmp (name, ".text") == 0) ++ h->esym.asym.sc = scText; ++ else if (strcmp (name, ".data") == 0) ++ h->esym.asym.sc = scData; ++ else if (strcmp (name, ".sdata") == 0) ++ h->esym.asym.sc = scSData; ++ else if (strcmp (name, ".rodata") == 0 ++ || strcmp (name, ".rdata") == 0) ++ h->esym.asym.sc = scRData; ++ else if (strcmp (name, ".bss") == 0) ++ h->esym.asym.sc = scBss; ++ else if (strcmp (name, ".sbss") == 0) ++ h->esym.asym.sc = scSBss; ++ else if (strcmp (name, ".init") == 0) ++ h->esym.asym.sc = scInit; ++ else if (strcmp (name, ".fini") == 0) ++ h->esym.asym.sc = scFini; ++ else ++ h->esym.asym.sc = scAbs; ++ } ++ } ++ ++ h->esym.asym.reserved = 0; ++ h->esym.asym.index = indexNil; ++ } ++ ++ if (h->root.root.type == bfd_link_hash_common) ++ h->esym.asym.value = h->root.root.u.c.size; ++ else if (h->root.root.type == bfd_link_hash_defined ++ || h->root.root.type == bfd_link_hash_defweak) ++ { ++ if (h->esym.asym.sc == scCommon) ++ h->esym.asym.sc = scBss; ++ else if (h->esym.asym.sc == scSCommon) ++ h->esym.asym.sc = scSBss; ++ ++ sec = h->root.root.u.def.section; ++ output_section = sec->output_section; ++ if (output_section != NULL) ++ h->esym.asym.value = (h->root.root.u.def.value ++ + sec->output_offset ++ + output_section->vma); ++ else ++ h->esym.asym.value = 0; ++ } ++ ++ if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, ++ h->root.root.root.string, ++ &h->esym)) ++ { ++ einfo->failed = TRUE; ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Search for and possibly create a got entry. */ ++ ++static struct sw_64_elf_got_entry * ++get_got_entry (bfd *abfd, struct sw_64_elf_link_hash_entry *h, ++ unsigned long r_type, unsigned long r_symndx, ++ bfd_vma r_addend) ++{ ++ struct sw_64_elf_got_entry *gotent; ++ struct sw_64_elf_got_entry **slot; ++ ++ if (h) ++ slot = &h->got_entries; ++ else ++ { ++ /* This is a local .got entry -- record for merge. */ ++ ++ struct sw_64_elf_got_entry **local_got_entries; ++ ++ local_got_entries = sw_64_elf_tdata(abfd)->local_got_entries; ++ if (!local_got_entries) ++ { ++ bfd_size_type size; ++ Elf_Internal_Shdr *symtab_hdr; ++ ++ symtab_hdr = &elf_tdata(abfd)->symtab_hdr; ++ size = symtab_hdr->sh_info; ++ size *= sizeof (struct sw_64_elf_got_entry *); ++ ++ local_got_entries ++ = (struct sw_64_elf_got_entry **) bfd_zalloc (abfd, size); ++ if (!local_got_entries) ++ return NULL; ++ ++ sw_64_elf_tdata (abfd)->local_got_entries = local_got_entries; ++ } ++ ++ slot = &local_got_entries[r_symndx]; ++ } ++ ++ for (gotent = *slot; gotent ; gotent = gotent->next) ++ if (gotent->gotobj == abfd ++ && gotent->reloc_type == r_type ++ && gotent->addend == r_addend) ++ break; ++ ++ if (!gotent) ++ { ++ int entry_size; ++ size_t amt; ++ ++ amt = sizeof (struct sw_64_elf_got_entry); ++ gotent = (struct sw_64_elf_got_entry *) bfd_alloc (abfd, amt); ++ if (!gotent) ++ return NULL; ++ ++ gotent->gotobj = abfd; ++ gotent->addend = r_addend; ++ gotent->got_offset = -1; ++ gotent->plt_offset = -1; ++ gotent->use_count = 1; ++ gotent->reloc_type = r_type; ++ gotent->reloc_done = 0; ++ gotent->reloc_xlated = 0; ++ ++ gotent->next = *slot; ++ *slot = gotent; ++ ++ entry_size = sw_64_got_entry_size (r_type); ++ sw_64_elf_tdata (abfd)->total_got_size += entry_size; ++ if (!h) ++ sw_64_elf_tdata(abfd)->local_got_size += entry_size; ++ } ++ else ++ gotent->use_count += 1; ++ ++ return gotent; ++} ++ ++static bfd_boolean ++elf64_sw_64_want_plt (struct sw_64_elf_link_hash_entry *ah) ++{ ++ return ((ah->root.type == STT_FUNC ++ || ah->root.root.type == bfd_link_hash_undefweak ++ || ah->root.root.type == bfd_link_hash_undefined) ++ && (ah->flags & SW_64_ELF_LINK_HASH_LU_PLT) != 0 ++ && (ah->flags & ~SW_64_ELF_LINK_HASH_LU_PLT) == 0); ++} ++ ++/* Whether to sort relocs output by ld -r or ld --emit-relocs, by r_offset. ++ Don't do so for code sections. We want to keep ordering of LITERAL/LITUSE ++ as is. On the other hand, elf-eh-frame.c processing requires .eh_frame ++ relocs to be sorted. */ ++ ++static bfd_boolean ++elf64_sw_64_sort_relocs_p (asection *sec) ++{ ++ return (sec->flags & SEC_CODE) == 0; ++} ++ ++ ++/* Handle dynamic relocations when doing an Sw_64 ELF link. */ ++ ++static bfd_boolean ++elf64_sw_64_check_relocs (bfd *abfd, struct bfd_link_info *info, ++ asection *sec, const Elf_Internal_Rela *relocs) ++{ ++ bfd *dynobj; ++ asection *sreloc; ++ Elf_Internal_Shdr *symtab_hdr; ++ struct sw_64_elf_link_hash_entry **sym_hashes; ++ const Elf_Internal_Rela *rel, *relend; ++ ++ if (bfd_link_relocatable (info)) ++ return TRUE; ++ ++ BFD_ASSERT (is_sw_64_elf (abfd)); ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ if (dynobj == NULL) ++ elf_hash_table (info)->dynobj = dynobj = abfd; ++ ++ sreloc = NULL; ++ symtab_hdr = &elf_symtab_hdr (abfd); ++ sym_hashes = sw_64_elf_sym_hashes (abfd); ++ ++ relend = relocs + sec->reloc_count; ++ for (rel = relocs; rel < relend; ++rel) ++ { ++ enum { ++ NEED_GOT = 1, ++ NEED_GOT_ENTRY = 2, ++ NEED_DYNREL = 4 ++ }; ++ ++ unsigned long r_symndx, r_type; ++ struct sw_64_elf_link_hash_entry *h; ++ unsigned int gotent_flags; ++ bfd_boolean maybe_dynamic; ++ unsigned int need; ++ bfd_vma addend; ++ ++ r_symndx = ELF64_R_SYM (rel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ h = NULL; ++ else ++ { ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ ++ while (h->root.root.type == bfd_link_hash_indirect ++ || h->root.root.type == bfd_link_hash_warning) ++ h = (struct sw_64_elf_link_hash_entry *)h->root.root.u.i.link; ++ ++ /* PR15323, ref flags aren't set for references in the same ++ object. */ ++ h->root.ref_regular = 1; ++ } ++ ++ /* We can only get preliminary data on whether a symbol is ++ locally or externally defined, as not all of the input files ++ have yet been processed. Do something with what we know, as ++ this may help reduce memory usage and processing time later. */ ++ maybe_dynamic = FALSE; ++ if (h && ((bfd_link_pic (info) ++ && (!info->symbolic ++ || info->unresolved_syms_in_shared_libs == RM_IGNORE)) ++ || !h->root.def_regular ++ || h->root.root.type == bfd_link_hash_defweak)) ++ maybe_dynamic = TRUE; ++ ++ need = 0; ++ gotent_flags = 0; ++ r_type = ELF64_R_TYPE (rel->r_info); ++ addend = rel->r_addend; ++ ++ switch (r_type) ++ { ++ case R_SW_64_LITERAL: ++ need = NEED_GOT | NEED_GOT_ENTRY; ++ ++ /* Remember how this literal is used from its LITUSEs. ++ This will be important when it comes to decide if we can ++ create a .plt entry for a function symbol. */ ++ while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_SW_64_LITUSE) ++ if (rel->r_addend >= 1 && rel->r_addend <= 6) ++ gotent_flags |= 1 << rel->r_addend; ++ --rel; ++ ++ /* No LITUSEs -- presumably the address is used somehow. */ ++ if (gotent_flags == 0) ++ gotent_flags = SW_64_ELF_LINK_HASH_LU_ADDR; ++ break; ++ ++ case R_SW_64_GPDISP: ++ case R_SW_64_GPREL16: ++ case R_SW_64_GPREL32: ++ case R_SW_64_GPRELHIGH: ++ case R_SW_64_GPRELLOW: ++ case R_SW_64_BRSGP: ++ need = NEED_GOT; ++ break; ++ ++ case R_SW_64_REFLONG: ++ case R_SW_64_REFQUAD: ++ if (bfd_link_pic (info) || maybe_dynamic) ++ need = NEED_DYNREL; ++ break; ++ ++ case R_SW_64_TLSLDM: ++ /* The symbol for a TLSLDM reloc is ignored. Collapse the ++ reloc to the STN_UNDEF (0) symbol so that they all match. */ ++ r_symndx = STN_UNDEF; ++ h = 0; ++ maybe_dynamic = FALSE; ++ /* FALLTHRU */ ++ ++ case R_SW_64_TLSGD: ++ case R_SW_64_GOTDTPREL: ++ need = NEED_GOT | NEED_GOT_ENTRY; ++ break; ++ ++ case R_SW_64_GOTTPREL: ++ need = NEED_GOT | NEED_GOT_ENTRY; ++ gotent_flags = SW_64_ELF_LINK_HASH_TLS_IE; ++ if (bfd_link_pic (info)) ++ info->flags |= DF_STATIC_TLS; ++ break; ++ ++ case R_SW_64_TPREL64: ++ if (bfd_link_dll (info)) ++ { ++ info->flags |= DF_STATIC_TLS; ++ need = NEED_DYNREL; ++ } ++ else if (maybe_dynamic) ++ need = NEED_DYNREL; ++ break; ++ } ++ ++ if (need & NEED_GOT) ++ { ++ if (sw_64_elf_tdata(abfd)->gotobj == NULL) ++ { ++ if (!elf64_sw_64_create_got_section (abfd, info)) ++ return FALSE; ++ } ++ } ++ ++ if (need & NEED_GOT_ENTRY) ++ { ++ struct sw_64_elf_got_entry *gotent; ++ ++ gotent = get_got_entry (abfd, h, r_type, r_symndx, addend); ++ if (!gotent) ++ return FALSE; ++ ++ if (gotent_flags) ++ { ++ gotent->flags |= gotent_flags; ++ if (h) ++ { ++ gotent_flags |= h->flags; ++ h->flags = gotent_flags; ++ ++ /* Make a guess as to whether a .plt entry is needed. */ ++ /* ??? It appears that we won't make it into ++ adjust_dynamic_symbol for symbols that remain ++ totally undefined. Copying this check here means ++ we can create a plt entry for them too. */ ++ h->root.needs_plt ++ = (maybe_dynamic && elf64_sw_64_want_plt (h)); ++ } ++ } ++ } ++ ++ if (need & NEED_DYNREL) ++ { ++ /* We need to create the section here now whether we eventually ++ use it or not so that it gets mapped to an output section by ++ the linker. If not used, we'll kill it in size_dynamic_sections. */ ++ if (sreloc == NULL) ++ { ++ sreloc = _bfd_elf_make_dynamic_reloc_section ++ (sec, dynobj, 3, abfd, /*rela?*/ TRUE); ++ ++ if (sreloc == NULL) ++ return FALSE; ++ } ++ ++ if (h) ++ { ++ /* Since we havn't seen all of the input symbols yet, we ++ don't know whether we'll actually need a dynamic relocation ++ entry for this reloc. So make a record of it. Once we ++ find out if this thing needs dynamic relocation we'll ++ expand the relocation sections by the appropriate amount. */ ++ ++ struct sw_64_elf_reloc_entry *rent; ++ ++ for (rent = h->reloc_entries; rent; rent = rent->next) ++ if (rent->rtype == r_type && rent->srel == sreloc) ++ break; ++ ++ if (!rent) ++ { ++ size_t amt = sizeof (struct sw_64_elf_reloc_entry); ++ rent = (struct sw_64_elf_reloc_entry *) bfd_alloc (abfd, amt); ++ if (!rent) ++ return FALSE; ++ ++ rent->srel = sreloc; ++ rent->sec = sec; ++ rent->rtype = r_type; ++ rent->count = 1; ++ ++ rent->next = h->reloc_entries; ++ h->reloc_entries = rent; ++ } ++ else ++ rent->count++; ++ } ++ else if (bfd_link_pic (info)) ++ { ++ /* If this is a shared library, and the section is to be ++ loaded into memory, we need a RELATIVE reloc. */ ++ sreloc->size += sizeof (Elf64_External_Rela); ++ if (sec->flags & SEC_READONLY) ++ { ++ info->flags |= DF_TEXTREL; ++ info->callbacks->minfo ++ (_("%pB: dynamic relocation against `%pT' in " ++ "read-only section `%pA'\n"), ++ sec->owner, h->root.root.root.string, sec); ++ } ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Return the section that should be marked against GC for a given ++ relocation. */ ++ ++static asection * ++elf64_sw_64_gc_mark_hook (asection *sec, struct bfd_link_info *info, ++ Elf_Internal_Rela *rel, ++ struct elf_link_hash_entry *h, Elf_Internal_Sym *sym) ++{ ++ /* These relocations don't really reference a symbol. Instead we store ++ extra data in their addend slot. Ignore the symbol. */ ++ switch (ELF64_R_TYPE (rel->r_info)) ++ { ++ case R_SW_64_LITUSE: ++ case R_SW_64_GPDISP: ++ case R_SW_64_HINT: ++ return NULL; ++ } ++ ++ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); ++} ++ ++/* Adjust a symbol defined by a dynamic object and referenced by a ++ regular object. The current definition is in some section of the ++ dynamic object, but we're not including those sections. We have to ++ change the definition to something the rest of the link can ++ understand. */ ++ ++static bfd_boolean ++elf64_sw_64_adjust_dynamic_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h) ++{ ++ bfd *dynobj; ++ asection *s; ++ struct sw_64_elf_link_hash_entry *ah; ++ ++ dynobj = elf_hash_table(info)->dynobj; ++ ah = (struct sw_64_elf_link_hash_entry *)h; ++ ++ /* Now that we've seen all of the input symbols, finalize our decision ++ about whether this symbol should get a .plt entry. Irritatingly, it ++ is common for folk to leave undefined symbols in shared libraries, ++ and they still expect lazy binding; accept undefined symbols in lieu ++ of STT_FUNC. */ ++ if (sw_64_elf_dynamic_symbol_p (h, info) && elf64_sw_64_want_plt (ah)) ++ { ++ h->needs_plt = TRUE; ++ ++ s = elf_hash_table(info)->splt; ++ if (!s && !elf64_sw_64_create_dynamic_sections (dynobj, info)) ++ return FALSE; ++ ++ /* We need one plt entry per got subsection. Delay allocation of ++ the actual plt entries until size_plt_section, called from ++ size_dynamic_sections or during relaxation. */ ++ ++ return TRUE; ++ } ++ else ++ h->needs_plt = FALSE; ++ ++ /* If this is a weak symbol, and there is a real definition, the ++ processor independent code will have arranged for us to see the ++ real definition first, and we can just use the same value. */ ++ if (h->is_weakalias) ++ { ++ struct elf_link_hash_entry *def = weakdef (h); ++ BFD_ASSERT (def->root.type == bfd_link_hash_defined); ++ h->root.u.def.section = def->root.u.def.section; ++ h->root.u.def.value = def->root.u.def.value; ++ return TRUE; ++ } ++ ++ /* This is a reference to a symbol defined by a dynamic object which ++ is not a function. The Sw_64, since it uses .got entries for all ++ symbols even in regular objects, does not need the hackery of a ++ .dynbss section and COPY dynamic relocations. */ ++ ++ return TRUE; ++} ++ ++/* Record STO_SW_64_NOPV and STO_SW_64_STD_GPLOAD. */ ++ ++static void ++elf64_sw_64_merge_symbol_attribute (struct elf_link_hash_entry *h, ++ const Elf_Internal_Sym *isym, ++ bfd_boolean definition, ++ bfd_boolean dynamic) ++{ ++ if (!dynamic && definition) ++ h->other = ((h->other & ELF_ST_VISIBILITY (-1)) ++ | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); ++} ++ ++/* Symbol versioning can create new symbols, and make our old symbols ++ indirect to the new ones. Consolidate the got and reloc information ++ in these situations. */ ++ ++static void ++elf64_sw_64_copy_indirect_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *dir, ++ struct elf_link_hash_entry *ind) ++{ ++ struct sw_64_elf_link_hash_entry *hi ++ = (struct sw_64_elf_link_hash_entry *) ind; ++ struct sw_64_elf_link_hash_entry *hs ++ = (struct sw_64_elf_link_hash_entry *) dir; ++ ++ /* Do the merging in the superclass. */ ++ _bfd_elf_link_hash_copy_indirect(info, dir, ind); ++ ++ /* Merge the flags. Whee. */ ++ hs->flags |= hi->flags; ++ ++ /* ??? It's unclear to me what's really supposed to happen when ++ "merging" defweak and defined symbols, given that we don't ++ actually throw away the defweak. This more-or-less copies ++ the logic related to got and plt entries in the superclass. */ ++ if (ind->root.type != bfd_link_hash_indirect) ++ return; ++ ++ /* Merge the .got entries. Cannibalize the old symbol's list in ++ doing so, since we don't need it anymore. */ ++ ++ if (hs->got_entries == NULL) ++ hs->got_entries = hi->got_entries; ++ else ++ { ++ struct sw_64_elf_got_entry *gi, *gs, *gin, *gsh; ++ ++ gsh = hs->got_entries; ++ for (gi = hi->got_entries; gi ; gi = gin) ++ { ++ gin = gi->next; ++ for (gs = gsh; gs ; gs = gs->next) ++ if (gi->gotobj == gs->gotobj ++ && gi->reloc_type == gs->reloc_type ++ && gi->addend == gs->addend) ++ { ++ gs->use_count += gi->use_count; ++ goto got_found; ++ } ++ gi->next = hs->got_entries; ++ hs->got_entries = gi; ++ got_found:; ++ } ++ } ++ hi->got_entries = NULL; ++ ++ /* And similar for the reloc entries. */ ++ ++ if (hs->reloc_entries == NULL) ++ hs->reloc_entries = hi->reloc_entries; ++ else ++ { ++ struct sw_64_elf_reloc_entry *ri, *rs, *rin, *rsh; ++ ++ rsh = hs->reloc_entries; ++ for (ri = hi->reloc_entries; ri ; ri = rin) ++ { ++ rin = ri->next; ++ for (rs = rsh; rs ; rs = rs->next) ++ if (ri->rtype == rs->rtype && ri->srel == rs->srel) ++ { ++ rs->count += ri->count; ++ goto found_reloc; ++ } ++ ri->next = hs->reloc_entries; ++ hs->reloc_entries = ri; ++ found_reloc:; ++ } ++ } ++ hi->reloc_entries = NULL; ++} ++ ++/* Is it possible to merge two object file's .got tables? */ ++ ++static bfd_boolean ++elf64_sw_64_can_merge_gots (bfd *a, bfd *b) ++{ ++ int total = sw_64_elf_tdata (a)->total_got_size; ++ bfd *bsub; ++ ++ /* Trivial quick fallout test. */ ++ if (total + sw_64_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE) ++ return TRUE; ++ ++ /* By their nature, local .got entries cannot be merged. */ ++ if ((total += sw_64_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE) ++ return FALSE; ++ ++ /* Failing the common trivial comparison, we must effectively ++ perform the merge. Not actually performing the merge means that ++ we don't have to store undo information in case we fail. */ ++ for (bsub = b; bsub ; bsub = sw_64_elf_tdata (bsub)->in_got_link_next) ++ { ++ struct sw_64_elf_link_hash_entry **hashes = sw_64_elf_sym_hashes (bsub); ++ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr; ++ int i, n; ++ ++ n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info; ++ for (i = 0; i < n; ++i) ++ { ++ struct sw_64_elf_got_entry *ae, *be; ++ struct sw_64_elf_link_hash_entry *h; ++ ++ h = hashes[i]; ++ while (h->root.root.type == bfd_link_hash_indirect ++ || h->root.root.type == bfd_link_hash_warning) ++ h = (struct sw_64_elf_link_hash_entry *)h->root.root.u.i.link; ++ ++ for (be = h->got_entries; be ; be = be->next) ++ { ++ if (be->use_count == 0) ++ continue; ++ if (be->gotobj != b) ++ continue; ++ ++ for (ae = h->got_entries; ae ; ae = ae->next) ++ if (ae->gotobj == a ++ && ae->reloc_type == be->reloc_type ++ && ae->addend == be->addend) ++ goto global_found; ++ ++ total += sw_64_got_entry_size (be->reloc_type); ++ if (total > MAX_GOT_SIZE) ++ return FALSE; ++ global_found:; ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Actually merge two .got tables. */ ++ ++static void ++elf64_sw_64_merge_gots (bfd *a, bfd *b) ++{ ++ int total = sw_64_elf_tdata (a)->total_got_size; ++ bfd *bsub; ++ ++ /* Remember local expansion. */ ++ { ++ int e = sw_64_elf_tdata (b)->local_got_size; ++ total += e; ++ sw_64_elf_tdata (a)->local_got_size += e; ++ } ++ ++ for (bsub = b; bsub ; bsub = sw_64_elf_tdata (bsub)->in_got_link_next) ++ { ++ struct sw_64_elf_got_entry **local_got_entries; ++ struct sw_64_elf_link_hash_entry **hashes; ++ Elf_Internal_Shdr *symtab_hdr; ++ int i, n; ++ ++ /* Let the local .got entries know they are part of a new subsegment. */ ++ local_got_entries = sw_64_elf_tdata (bsub)->local_got_entries; ++ if (local_got_entries) ++ { ++ n = elf_tdata (bsub)->symtab_hdr.sh_info; ++ for (i = 0; i < n; ++i) ++ { ++ struct sw_64_elf_got_entry *ent; ++ for (ent = local_got_entries[i]; ent; ent = ent->next) ++ ent->gotobj = a; ++ } ++ } ++ ++ /* Merge the global .got entries. */ ++ hashes = sw_64_elf_sym_hashes (bsub); ++ symtab_hdr = &elf_tdata (bsub)->symtab_hdr; ++ ++ n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info; ++ for (i = 0; i < n; ++i) ++ { ++ struct sw_64_elf_got_entry *ae, *be, **pbe, **start; ++ struct sw_64_elf_link_hash_entry *h; ++ ++ h = hashes[i]; ++ while (h->root.root.type == bfd_link_hash_indirect ++ || h->root.root.type == bfd_link_hash_warning) ++ h = (struct sw_64_elf_link_hash_entry *)h->root.root.u.i.link; ++ ++ pbe = start = &h->got_entries; ++ while ((be = *pbe) != NULL) ++ { ++ if (be->use_count == 0) ++ { ++ *pbe = be->next; ++ memset (be, 0xa5, sizeof (*be)); ++ goto kill; ++ } ++ if (be->gotobj != b) ++ goto next; ++ ++ for (ae = *start; ae ; ae = ae->next) ++ if (ae->gotobj == a ++ && ae->reloc_type == be->reloc_type ++ && ae->addend == be->addend) ++ { ++ ae->flags |= be->flags; ++ ae->use_count += be->use_count; ++ *pbe = be->next; ++ memset (be, 0xa5, sizeof (*be)); ++ goto kill; ++ } ++ be->gotobj = a; ++ total += sw_64_got_entry_size (be->reloc_type); ++ ++ next:; ++ pbe = &be->next; ++ kill:; ++ } ++ } ++ ++ sw_64_elf_tdata (bsub)->gotobj = a; ++ } ++ sw_64_elf_tdata (a)->total_got_size = total; ++ ++ /* Merge the two in_got chains. */ ++ { ++ bfd *next; ++ ++ bsub = a; ++ while ((next = sw_64_elf_tdata (bsub)->in_got_link_next) != NULL) ++ bsub = next; ++ ++ sw_64_elf_tdata (bsub)->in_got_link_next = b; ++ } ++} ++ ++/* Calculate the offsets for the got entries. */ ++ ++static bfd_boolean ++elf64_sw_64_calc_got_offsets_for_symbol (struct sw_64_elf_link_hash_entry *h, ++ void * arg ATTRIBUTE_UNUSED) ++{ ++ struct sw_64_elf_got_entry *gotent; ++ ++ for (gotent = h->got_entries; gotent; gotent = gotent->next) ++ if (gotent->use_count > 0) ++ { ++ struct sw_64_elf_obj_tdata *td; ++ bfd_size_type *plge; ++ ++ td = sw_64_elf_tdata (gotent->gotobj); ++ plge = &td->got->size; ++ gotent->got_offset = *plge; ++ *plge += sw_64_got_entry_size (gotent->reloc_type); ++ } ++ ++ return TRUE; ++} ++ ++static void ++elf64_sw_64_calc_got_offsets (struct bfd_link_info *info) ++{ ++ bfd *i, *got_list; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return; ++ got_list = htab->got_list; ++ ++ /* First, zero out the .got sizes, as we may be recalculating the ++ .got after optimizing it. */ ++ for (i = got_list; i ; i = sw_64_elf_tdata(i)->got_link_next) ++ sw_64_elf_tdata(i)->got->size = 0; ++ ++ /* Next, fill in the offsets for all the global entries. */ ++ sw_64_elf_link_hash_traverse (htab, ++ elf64_sw_64_calc_got_offsets_for_symbol, ++ NULL); ++ ++ /* Finally, fill in the offsets for the local entries. */ ++ for (i = got_list; i ; i = sw_64_elf_tdata(i)->got_link_next) ++ { ++ bfd_size_type got_offset = sw_64_elf_tdata(i)->got->size; ++ bfd *j; ++ ++ for (j = i; j ; j = sw_64_elf_tdata(j)->in_got_link_next) ++ { ++ struct sw_64_elf_got_entry **local_got_entries, *gotent; ++ int k, n; ++ ++ local_got_entries = sw_64_elf_tdata(j)->local_got_entries; ++ if (!local_got_entries) ++ continue; ++ ++ for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k) ++ for (gotent = local_got_entries[k]; gotent; gotent = gotent->next) ++ if (gotent->use_count > 0) ++ { ++ gotent->got_offset = got_offset; ++ got_offset += sw_64_got_entry_size (gotent->reloc_type); ++ } ++ } ++ ++ sw_64_elf_tdata(i)->got->size = got_offset; ++ } ++} ++ ++/* Constructs the gots. */ ++ ++static bfd_boolean ++elf64_sw_64_size_got_sections (struct bfd_link_info *info, ++ bfd_boolean may_merge) ++{ ++ bfd *i, *got_list, *cur_got_obj = NULL; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ got_list = htab->got_list; ++ ++ /* On the first time through, pretend we have an existing got list ++ consisting of all of the input files. */ ++ if (got_list == NULL) ++ { ++ for (i = info->input_bfds; i ; i = i->link.next) ++ { ++ bfd *this_got; ++ ++ if (! is_sw_64_elf (i)) ++ continue; ++ ++ this_got = sw_64_elf_tdata (i)->gotobj; ++ if (this_got == NULL) ++ continue; ++ ++ /* We are assuming no merging has yet occurred. */ ++ BFD_ASSERT (this_got == i); ++ ++ if (sw_64_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE) ++ { ++ /* Yikes! A single object file has too many entries. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: .got subsegment exceeds 64K (size %d)"), ++ i, sw_64_elf_tdata (this_got)->total_got_size); ++ return FALSE; ++ } ++ ++ if (got_list == NULL) ++ got_list = this_got; ++ else ++ sw_64_elf_tdata(cur_got_obj)->got_link_next = this_got; ++ cur_got_obj = this_got; ++ } ++ ++ /* Strange degenerate case of no got references. */ ++ if (got_list == NULL) ++ return TRUE; ++ ++ htab->got_list = got_list; ++ } ++ ++ cur_got_obj = got_list; ++ if (cur_got_obj == NULL) ++ return FALSE; ++ ++ if (may_merge) ++ { ++ i = sw_64_elf_tdata(cur_got_obj)->got_link_next; ++ while (i != NULL) ++ { ++ if (elf64_sw_64_can_merge_gots (cur_got_obj, i)) ++ { ++ elf64_sw_64_merge_gots (cur_got_obj, i); ++ ++ sw_64_elf_tdata(i)->got->size = 0; ++ i = sw_64_elf_tdata(i)->got_link_next; ++ sw_64_elf_tdata(cur_got_obj)->got_link_next = i; ++ } ++ else ++ { ++ cur_got_obj = i; ++ i = sw_64_elf_tdata(i)->got_link_next; ++ } ++ } ++ } ++ ++ /* Once the gots have been merged, fill in the got offsets for ++ everything therein. */ ++ elf64_sw_64_calc_got_offsets (info); ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++elf64_sw_64_size_plt_section_1 (struct sw_64_elf_link_hash_entry *h, ++ void * data) ++{ ++ asection *splt = (asection *) data; ++ struct sw_64_elf_got_entry *gotent; ++ bfd_boolean saw_one = FALSE; ++ ++ /* If we didn't need an entry before, we still don't. */ ++ if (!h->root.needs_plt) ++ return TRUE; ++ ++ /* For each LITERAL got entry still in use, allocate a plt entry. */ ++ for (gotent = h->got_entries; gotent ; gotent = gotent->next) ++ if (gotent->reloc_type == R_SW_64_LITERAL ++ && gotent->use_count > 0) ++ { ++ if (splt->size == 0) ++ splt->size = PLT_HEADER_SIZE; ++ gotent->plt_offset = splt->size; ++ splt->size += PLT_ENTRY_SIZE; ++ saw_one = TRUE; ++ } ++ ++ /* If there weren't any, there's no longer a need for the PLT entry. */ ++ if (!saw_one) ++ h->root.needs_plt = FALSE; ++ ++ return TRUE; ++} ++ ++/* Called from relax_section to rebuild the PLT in light of potential changes ++ in the function's status. */ ++ ++static void ++elf64_sw_64_size_plt_section (struct bfd_link_info *info) ++{ ++ asection *splt, *spltrel, *sgotplt; ++ unsigned long entries; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return; ++ ++ splt = elf_hash_table(info)->splt; ++ if (splt == NULL) ++ return; ++ ++ splt->size = 0; ++ ++ sw_64_elf_link_hash_traverse (htab, ++ elf64_sw_64_size_plt_section_1, splt); ++ ++ /* Every plt entry requires a JMP_SLOT relocation. */ ++ spltrel = elf_hash_table(info)->srelplt; ++ entries = 0; ++ if (splt->size) ++ { ++ if (elf64_sw_64_use_secureplt) ++ entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE; ++ else ++ entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE; ++ } ++ spltrel->size = entries * sizeof (Elf64_External_Rela); ++ ++ /* When using the secureplt, we need two words somewhere in the data ++ segment for the dynamic linker to tell us where to go. This is the ++ entire contents of the .got.plt section. */ ++ if (elf64_sw_64_use_secureplt) ++ { ++ sgotplt = elf_hash_table(info)->sgotplt; ++ sgotplt->size = entries ? 16 : 0; ++ } ++} ++ ++static bfd_boolean ++elf64_sw_64_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ bfd *i; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ if (bfd_link_relocatable (info)) ++ return TRUE; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ if (!elf64_sw_64_size_got_sections (info, TRUE)) ++ return FALSE; ++ ++ /* Allocate space for all of the .got subsections. */ ++ i = htab->got_list; ++ for ( ; i ; i = sw_64_elf_tdata(i)->got_link_next) ++ { ++ asection *s = sw_64_elf_tdata(i)->got; ++ if (s->size > 0) ++ { ++ s->contents = (bfd_byte *) bfd_zalloc (i, s->size); ++ if (s->contents == NULL) ++ return FALSE; ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* The number of dynamic relocations required by a static relocation. */ ++ ++static int ++sw_64_dynamic_entries_for_reloc (int r_type, int dynamic, int shared, int pie) ++{ ++ switch (r_type) ++ { ++ /* May appear in GOT entries. */ ++ case R_SW_64_TLSGD: ++ return (dynamic ? 2 : shared ? 1 : 0); ++ case R_SW_64_TLSLDM: ++ return shared; ++ case R_SW_64_LITERAL: ++ return dynamic || shared; ++ case R_SW_64_GOTTPREL: ++ return dynamic || (shared && !pie); ++ case R_SW_64_GOTDTPREL: ++ return dynamic; ++ ++ /* May appear in data sections. */ ++ case R_SW_64_REFLONG: ++ case R_SW_64_REFQUAD: ++ return dynamic || shared; ++ case R_SW_64_TPREL64: ++ return dynamic || (shared && !pie); ++ ++ /* Everything else is illegal. We'll issue an error during ++ relocate_section. */ ++ default: ++ return 0; ++ } ++} ++ ++/* Work out the sizes of the dynamic relocation entries. */ ++ ++static bfd_boolean ++elf64_sw_64_calc_dynrel_sizes (struct sw_64_elf_link_hash_entry *h, ++ struct bfd_link_info *info) ++{ ++ bfd_boolean dynamic; ++ struct sw_64_elf_reloc_entry *relent; ++ unsigned long entries; ++ ++ /* If the symbol was defined as a common symbol in a regular object ++ file, and there was no definition in any dynamic object, then the ++ linker will have allocated space for the symbol in a common ++ section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been ++ set. This is done for dynamic symbols in ++ elf_adjust_dynamic_symbol but this is not done for non-dynamic ++ symbols, somehow. */ ++ if (!h->root.def_regular ++ && h->root.ref_regular ++ && !h->root.def_dynamic ++ && (h->root.root.type == bfd_link_hash_defined ++ || h->root.root.type == bfd_link_hash_defweak) ++ && !(h->root.root.u.def.section->owner->flags & DYNAMIC)) ++ h->root.def_regular = 1; ++ ++ /* If the symbol is dynamic, we'll need all the relocations in their ++ natural form. If this is a shared object, and it has been forced ++ local, we'll need the same number of RELATIVE relocations. */ ++ dynamic = sw_64_elf_dynamic_symbol_p (&h->root, info); ++ ++ /* If the symbol is a hidden undefined weak, then we never have any ++ relocations. Avoid the loop which may want to add RELATIVE relocs ++ based on bfd_link_pic (info). */ ++ if (h->root.root.type == bfd_link_hash_undefweak && !dynamic) ++ return TRUE; ++ ++ for (relent = h->reloc_entries; relent; relent = relent->next) ++ { ++ entries = sw_64_dynamic_entries_for_reloc (relent->rtype, dynamic, ++ bfd_link_pic (info), ++ bfd_link_pie (info)); ++ if (entries) ++ { ++ asection *sec = relent->sec; ++ relent->srel->size += ++ entries * sizeof (Elf64_External_Rela) * relent->count; ++ if ((sec->flags & SEC_READONLY) != 0) ++ { ++ info->flags |= DT_TEXTREL; ++ info->callbacks->minfo ++ (_("%pB: dynamic relocation against `%pT' in " ++ "read-only section `%pA'\n"), ++ sec->owner, h->root.root.root.string, sec); ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Subroutine of elf64_sw_64_size_rela_got_section for doing the ++ global symbols. */ ++ ++static bfd_boolean ++elf64_sw_64_size_rela_got_1 (struct sw_64_elf_link_hash_entry *h, ++ struct bfd_link_info *info) ++{ ++ bfd_boolean dynamic; ++ struct sw_64_elf_got_entry *gotent; ++ unsigned long entries; ++ ++ /* If we're using a plt for this symbol, then all of its relocations ++ for its got entries go into .rela.plt. */ ++ if (h->root.needs_plt) ++ return TRUE; ++ ++ /* If the symbol is dynamic, we'll need all the relocations in their ++ natural form. If this is a shared object, and it has been forced ++ local, we'll need the same number of RELATIVE relocations. */ ++ dynamic = sw_64_elf_dynamic_symbol_p (&h->root, info); ++ ++ /* If the symbol is a hidden undefined weak, then we never have any ++ relocations. Avoid the loop which may want to add RELATIVE relocs ++ based on bfd_link_pic (info). */ ++ if (h->root.root.type == bfd_link_hash_undefweak && !dynamic) ++ return TRUE; ++ ++ entries = 0; ++ for (gotent = h->got_entries; gotent ; gotent = gotent->next) ++ if (gotent->use_count > 0) ++ entries += sw_64_dynamic_entries_for_reloc (gotent->reloc_type, dynamic, ++ bfd_link_pic (info), ++ bfd_link_pie (info)); ++ ++ if (entries > 0) ++ { ++ asection *srel = elf_hash_table(info)->srelgot; ++ BFD_ASSERT (srel != NULL); ++ srel->size += sizeof (Elf64_External_Rela) * entries; ++ } ++ ++ return TRUE; ++} ++ ++/* Set the sizes of the dynamic relocation sections. */ ++ ++static void ++elf64_sw_64_size_rela_got_section (struct bfd_link_info *info) ++{ ++ unsigned long entries; ++ bfd *i; ++ asection *srel; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return; ++ ++ /* Shared libraries often require RELATIVE relocs, and some relocs ++ require attention for the main application as well. */ ++ ++ entries = 0; ++ for (i = htab->got_list; ++ i ; i = sw_64_elf_tdata(i)->got_link_next) ++ { ++ bfd *j; ++ ++ for (j = i; j ; j = sw_64_elf_tdata(j)->in_got_link_next) ++ { ++ struct sw_64_elf_got_entry **local_got_entries, *gotent; ++ int k, n; ++ ++ local_got_entries = sw_64_elf_tdata(j)->local_got_entries; ++ if (!local_got_entries) ++ continue; ++ ++ for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k) ++ for (gotent = local_got_entries[k]; ++ gotent ; gotent = gotent->next) ++ if (gotent->use_count > 0) ++ entries += (sw_64_dynamic_entries_for_reloc ++ (gotent->reloc_type, 0, bfd_link_pic (info), ++ bfd_link_pie (info))); ++ } ++ } ++ ++ srel = elf_hash_table(info)->srelgot; ++ if (!srel) ++ { ++ BFD_ASSERT (entries == 0); ++ return; ++ } ++ srel->size = sizeof (Elf64_External_Rela) * entries; ++ ++ /* Now do the non-local symbols. */ ++ sw_64_elf_link_hash_traverse (htab, ++ elf64_sw_64_size_rela_got_1, info); ++} ++ ++/* Set the sizes of the dynamic sections. */ ++ ++static bfd_boolean ++elf64_sw_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ bfd *dynobj; ++ asection *s; ++ bfd_boolean relplt, relocs; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ dynobj = elf_hash_table(info)->dynobj; ++ BFD_ASSERT(dynobj != NULL); ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ /* Set the contents of the .interp section to the interpreter. */ ++ if (bfd_link_executable (info) && !info->nointerp) ++ { ++ s = bfd_get_linker_section (dynobj, ".interp"); ++ BFD_ASSERT (s != NULL); ++ s->size = sizeof ELF_DYNAMIC_INTERPRETER; ++ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; ++ } ++ ++ /* Now that we've seen all of the input files, we can decide which ++ symbols need dynamic relocation entries and which don't. We've ++ collected information in check_relocs that we can now apply to ++ size the dynamic relocation sections. */ ++ sw_64_elf_link_hash_traverse (htab, ++ elf64_sw_64_calc_dynrel_sizes, info); ++ ++ elf64_sw_64_size_rela_got_section (info); ++ elf64_sw_64_size_plt_section (info); ++ } ++ /* else we're not dynamic and by definition we don't need such things. */ ++ ++ /* The check_relocs and adjust_dynamic_symbol entry points have ++ determined the sizes of the various dynamic sections. Allocate ++ memory for them. */ ++ relplt = FALSE; ++ relocs = FALSE; ++ for (s = dynobj->sections; s != NULL; s = s->next) ++ { ++ const char *name; ++ ++ if (!(s->flags & SEC_LINKER_CREATED)) ++ continue; ++ ++ /* It's OK to base decisions on the section name, because none ++ of the dynobj section names depend upon the input files. */ ++ name = bfd_section_name (s); ++ ++ if (CONST_STRNEQ (name, ".rela")) ++ { ++ if (s->size != 0) ++ { ++ if (strcmp (name, ".rela.plt") == 0) ++ relplt = TRUE; ++ else ++ relocs = TRUE; ++ ++ /* We use the reloc_count field as a counter if we need ++ to copy relocs into the output file. */ ++ s->reloc_count = 0; ++ } ++ } ++ else if (! CONST_STRNEQ (name, ".got") ++ && strcmp (name, ".plt") != 0 ++ && strcmp (name, ".dynbss") != 0) ++ { ++ /* It's not one of our dynamic sections, so don't allocate space. */ ++ continue; ++ } ++ ++ if (s->size == 0) ++ { ++ /* If we don't need this section, strip it from the output file. ++ This is to handle .rela.bss and .rela.plt. We must create it ++ in create_dynamic_sections, because it must be created before ++ the linker maps input sections to output sections. The ++ linker does that before adjust_dynamic_symbol is called, and ++ it is that function which decides whether anything needs to ++ go into these sections. */ ++ if (!CONST_STRNEQ (name, ".got")) ++ s->flags |= SEC_EXCLUDE; ++ } ++ else if ((s->flags & SEC_HAS_CONTENTS) != 0) ++ { ++ /* Allocate memory for the section contents. */ ++ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); ++ if (s->contents == NULL) ++ return FALSE; ++ } ++ } ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ /* Add some entries to the .dynamic section. We fill in the ++ values later, in elf64_sw_64_finish_dynamic_sections, but we ++ must add the entries now so that we get the correct size for ++ the .dynamic section. The DT_DEBUG entry is filled in by the ++ dynamic linker and used by the debugger. */ ++#define add_dynamic_entry(TAG, VAL) \ ++ _bfd_elf_add_dynamic_entry (info, TAG, VAL) ++ ++ if (!_bfd_elf_add_dynamic_tags (output_bfd, info, ++ relocs || relplt)) ++ return FALSE; ++ ++ if (relplt ++ && elf64_sw_64_use_secureplt ++ && !add_dynamic_entry (DT_SW_64_PLTRO, 1)) ++ return FALSE; ++ } ++#undef add_dynamic_entry ++ ++ return TRUE; ++} ++ ++/* These functions do relaxation for Sw_64 ELF. ++ ++ Currently I'm only handling what I can do with existing compiler ++ and assembler support, which means no instructions are removed, ++ though some may be nopped. At this time GCC does not emit enough ++ information to do all of the relaxing that is possible. It will ++ take some not small amount of work for that to happen. ++ ++ There are a couple of interesting papers that I once read on this ++ subject, that I cannot find references to at the moment, that ++ related to Sw_64 in particular. They are by David Wall, then of ++ DEC WRL. */ ++ ++struct sw_64_relax_info ++{ ++ bfd *abfd; ++ asection *sec; ++ bfd_byte *contents; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Rela *relocs, *relend; ++ struct bfd_link_info *link_info; ++ bfd_vma gp; ++ bfd *gotobj; ++ asection *tsec; ++ struct sw_64_elf_link_hash_entry *h; ++ struct sw_64_elf_got_entry **first_gotent; ++ struct sw_64_elf_got_entry *gotent; ++ bfd_boolean changed_contents; ++ bfd_boolean changed_relocs; ++ unsigned char other; ++}; ++ ++static Elf_Internal_Rela * ++elf64_sw_64_find_reloc_at_ofs (Elf_Internal_Rela *rel, ++ Elf_Internal_Rela *relend, ++ bfd_vma offset, int type) ++{ ++ while (rel < relend) ++ { ++ if (rel->r_offset == offset ++ && ELF64_R_TYPE (rel->r_info) == (unsigned int) type) ++ return rel; ++ ++rel; ++ } ++ return NULL; ++} ++ ++static bfd_boolean ++elf64_sw_64_relax_got_load (struct sw_64_relax_info *info, bfd_vma symval, ++ Elf_Internal_Rela *irel, unsigned long r_type) ++{ ++ unsigned int insn; ++ bfd_signed_vma disp; ++ ++ /* Get the instruction. */ ++ insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset); ++ ++ if (insn >> 26 != OP_LDQ) ++ { ++ reloc_howto_type *howto = elf64_sw_64_howto_table + r_type; ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: %pA+%#" PRIx64 ": warning: " ++ "%s relocation against unexpected insn"), ++ info->abfd, info->sec, (uint64_t) irel->r_offset, howto->name); ++ return TRUE; ++ } ++ ++ /* Can't relax dynamic symbols. */ ++ if (info->h != NULL ++ && sw_64_elf_dynamic_symbol_p (&info->h->root, info->link_info)) ++ return TRUE; ++ ++ /* Can't use local-exec relocations in shared libraries. */ ++ if (r_type == R_SW_64_GOTTPREL ++ && bfd_link_dll (info->link_info)) ++ return TRUE; ++ ++ if (r_type == R_SW_64_LITERAL) ++ { ++ /* Look for nice constant addresses. This includes the not-uncommon ++ special case of 0 for undefweak symbols. */ ++ if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak) ++ || (!bfd_link_pic (info->link_info) ++ && (symval >= (bfd_vma)-0x8000 || symval < 0x8000))) ++ { ++ disp = 0; ++ insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16); ++ insn |= (symval & 0xffff); ++ r_type = R_SW_64_NONE; ++ } ++ else ++ { ++ /* We may only create GPREL relocs during the second pass. */ ++ if (info->link_info->relax_pass == 0) ++ return TRUE; ++ ++ disp = symval - info->gp; ++ insn = (OP_LDA << 26) | (insn & 0x03ff0000); ++ r_type = R_SW_64_GPREL16; ++ } ++ } ++ else ++ { ++ bfd_vma dtp_base, tp_base; ++ ++ BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL); ++ dtp_base = sw_64_get_dtprel_base (info->link_info); ++ tp_base = sw_64_get_tprel_base (info->link_info); ++ disp = symval - (r_type == R_SW_64_GOTDTPREL ? dtp_base : tp_base); ++ ++ insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16); ++ ++ switch (r_type) ++ { ++ case R_SW_64_GOTDTPREL: ++ r_type = R_SW_64_DTPREL16; ++ break; ++ case R_SW_64_GOTTPREL: ++ r_type = R_SW_64_TPREL16; ++ break; ++ default: ++ BFD_ASSERT (0); ++ return FALSE; ++ } ++ } ++ ++ if (disp < -0x8000 || disp >= 0x8000) ++ return TRUE; ++ ++ bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset); ++ info->changed_contents = TRUE; ++ ++ /* Reduce the use count on this got entry by one, possibly ++ eliminating it. */ ++ if (--info->gotent->use_count == 0) ++ { ++ int sz = sw_64_got_entry_size (r_type); ++ sw_64_elf_tdata (info->gotobj)->total_got_size -= sz; ++ if (!info->h) ++ sw_64_elf_tdata (info->gotobj)->local_got_size -= sz; ++ } ++ ++ /* Smash the existing GOT relocation for its 16-bit immediate pair. */ ++ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type); ++ info->changed_relocs = TRUE; ++ ++ /* ??? Search forward through this basic block looking for insns ++ that use the target register. Stop after an insn modifying the ++ register is seen, or after a branch or call. ++ ++ Any such memory load insn may be substituted by a load directly ++ off the GP. This allows the memory load insn to be issued before ++ the calculated GP register would otherwise be ready. ++ ++ Any such jsr insn can be replaced by a bsr if it is in range. ++ ++ This would mean that we'd have to _add_ relocations, the pain of ++ which gives one pause. */ ++ ++ return TRUE; ++} ++ ++static bfd_vma ++elf64_sw_64_relax_opt_call (struct sw_64_relax_info *info, bfd_vma symval) ++{ ++ /* If the function has the same gp, and we can identify that the ++ function does not use its function pointer, we can eliminate the ++ address load. */ ++ ++ /* If the symbol is marked NOPV, we are being told the function never ++ needs its procedure value. */ ++ if ((info->other & STO_SW_64_STD_GPLOAD) == STO_SW_64_NOPV) ++ return symval; ++ ++ /* If the symbol is marked STD_GP, we are being told the function does ++ a normal ldgp in the first two words. */ ++ else if ((info->other & STO_SW_64_STD_GPLOAD) == STO_SW_64_STD_GPLOAD) ++ ; ++ ++ /* Otherwise, we may be able to identify a GP load in the first two ++ words, which we can then skip. */ ++ else ++ { ++ Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp; ++ bfd_vma ofs; ++ ++ /* Load the relocations from the section that the target symbol is in. */ ++ if (info->sec == info->tsec) ++ { ++ tsec_relocs = info->relocs; ++ tsec_relend = info->relend; ++ tsec_free = NULL; ++ } ++ else ++ { ++ tsec_relocs = (_bfd_elf_link_read_relocs ++ (info->abfd, info->tsec, NULL, ++ (Elf_Internal_Rela *) NULL, ++ info->link_info->keep_memory)); ++ if (tsec_relocs == NULL) ++ return 0; ++ tsec_relend = tsec_relocs + info->tsec->reloc_count; ++ tsec_free = (elf_section_data (info->tsec)->relocs == tsec_relocs ++ ? NULL ++ : tsec_relocs); ++ } ++ ++ /* Recover the symbol's offset within the section. */ ++ ofs = (symval - info->tsec->output_section->vma ++ - info->tsec->output_offset); ++ ++ /* Look for a GPDISP reloc. */ ++ gpdisp = (elf64_sw_64_find_reloc_at_ofs ++ (tsec_relocs, tsec_relend, ofs, R_SW_64_GPDISP)); ++ ++ if (!gpdisp || gpdisp->r_addend != 4) ++ { ++ free (tsec_free); ++ return 0; ++ } ++ free (tsec_free); ++ } ++ ++ /* We've now determined that we can skip an initial gp load. Verify ++ that the call and the target use the same gp. */ ++ if (info->link_info->output_bfd->xvec != info->tsec->owner->xvec ++ || info->gotobj != sw_64_elf_tdata (info->tsec->owner)->gotobj) ++ return 0; ++ ++ return symval + 8; ++} ++ ++static bfd_boolean ++elf64_sw_64_relax_with_lituse (struct sw_64_relax_info *info, ++ bfd_vma symval, Elf_Internal_Rela *irel) ++{ ++ Elf_Internal_Rela *urel, *erel, *irelend = info->relend; ++ int flags; ++ bfd_signed_vma disp; ++ bfd_boolean fits16; ++ bfd_boolean fits32; ++ bfd_boolean lit_reused = FALSE; ++ bfd_boolean all_optimized = TRUE; ++ bfd_boolean changed_contents; ++ bfd_boolean changed_relocs; ++ bfd_byte *contents = info->contents; ++ bfd *abfd = info->abfd; ++ bfd_vma sec_output_vma; ++ unsigned int lit_insn; ++ int relax_pass; ++ ++ lit_insn = bfd_get_32 (abfd, contents + irel->r_offset); ++ if (lit_insn >> 26 != OP_LDQ) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: %pA+%#" PRIx64 ": warning: " ++ "%s relocation against unexpected insn"), ++ abfd, info->sec, (uint64_t) irel->r_offset, "LITERAL"); ++ return TRUE; ++ } ++ ++ /* Can't relax dynamic symbols. */ ++ if (sw_64_elf_dynamic_symbol_p (&info->h->root, info->link_info)) ++ return TRUE; ++ ++ changed_contents = info->changed_contents; ++ changed_relocs = info->changed_relocs; ++ sec_output_vma = info->sec->output_section->vma + info->sec->output_offset; ++ relax_pass = info->link_info->relax_pass; ++ ++ /* Summarize how this particular LITERAL is used. */ ++ for (erel = irel+1, flags = 0; erel < irelend; ++erel) ++ { ++ if (ELF64_R_TYPE (erel->r_info) != R_SW_64_LITUSE) ++ break; ++ if (erel->r_addend <= 6) ++ flags |= 1 << erel->r_addend; ++ } ++ ++ /* A little preparation for the loop... */ ++ disp = symval - info->gp; ++ ++ for (urel = irel+1; urel < erel; ++urel) ++ { ++ bfd_vma urel_r_offset = urel->r_offset; ++ unsigned int insn; ++ int insn_disp; ++ bfd_signed_vma xdisp; ++ Elf_Internal_Rela nrel; ++ ++ insn = bfd_get_32 (abfd, contents + urel_r_offset); ++ ++ switch (urel->r_addend) ++ { ++ case LITUSE_SW_64_ADDR: ++ default: ++ /* This type is really just a placeholder to note that all ++ uses cannot be optimized, but to still allow some. */ ++ all_optimized = FALSE; ++ break; ++ ++ case LITUSE_SW_64_BASE: ++ /* We may only create GPREL relocs during the second pass. */ ++ if (relax_pass == 0) ++ { ++ all_optimized = FALSE; ++ break; ++ } ++ ++ /* We can always optimize 16-bit displacements. */ ++ ++ /* Extract the displacement from the instruction, sign-extending ++ it if necessary, then test whether it is within 16 or 32 bits ++ displacement from GP. */ ++ insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000; ++ ++ xdisp = disp + insn_disp; ++ fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000); ++ fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000 ++ && xdisp < 0x7fff8000); ++ ++ if (fits16) ++ { ++ /* Take the op code and dest from this insn, take the base ++ register from the literal insn. Leave the offset alone. */ ++ insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000); ++ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset); ++ changed_contents = TRUE; ++ ++ nrel = *urel; ++ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), ++ R_SW_64_GPREL16); ++ nrel.r_addend = irel->r_addend; ++ ++ /* As we adjust, move the reloc to the end so that we don't ++ break the LITERAL+LITUSE chain. */ ++ if (urel < --erel) ++ *urel-- = *erel; ++ *erel = nrel; ++ changed_relocs = TRUE; ++ } ++ ++ /* If all mem+byte, we can optimize 32-bit mem displacements. */ ++ else if (fits32 && !(flags & ~6)) ++ { ++ /* FIXME: sanity check that lit insn Ra is mem insn Rb. */ ++ ++ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), ++ R_SW_64_GPRELHIGH); ++ lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000); ++ bfd_put_32 (abfd, (bfd_vma) lit_insn, contents + irel->r_offset); ++ lit_reused = TRUE; ++ changed_contents = TRUE; ++ ++ /* Since all relocs must be optimized, don't bother swapping ++ this relocation to the end. */ ++ urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), ++ R_SW_64_GPRELLOW); ++ urel->r_addend = irel->r_addend; ++ changed_relocs = TRUE; ++ } ++ else ++ all_optimized = FALSE; ++ break; ++ ++ case LITUSE_SW_64_BYTOFF: ++ /* We can always optimize byte instructions. */ ++ ++ /* FIXME: sanity check the insn for byte op. Check that the ++ literal dest reg is indeed Rb in the byte insn. */ ++ ++ insn &= ~ (unsigned) 0x001ff000; ++ insn |= ((symval & 7) << 13) | 0x1000; ++ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset); ++ changed_contents = TRUE; ++ ++ nrel = *urel; ++ nrel.r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ nrel.r_addend = 0; ++ ++ /* As we adjust, move the reloc to the end so that we don't ++ break the LITERAL+LITUSE chain. */ ++ if (urel < --erel) ++ *urel-- = *erel; ++ *erel = nrel; ++ changed_relocs = TRUE; ++ break; ++ ++ case LITUSE_SW_64_JSR: ++ case LITUSE_SW_64_TLSGD: ++ case LITUSE_SW_64_TLSLDM: ++ case LITUSE_SW_64_JSRDIRECT: ++ { ++ bfd_vma optdest, org; ++ bfd_signed_vma odisp; ++ ++ /* For undefined weak symbols, we're mostly interested in getting ++ rid of the got entry whenever possible, so optimize this to a ++ use of the zero register. */ ++ if (info->h && info->h->root.root.type == bfd_link_hash_undefweak) ++ { ++ insn |= 31 << 16; ++ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset); ++ ++ changed_contents = TRUE; ++ break; ++ } ++ ++ /* If not zero, place to jump without needing pv. */ ++ optdest = elf64_sw_64_relax_opt_call (info, symval); ++ org = sec_output_vma + urel_r_offset + 4; ++ odisp = (optdest ? optdest : symval) - org; ++ ++ if (odisp >= -0x400000 && odisp < 0x400000) ++ { ++ Elf_Internal_Rela *xrel; ++ ++ /* Preserve branch prediction call stack when possible. */ ++ if ((insn & INSN_JSR_MASK) == INSN_JSR) ++ insn = (OP_BSR << 26) | (insn & 0x03e00000); ++ else ++ insn = (OP_BR << 26) | (insn & 0x03e00000); ++ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset); ++ changed_contents = TRUE; ++ ++ nrel = *urel; ++ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), ++ R_SW_64_BRADDR); ++ nrel.r_addend = irel->r_addend; ++ ++ if (optdest) ++ nrel.r_addend += optdest - symval; ++ else ++ all_optimized = FALSE; ++ ++ /* Kill any HINT reloc that might exist for this insn. */ ++ xrel = (elf64_sw_64_find_reloc_at_ofs ++ (info->relocs, info->relend, urel_r_offset, ++ R_SW_64_HINT)); ++ if (xrel) ++ xrel->r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ ++ /* As we adjust, move the reloc to the end so that we don't ++ break the LITERAL+LITUSE chain. */ ++ if (urel < --erel) ++ *urel-- = *erel; ++ *erel = nrel; ++ ++ info->changed_relocs = TRUE; ++ } ++ else ++ all_optimized = FALSE; ++ ++ /* Even if the target is not in range for a direct branch, ++ if we share a GP, we can eliminate the gp reload. */ ++ if (optdest) ++ { ++ Elf_Internal_Rela *gpdisp ++ = (elf64_sw_64_find_reloc_at_ofs ++ (info->relocs, irelend, urel_r_offset + 4, ++ R_SW_64_GPDISP)); ++ if (gpdisp) ++ { ++ bfd_byte *p_ldah = contents + gpdisp->r_offset; ++ bfd_byte *p_lda = p_ldah + gpdisp->r_addend; ++ unsigned int ldah = bfd_get_32 (abfd, p_ldah); ++ unsigned int lda = bfd_get_32 (abfd, p_lda); ++ ++ /* Verify that the instruction is "ldah $29,0($26)". ++ Consider a function that ends in a noreturn call, ++ and that the next function begins with an ldgp, ++ and that by accident there is no padding between. ++ In that case the insn would use $27 as the base. */ ++#ifndef XWB20200308 ++ if (ldah == 0xffba0000 && lda == 0xfbba0000) ++#else ++ if (ldah == 0x27ba0000 && lda == 0x23bd0000) ++#endif ++ { ++ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_ldah); ++ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_lda); ++ ++ gpdisp->r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ changed_contents = TRUE; ++ changed_relocs = TRUE; ++ } ++ } ++ } ++ } ++ break; ++ } ++ } ++ ++ /* If we reused the literal instruction, we must have optimized all. */ ++ BFD_ASSERT(!lit_reused || all_optimized); ++ ++ /* If all cases were optimized, we can reduce the use count on this ++ got entry by one, possibly eliminating it. */ ++ if (all_optimized) ++ { ++ if (--info->gotent->use_count == 0) ++ { ++ int sz = sw_64_got_entry_size (R_SW_64_LITERAL); ++ sw_64_elf_tdata (info->gotobj)->total_got_size -= sz; ++ if (!info->h) ++ sw_64_elf_tdata (info->gotobj)->local_got_size -= sz; ++ } ++ ++ /* If the literal instruction is no longer needed (it may have been ++ reused. We can eliminate it. */ ++ /* ??? For now, I don't want to deal with compacting the section, ++ so just nop it out. */ ++ if (!lit_reused) ++ { ++ irel->r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ changed_relocs = TRUE; ++ ++ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, contents + irel->r_offset); ++ changed_contents = TRUE; ++ } ++ } ++ ++ info->changed_contents = changed_contents; ++ info->changed_relocs = changed_relocs; ++ ++ if (all_optimized || relax_pass == 0) ++ return TRUE; ++ return elf64_sw_64_relax_got_load (info, symval, irel, R_SW_64_LITERAL); ++} ++ ++static bfd_boolean ++elf64_sw_64_relax_tls_get_addr (struct sw_64_relax_info *info, bfd_vma symval, ++ Elf_Internal_Rela *irel, bfd_boolean is_gd) ++{ ++ bfd_byte *pos[5]; ++ unsigned int insn, tlsgd_reg; ++ Elf_Internal_Rela *gpdisp, *hint; ++ bfd_boolean dynamic, use_gottprel; ++ unsigned long new_symndx; ++ ++ dynamic = (info->h != NULL ++ && sw_64_elf_dynamic_symbol_p (&info->h->root, info->link_info)); ++ ++ /* If a TLS symbol is accessed using IE at least once, there is no point ++ to use dynamic model for it. */ ++ if (is_gd && info->h && (info->h->flags & SW_64_ELF_LINK_HASH_TLS_IE)) ++ ; ++ ++ /* If the symbol is local, and we've already committed to DF_STATIC_TLS, ++ then we might as well relax to IE. */ ++ else if (bfd_link_pic (info->link_info) && !dynamic ++ && (info->link_info->flags & DF_STATIC_TLS)) ++ ; ++ ++ /* Otherwise we must be building an executable to do anything. */ ++ else if (bfd_link_pic (info->link_info)) ++ return TRUE; ++ ++ /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and ++ the matching LITUSE_TLS relocations. */ ++ if (irel + 2 >= info->relend) ++ return TRUE; ++ if (ELF64_R_TYPE (irel[1].r_info) != R_SW_64_LITERAL ++ || ELF64_R_TYPE (irel[2].r_info) != R_SW_64_LITUSE ++ || irel[2].r_addend != (is_gd ? LITUSE_SW_64_TLSGD : LITUSE_SW_64_TLSLDM)) ++ return TRUE; ++ ++ /* There must be a GPDISP relocation positioned immediately after the ++ LITUSE relocation. */ ++ gpdisp = elf64_sw_64_find_reloc_at_ofs (info->relocs, info->relend, ++ irel[2].r_offset + 4, R_SW_64_GPDISP); ++ if (!gpdisp) ++ return TRUE; ++ ++ pos[0] = info->contents + irel[0].r_offset; ++ pos[1] = info->contents + irel[1].r_offset; ++ pos[2] = info->contents + irel[2].r_offset; ++ pos[3] = info->contents + gpdisp->r_offset; ++ pos[4] = pos[3] + gpdisp->r_addend; ++ ++ /* Beware of the compiler hoisting part of the sequence out a loop ++ and adjusting the destination register for the TLSGD insn. If this ++ happens, there will be a move into $16 before the JSR insn, so only ++ transformations of the first insn pair should use this register. */ ++ tlsgd_reg = bfd_get_32 (info->abfd, pos[0]); ++ tlsgd_reg = (tlsgd_reg >> 21) & 31; ++ ++ /* Generally, the positions are not allowed to be out of order, lest the ++ modified insn sequence have different register lifetimes. We can make ++ an exception when pos 1 is adjacent to pos 0. */ ++ if (pos[1] + 4 == pos[0]) ++ { ++ bfd_byte *tmp = pos[0]; ++ pos[0] = pos[1]; ++ pos[1] = tmp; ++ } ++ if (pos[1] >= pos[2] || pos[2] >= pos[3]) ++ return TRUE; ++ ++ /* Reduce the use count on the LITERAL relocation. Do this before we ++ smash the symndx when we adjust the relocations below. */ ++ { ++ struct sw_64_elf_got_entry *lit_gotent; ++ struct sw_64_elf_link_hash_entry *lit_h; ++ unsigned long indx; ++ ++ BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info); ++ indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info; ++ lit_h = sw_64_elf_sym_hashes (info->abfd)[indx]; ++ ++ while (lit_h->root.root.type == bfd_link_hash_indirect ++ || lit_h->root.root.type == bfd_link_hash_warning) ++ lit_h = (struct sw_64_elf_link_hash_entry *) lit_h->root.root.u.i.link; ++ ++ for (lit_gotent = lit_h->got_entries; lit_gotent ; ++ lit_gotent = lit_gotent->next) ++ if (lit_gotent->gotobj == info->gotobj ++ && lit_gotent->reloc_type == R_SW_64_LITERAL ++ && lit_gotent->addend == irel[1].r_addend) ++ break; ++ BFD_ASSERT (lit_gotent); ++ ++ if (--lit_gotent->use_count == 0) ++ { ++ int sz = sw_64_got_entry_size (R_SW_64_LITERAL); ++ sw_64_elf_tdata (info->gotobj)->total_got_size -= sz; ++ } ++ } ++ ++ /* Change ++ ++ lda $16,x($gp) !tlsgd!1 ++ ldq $27,__tls_get_addr($gp) !literal!1 ++ jsr $26,($27),__tls_get_addr !lituse_tlsgd!1 ++ ldah $29,0($26) !gpdisp!2 ++ lda $29,0($29) !gpdisp!2 ++ to ++ ldq $16,x($gp) !gottprel ++ unop ++ call_pal rduniq ++ addq $16,$0,$0 ++ unop ++ or the first pair to ++ lda $16,x($gp) !tprel ++ unop ++ or ++ ldah $16,x($gp) !tprelhi ++ lda $16,x($16) !tprello ++ ++ as appropriate. */ ++ ++ use_gottprel = FALSE; ++ new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : STN_UNDEF; ++ ++ /* Some compilers warn about a Boolean-looking expression being ++ used in a switch. The explicit cast silences them. */ ++ switch ((int) (!dynamic && !bfd_link_pic (info->link_info))) ++ { ++ case 1: ++ { ++ bfd_vma tp_base; ++ bfd_signed_vma disp; ++ ++ BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL); ++ tp_base = sw_64_get_tprel_base (info->link_info); ++ disp = symval - tp_base; ++ ++ if (disp >= -0x8000 && disp < 0x8000) ++ { ++ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (31 << 16); ++ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); ++ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]); ++ ++ irel[0].r_offset = pos[0] - info->contents; ++ irel[0].r_info = ELF64_R_INFO (new_symndx, R_SW_64_TPREL16); ++ irel[1].r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ break; ++ } ++ else if (disp >= -(bfd_signed_vma) 0x80000000 ++ && disp < (bfd_signed_vma) 0x7fff8000 ++ && pos[0] + 4 == pos[1]) ++ { ++ insn = (OP_LDAH << 26) | (tlsgd_reg << 21) | (31 << 16); ++ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); ++ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (tlsgd_reg << 16); ++ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]); ++ ++ irel[0].r_offset = pos[0] - info->contents; ++ irel[0].r_info = ELF64_R_INFO (new_symndx, R_SW_64_TPRELHI); ++ irel[1].r_offset = pos[1] - info->contents; ++ irel[1].r_info = ELF64_R_INFO (new_symndx, R_SW_64_TPRELLO); ++ break; ++ } ++ } ++ /* FALLTHRU */ ++ ++ default: ++ use_gottprel = TRUE; ++ ++ insn = (OP_LDQ << 26) | (tlsgd_reg << 21) | (29 << 16); ++ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); ++ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]); ++ ++ irel[0].r_offset = pos[0] - info->contents; ++ irel[0].r_info = ELF64_R_INFO (new_symndx, R_SW_64_GOTTPREL); ++ irel[1].r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ break; ++ } ++ ++ bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]); ++ ++ insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0); ++ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]); ++ ++ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]); ++ ++ irel[2].r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ gpdisp->r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ ++ hint = elf64_sw_64_find_reloc_at_ofs (info->relocs, info->relend, ++ irel[2].r_offset, R_SW_64_HINT); ++ if (hint) ++ hint->r_info = ELF64_R_INFO (0, R_SW_64_NONE); ++ ++ info->changed_contents = TRUE; ++ info->changed_relocs = TRUE; ++ ++ /* Reduce the use count on the TLSGD/TLSLDM relocation. */ ++ if (--info->gotent->use_count == 0) ++ { ++ int sz = sw_64_got_entry_size (info->gotent->reloc_type); ++ sw_64_elf_tdata (info->gotobj)->total_got_size -= sz; ++ if (!info->h) ++ sw_64_elf_tdata (info->gotobj)->local_got_size -= sz; ++ } ++ ++ /* If we've switched to a GOTTPREL relocation, increment the reference ++ count on that got entry. */ ++ if (use_gottprel) ++ { ++ struct sw_64_elf_got_entry *tprel_gotent; ++ ++ for (tprel_gotent = *info->first_gotent; tprel_gotent ; ++ tprel_gotent = tprel_gotent->next) ++ if (tprel_gotent->gotobj == info->gotobj ++ && tprel_gotent->reloc_type == R_SW_64_GOTTPREL ++ && tprel_gotent->addend == irel->r_addend) ++ break; ++ if (tprel_gotent) ++ tprel_gotent->use_count++; ++ else ++ { ++ if (info->gotent->use_count == 0) ++ tprel_gotent = info->gotent; ++ else ++ { ++ tprel_gotent = (struct sw_64_elf_got_entry *) ++ bfd_alloc (info->abfd, sizeof (struct sw_64_elf_got_entry)); ++ if (!tprel_gotent) ++ return FALSE; ++ ++ tprel_gotent->next = *info->first_gotent; ++ *info->first_gotent = tprel_gotent; ++ ++ tprel_gotent->gotobj = info->gotobj; ++ tprel_gotent->addend = irel->r_addend; ++ tprel_gotent->got_offset = -1; ++ tprel_gotent->reloc_done = 0; ++ tprel_gotent->reloc_xlated = 0; ++ } ++ ++ tprel_gotent->use_count = 1; ++ tprel_gotent->reloc_type = R_SW_64_GOTTPREL; ++ } ++ } ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++elf64_sw_64_relax_section (bfd *abfd, asection *sec, ++ struct bfd_link_info *link_info, bfd_boolean *again) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel, *irelend; ++ Elf_Internal_Sym *isymbuf = NULL; ++ struct sw_64_elf_got_entry **local_got_entries; ++ struct sw_64_relax_info info; ++ struct sw_64_elf_link_hash_table * htab; ++ int relax_pass; ++ ++ htab = sw_64_elf_hash_table (link_info); ++ if (htab == NULL) ++ return FALSE; ++ ++ /* There's nothing to change, yet. */ ++ *again = FALSE; ++ ++ if (bfd_link_relocatable (link_info) ++ || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC)) ++ != (SEC_CODE | SEC_RELOC | SEC_ALLOC)) ++ || sec->reloc_count == 0) ++ return TRUE; ++ ++ BFD_ASSERT (is_sw_64_elf (abfd)); ++ relax_pass = link_info->relax_pass; ++ ++ /* Make sure our GOT and PLT tables are up-to-date. */ ++ if (htab->relax_trip != link_info->relax_trip) ++ { ++ htab->relax_trip = link_info->relax_trip; ++ ++ /* This should never fail after the initial round, since the only error ++ is GOT overflow, and relaxation only shrinks the table. However, we ++ may only merge got sections during the first pass. If we merge ++ sections after we've created GPREL relocs, the GP for the merged ++ section backs up which may put the relocs out of range. */ ++ if (!elf64_sw_64_size_got_sections (link_info, relax_pass == 0)) ++ abort (); ++ if (elf_hash_table (link_info)->dynamic_sections_created) ++ { ++ elf64_sw_64_size_plt_section (link_info); ++ elf64_sw_64_size_rela_got_section (link_info); ++ } ++ } ++ ++ symtab_hdr = &elf_symtab_hdr (abfd); ++ local_got_entries = sw_64_elf_tdata(abfd)->local_got_entries; ++ ++ /* Load the relocations for this section. */ ++ internal_relocs = (_bfd_elf_link_read_relocs ++ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, ++ link_info->keep_memory)); ++ if (internal_relocs == NULL) ++ return FALSE; ++ ++ memset(&info, 0, sizeof (info)); ++ info.abfd = abfd; ++ info.sec = sec; ++ info.link_info = link_info; ++ info.symtab_hdr = symtab_hdr; ++ info.relocs = internal_relocs; ++ info.relend = irelend = internal_relocs + sec->reloc_count; ++ ++ /* Find the GP for this object. Do not store the result back via ++ _bfd_set_gp_value, since this could change again before final. */ ++ info.gotobj = sw_64_elf_tdata (abfd)->gotobj; ++ if (info.gotobj) ++ { ++ asection *sgot = sw_64_elf_tdata (info.gotobj)->got; ++ info.gp = (sgot->output_section->vma ++ + sgot->output_offset ++ + 0x8000); ++ } ++ ++ /* Get the section contents. */ ++ if (elf_section_data (sec)->this_hdr.contents != NULL) ++ info.contents = elf_section_data (sec)->this_hdr.contents; ++ else ++ { ++ if (!bfd_malloc_and_get_section (abfd, sec, &info.contents)) ++ goto error_return; ++ } ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ bfd_vma symval; ++ struct sw_64_elf_got_entry *gotent; ++ unsigned long r_type = ELF64_R_TYPE (irel->r_info); ++ unsigned long r_symndx = ELF64_R_SYM (irel->r_info); ++ ++ /* Early exit for unhandled or unrelaxable relocations. */ ++ if (r_type != R_SW_64_LITERAL) ++ { ++ /* We complete everything except LITERAL in the first pass. */ ++ if (relax_pass != 0) ++ continue; ++ if (r_type == R_SW_64_TLSLDM) ++ { ++ /* The symbol for a TLSLDM reloc is ignored. Collapse the ++ reloc to the STN_UNDEF (0) symbol so that they all match. */ ++ r_symndx = STN_UNDEF; ++ } ++ else if (r_type != R_SW_64_GOTDTPREL ++ && r_type != R_SW_64_GOTTPREL ++ && r_type != R_SW_64_TLSGD) ++ continue; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* A local symbol. */ ++ Elf_Internal_Sym *isym; ++ ++ /* Read this BFD's local symbols. */ ++ if (isymbuf == NULL) ++ { ++ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; ++ if (isymbuf == NULL) ++ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, 0, ++ NULL, NULL, NULL); ++ if (isymbuf == NULL) ++ goto error_return; ++ } ++ ++ isym = isymbuf + r_symndx; ++ ++ /* Given the symbol for a TLSLDM reloc is ignored, this also ++ means forcing the symbol value to the tp base. */ ++ if (r_type == R_SW_64_TLSLDM) ++ { ++ info.tsec = bfd_abs_section_ptr; ++ symval = sw_64_get_tprel_base (info.link_info); ++ } ++ else ++ { ++ symval = isym->st_value; ++ if (isym->st_shndx == SHN_UNDEF) ++ continue; ++ else if (isym->st_shndx == SHN_ABS) ++ info.tsec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ info.tsec = bfd_com_section_ptr; ++ else ++ info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ } ++ ++ info.h = NULL; ++ info.other = isym->st_other; ++ if (local_got_entries) ++ info.first_gotent = &local_got_entries[r_symndx]; ++ else ++ { ++ info.first_gotent = &info.gotent; ++ info.gotent = NULL; ++ } ++ } ++ else ++ { ++ unsigned long indx; ++ struct sw_64_elf_link_hash_entry *h; ++ ++ indx = r_symndx - symtab_hdr->sh_info; ++ h = sw_64_elf_sym_hashes (abfd)[indx]; ++ BFD_ASSERT (h != NULL); ++ ++ while (h->root.root.type == bfd_link_hash_indirect ++ || h->root.root.type == bfd_link_hash_warning) ++ h = (struct sw_64_elf_link_hash_entry *)h->root.root.u.i.link; ++ ++ /* If the symbol is undefined, we can't do anything with it. */ ++ if (h->root.root.type == bfd_link_hash_undefined) ++ continue; ++ ++ /* If the symbol isn't defined in the current module, ++ again we can't do anything. */ ++ if (h->root.root.type == bfd_link_hash_undefweak) ++ { ++ info.tsec = bfd_abs_section_ptr; ++ symval = 0; ++ } ++ else if (!h->root.def_regular) ++ { ++ /* Except for TLSGD relocs, which can sometimes be ++ relaxed to GOTTPREL relocs. */ ++ if (r_type != R_SW_64_TLSGD) ++ continue; ++ info.tsec = bfd_abs_section_ptr; ++ symval = 0; ++ } ++ else ++ { ++ info.tsec = h->root.root.u.def.section; ++ symval = h->root.root.u.def.value; ++ } ++ ++ info.h = h; ++ info.other = h->root.other; ++ info.first_gotent = &h->got_entries; ++ } ++ ++ /* Search for the got entry to be used by this relocation. */ ++ for (gotent = *info.first_gotent; gotent ; gotent = gotent->next) ++ if (gotent->gotobj == info.gotobj ++ && gotent->reloc_type == r_type ++ && gotent->addend == irel->r_addend) ++ break; ++ info.gotent = gotent; ++ ++ symval += info.tsec->output_section->vma + info.tsec->output_offset; ++ symval += irel->r_addend; ++ ++ switch (r_type) ++ { ++ case R_SW_64_LITERAL: ++ BFD_ASSERT(info.gotent != NULL); ++ ++ /* If there exist LITUSE relocations immediately following, this ++ opens up all sorts of interesting optimizations, because we ++ now know every location that this address load is used. */ ++ if (irel+1 < irelend ++ && ELF64_R_TYPE (irel[1].r_info) == R_SW_64_LITUSE) ++ { ++ if (!elf64_sw_64_relax_with_lituse (&info, symval, irel)) ++ goto error_return; ++ } ++ else ++ { ++ if (!elf64_sw_64_relax_got_load (&info, symval, irel, r_type)) ++ goto error_return; ++ } ++ break; ++ ++ case R_SW_64_GOTDTPREL: ++ case R_SW_64_GOTTPREL: ++ BFD_ASSERT(info.gotent != NULL); ++ if (!elf64_sw_64_relax_got_load (&info, symval, irel, r_type)) ++ goto error_return; ++ break; ++ ++ case R_SW_64_TLSGD: ++ case R_SW_64_TLSLDM: ++ BFD_ASSERT(info.gotent != NULL); ++ if (!elf64_sw_64_relax_tls_get_addr (&info, symval, irel, ++ r_type == R_SW_64_TLSGD)) ++ goto error_return; ++ break; ++ } ++ } ++ ++ if (isymbuf != NULL ++ && symtab_hdr->contents != (unsigned char *) isymbuf) ++ { ++ if (!link_info->keep_memory) ++ free (isymbuf); ++ else ++ { ++ /* Cache the symbols for elf_link_input_bfd. */ ++ symtab_hdr->contents = (unsigned char *) isymbuf; ++ } ++ } ++ ++ if (info.contents != NULL ++ && elf_section_data (sec)->this_hdr.contents != info.contents) ++ { ++ if (!info.changed_contents && !link_info->keep_memory) ++ free (info.contents); ++ else ++ { ++ /* Cache the section contents for elf_link_input_bfd. */ ++ elf_section_data (sec)->this_hdr.contents = info.contents; ++ } ++ } ++ ++ if (elf_section_data (sec)->relocs != internal_relocs) ++ { ++ if (!info.changed_relocs) ++ free (internal_relocs); ++ else ++ elf_section_data (sec)->relocs = internal_relocs; ++ } ++ ++ *again = info.changed_contents || info.changed_relocs; ++ ++ return TRUE; ++ ++ error_return: ++ if (symtab_hdr->contents != (unsigned char *) isymbuf) ++ free (isymbuf); ++ if (elf_section_data (sec)->this_hdr.contents != info.contents) ++ free (info.contents); ++ if (elf_section_data (sec)->relocs != internal_relocs) ++ free (internal_relocs); ++ return FALSE; ++} ++ ++/* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET) ++ into the next available slot in SREL. */ ++ ++static void ++elf64_sw_64_emit_dynrel (bfd *abfd, struct bfd_link_info *info, ++ asection *sec, asection *srel, bfd_vma offset, ++ long dynindx, long rtype, bfd_vma addend) ++{ ++ Elf_Internal_Rela outrel; ++ bfd_byte *loc; ++ ++ BFD_ASSERT (srel != NULL); ++ ++ outrel.r_info = ELF64_R_INFO (dynindx, rtype); ++ outrel.r_addend = addend; ++ ++ offset = _bfd_elf_section_offset (abfd, info, sec, offset); ++ if ((offset | 1) != (bfd_vma) -1) ++ outrel.r_offset = sec->output_section->vma + sec->output_offset + offset; ++ else ++ memset (&outrel, 0, sizeof (outrel)); ++ ++ loc = srel->contents; ++ loc += srel->reloc_count++ * sizeof (Elf64_External_Rela); ++ bfd_elf64_swap_reloca_out (abfd, &outrel, loc); ++ BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size); ++} ++ ++/* Relocate an Sw_64 ELF section for a relocatable link. ++ ++ We don't have to change anything unless the reloc is against a section ++ symbol, in which case we have to adjust according to where the section ++ symbol winds up in the output section. */ ++ ++static bfd_boolean ++elf64_sw_64_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ bfd *input_bfd, asection *input_section, ++ bfd_byte *contents ATTRIBUTE_UNUSED, ++ Elf_Internal_Rela *relocs, ++ Elf_Internal_Sym *local_syms, ++ asection **local_sections) ++{ ++ unsigned long symtab_hdr_sh_info; ++ Elf_Internal_Rela *rel; ++ Elf_Internal_Rela *relend; ++ struct elf_link_hash_entry **sym_hashes; ++ bfd_boolean ret_val = TRUE; ++ ++ symtab_hdr_sh_info = elf_symtab_hdr (input_bfd).sh_info; ++ sym_hashes = elf_sym_hashes (input_bfd); ++ ++ relend = relocs + input_section->reloc_count; ++ for (rel = relocs; rel < relend; rel++) ++ { ++ unsigned long r_symndx; ++ Elf_Internal_Sym *sym; ++ asection *sec; ++ unsigned long r_type; ++ ++ r_type = ELF64_R_TYPE (rel->r_info); ++ if (r_type >= R_SW_64_max) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unsupported relocation type %#x"), ++ input_bfd, (int) r_type); ++ bfd_set_error (bfd_error_bad_value); ++ ret_val = FALSE; ++ continue; ++ } ++ ++ /* The symbol associated with GPDISP and LITUSE is ++ immaterial. Only the addend is significant. */ ++ if (r_type == R_SW_64_GPDISP || r_type == R_SW_64_LITUSE) ++ continue; ++ ++ r_symndx = ELF64_R_SYM (rel->r_info); ++ if (r_symndx < symtab_hdr_sh_info) ++ { ++ sym = local_syms + r_symndx; ++ sec = local_sections[r_symndx]; ++ } ++ else ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = sym_hashes[r_symndx - symtab_hdr_sh_info]; ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ continue; ++ ++ sym = NULL; ++ sec = h->root.u.def.section; ++ } ++ ++ if (sec != NULL && discarded_section (sec)) ++ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, ++ rel, 1, relend, ++ elf64_sw_64_howto_table + r_type, 0, ++ contents); ++ ++ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) ++ rel->r_addend += sec->output_offset; ++ } ++ ++ return ret_val; ++} ++ ++/* Relocate an Sw_64 ELF section. */ ++ ++static bfd_boolean ++elf64_sw_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, ++ bfd *input_bfd, asection *input_section, ++ bfd_byte *contents, Elf_Internal_Rela *relocs, ++ Elf_Internal_Sym *local_syms, ++ asection **local_sections) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Rela *rel; ++ Elf_Internal_Rela *relend; ++ asection *sgot, *srel, *srelgot; ++ bfd *dynobj, *gotobj; ++ bfd_vma gp, tp_base, dtp_base; ++ struct sw_64_elf_got_entry **local_got_entries; ++ bfd_boolean ret_val; ++ ++ BFD_ASSERT (is_sw_64_elf (input_bfd)); ++ ++ /* Handle relocatable links with a smaller loop. */ ++ if (bfd_link_relocatable (info)) ++ return elf64_sw_64_relocate_section_r (output_bfd, info, input_bfd, ++ input_section, contents, relocs, ++ local_syms, local_sections); ++ ++ /* This is a final link. */ ++ ++ ret_val = TRUE; ++ ++ symtab_hdr = &elf_symtab_hdr (input_bfd); ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ srelgot = elf_hash_table (info)->srelgot; ++ ++ if (input_section->flags & SEC_ALLOC) ++ { ++ const char *section_name; ++ section_name = (bfd_elf_string_from_elf_section ++ (input_bfd, elf_elfheader(input_bfd)->e_shstrndx, ++ _bfd_elf_single_rel_hdr (input_section)->sh_name)); ++ BFD_ASSERT(section_name != NULL); ++ srel = bfd_get_linker_section (dynobj, section_name); ++ } ++ else ++ srel = NULL; ++ ++ /* Find the gp value for this input bfd. */ ++ gotobj = sw_64_elf_tdata (input_bfd)->gotobj; ++ if (gotobj) ++ { ++ sgot = sw_64_elf_tdata (gotobj)->got; ++ gp = _bfd_get_gp_value (gotobj); ++ if (gp == 0) ++ { ++ gp = (sgot->output_section->vma ++ + sgot->output_offset ++ + 0x8000); ++ _bfd_set_gp_value (gotobj, gp); ++ } ++ } ++ else ++ { ++ sgot = NULL; ++ gp = 0; ++ } ++ ++ local_got_entries = sw_64_elf_tdata(input_bfd)->local_got_entries; ++ ++ if (elf_hash_table (info)->tls_sec != NULL) ++ { ++ dtp_base = sw_64_get_dtprel_base (info); ++ tp_base = sw_64_get_tprel_base (info); ++ } ++ else ++ dtp_base = tp_base = 0; ++ ++ relend = relocs + input_section->reloc_count; ++ for (rel = relocs; rel < relend; rel++) ++ { ++ struct sw_64_elf_link_hash_entry *h = NULL; ++ struct sw_64_elf_got_entry *gotent; ++ bfd_reloc_status_type r; ++ reloc_howto_type *howto; ++ unsigned long r_symndx; ++ Elf_Internal_Sym *sym = NULL; ++ asection *sec = NULL; ++ bfd_vma value; ++ bfd_vma addend; ++ bfd_boolean dynamic_symbol_p; ++ bfd_boolean unresolved_reloc = FALSE; ++ bfd_boolean undef_weak_ref = FALSE; ++ unsigned long r_type; ++ ++ r_type = ELF64_R_TYPE(rel->r_info); ++ if (r_type >= R_SW_64_max) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unsupported relocation type %#x"), ++ input_bfd, (int) r_type); ++ bfd_set_error (bfd_error_bad_value); ++ ret_val = FALSE; ++ continue; ++ } ++ ++ howto = elf64_sw_64_howto_table + r_type; ++ r_symndx = ELF64_R_SYM(rel->r_info); ++ ++ /* The symbol for a TLSLDM reloc is ignored. Collapse the ++ reloc to the STN_UNDEF (0) symbol so that they all match. */ ++ if (r_type == R_SW_64_TLSLDM) ++ r_symndx = STN_UNDEF; ++ ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ asection *msec; ++ sym = local_syms + r_symndx; ++ sec = local_sections[r_symndx]; ++ msec = sec; ++ value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel); ++ ++ /* If this is a tp-relative relocation against sym STN_UNDEF (0), ++ this is hackery from relax_section. Force the value to ++ be the tls module base. */ ++ if (r_symndx == STN_UNDEF ++ && (r_type == R_SW_64_TLSLDM ++ || r_type == R_SW_64_GOTTPREL ++ || r_type == R_SW_64_TPREL64 ++ || r_type == R_SW_64_TPRELHI ++ || r_type == R_SW_64_TPRELLO ++ || r_type == R_SW_64_TPREL16)) ++ value = dtp_base; ++ ++ if (local_got_entries) ++ gotent = local_got_entries[r_symndx]; ++ else ++ gotent = NULL; ++ ++ /* Need to adjust local GOT entries' addends for SEC_MERGE ++ unless it has been done already. */ ++ if ((sec->flags & SEC_MERGE) ++ && ELF_ST_TYPE (sym->st_info) == STT_SECTION ++ && sec->sec_info_type == SEC_INFO_TYPE_MERGE ++ && gotent ++ && !gotent->reloc_xlated) ++ { ++ struct sw_64_elf_got_entry *ent; ++ ++ for (ent = gotent; ent; ent = ent->next) ++ { ++ ent->reloc_xlated = 1; ++ if (ent->use_count == 0) ++ continue; ++ msec = sec; ++ ent->addend = ++ _bfd_merged_section_offset (output_bfd, &msec, ++ elf_section_data (sec)-> ++ sec_info, ++ sym->st_value + ent->addend); ++ ent->addend -= sym->st_value; ++ ent->addend += msec->output_section->vma ++ + msec->output_offset ++ - sec->output_section->vma ++ - sec->output_offset; ++ } ++ } ++ ++ dynamic_symbol_p = FALSE; ++ } ++ else ++ { ++ bfd_boolean warned, ignored; ++ struct elf_link_hash_entry *hh; ++ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); ++ ++ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, ++ r_symndx, symtab_hdr, sym_hashes, ++ hh, sec, value, ++ unresolved_reloc, warned, ignored); ++ ++ if (warned) ++ continue; ++ ++ if (value == 0 ++ && ! unresolved_reloc ++ && hh->root.type == bfd_link_hash_undefweak) ++ undef_weak_ref = TRUE; ++ ++ h = (struct sw_64_elf_link_hash_entry *) hh; ++ dynamic_symbol_p = sw_64_elf_dynamic_symbol_p (&h->root, info); ++ gotent = h->got_entries; ++ } ++ ++ if (sec != NULL && discarded_section (sec)) ++ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, ++ rel, 1, relend, howto, 0, contents); ++ ++ addend = rel->r_addend; ++ value += addend; ++ ++ /* Search for the proper got entry. */ ++ for (; gotent ; gotent = gotent->next) ++ if (gotent->gotobj == gotobj ++ && gotent->reloc_type == r_type ++ && gotent->addend == addend) ++ break; ++ ++ switch (r_type) ++ { ++ case R_SW_64_GPDISP: ++ { ++ bfd_byte *p_ldah, *p_lda; ++ ++ BFD_ASSERT(gp != 0); ++ ++ value = (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->r_offset); ++ ++ p_ldah = contents + rel->r_offset; ++ p_lda = p_ldah + rel->r_addend; ++ ++ r = elf64_sw_64_do_reloc_gpdisp (input_bfd, gp - value, ++ p_ldah, p_lda); ++ } ++ break; ++ ++ case R_SW_64_LITERAL: ++ BFD_ASSERT(sgot != NULL); ++ BFD_ASSERT(gp != 0); ++ BFD_ASSERT(gotent != NULL); ++ BFD_ASSERT(gotent->use_count >= 1); ++ ++ if (!gotent->reloc_done) ++ { ++ gotent->reloc_done = 1; ++ ++ bfd_put_64 (output_bfd, value, ++ sgot->contents + gotent->got_offset); ++ ++ /* If the symbol has been forced local, output a ++ RELATIVE reloc, otherwise it will be handled in ++ finish_dynamic_symbol. */ ++ if (bfd_link_pic (info) ++ && !dynamic_symbol_p ++ && !undef_weak_ref) ++ elf64_sw_64_emit_dynrel (output_bfd, info, sgot, srelgot, ++ gotent->got_offset, 0, ++ R_SW_64_RELATIVE, value); ++ } ++ ++ value = (sgot->output_section->vma ++ + sgot->output_offset ++ + gotent->got_offset); ++ value -= gp; ++ goto default_reloc; ++ ++ case R_SW_64_GPREL32: ++ case R_SW_64_GPREL16: ++ case R_SW_64_GPRELLOW: ++ if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: gp-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ BFD_ASSERT(gp != 0); ++ value -= gp; ++ goto default_reloc; ++ ++ case R_SW_64_GPRELHIGH: ++ if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: gp-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ BFD_ASSERT(gp != 0); ++ value -= gp; ++ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1); ++ goto default_reloc; ++ ++ case R_SW_64_HINT: ++ /* A call to a dynamic symbol is definitely out of range of ++ the 16-bit displacement. Don't bother writing anything. */ ++ if (dynamic_symbol_p) ++ { ++ r = bfd_reloc_ok; ++ break; ++ } ++ /* The regular PC-relative stuff measures from the start of ++ the instruction rather than the end. */ ++ value -= 4; ++ goto default_reloc; ++ ++ case R_SW_64_BRADDR: ++ if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: pc-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ /* The regular PC-relative stuff measures from the start of ++ the instruction rather than the end. */ ++ value -= 4; ++ goto default_reloc; ++ ++ case R_SW_64_BRSGP: ++ { ++ int other; ++ const char *name; ++ ++ /* The regular PC-relative stuff measures from the start of ++ the instruction rather than the end. */ ++ value -= 4; ++ ++ /* The source and destination gp must be the same. Note that ++ the source will always have an assigned gp, since we forced ++ one in check_relocs, but that the destination may not, as ++ it might not have had any relocations at all. Also take ++ care not to crash if H is an undefined symbol. */ ++ if (h != NULL && sec != NULL ++ && sw_64_elf_tdata (sec->owner)->gotobj ++ && gotobj != sw_64_elf_tdata (sec->owner)->gotobj) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: change in gp: BRSGP %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ ++ /* The symbol should be marked either NOPV or STD_GPLOAD. */ ++ if (h != NULL) ++ other = h->root.other; ++ else ++ other = sym->st_other; ++ switch (other & STO_SW_64_STD_GPLOAD) ++ { ++ case STO_SW_64_NOPV: ++ break; ++ case STO_SW_64_STD_GPLOAD: ++ value += 8; ++ break; ++ default: ++ if (h != NULL) ++ name = h->root.root.root.string; ++ else ++ { ++ name = (bfd_elf_string_from_elf_section ++ (input_bfd, symtab_hdr->sh_link, sym->st_name)); ++ if (name == NULL) ++ name = _(""); ++ else if (name[0] == 0) ++ name = bfd_section_name (sec); ++ } ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: !samegp reloc against symbol without .prologue: %s"), ++ input_bfd, name); ++ ret_val = FALSE; ++ break; ++ } ++ ++ goto default_reloc; ++ } ++ ++ case R_SW_64_REFLONG: ++ case R_SW_64_REFQUAD: ++ case R_SW_64_DTPREL64: ++ case R_SW_64_TPREL64: ++ { ++ long dynindx, dyntype = r_type; ++ bfd_vma dynaddend; ++ ++ /* Careful here to remember RELATIVE relocations for global ++ variables for symbolic shared objects. */ ++ ++ if (dynamic_symbol_p) ++ { ++ BFD_ASSERT(h->root.dynindx != -1); ++ dynindx = h->root.dynindx; ++ dynaddend = addend; ++ addend = 0, value = 0; ++ } ++ else if (r_type == R_SW_64_DTPREL64) ++ { ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ value -= dtp_base; ++ goto default_reloc; ++ } ++ else if (r_type == R_SW_64_TPREL64) ++ { ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ if (!bfd_link_dll (info)) ++ { ++ value -= tp_base; ++ goto default_reloc; ++ } ++ dynindx = 0; ++ dynaddend = value - dtp_base; ++ } ++ else if (bfd_link_pic (info) ++ && r_symndx != STN_UNDEF ++ && (input_section->flags & SEC_ALLOC) ++ && !undef_weak_ref ++ && !(unresolved_reloc ++ && (_bfd_elf_section_offset (output_bfd, info, ++ input_section, ++ rel->r_offset) ++ == (bfd_vma) -1))) ++ { ++ if (r_type == R_SW_64_REFLONG) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unhandled dynamic relocation against %s"), ++ input_bfd, ++ h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ dynindx = 0; ++ dyntype = R_SW_64_RELATIVE; ++ dynaddend = value; ++ } ++ else ++ goto default_reloc; ++ ++ if (input_section->flags & SEC_ALLOC) ++ elf64_sw_64_emit_dynrel (output_bfd, info, input_section, ++ srel, rel->r_offset, dynindx, ++ dyntype, dynaddend); ++ } ++ goto default_reloc; ++ ++ case R_SW_64_SREL16: ++ case R_SW_64_SREL32: ++ case R_SW_64_SREL64: ++ if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: pc-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ else if (bfd_link_pic (info) ++ && undef_weak_ref) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: pc-relative relocation against undefined weak symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ ++ ++ /* ??? .eh_frame references to discarded sections will be smashed ++ to relocations against SHN_UNDEF. The .eh_frame format allows ++ NULL to be encoded as 0 in any format, so this works here. */ ++ if (r_symndx == STN_UNDEF ++ || (unresolved_reloc ++ && _bfd_elf_section_offset (output_bfd, info, ++ input_section, ++ rel->r_offset) == (bfd_vma) -1)) ++ howto = (elf64_sw_64_howto_table ++ + (r_type - R_SW_64_SREL32 + R_SW_64_REFLONG)); ++ goto default_reloc; ++ ++ case R_SW_64_TLSLDM: ++ /* Ignore the symbol for the relocation. The result is always ++ the current module. */ ++ dynamic_symbol_p = 0; ++ /* FALLTHRU */ ++ ++ case R_SW_64_TLSGD: ++ if (!gotent->reloc_done) ++ { ++ gotent->reloc_done = 1; ++ ++ /* Note that the module index for the main program is 1. */ ++ bfd_put_64 (output_bfd, ++ !bfd_link_pic (info) && !dynamic_symbol_p, ++ sgot->contents + gotent->got_offset); ++ ++ /* If the symbol has been forced local, output a ++ DTPMOD64 reloc, otherwise it will be handled in ++ finish_dynamic_symbol. */ ++ if (bfd_link_pic (info) && !dynamic_symbol_p) ++ elf64_sw_64_emit_dynrel (output_bfd, info, sgot, srelgot, ++ gotent->got_offset, 0, ++ R_SW_64_DTPMOD64, 0); ++ ++ if (dynamic_symbol_p || r_type == R_SW_64_TLSLDM) ++ value = 0; ++ else ++ { ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ value -= dtp_base; ++ } ++ bfd_put_64 (output_bfd, value, ++ sgot->contents + gotent->got_offset + 8); ++ } ++ ++ value = (sgot->output_section->vma ++ + sgot->output_offset ++ + gotent->got_offset); ++ value -= gp; ++ goto default_reloc; ++ ++ case R_SW_64_DTPRELHI: ++ case R_SW_64_DTPRELLO: ++ case R_SW_64_DTPREL16: ++ if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: dtp-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ value -= dtp_base; ++ if (r_type == R_SW_64_DTPRELHI) ++ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1); ++ goto default_reloc; ++ ++ case R_SW_64_TPRELHI: ++ case R_SW_64_TPRELLO: ++ case R_SW_64_TPREL16: ++ if (bfd_link_dll (info)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: TLS local exec code cannot be linked into shared objects"), ++ input_bfd); ++ ret_val = FALSE; ++ } ++ else if (dynamic_symbol_p) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: tp-relative relocation against dynamic symbol %s"), ++ input_bfd, h->root.root.root.string); ++ ret_val = FALSE; ++ } ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ value -= tp_base; ++ if (r_type == R_SW_64_TPRELHI) ++ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1); ++ goto default_reloc; ++ ++ case R_SW_64_GOTDTPREL: ++ case R_SW_64_GOTTPREL: ++ BFD_ASSERT(sgot != NULL); ++ BFD_ASSERT(gp != 0); ++ BFD_ASSERT(gotent != NULL); ++ BFD_ASSERT(gotent->use_count >= 1); ++ ++ if (!gotent->reloc_done) ++ { ++ gotent->reloc_done = 1; ++ ++ if (dynamic_symbol_p) ++ value = 0; ++ else ++ { ++ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); ++ if (r_type == R_SW_64_GOTDTPREL) ++ value -= dtp_base; ++ else if (bfd_link_executable (info)) ++ value -= tp_base; ++ else ++ { ++ elf64_sw_64_emit_dynrel (output_bfd, info, sgot, srelgot, ++ gotent->got_offset, 0, ++ R_SW_64_TPREL64, ++ value - dtp_base); ++ value = 0; ++ } ++ } ++ bfd_put_64 (output_bfd, value, ++ sgot->contents + gotent->got_offset); ++ } ++ ++ value = (sgot->output_section->vma ++ + sgot->output_offset ++ + gotent->got_offset); ++ value -= gp; ++ goto default_reloc; ++ ++ default: ++ default_reloc: ++ r = _bfd_final_link_relocate (howto, input_bfd, input_section, ++ contents, rel->r_offset, value, 0); ++ break; ++ } ++ ++ switch (r) ++ { ++ case bfd_reloc_ok: ++ break; ++ ++ case bfd_reloc_overflow: ++ { ++ const char *name; ++ ++ /* Don't warn if the overflow is due to pc relative reloc ++ against discarded section. Section optimization code should ++ handle it. */ ++ ++ if (r_symndx < symtab_hdr->sh_info ++ && sec != NULL && howto->pc_relative ++ && discarded_section (sec)) ++ break; ++ ++ if (h != NULL) ++ name = NULL; ++ else ++ { ++ name = (bfd_elf_string_from_elf_section ++ (input_bfd, symtab_hdr->sh_link, sym->st_name)); ++ if (name == NULL) ++ return FALSE; ++ if (*name == '\0') ++ name = bfd_section_name (sec); ++ } ++ (*info->callbacks->reloc_overflow) ++ (info, (h ? &h->root.root : NULL), name, howto->name, ++ (bfd_vma) 0, input_bfd, input_section, rel->r_offset); ++ } ++ break; ++ ++ default: ++ case bfd_reloc_outofrange: ++ abort (); ++ } ++ } ++ ++ return ret_val; ++} ++ ++/* Finish up dynamic symbol handling. We set the contents of various ++ dynamic sections here. */ ++ ++static bfd_boolean ++elf64_sw_64_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ struct sw_64_elf_link_hash_entry *ah = (struct sw_64_elf_link_hash_entry *)h; ++ ++ if (h->needs_plt) ++ { ++ /* Fill in the .plt entry for this symbol. */ ++ asection *splt, *sgot, *srel; ++ Elf_Internal_Rela outrel; ++ bfd_byte *loc; ++ bfd_vma got_addr, plt_addr; ++ bfd_vma plt_index; ++ struct sw_64_elf_got_entry *gotent; ++ ++ BFD_ASSERT (h->dynindx != -1); ++ ++ splt = elf_hash_table (info)->splt; ++ BFD_ASSERT (splt != NULL); ++ srel = elf_hash_table (info)->srelplt; ++ BFD_ASSERT (srel != NULL); ++ ++ for (gotent = ah->got_entries; gotent ; gotent = gotent->next) ++ if (gotent->reloc_type == R_SW_64_LITERAL ++ && gotent->use_count > 0) ++ { ++ unsigned int insn; ++ int disp; ++ ++ sgot = sw_64_elf_tdata (gotent->gotobj)->got; ++ BFD_ASSERT (sgot != NULL); ++ ++ BFD_ASSERT (gotent->got_offset != -1); ++ BFD_ASSERT (gotent->plt_offset != -1); ++ ++ got_addr = (sgot->output_section->vma ++ + sgot->output_offset ++ + gotent->got_offset); ++ plt_addr = (splt->output_section->vma ++ + splt->output_offset ++ + gotent->plt_offset); ++ ++ plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; ++ ++ /* Fill in the entry in the procedure linkage table. */ ++ if (elf64_sw_64_use_secureplt) ++ { ++ disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4); ++ insn = INSN_AD (INSN_BR, 31, disp); ++ bfd_put_32 (output_bfd, insn, ++ splt->contents + gotent->plt_offset); ++ ++ plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE) ++ / NEW_PLT_ENTRY_SIZE); ++ } ++ else ++ { ++ disp = -(gotent->plt_offset + 4); ++ insn = INSN_AD (INSN_BR, 28, disp); ++ bfd_put_32 (output_bfd, insn, ++ splt->contents + gotent->plt_offset); ++ bfd_put_32 (output_bfd, INSN_UNOP, ++ splt->contents + gotent->plt_offset + 4); ++ bfd_put_32 (output_bfd, INSN_UNOP, ++ splt->contents + gotent->plt_offset + 8); ++ ++ plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE) ++ / OLD_PLT_ENTRY_SIZE); ++ } ++ ++ /* Fill in the entry in the .rela.plt section. */ ++ outrel.r_offset = got_addr; ++ outrel.r_info = ELF64_R_INFO(h->dynindx, R_SW_64_JMP_SLOT); ++ outrel.r_addend = 0; ++ ++ loc = srel->contents + plt_index * sizeof (Elf64_External_Rela); ++ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); ++ ++ /* Fill in the entry in the .got. */ ++ bfd_put_64 (output_bfd, plt_addr, ++ sgot->contents + gotent->got_offset); ++ } ++ } ++ else if (sw_64_elf_dynamic_symbol_p (h, info)) ++ { ++ /* Fill in the dynamic relocations for this symbol's .got entries. */ ++ asection *srel; ++ struct sw_64_elf_got_entry *gotent; ++ ++ srel = elf_hash_table (info)->srelgot; ++ BFD_ASSERT (srel != NULL); ++ ++ for (gotent = ((struct sw_64_elf_link_hash_entry *) h)->got_entries; ++ gotent != NULL; ++ gotent = gotent->next) ++ { ++ asection *sgot; ++ long r_type; ++ ++ if (gotent->use_count == 0) ++ continue; ++ ++ sgot = sw_64_elf_tdata (gotent->gotobj)->got; ++ ++ r_type = gotent->reloc_type; ++ switch (r_type) ++ { ++ case R_SW_64_LITERAL: ++ r_type = R_SW_64_GLOB_DAT; ++ break; ++ case R_SW_64_TLSGD: ++ r_type = R_SW_64_DTPMOD64; ++ break; ++ case R_SW_64_GOTDTPREL: ++ r_type = R_SW_64_DTPREL64; ++ break; ++ case R_SW_64_GOTTPREL: ++ r_type = R_SW_64_TPREL64; ++ break; ++ case R_SW_64_TLSLDM: ++ default: ++ abort (); ++ } ++ ++ elf64_sw_64_emit_dynrel (output_bfd, info, sgot, srel, ++ gotent->got_offset, h->dynindx, ++ r_type, gotent->addend); ++ ++ if (gotent->reloc_type == R_SW_64_TLSGD) ++ elf64_sw_64_emit_dynrel (output_bfd, info, sgot, srel, ++ gotent->got_offset + 8, h->dynindx, ++ R_SW_64_DTPREL64, gotent->addend); ++ } ++ } ++ ++ /* Mark some specially defined symbols as absolute. */ ++ if (h == elf_hash_table (info)->hdynamic ++ || h == elf_hash_table (info)->hgot ++ || h == elf_hash_table (info)->hplt) ++ sym->st_shndx = SHN_ABS; ++ ++ return TRUE; ++} ++ ++/* Finish up the dynamic sections. */ ++ ++static bfd_boolean ++elf64_sw_64_finish_dynamic_sections (bfd *output_bfd, ++ struct bfd_link_info *info) ++{ ++ bfd *dynobj; ++ asection *sdyn; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ sdyn = bfd_get_linker_section (dynobj, ".dynamic"); ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ asection *splt, *sgotplt, *srelaplt; ++ Elf64_External_Dyn *dyncon, *dynconend; ++ bfd_vma plt_vma, gotplt_vma; ++ ++ splt = elf_hash_table (info)->splt; ++ srelaplt = elf_hash_table (info)->srelplt; ++ BFD_ASSERT (splt != NULL && sdyn != NULL); ++ ++ plt_vma = splt->output_section->vma + splt->output_offset; ++ ++ gotplt_vma = 0; ++ if (elf64_sw_64_use_secureplt) ++ { ++ sgotplt = elf_hash_table (info)->sgotplt; ++ BFD_ASSERT (sgotplt != NULL); ++ if (sgotplt->size > 0) ++ gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset; ++ } ++ ++ dyncon = (Elf64_External_Dyn *) sdyn->contents; ++ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); ++ for (; dyncon < dynconend; dyncon++) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); ++ ++ switch (dyn.d_tag) ++ { ++ case DT_PLTGOT: ++ dyn.d_un.d_ptr ++ = elf64_sw_64_use_secureplt ? gotplt_vma : plt_vma; ++ break; ++ case DT_PLTRELSZ: ++ dyn.d_un.d_val = srelaplt ? srelaplt->size : 0; ++ break; ++ case DT_JMPREL: ++ dyn.d_un.d_ptr = srelaplt ? (srelaplt->output_section->vma ++ + srelaplt->output_offset) : 0; ++ break; ++ } ++ ++ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); ++ } ++ ++ /* Initialize the plt header. */ ++ if (splt->size > 0) ++ { ++ unsigned int insn; ++ int ofs; ++ ++ if (elf64_sw_64_use_secureplt) ++ { ++ ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE); ++ ++ insn = INSN_ABC (INSN_SUBQ, 27, 28, 25); ++ bfd_put_32 (output_bfd, insn, splt->contents); ++ ++ insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16); ++ bfd_put_32 (output_bfd, insn, splt->contents + 4); ++ ++ insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25); ++ bfd_put_32 (output_bfd, insn, splt->contents + 8); ++ ++ insn = INSN_ABO (INSN_LDA, 28, 28, ofs); ++ bfd_put_32 (output_bfd, insn, splt->contents + 12); ++ ++ insn = INSN_ABO (INSN_LDQ, 27, 28, 0); ++ bfd_put_32 (output_bfd, insn, splt->contents + 16); ++ ++ insn = INSN_ABC (INSN_ADDQ, 25, 25, 25); ++ bfd_put_32 (output_bfd, insn, splt->contents + 20); ++ ++ insn = INSN_ABO (INSN_LDQ, 28, 28, 8); ++ bfd_put_32 (output_bfd, insn, splt->contents + 24); ++ ++ insn = INSN_AB (INSN_JMP, 31, 27); ++ bfd_put_32 (output_bfd, insn, splt->contents + 28); ++ ++ insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE); ++ bfd_put_32 (output_bfd, insn, splt->contents + 32); ++ } ++ else ++ { ++ insn = INSN_AD (INSN_BR, 27, 0); /* br $27, .+4 */ ++ bfd_put_32 (output_bfd, insn, splt->contents); ++ ++ insn = INSN_ABO (INSN_LDQ, 27, 27, 12); ++ bfd_put_32 (output_bfd, insn, splt->contents + 4); ++ ++ insn = INSN_UNOP; ++ bfd_put_32 (output_bfd, insn, splt->contents + 8); ++ ++ insn = INSN_AB (INSN_JMP, 27, 27); ++ bfd_put_32 (output_bfd, insn, splt->contents + 12); ++ ++ /* The next two words will be filled in by ld.so. */ ++ bfd_put_64 (output_bfd, 0, splt->contents + 16); ++ bfd_put_64 (output_bfd, 0, splt->contents + 24); ++ } ++ ++ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0; ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* We need to use a special link routine to handle the .mdebug section. ++ We need to merge all instances of these sections together, not write ++ them all out sequentially. */ ++ ++static bfd_boolean ++elf64_sw_64_final_link (bfd *abfd, struct bfd_link_info *info) ++{ ++ asection *o; ++ struct bfd_link_order *p; ++ asection *mdebug_sec; ++ struct ecoff_debug_info debug; ++ const struct ecoff_debug_swap *swap ++ = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; ++ HDRR *symhdr = &debug.symbolic_header; ++ void * mdebug_handle = NULL; ++ struct sw_64_elf_link_hash_table * htab; ++ ++ htab = sw_64_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ /* Go through the sections and collect the mdebug information. */ ++ mdebug_sec = NULL; ++ for (o = abfd->sections; o != (asection *) NULL; o = o->next) ++ { ++ if (strcmp (o->name, ".mdebug") == 0) ++ { ++ struct extsym_info einfo; ++ ++ /* We have found the .mdebug section in the output file. ++ Look through all the link_orders comprising it and merge ++ the information together. */ ++ symhdr->magic = swap->sym_magic; ++ /* FIXME: What should the version stamp be? */ ++ symhdr->vstamp = 0; ++ symhdr->ilineMax = 0; ++ symhdr->cbLine = 0; ++ symhdr->idnMax = 0; ++ symhdr->ipdMax = 0; ++ symhdr->isymMax = 0; ++ symhdr->ioptMax = 0; ++ symhdr->iauxMax = 0; ++ symhdr->issMax = 0; ++ symhdr->issExtMax = 0; ++ symhdr->ifdMax = 0; ++ symhdr->crfd = 0; ++ symhdr->iextMax = 0; ++ ++ /* We accumulate the debugging information itself in the ++ debug_info structure. */ ++ debug.line = NULL; ++ debug.external_dnr = NULL; ++ debug.external_pdr = NULL; ++ debug.external_sym = NULL; ++ debug.external_opt = NULL; ++ debug.external_aux = NULL; ++ debug.ss = NULL; ++ debug.ssext = debug.ssext_end = NULL; ++ debug.external_fdr = NULL; ++ debug.external_rfd = NULL; ++ debug.external_ext = debug.external_ext_end = NULL; ++ ++ mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); ++ if (mdebug_handle == NULL) ++ return FALSE; ++ ++ if (1) ++ { ++ asection *s; ++ EXTR esym; ++ bfd_vma last = 0; ++ unsigned int i; ++ static const char * const name[] = ++ { ++ ".text", ".init", ".fini", ".data", ++ ".rodata", ".sdata", ".sbss", ".bss" ++ }; ++ static const int sc[] = { scText, scInit, scFini, scData, ++ scRData, scSData, scSBss, scBss }; ++ ++ esym.jmptbl = 0; ++ esym.cobol_main = 0; ++ esym.weakext = 0; ++ esym.reserved = 0; ++ esym.ifd = ifdNil; ++ esym.asym.iss = issNil; ++ esym.asym.st = stLocal; ++ esym.asym.reserved = 0; ++ esym.asym.index = indexNil; ++ for (i = 0; i < 8; i++) ++ { ++ esym.asym.sc = sc[i]; ++ s = bfd_get_section_by_name (abfd, name[i]); ++ if (s != NULL) ++ { ++ esym.asym.value = s->vma; ++ last = s->vma + s->size; ++ } ++ else ++ esym.asym.value = last; ++ ++ if (! bfd_ecoff_debug_one_external (abfd, &debug, swap, ++ name[i], &esym)) ++ return FALSE; ++ } ++ } ++ ++ for (p = o->map_head.link_order; ++ p != (struct bfd_link_order *) NULL; ++ p = p->next) ++ { ++ asection *input_section; ++ bfd *input_bfd; ++ const struct ecoff_debug_swap *input_swap; ++ struct ecoff_debug_info input_debug; ++ char *eraw_src; ++ char *eraw_end; ++ ++ if (p->type != bfd_indirect_link_order) ++ { ++ if (p->type == bfd_data_link_order) ++ continue; ++ abort (); ++ } ++ ++ input_section = p->u.indirect.section; ++ input_bfd = input_section->owner; ++ ++ if (! is_sw_64_elf (input_bfd)) ++ /* I don't know what a non SW_64 ELF bfd would be ++ doing with a .mdebug section, but I don't really ++ want to deal with it. */ ++ continue; ++ ++ input_swap = (get_elf_backend_data (input_bfd) ++ ->elf_backend_ecoff_debug_swap); ++ ++ BFD_ASSERT (p->size == input_section->size); ++ ++ /* The ECOFF linking code expects that we have already ++ read in the debugging information and set up an ++ ecoff_debug_info structure, so we do that now. */ ++ if (!elf64_sw_64_read_ecoff_info (input_bfd, input_section, ++ &input_debug)) ++ return FALSE; ++ ++ if (! (bfd_ecoff_debug_accumulate ++ (mdebug_handle, abfd, &debug, swap, input_bfd, ++ &input_debug, input_swap, info))) ++ return FALSE; ++ ++ /* Loop through the external symbols. For each one with ++ interesting information, try to find the symbol in ++ the linker global hash table and save the information ++ for the output external symbols. */ ++ eraw_src = (char *) input_debug.external_ext; ++ eraw_end = (eraw_src ++ + (input_debug.symbolic_header.iextMax ++ * input_swap->external_ext_size)); ++ for (; ++ eraw_src < eraw_end; ++ eraw_src += input_swap->external_ext_size) ++ { ++ EXTR ext; ++ const char *name; ++ struct sw_64_elf_link_hash_entry *h; ++ ++ (*input_swap->swap_ext_in) (input_bfd, eraw_src, &ext); ++ if (ext.asym.sc == scNil ++ || ext.asym.sc == scUndefined ++ || ext.asym.sc == scSUndefined) ++ continue; ++ ++ name = input_debug.ssext + ext.asym.iss; ++ h = sw_64_elf_link_hash_lookup (htab, name, FALSE, FALSE, TRUE); ++ if (h == NULL || h->esym.ifd != -2) ++ continue; ++ ++ if (ext.ifd != -1) ++ { ++ BFD_ASSERT (ext.ifd ++ < input_debug.symbolic_header.ifdMax); ++ ext.ifd = input_debug.ifdmap[ext.ifd]; ++ } ++ ++ h->esym = ext; ++ } ++ ++ /* Free up the information we just read. */ ++ free (input_debug.line); ++ free (input_debug.external_dnr); ++ free (input_debug.external_pdr); ++ free (input_debug.external_sym); ++ free (input_debug.external_opt); ++ free (input_debug.external_aux); ++ free (input_debug.ss); ++ free (input_debug.ssext); ++ free (input_debug.external_fdr); ++ free (input_debug.external_rfd); ++ free (input_debug.external_ext); ++ ++ /* Hack: reset the SEC_HAS_CONTENTS flag so that ++ elf_link_input_bfd ignores this section. */ ++ input_section->flags &=~ SEC_HAS_CONTENTS; ++ } ++ ++ /* Build the external symbol information. */ ++ einfo.abfd = abfd; ++ einfo.info = info; ++ einfo.debug = &debug; ++ einfo.swap = swap; ++ einfo.failed = FALSE; ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf64_sw_64_output_extsym, ++ &einfo); ++ if (einfo.failed) ++ return FALSE; ++ ++ /* Set the size of the .mdebug section. */ ++ o->size = bfd_ecoff_debug_size (abfd, &debug, swap); ++ ++ /* Skip this section later on (I don't think this currently ++ matters, but someday it might). */ ++ o->map_head.link_order = (struct bfd_link_order *) NULL; ++ ++ mdebug_sec = o; ++ } ++ } ++ ++ /* Invoke the regular ELF backend linker to do all the work. */ ++ if (! bfd_elf_final_link (abfd, info)) ++ return FALSE; ++ ++ /* Now write out the computed sections. */ ++ ++ /* The .got subsections... */ ++ { ++ bfd *i, *dynobj = elf_hash_table(info)->dynobj; ++ for (i = htab->got_list; ++ i != NULL; ++ i = sw_64_elf_tdata(i)->got_link_next) ++ { ++ asection *sgot; ++ ++ /* elf_bfd_final_link already did everything in dynobj. */ ++ if (i == dynobj) ++ continue; ++ ++ sgot = sw_64_elf_tdata(i)->got; ++ if (! bfd_set_section_contents (abfd, sgot->output_section, ++ sgot->contents, ++ (file_ptr) sgot->output_offset, ++ sgot->size)) ++ return FALSE; ++ } ++ } ++ ++ if (mdebug_sec != (asection *) NULL) ++ { ++ BFD_ASSERT (abfd->output_has_begun); ++ if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, ++ swap, info, ++ mdebug_sec->filepos)) ++ return FALSE; ++ ++ bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); ++ } ++ ++ return TRUE; ++} ++ ++static enum elf_reloc_type_class ++elf64_sw_64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ const asection *rel_sec ATTRIBUTE_UNUSED, ++ const Elf_Internal_Rela *rela) ++{ ++ switch ((int) ELF64_R_TYPE (rela->r_info)) ++ { ++ case R_SW_64_RELATIVE: ++ return reloc_class_relative; ++ case R_SW_64_JMP_SLOT: ++ return reloc_class_plt; ++ case R_SW_64_COPY: ++ return reloc_class_copy; ++ default: ++ return reloc_class_normal; ++ } ++} ++ ++static const struct bfd_elf_special_section elf64_sw_64_special_sections[] = ++{ ++ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_SW_64_GPREL }, ++ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_SW_64_GPREL }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++/* ECOFF swapping routines. These are used when dealing with the ++ .mdebug section, which is in the ECOFF debugging format. Copied ++ from elf32-mips.c. */ ++static const struct ecoff_debug_swap ++elf64_sw_64_ecoff_debug_swap = ++{ ++ /* Symbol table magic number. */ ++ magicSym2, ++ /* Alignment of debugging information. E.g., 4. */ ++ 8, ++ /* Sizes of external symbolic information. */ ++ sizeof (struct hdr_ext), ++ sizeof (struct dnr_ext), ++ sizeof (struct pdr_ext), ++ sizeof (struct sym_ext), ++ sizeof (struct opt_ext), ++ sizeof (struct fdr_ext), ++ sizeof (struct rfd_ext), ++ sizeof (struct ext_ext), ++ /* Functions to swap in external symbolic data. */ ++ ecoff_swap_hdr_in, ++ ecoff_swap_dnr_in, ++ ecoff_swap_pdr_in, ++ ecoff_swap_sym_in, ++ ecoff_swap_opt_in, ++ ecoff_swap_fdr_in, ++ ecoff_swap_rfd_in, ++ ecoff_swap_ext_in, ++ _bfd_ecoff_swap_tir_in, ++ _bfd_ecoff_swap_rndx_in, ++ /* Functions to swap out external symbolic data. */ ++ ecoff_swap_hdr_out, ++ ecoff_swap_dnr_out, ++ ecoff_swap_pdr_out, ++ ecoff_swap_sym_out, ++ ecoff_swap_opt_out, ++ ecoff_swap_fdr_out, ++ ecoff_swap_rfd_out, ++ ecoff_swap_ext_out, ++ _bfd_ecoff_swap_tir_out, ++ _bfd_ecoff_swap_rndx_out, ++ /* Function to read in symbolic data. */ ++ elf64_sw_64_read_ecoff_info ++}; ++ ++/* Use a non-standard hash bucket size of 8. */ ++ ++static const struct elf_size_info sw_64_elf_size_info = ++{ ++ sizeof (Elf64_External_Ehdr), ++ sizeof (Elf64_External_Phdr), ++ sizeof (Elf64_External_Shdr), ++ sizeof (Elf64_External_Rel), ++ sizeof (Elf64_External_Rela), ++ sizeof (Elf64_External_Sym), ++ sizeof (Elf64_External_Dyn), ++ sizeof (Elf_External_Note), ++ 8, ++ 1, ++ 64, 3, ++ ELFCLASS64, EV_CURRENT, ++ bfd_elf64_write_out_phdrs, ++ bfd_elf64_write_shdrs_and_ehdr, ++ bfd_elf64_checksum_contents, ++ bfd_elf64_write_relocs, ++ bfd_elf64_swap_symbol_in, ++ bfd_elf64_swap_symbol_out, ++ bfd_elf64_slurp_reloc_table, ++ bfd_elf64_slurp_symbol_table, ++ bfd_elf64_swap_dyn_in, ++ bfd_elf64_swap_dyn_out, ++ bfd_elf64_swap_reloc_in, ++ bfd_elf64_swap_reloc_out, ++ bfd_elf64_swap_reloca_in, ++ bfd_elf64_swap_reloca_out ++}; ++ ++#define TARGET_LITTLE_SYM sw_64_elf64_vec ++#define TARGET_LITTLE_NAME "elf64-sw_64" ++#define ELF_ARCH bfd_arch_sw_64 ++#define ELF_TARGET_ID SW_64_ELF_DATA ++#define ELF_MACHINE_CODE EM_SW_64 ++#define ELF_MAXPAGESIZE 0x10000 ++#define ELF_COMMONPAGESIZE 0x2000 ++ ++#define bfd_elf64_bfd_link_hash_table_create \ ++ elf64_sw_64_bfd_link_hash_table_create ++ ++#define bfd_elf64_bfd_reloc_type_lookup \ ++ elf64_sw_64_bfd_reloc_type_lookup ++#define bfd_elf64_bfd_reloc_name_lookup \ ++ elf64_sw_64_bfd_reloc_name_lookup ++#define elf_info_to_howto \ ++ elf64_sw_64_info_to_howto ++ ++#define bfd_elf64_mkobject \ ++ elf64_sw_64_mkobject ++#define elf_backend_object_p \ ++ elf64_sw_64_object_p ++ ++#define elf_backend_section_from_shdr \ ++ elf64_sw_64_section_from_shdr ++#define elf_backend_section_flags \ ++ elf64_sw_64_section_flags ++#define elf_backend_fake_sections \ ++ elf64_sw_64_fake_sections ++ ++#define bfd_elf64_bfd_is_local_label_name \ ++ elf64_sw_64_is_local_label_name ++#define bfd_elf64_find_nearest_line \ ++ elf64_sw_64_find_nearest_line ++#define bfd_elf64_bfd_relax_section \ ++ elf64_sw_64_relax_section ++ ++#define elf_backend_add_symbol_hook \ ++ elf64_sw_64_add_symbol_hook ++#define elf_backend_relocs_compatible \ ++ _bfd_elf_relocs_compatible ++#define elf_backend_sort_relocs_p \ ++ elf64_sw_64_sort_relocs_p ++#define elf_backend_check_relocs \ ++ elf64_sw_64_check_relocs ++#define elf_backend_create_dynamic_sections \ ++ elf64_sw_64_create_dynamic_sections ++#define elf_backend_adjust_dynamic_symbol \ ++ elf64_sw_64_adjust_dynamic_symbol ++#define elf_backend_merge_symbol_attribute \ ++ elf64_sw_64_merge_symbol_attribute ++#define elf_backend_copy_indirect_symbol \ ++ elf64_sw_64_copy_indirect_symbol ++#define elf_backend_always_size_sections \ ++ elf64_sw_64_always_size_sections ++#define elf_backend_size_dynamic_sections \ ++ elf64_sw_64_size_dynamic_sections ++#define elf_backend_omit_section_dynsym \ ++ _bfd_elf_omit_section_dynsym_all ++#define elf_backend_relocate_section \ ++ elf64_sw_64_relocate_section ++#define elf_backend_finish_dynamic_symbol \ ++ elf64_sw_64_finish_dynamic_symbol ++#define elf_backend_finish_dynamic_sections \ ++ elf64_sw_64_finish_dynamic_sections ++#define bfd_elf64_bfd_final_link \ ++ elf64_sw_64_final_link ++#define elf_backend_reloc_type_class \ ++ elf64_sw_64_reloc_type_class ++ ++#define elf_backend_can_gc_sections 1 ++#define elf_backend_gc_mark_hook elf64_sw_64_gc_mark_hook ++ ++#define elf_backend_ecoff_debug_swap \ ++ &elf64_sw_64_ecoff_debug_swap ++ ++#define elf_backend_size_info \ ++ sw_64_elf_size_info ++ ++#define elf_backend_special_sections \ ++ elf64_sw_64_special_sections ++ ++#define elf_backend_strip_zero_sized_dynamic_sections \ ++ _bfd_elf_strip_zero_sized_dynamic_sections ++ ++/* A few constants that determine how the .plt section is set up. */ ++#define elf_backend_want_got_plt 0 ++#define elf_backend_plt_readonly 0 ++#define elf_backend_want_plt_sym 1 ++#define elf_backend_got_header_size 0 ++#define elf_backend_dtrel_excludes_plt 1 ++ ++#include "elf64-target.h" ++ ++/* FreeBSD support. */ ++ ++#undef TARGET_LITTLE_SYM ++#define TARGET_LITTLE_SYM sw_64_elf64_fbsd_vec ++#undef TARGET_LITTLE_NAME ++#define TARGET_LITTLE_NAME "elf64-sw_64-freebsd" ++#undef ELF_OSABI ++#define ELF_OSABI ELFOSABI_FREEBSD ++ ++/* The kernel recognizes executables as valid only if they carry a ++ "FreeBSD" label in the ELF header. So we put this label on all ++ executables and (for simplicity) also all other object files. */ ++ ++static bfd_boolean ++elf64_sw_64_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info) ++{ ++ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ ++ ++ if (!_bfd_elf_init_file_header (abfd, info)) ++ return FALSE; ++ ++ i_ehdrp = elf_elfheader (abfd); ++ ++ /* Put an ABI label supported by FreeBSD >= 4.1. */ ++ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; ++#ifdef OLD_FREEBSD_ABI_LABEL ++ /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ ++ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); ++#endif ++ return TRUE; ++} ++ ++#undef elf_backend_init_file_header ++#define elf_backend_init_file_header \ ++ elf64_sw_64_fbsd_init_file_header ++ ++#undef elf64_bed ++#define elf64_bed elf64_sw_64_fbsd_bed ++ ++#include "elf64-target.h" +diff -Nuar gdb-10.2/bfd/elf-bfd.h gdb-10.2/bfd/elf-bfd.h +--- gdb-10.2/bfd/elf-bfd.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/elf-bfd.h 2025-04-16 17:06:51.912086800 +0800 +@@ -27,6 +27,8 @@ + #include "elf/internal.h" + #include "bfdlink.h" + ++#include ++ + #ifdef __cplusplus + extern "C" { + #endif +@@ -488,6 +490,7 @@ + { + AARCH64_ELF_DATA = 1, + ALPHA_ELF_DATA, ++ SW_64_ELF_DATA, + ARC_ELF_DATA, + ARM_ELF_DATA, + AVR_ELF_DATA, +diff -Nuar gdb-10.2/bfd/elf-bfd.h.orig gdb-10.2/bfd/elf-bfd.h.orig +--- gdb-10.2/bfd/elf-bfd.h.orig 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/elf-bfd.h.orig 2025-04-16 17:06:41.932086800 +0800 +@@ -0,0 +1,3093 @@ ++/* BFD back-end data structures for ELF files. ++ Copyright (C) 1992-2020 Free Software Foundation, Inc. ++ Written by Cygnus Support. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifndef _LIBELF_H_ ++#define _LIBELF_H_ 1 ++ ++#include "elf/common.h" ++#include "elf/external.h" ++#include "elf/internal.h" ++#include "bfdlink.h" ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* The number of entries in a section is its size divided by the size ++ of a single entry. This is normally only applicable to reloc and ++ symbol table sections. ++ PR 9934: It is possible to have relocations that do not refer to ++ symbols, thus it is also possible to have a relocation section in ++ an object file, but no symbol table. */ ++#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0) ++ ++/* If size isn't specified as 64 or 32, NAME macro should fail. */ ++#ifndef NAME ++#if ARCH_SIZE == 64 ++#define NAME(x, y) x ## 64 ## _ ## y ++#endif ++#if ARCH_SIZE == 32 ++#define NAME(x, y) x ## 32 ## _ ## y ++#endif ++#endif ++ ++#ifndef NAME ++#define NAME(x, y) x ## NOSIZE ## _ ## y ++#endif ++ ++#define ElfNAME(X) NAME(Elf,X) ++#define elfNAME(X) NAME(elf,X) ++ ++/* Information held for an ELF symbol. The first field is the ++ corresponding asymbol. Every symbol is an ELF file is actually a ++ pointer to this structure, although it is often handled as a ++ pointer to an asymbol. */ ++ ++typedef struct ++{ ++ /* The BFD symbol. */ ++ asymbol symbol; ++ /* ELF symbol information. */ ++ Elf_Internal_Sym internal_elf_sym; ++ /* Backend specific information. */ ++ union ++ { ++ unsigned int hppa_arg_reloc; ++ void *mips_extr; ++ void *any; ++ } ++ tc_data; ++ ++ /* Version information. This is from an Elf_Internal_Versym ++ structure in a SHT_GNU_versym section. It is zero if there is no ++ version information. */ ++ unsigned short version; ++ ++} elf_symbol_type; ++ ++struct elf_strtab_hash; ++struct got_entry; ++struct plt_entry; ++ ++union gotplt_union ++ { ++ bfd_signed_vma refcount; ++ bfd_vma offset; ++ struct got_entry *glist; ++ struct plt_entry *plist; ++ }; ++ ++struct elf_link_virtual_table_entry ++ { ++ /* Virtual table entry use information. This array is nominally of size ++ size/sizeof(target_void_pointer), though we have to be able to assume ++ and track a size while the symbol is still undefined. It is indexed ++ via offset/sizeof(target_void_pointer). */ ++ size_t size; ++ bfd_boolean *used; ++ ++ /* Virtual table derivation info. */ ++ struct elf_link_hash_entry *parent; ++ }; ++ ++/* ELF symbol version. */ ++enum elf_symbol_version ++ { ++ unknown = 0, ++ unversioned, ++ versioned, ++ versioned_hidden ++ }; ++ ++/* ELF linker hash table entries. */ ++ ++struct elf_link_hash_entry ++{ ++ struct bfd_link_hash_entry root; ++ ++ /* Symbol index in output file. This is initialized to -1. It is ++ set to -2 if the symbol is used by a reloc. It is set to -3 if ++ this symbol is defined in a discarded section. */ ++ long indx; ++ ++ /* Symbol index as a dynamic symbol. Initialized to -1, and remains ++ -1 if this is not a dynamic symbol. */ ++ /* ??? Note that this is consistently used as a synonym for tests ++ against whether we can perform various simplifying transformations ++ to the code. (E.g. changing a pc-relative jump to a PLT entry ++ into a pc-relative jump to the target function.) That test, which ++ is often relatively complex, and someplaces wrong or incomplete, ++ should really be replaced by a predicate in elflink.c. ++ ++ End result: this field -1 does not indicate that the symbol is ++ not in the dynamic symbol table, but rather that the symbol is ++ not visible outside this DSO. */ ++ long dynindx; ++ ++ /* If this symbol requires an entry in the global offset table, the ++ processor specific backend uses this field to track usage and ++ final offset. Two schemes are supported: The first assumes that ++ a symbol may only have one GOT entry, and uses REFCOUNT until ++ size_dynamic_sections, at which point the contents of the .got is ++ fixed. Afterward, if OFFSET is -1, then the symbol does not ++ require a global offset table entry. The second scheme allows ++ multiple GOT entries per symbol, managed via a linked list ++ pointed to by GLIST. */ ++ union gotplt_union got; ++ ++ /* Same, but tracks a procedure linkage table entry. */ ++ union gotplt_union plt; ++ ++ /* Symbol size. NB: All fields starting from here are cleared by ++ _bfd_elf_link_hash_newfunc. */ ++ bfd_size_type size; ++ ++ /* Track dynamic relocs copied for this symbol. */ ++ struct elf_dyn_relocs *dyn_relocs; ++ ++ /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */ ++ unsigned int type : 8; ++ ++ /* Symbol st_other value, symbol visibility. */ ++ unsigned int other : 8; ++ ++ /* The symbol's st_target_internal value (see Elf_Internal_Sym). */ ++ unsigned int target_internal : 8; ++ ++ /* Symbol is referenced by a non-shared object (other than the object ++ in which it is defined). */ ++ unsigned int ref_regular : 1; ++ /* Symbol is defined by a non-shared object. */ ++ unsigned int def_regular : 1; ++ /* Symbol is referenced by a shared object. */ ++ unsigned int ref_dynamic : 1; ++ /* Symbol is defined by a shared object. */ ++ unsigned int def_dynamic : 1; ++ /* Symbol has a non-weak reference from a non-shared object (other than ++ the object in which it is defined). */ ++ unsigned int ref_regular_nonweak : 1; ++ /* Dynamic symbol has been adjustd. */ ++ unsigned int dynamic_adjusted : 1; ++ /* Symbol needs a copy reloc. */ ++ unsigned int needs_copy : 1; ++ /* Symbol needs a procedure linkage table entry. */ ++ unsigned int needs_plt : 1; ++ /* Symbol appears in a non-ELF input file. */ ++ unsigned int non_elf : 1; ++ /* Symbol version information. */ ++ ENUM_BITFIELD (elf_symbol_version) versioned : 2; ++ /* Symbol was forced to local scope due to a version script file. */ ++ unsigned int forced_local : 1; ++ /* Symbol was forced to be dynamic due to a version script file. */ ++ unsigned int dynamic : 1; ++ /* Symbol was marked during garbage collection. */ ++ unsigned int mark : 1; ++ /* Symbol is referenced by a non-GOT/non-PLT relocation. This is ++ not currently set by all the backends. */ ++ unsigned int non_got_ref : 1; ++ /* Symbol has a definition in a shared object. ++ FIXME: There is no real need for this field if def_dynamic is never ++ cleared and all places that test def_dynamic also test def_regular. */ ++ unsigned int dynamic_def : 1; ++ /* Symbol has a non-weak reference from a shared object. */ ++ unsigned int ref_dynamic_nonweak : 1; ++ /* Symbol is referenced with a relocation where C/C++ pointer equality ++ matters. */ ++ unsigned int pointer_equality_needed : 1; ++ /* Symbol is a unique global symbol. */ ++ unsigned int unique_global : 1; ++ /* Symbol is defined by a shared library with non-default visibility ++ in a read/write section. */ ++ unsigned int protected_def : 1; ++ /* Symbol is __start_SECNAME or __stop_SECNAME to mark section ++ SECNAME. */ ++ unsigned int start_stop : 1; ++ /* Symbol is or was a weak defined symbol from a dynamic object with ++ a strong defined symbol alias. U.ALIAS points to a list of aliases, ++ the definition having is_weakalias clear. */ ++ unsigned int is_weakalias : 1; ++ ++ /* String table index in .dynstr if this is a dynamic symbol. */ ++ unsigned long dynstr_index; ++ ++ union ++ { ++ /* Points to a circular list of non-function symbol aliases. */ ++ struct elf_link_hash_entry *alias; ++ ++ /* Hash value of the name computed using the ELF hash function. ++ Used part way through size_dynamic_sections, after we've finished ++ with aliases. */ ++ unsigned long elf_hash_value; ++ } u; ++ ++ /* Version information. */ ++ union ++ { ++ /* This field is used for a symbol which is not defined in a ++ regular object. It points to the version information read in ++ from the dynamic object. */ ++ Elf_Internal_Verdef *verdef; ++ /* This field is used for a symbol which is defined in a regular ++ object. It is set up in size_dynamic_sections. It points to ++ the version information we should write out for this symbol. */ ++ struct bfd_elf_version_tree *vertree; ++ } verinfo; ++ ++ union ++ { ++ /* For __start_SECNAME and __stop_SECNAME symbols, record the first ++ input section whose section name is SECNAME. */ ++ asection *start_stop_section; ++ ++ /* Vtable information. */ ++ struct elf_link_virtual_table_entry *vtable; ++ } u2; ++}; ++ ++/* Return the strong definition for a weak symbol with aliases. */ ++ ++static inline struct elf_link_hash_entry * ++weakdef (struct elf_link_hash_entry *h) ++{ ++ while (h->is_weakalias) ++ h = h->u.alias; ++ return h; ++} ++ ++/* Will references to this symbol always reference the symbol ++ in this object? */ ++#define SYMBOL_REFERENCES_LOCAL(INFO, H) \ ++ _bfd_elf_symbol_refs_local_p (H, INFO, 0) ++ ++/* Will _calls_ to this symbol always call the version in this object? */ ++#define SYMBOL_CALLS_LOCAL(INFO, H) \ ++ _bfd_elf_symbol_refs_local_p (H, INFO, 1) ++ ++/* Whether an undefined weak symbol should resolve to its link-time ++ value, even in PIC or PIE objects. */ ++#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \ ++ ((H)->root.type == bfd_link_hash_undefweak \ ++ && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \ ++ || (INFO)->dynamic_undefined_weak == 0)) ++ ++/* Common symbols that are turned into definitions don't have the ++ DEF_REGULAR flag set, so they might appear to be undefined. ++ Symbols defined in linker scripts also don't have DEF_REGULAR set. */ ++#define ELF_COMMON_DEF_P(H) \ ++ (!(H)->def_regular \ ++ && !(H)->def_dynamic \ ++ && (H)->root.type == bfd_link_hash_defined) ++ ++/* Records local symbols to be emitted in the dynamic symbol table. */ ++ ++struct elf_link_local_dynamic_entry ++{ ++ struct elf_link_local_dynamic_entry *next; ++ ++ /* The input bfd this symbol came from. */ ++ bfd *input_bfd; ++ ++ /* The index of the local symbol being copied. */ ++ long input_indx; ++ ++ /* The index in the outgoing dynamic symbol table. */ ++ long dynindx; ++ ++ /* A copy of the input symbol. */ ++ Elf_Internal_Sym isym; ++}; ++ ++struct elf_link_loaded_list ++{ ++ struct elf_link_loaded_list *next; ++ bfd *abfd; ++}; ++ ++/* Structures used by the eh_frame optimization code. */ ++struct eh_cie_fde ++{ ++ union { ++ struct { ++ /* If REMOVED == 1, this is the CIE that the FDE originally used. ++ The CIE belongs to the same .eh_frame input section as the FDE. ++ ++ If REMOVED == 0, this is the CIE that we have chosen to use for ++ the output FDE. The CIE's REMOVED field is also 0, but the CIE ++ might belong to a different .eh_frame input section from the FDE. ++ ++ May be NULL to signify that the FDE should be discarded. */ ++ struct eh_cie_fde *cie_inf; ++ struct eh_cie_fde *next_for_section; ++ } fde; ++ struct { ++ /* CIEs have three states: ++ ++ - REMOVED && !MERGED: Slated for removal because we haven't yet ++ proven that an FDE needs it. FULL_CIE, if nonnull, points to ++ more detailed information about the CIE. ++ ++ - REMOVED && MERGED: We have merged this CIE with MERGED_WITH, ++ which may not belong to the same input section. ++ ++ - !REMOVED: We have decided to keep this CIE. SEC is the ++ .eh_frame input section that contains the CIE. */ ++ union { ++ struct cie *full_cie; ++ struct eh_cie_fde *merged_with; ++ asection *sec; ++ } u; ++ ++ /* The offset of the personality data from the start of the CIE, ++ or 0 if the CIE doesn't have any. */ ++ unsigned int personality_offset : 8; ++ ++ /* Length of augmentation. aug_str_len is the length of the ++ string including null terminator. aug_data_len is the length ++ of the rest up to the initial insns. */ ++ unsigned int aug_str_len : 3; ++ unsigned int aug_data_len : 5; ++ ++ /* True if we have marked relocations associated with this CIE. */ ++ unsigned int gc_mark : 1; ++ ++ /* True if we have decided to turn an absolute LSDA encoding into ++ a PC-relative one. */ ++ unsigned int make_lsda_relative : 1; ++ ++ /* True if we have decided to turn an absolute personality ++ encoding into a PC-relative one. */ ++ unsigned int make_per_encoding_relative : 1; ++ ++ /* True if the CIE contains personality data and if that ++ data uses a PC-relative encoding. Always true when ++ make_per_encoding_relative is. */ ++ unsigned int per_encoding_relative : 1; ++ ++ /* True if the CIE contains personality data aligned to a ++ multiple of eight bytes. */ ++ unsigned int per_encoding_aligned8 : 1; ++ ++ /* True if we need to add an 'R' (FDE encoding) entry to the ++ CIE's augmentation data. */ ++ unsigned int add_fde_encoding : 1; ++ ++ /* True if we have merged this CIE with another. */ ++ unsigned int merged : 1; ++ ++ /* Unused bits. */ ++ unsigned int pad1 : 9; ++ } cie; ++ } u; ++ unsigned int reloc_index; ++ unsigned int size; ++ unsigned int offset; ++ unsigned int new_offset; ++ unsigned int fde_encoding : 8; ++ unsigned int lsda_encoding : 8; ++ unsigned int lsda_offset : 8; ++ ++ /* True if this entry represents a CIE, false if it represents an FDE. */ ++ unsigned int cie : 1; ++ ++ /* True if this entry is currently marked for removal. */ ++ unsigned int removed : 1; ++ ++ /* True if we need to add a 'z' (augmentation size) entry to the CIE's ++ augmentation data, and an associated byte to each of the CIE's FDEs. */ ++ unsigned int add_augmentation_size : 1; ++ ++ /* True if we have decided to convert absolute FDE relocations into ++ relative ones. This applies to the first relocation in the FDE, ++ which is against the code that the FDE describes. */ ++ unsigned int make_relative : 1; ++ ++ /* Unused bits. */ ++ unsigned int pad1 : 4; ++ ++ unsigned int *set_loc; ++}; ++ ++struct eh_frame_sec_info ++{ ++ unsigned int count; ++ struct cie *cies; ++ struct eh_cie_fde entry[1]; ++}; ++ ++struct eh_frame_array_ent ++{ ++ bfd_vma initial_loc; ++ bfd_size_type range; ++ bfd_vma fde; ++}; ++ ++struct htab; ++ ++#define DWARF2_EH_HDR 1 ++#define COMPACT_EH_HDR 2 ++ ++/* Endian-neutral code indicating that a function cannot be unwound. */ ++#define COMPACT_EH_CANT_UNWIND_OPCODE 0x015d5d01 ++ ++struct dwarf_eh_frame_hdr_info ++{ ++ struct htab *cies; ++ unsigned int fde_count; ++ /* TRUE if .eh_frame_hdr should contain the sorted search table. ++ We build it if we successfully read all .eh_frame input sections ++ and recognize them. */ ++ bfd_boolean table; ++ struct eh_frame_array_ent *array; ++}; ++ ++struct compact_eh_frame_hdr_info ++{ ++ unsigned int allocated_entries; ++ /* eh_frame_entry fragments. */ ++ asection **entries; ++}; ++ ++struct eh_frame_hdr_info ++{ ++ asection *hdr_sec; ++ unsigned int array_count; ++ bfd_boolean frame_hdr_is_compact; ++ union ++ { ++ struct dwarf_eh_frame_hdr_info dwarf; ++ struct compact_eh_frame_hdr_info compact; ++ } ++ u; ++}; ++ ++/* Enum used to identify target specific extensions to the elf_obj_tdata ++ and elf_link_hash_table structures. Note the enums deliberately start ++ from 1 so that we can detect an uninitialized field. The generic value ++ is last so that additions to this enum do not need to modify more than ++ one line. */ ++enum elf_target_id ++{ ++ AARCH64_ELF_DATA = 1, ++ ALPHA_ELF_DATA, ++ ARC_ELF_DATA, ++ ARM_ELF_DATA, ++ AVR_ELF_DATA, ++ BFIN_ELF_DATA, ++ CRIS_ELF_DATA, ++ CSKY_ELF_DATA, ++ FRV_ELF_DATA, ++ HPPA32_ELF_DATA, ++ HPPA64_ELF_DATA, ++ I386_ELF_DATA, ++ IA64_ELF_DATA, ++ LM32_ELF_DATA, ++ M32R_ELF_DATA, ++ M68HC11_ELF_DATA, ++ M68K_ELF_DATA, ++ METAG_ELF_DATA, ++ MICROBLAZE_ELF_DATA, ++ MIPS_ELF_DATA, ++ MN10300_ELF_DATA, ++ NDS32_ELF_DATA, ++ NIOS2_ELF_DATA, ++ OR1K_ELF_DATA, ++ PPC32_ELF_DATA, ++ PPC64_ELF_DATA, ++ PRU_ELF_DATA, ++ S390_ELF_DATA, ++ SH_ELF_DATA, ++ SPARC_ELF_DATA, ++ SPU_ELF_DATA, ++ TIC6X_ELF_DATA, ++ X86_64_ELF_DATA, ++ XTENSA_ELF_DATA, ++ TILEGX_ELF_DATA, ++ TILEPRO_ELF_DATA, ++ RISCV_ELF_DATA, ++ GENERIC_ELF_DATA ++}; ++ ++struct elf_sym_strtab ++{ ++ Elf_Internal_Sym sym; ++ unsigned long dest_index; ++ unsigned long destshndx_index; ++}; ++ ++struct bfd_link_needed_list ++{ ++ struct bfd_link_needed_list *next; ++ bfd *by; ++ const char *name; ++}; ++ ++enum elf_target_os ++{ ++ is_normal, ++ is_symbian, /* Symbian OS. */ ++ is_solaris, /* Solaris. */ ++ is_vxworks, /* VxWorks. */ ++ is_nacl /* Native Client. */ ++}; ++ ++/* Used by bfd_sym_from_r_symndx to cache a small number of local ++ symbols. */ ++#define LOCAL_SYM_CACHE_SIZE 32 ++struct sym_cache ++{ ++ bfd *abfd; ++ unsigned long indx[LOCAL_SYM_CACHE_SIZE]; ++ Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE]; ++}; ++ ++/* ELF linker hash table. */ ++ ++struct elf_link_hash_table ++{ ++ struct bfd_link_hash_table root; ++ ++ /* An identifier used to distinguish different target ++ specific extensions to this structure. */ ++ enum elf_target_id hash_table_id; ++ ++ /* Whether we have created the special dynamic sections required ++ when linking against or generating a shared object. */ ++ bfd_boolean dynamic_sections_created; ++ ++ /* Whether dynamic relocations are present. */ ++ bfd_boolean dynamic_relocs; ++ ++ /* True if this target has relocatable executables, so needs dynamic ++ section symbols. */ ++ bfd_boolean is_relocatable_executable; ++ ++ /* TRUE if there are IFUNC resolvers. */ ++ bfd_boolean ifunc_resolvers; ++ ++ /* TRUE if DT_PLTGOT is a required dynamic tag. */ ++ bfd_boolean dt_pltgot_required; ++ ++ /* TRUE if DT_JMPREL is a required dynamic tag. */ ++ bfd_boolean dt_jmprel_required; ++ ++ /* The BFD used to hold special sections created by the linker. ++ This will be the first BFD found which requires these sections to ++ be created. */ ++ bfd *dynobj; ++ ++ /* The value to use when initialising got.refcount/offset and ++ plt.refcount/offset in an elf_link_hash_entry. Set to zero when ++ the values are refcounts. Set to init_got_offset/init_plt_offset ++ in size_dynamic_sections when the values may be offsets. */ ++ union gotplt_union init_got_refcount; ++ union gotplt_union init_plt_refcount; ++ ++ /* The value to use for got.refcount/offset and plt.refcount/offset ++ when the values may be offsets. Normally (bfd_vma) -1. */ ++ union gotplt_union init_got_offset; ++ union gotplt_union init_plt_offset; ++ ++ /* The number of symbols found in the link which is intended for the ++ mandatory DT_SYMTAB tag (.dynsym section) in .dynamic section. */ ++ bfd_size_type dynsymcount; ++ bfd_size_type local_dynsymcount; ++ ++ /* The string table of dynamic symbols, which becomes the .dynstr ++ section. */ ++ struct elf_strtab_hash *dynstr; ++ ++ /* The number of symbol strings found in the link which must be put ++ into the .strtab section. */ ++ bfd_size_type strtabcount; ++ ++ /* The array size of the symbol string table, which becomes the ++ .strtab section. */ ++ bfd_size_type strtabsize; ++ ++ /* The array of strings, which becomes the .strtab section. */ ++ struct elf_sym_strtab *strtab; ++ ++ /* The number of buckets in the hash table in the .hash section. ++ This is based on the number of dynamic symbols. */ ++ bfd_size_type bucketcount; ++ ++ /* A linked list of DT_NEEDED names found in dynamic objects ++ included in the link. */ ++ struct bfd_link_needed_list *needed; ++ ++ /* Sections in the output bfd that provides a section symbol ++ to be used by relocations emitted against local symbols. ++ Most targets will not use data_index_section. */ ++ asection *text_index_section; ++ asection *data_index_section; ++ ++ /* The _GLOBAL_OFFSET_TABLE_ symbol. */ ++ struct elf_link_hash_entry *hgot; ++ ++ /* The _PROCEDURE_LINKAGE_TABLE_ symbol. */ ++ struct elf_link_hash_entry *hplt; ++ ++ /* The _DYNAMIC symbol. */ ++ struct elf_link_hash_entry *hdynamic; ++ ++ /* A pointer to information used to merge SEC_MERGE sections. */ ++ void *merge_info; ++ ++ /* Used to link stabs in sections. */ ++ struct stab_info stab_info; ++ ++ /* Used by eh_frame code when editing .eh_frame. */ ++ struct eh_frame_hdr_info eh_info; ++ ++ /* A linked list of local symbols to be added to .dynsym. */ ++ struct elf_link_local_dynamic_entry *dynlocal; ++ ++ /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic ++ objects included in the link. */ ++ struct bfd_link_needed_list *runpath; ++ ++ /* Cached first output tls section and size of PT_TLS segment. */ ++ asection *tls_sec; ++ bfd_size_type tls_size; /* Bytes. */ ++ ++ /* The offset into splt of the PLT entry for the TLS descriptor ++ resolver. Special values are 0, if not necessary (or not found ++ to be necessary yet), and -1 if needed but not determined ++ yet. */ ++ bfd_vma tlsdesc_plt; ++ ++ /* The GOT offset for the lazy trampoline. Communicated to the ++ loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1 ++ indicates an offset is not allocated. */ ++ bfd_vma tlsdesc_got; ++ ++ /* Target OS for linker output. */ ++ enum elf_target_os target_os; ++ ++ /* A linked list of dynamic BFD's loaded in the link. */ ++ struct elf_link_loaded_list *dyn_loaded; ++ ++ /* Small local sym cache. */ ++ struct sym_cache sym_cache; ++ ++ /* Short-cuts to get to dynamic linker sections. */ ++ asection *sgot; ++ asection *sgotplt; ++ asection *srelgot; ++ asection *splt; ++ asection *srelplt; ++ asection *sdynbss; ++ asection *srelbss; ++ asection *sdynrelro; ++ asection *sreldynrelro; ++ asection *igotplt; ++ asection *iplt; ++ asection *irelplt; ++ asection *irelifunc; ++ asection *dynsym; ++}; ++ ++/* Look up an entry in an ELF linker hash table. */ ++ ++#define elf_link_hash_lookup(table, string, create, copy, follow) \ ++ ((struct elf_link_hash_entry *) \ ++ bfd_link_hash_lookup (&(table)->root, (string), (create), \ ++ (copy), (follow))) ++ ++/* Traverse an ELF linker hash table. */ ++ ++#define elf_link_hash_traverse(table, func, info) \ ++ (bfd_link_hash_traverse \ ++ (&(table)->root, \ ++ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ ++ (info))) ++ ++/* Get the ELF linker hash table from a link_info structure. */ ++ ++#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash)) ++ ++#define elf_hash_table_id(table) ((table) -> hash_table_id) ++ ++/* Returns TRUE if the hash table is a struct elf_link_hash_table. */ ++#define is_elf_hash_table(htab) \ ++ (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table) ++ ++/* Constant information held for an ELF backend. */ ++ ++struct elf_size_info { ++ unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr; ++ unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note; ++ ++ /* The size of entries in the .hash section. */ ++ unsigned char sizeof_hash_entry; ++ ++ /* The number of internal relocations to allocate per external ++ relocation entry. */ ++ unsigned char int_rels_per_ext_rel; ++ /* We use some fixed size arrays. This should be large enough to ++ handle all back-ends. */ ++#define MAX_INT_RELS_PER_EXT_REL 3 ++ ++ unsigned char arch_size, log_file_align; ++ unsigned char elfclass, ev_current; ++ int (*write_out_phdrs) ++ (bfd *, const Elf_Internal_Phdr *, unsigned int); ++ bfd_boolean ++ (*write_shdrs_and_ehdr) (bfd *); ++ bfd_boolean (*checksum_contents) ++ (bfd * , void (*) (const void *, size_t, void *), void *); ++ void (*write_relocs) ++ (bfd *, asection *, void *); ++ bfd_boolean (*swap_symbol_in) ++ (bfd *, const void *, const void *, Elf_Internal_Sym *); ++ void (*swap_symbol_out) ++ (bfd *, const Elf_Internal_Sym *, void *, void *); ++ bfd_boolean (*slurp_reloc_table) ++ (bfd *, asection *, asymbol **, bfd_boolean); ++ long (*slurp_symbol_table) ++ (bfd *, asymbol **, bfd_boolean); ++ void (*swap_dyn_in) ++ (bfd *, const void *, Elf_Internal_Dyn *); ++ void (*swap_dyn_out) ++ (bfd *, const Elf_Internal_Dyn *, void *); ++ ++ /* This function is called to swap in a REL relocation. If an ++ external relocation corresponds to more than one internal ++ relocation, then all relocations are swapped in at once. */ ++ void (*swap_reloc_in) ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++ ++ /* This function is called to swap out a REL relocation. */ ++ void (*swap_reloc_out) ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++ ++ /* This function is called to swap in a RELA relocation. If an ++ external relocation corresponds to more than one internal ++ relocation, then all relocations are swapped in at once. */ ++ void (*swap_reloca_in) ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++ ++ /* This function is called to swap out a RELA relocation. */ ++ void (*swap_reloca_out) ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++}; ++ ++#define elf_symbol_from(ABFD,S) \ ++ (((S)->the_bfd != NULL \ ++ && (S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \ ++ && (S)->the_bfd->tdata.elf_obj_data != 0) \ ++ ? (elf_symbol_type *) (S) \ ++ : 0) ++ ++enum elf_reloc_type_class { ++ reloc_class_normal, ++ reloc_class_relative, ++ reloc_class_copy, ++ reloc_class_ifunc, ++ reloc_class_plt ++}; ++ ++struct elf_reloc_cookie ++{ ++ Elf_Internal_Rela *rels, *rel, *relend; ++ Elf_Internal_Sym *locsyms; ++ bfd *abfd; ++ size_t locsymcount; ++ size_t extsymoff; ++ struct elf_link_hash_entry **sym_hashes; ++ int r_sym_shift; ++ bfd_boolean bad_symtab; ++}; ++ ++/* The level of IRIX compatibility we're striving for. */ ++ ++typedef enum { ++ ict_none, ++ ict_irix5, ++ ict_irix6 ++} irix_compat_t; ++ ++/* Mapping of ELF section names and types. */ ++struct bfd_elf_special_section ++{ ++ const char *prefix; ++ unsigned int prefix_length; ++ /* 0 means name must match PREFIX exactly. ++ -1 means name must start with PREFIX followed by an arbitrary string. ++ -2 means name must match PREFIX exactly or consist of PREFIX followed ++ by a dot then anything. ++ > 0 means name must start with the first PREFIX_LENGTH chars of ++ PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */ ++ signed int suffix_length; ++ unsigned int type; ++ bfd_vma attr; ++}; ++ ++enum action_discarded ++ { ++ COMPLAIN = 1, ++ PRETEND = 2 ++ }; ++ ++typedef asection * (*elf_gc_mark_hook_fn) ++ (asection *, struct bfd_link_info *, Elf_Internal_Rela *, ++ struct elf_link_hash_entry *, Elf_Internal_Sym *); ++ ++enum elf_property_kind ++ { ++ /* A new property. */ ++ property_unknown = 0, ++ /* A property ignored by backend. */ ++ property_ignored, ++ /* A corrupt property reported by backend. */ ++ property_corrupt, ++ /* A property should be removed due to property merge. */ ++ property_remove, ++ /* A property which is a number. */ ++ property_number ++ }; ++ ++typedef struct elf_property ++{ ++ unsigned int pr_type; ++ unsigned int pr_datasz; ++ union ++ { ++ /* For property_number, this is a number. */ ++ bfd_vma number; ++ /* Add a new one if elf_property_kind is updated. */ ++ } u; ++ enum elf_property_kind pr_kind; ++} elf_property; ++ ++typedef struct elf_property_list ++{ ++ struct elf_property_list *next; ++ struct elf_property property; ++} elf_property_list; ++ ++struct bfd_elf_section_reloc_data; ++ ++struct elf_backend_data ++{ ++ /* The architecture for this backend. */ ++ enum bfd_architecture arch; ++ ++ /* An identifier used to distinguish different target specific ++ extensions to elf_obj_tdata and elf_link_hash_table structures. */ ++ enum elf_target_id target_id; ++ ++ /* Target OS. */ ++ enum elf_target_os target_os; ++ ++ /* The ELF machine code (EM_xxxx) for this backend. */ ++ int elf_machine_code; ++ ++ /* EI_OSABI. */ ++ int elf_osabi; ++ ++ /* The maximum page size for this backend. */ ++ bfd_vma maxpagesize; ++ ++ /* The minimum page size for this backend. An input object will not be ++ considered page aligned unless its sections are correctly aligned for ++ pages at least this large. May be smaller than maxpagesize. */ ++ bfd_vma minpagesize; ++ ++ /* The common page size for this backend. */ ++ bfd_vma commonpagesize; ++ ++ /* The value of commonpagesize to use when -z relro for this backend. */ ++ bfd_vma relropagesize; ++ ++ /* The BFD flags applied to sections created for dynamic linking. */ ++ flagword dynamic_sec_flags; ++ ++ /* Architecture-specific data for this backend. ++ This is actually a pointer to some type like struct elf_ARCH_data. */ ++ const void *arch_data; ++ ++ /* A function to translate an ELF RELA relocation to a BFD arelent ++ structure. Returns TRUE upon success, FALSE otherwise. */ ++ bfd_boolean (*elf_info_to_howto) ++ (bfd *, arelent *, Elf_Internal_Rela *); ++ ++ /* A function to translate an ELF REL relocation to a BFD arelent ++ structure. Returns TRUE upon success, FALSE otherwise. */ ++ bfd_boolean (*elf_info_to_howto_rel) ++ (bfd *, arelent *, Elf_Internal_Rela *); ++ ++ /* A function to determine whether a symbol is global when ++ partitioning the symbol table into local and global symbols. ++ This should be NULL for most targets, in which case the correct ++ thing will be done. MIPS ELF, at least on the Irix 5, has ++ special requirements. */ ++ bfd_boolean (*elf_backend_sym_is_global) ++ (bfd *, asymbol *); ++ ++ /* The remaining functions are hooks which are called only if they ++ are not NULL. */ ++ ++ /* A function to permit a backend specific check on whether a ++ particular BFD format is relevant for an object file, and to ++ permit the backend to set any global information it wishes. When ++ this is called elf_elfheader is set, but anything else should be ++ used with caution. If this returns FALSE, the check_format ++ routine will return a bfd_error_wrong_format error. */ ++ bfd_boolean (*elf_backend_object_p) ++ (bfd *); ++ ++ /* A function to do additional symbol processing when reading the ++ ELF symbol table. This is where any processor-specific special ++ section indices are handled. */ ++ void (*elf_backend_symbol_processing) ++ (bfd *, asymbol *); ++ ++ /* A function to do additional symbol processing after reading the ++ entire ELF symbol table. */ ++ bfd_boolean (*elf_backend_symbol_table_processing) ++ (bfd *, elf_symbol_type *, unsigned int); ++ ++ /* A function to set the type of the info field. Processor-specific ++ types should be handled here. */ ++ int (*elf_backend_get_symbol_type) ++ (Elf_Internal_Sym *, int); ++ ++ /* A function to return the linker hash table entry of a symbol that ++ might be satisfied by an archive symbol. */ ++ struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup) ++ (bfd *, struct bfd_link_info *, const char *); ++ ++ /* Return true if local section symbols should have a non-null st_name. ++ NULL implies false. */ ++ bfd_boolean (*elf_backend_name_local_section_symbols) ++ (bfd *); ++ ++ /* A function to do additional processing on the ELF section header ++ just before writing it out. This is used to set the flags and ++ type fields for some sections, or to actually write out data for ++ unusual sections. */ ++ bfd_boolean (*elf_backend_section_processing) ++ (bfd *, Elf_Internal_Shdr *); ++ ++ /* A function to handle unusual section types when creating BFD ++ sections from ELF sections. */ ++ bfd_boolean (*elf_backend_section_from_shdr) ++ (bfd *, Elf_Internal_Shdr *, const char *, int); ++ ++ /* A function to convert machine dependent ELF section header flags to ++ BFD internal section header flags. */ ++ bfd_boolean (*elf_backend_section_flags) ++ (const Elf_Internal_Shdr *); ++ ++ /* A function that returns a struct containing ELF section flags and ++ type for the given BFD section. */ ++ const struct bfd_elf_special_section * (*get_sec_type_attr) ++ (bfd *, asection *); ++ ++ /* A function to handle unusual program segment types when creating BFD ++ sections from ELF program segments. */ ++ bfd_boolean (*elf_backend_section_from_phdr) ++ (bfd *, Elf_Internal_Phdr *, int, const char *); ++ ++ /* A function to set up the ELF section header for a BFD section in ++ preparation for writing it out. This is where the flags and type ++ fields are set for unusual sections. */ ++ bfd_boolean (*elf_backend_fake_sections) ++ (bfd *, Elf_Internal_Shdr *, asection *); ++ ++ /* A function to get the ELF section index for a BFD section. If ++ this returns TRUE, the section was found. If it is a normal ELF ++ section, *RETVAL should be left unchanged. If it is not a normal ++ ELF section *RETVAL should be set to the SHN_xxxx index. */ ++ bfd_boolean (*elf_backend_section_from_bfd_section) ++ (bfd *, asection *, int *retval); ++ ++ /* If this field is not NULL, it is called by the add_symbols phase ++ of a link just before adding a symbol to the global linker hash ++ table. It may modify any of the fields as it wishes. If *NAME ++ is set to NULL, the symbol will be skipped rather than being ++ added to the hash table. This function is responsible for ++ handling all processor dependent symbol bindings and section ++ indices, and must set at least *FLAGS and *SEC for each processor ++ dependent case; failure to do so will cause a link error. */ ++ bfd_boolean (*elf_add_symbol_hook) ++ (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *, ++ const char **name, flagword *flags, asection **sec, bfd_vma *value); ++ ++ /* If this field is not NULL, it is called by the elf_link_output_sym ++ phase of a link for each symbol which will appear in the object file. ++ On error, this function returns 0. 1 is returned when the symbol ++ should be output, 2 is returned when the symbol should be discarded. */ ++ int (*elf_backend_link_output_symbol_hook) ++ (struct bfd_link_info *info, const char *, Elf_Internal_Sym *, ++ asection *, struct elf_link_hash_entry *); ++ ++ /* The CREATE_DYNAMIC_SECTIONS function is called by the ELF backend ++ linker the first time it encounters a dynamic object in the link. ++ This function must create any sections required for dynamic ++ linking. The ABFD argument is a dynamic object. The .interp, ++ .dynamic, .dynsym, .dynstr, and .hash functions have already been ++ created, and this function may modify the section flags if ++ desired. This function will normally create the .got and .plt ++ sections, but different backends have different requirements. */ ++ bfd_boolean (*elf_backend_create_dynamic_sections) ++ (bfd *abfd, struct bfd_link_info *info); ++ ++ /* When creating a shared library, determine whether to omit the ++ dynamic symbol for the section. */ ++ bfd_boolean (*elf_backend_omit_section_dynsym) ++ (bfd *output_bfd, struct bfd_link_info *info, asection *osec); ++ ++ /* Return TRUE if relocations of targets are compatible to the extent ++ that CHECK_RELOCS will properly process them. PR 4424. */ ++ bfd_boolean (*relocs_compatible) (const bfd_target *, const bfd_target *); ++ ++ /* The CHECK_RELOCS function is called by the add_symbols phase of ++ the ELF backend linker. It is called once for each section with ++ relocs of an object file, just after the symbols for the object ++ file have been added to the global linker hash table. The ++ function must look through the relocs and do any special handling ++ required. This generally means allocating space in the global ++ offset table, and perhaps allocating space for a reloc. The ++ relocs are always passed as Rela structures; if the section ++ actually uses Rel structures, the r_addend field will always be ++ zero. */ ++ bfd_boolean (*check_relocs) ++ (bfd *abfd, struct bfd_link_info *info, asection *o, ++ const Elf_Internal_Rela *relocs); ++ ++ /* The CHECK_DIRECTIVES function is called once per input file by ++ the add_symbols phase of the ELF backend linker. The function ++ must inspect the bfd and create any additional symbols according ++ to any custom directives in the bfd. */ ++ bfd_boolean (*check_directives) ++ (bfd *abfd, struct bfd_link_info *info); ++ ++ /* The NOTICE_AS_NEEDED function is called as the linker is about to ++ handle an as-needed lib (ACT = notice_as_needed), and after the ++ linker has decided to keep the lib (ACT = notice_needed) or when ++ the lib is not needed (ACT = notice_not_needed). */ ++ bfd_boolean (*notice_as_needed) ++ (bfd *abfd, struct bfd_link_info *info, enum notice_asneeded_action act); ++ ++ /* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend ++ linker for every symbol which is defined by a dynamic object and ++ referenced by a regular object. This is called after all the ++ input files have been seen, but before the SIZE_DYNAMIC_SECTIONS ++ function has been called. The hash table entry should be ++ bfd_link_hash_defined ore bfd_link_hash_defweak, and it should be ++ defined in a section from a dynamic object. Dynamic object ++ sections are not included in the final link, and this function is ++ responsible for changing the value to something which the rest of ++ the link can deal with. This will normally involve adding an ++ entry to the .plt or .got or some such section, and setting the ++ symbol to point to that. */ ++ bfd_boolean (*elf_backend_adjust_dynamic_symbol) ++ (struct bfd_link_info *info, struct elf_link_hash_entry *h); ++ ++ /* The ALWAYS_SIZE_SECTIONS function is called by the backend linker ++ after all the linker input files have been seen but before the ++ section sizes have been set. This is called after ++ ADJUST_DYNAMIC_SYMBOL, but before SIZE_DYNAMIC_SECTIONS. */ ++ bfd_boolean (*elf_backend_always_size_sections) ++ (bfd *output_bfd, struct bfd_link_info *info); ++ ++ /* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend ++ linker after all the linker input files have been seen but before ++ the sections sizes have been set. This is called after ++ ADJUST_DYNAMIC_SYMBOL has been called on all appropriate symbols. ++ It is only called when linking against a dynamic object. It must ++ set the sizes of the dynamic sections, and may fill in their ++ contents as well. The generic ELF linker can handle the .dynsym, ++ .dynstr and .hash sections. This function must handle the ++ .interp section and any sections created by the ++ CREATE_DYNAMIC_SECTIONS entry point. */ ++ bfd_boolean (*elf_backend_size_dynamic_sections) ++ (bfd *output_bfd, struct bfd_link_info *info); ++ ++ /* The STRIP_ZERO_SIZED_DYNAMIC_SECTIONS function is called by the ++ ELF backend linker to strip zero-sized dynamic sections after ++ the section sizes have been set. */ ++ bfd_boolean (*elf_backend_strip_zero_sized_dynamic_sections) ++ (struct bfd_link_info *info); ++ ++ /* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections ++ we keep to use as a base for relocs and symbols. */ ++ void (*elf_backend_init_index_section) ++ (bfd *output_bfd, struct bfd_link_info *info); ++ ++ /* The RELOCATE_SECTION function is called by the ELF backend linker ++ to handle the relocations for a section. ++ ++ The relocs are always passed as Rela structures; if the section ++ actually uses Rel structures, the r_addend field will always be ++ zero. ++ ++ This function is responsible for adjust the section contents as ++ necessary, and (if using Rela relocs and generating a ++ relocatable output file) adjusting the reloc addend as ++ necessary. ++ ++ This function does not have to worry about setting the reloc ++ address or the reloc symbol index. ++ ++ LOCAL_SYMS is a pointer to the swapped in local symbols. ++ ++ LOCAL_SECTIONS is an array giving the section in the input file ++ corresponding to the st_shndx field of each local symbol. ++ ++ The global hash table entry for the global symbols can be found ++ via elf_sym_hashes (input_bfd). ++ ++ When generating relocatable output, this function must handle ++ STB_LOCAL/STT_SECTION symbols specially. The output symbol is ++ going to be the section symbol corresponding to the output ++ section, which means that the addend must be adjusted ++ accordingly. ++ ++ Returns FALSE on error, TRUE on success, 2 if successful and ++ relocations should be written for this section. */ ++ int (*elf_backend_relocate_section) ++ (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, ++ asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, ++ Elf_Internal_Sym *local_syms, asection **local_sections); ++ ++ /* The FINISH_DYNAMIC_SYMBOL function is called by the ELF backend ++ linker just before it writes a symbol out to the .dynsym section. ++ The processor backend may make any required adjustment to the ++ symbol. It may also take the opportunity to set contents of the ++ dynamic sections. Note that FINISH_DYNAMIC_SYMBOL is called on ++ all .dynsym symbols, while ADJUST_DYNAMIC_SYMBOL is only called ++ on those symbols which are defined by a dynamic object. */ ++ bfd_boolean (*elf_backend_finish_dynamic_symbol) ++ (bfd *output_bfd, struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, Elf_Internal_Sym *sym); ++ ++ /* The FINISH_DYNAMIC_SECTIONS function is called by the ELF backend ++ linker just before it writes all the dynamic sections out to the ++ output file. The FINISH_DYNAMIC_SYMBOL will have been called on ++ all dynamic symbols. */ ++ bfd_boolean (*elf_backend_finish_dynamic_sections) ++ (bfd *output_bfd, struct bfd_link_info *info); ++ ++ /* A function to do any beginning processing needed for the ELF file ++ before building the ELF headers and computing file positions. */ ++ void (*elf_backend_begin_write_processing) ++ (bfd *, struct bfd_link_info *); ++ ++ /* A function to do any final processing needed for the ELF file ++ before writing it out. */ ++ bfd_boolean (*elf_backend_final_write_processing) ++ (bfd *); ++ ++ /* This function is called by get_program_header_size. It should ++ return the number of additional program segments which this BFD ++ will need. It should return -1 on error. */ ++ int (*elf_backend_additional_program_headers) ++ (bfd *, struct bfd_link_info *); ++ ++ /* This function is called to modify an existing segment map in a ++ backend specific fashion. */ ++ bfd_boolean (*elf_backend_modify_segment_map) ++ (bfd *, struct bfd_link_info *); ++ ++ /* This function is called to modify program headers just before ++ they are written. */ ++ bfd_boolean (*elf_backend_modify_headers) ++ (bfd *, struct bfd_link_info *); ++ ++ /* This function is called to see if the PHDR header should be ++ checked for validity. */ ++ bfd_boolean (*elf_backend_allow_non_load_phdr) ++ (bfd *, const Elf_Internal_Phdr *, unsigned); ++ ++ /* This function is called before section garbage collection to ++ mark entry symbol sections. */ ++ void (*gc_keep) ++ (struct bfd_link_info *); ++ ++ /* This function is called during section garbage collection to ++ mark sections that define global symbols. */ ++ bfd_boolean (*gc_mark_dynamic_ref) ++ (struct elf_link_hash_entry *, void *); ++ ++ /* This function is called during section gc to discover the section a ++ particular relocation refers to. */ ++ elf_gc_mark_hook_fn gc_mark_hook; ++ ++ /* This function, if defined, is called after the first gc marking pass ++ to allow the backend to mark additional sections. */ ++ bfd_boolean (*gc_mark_extra_sections) ++ (struct bfd_link_info *, elf_gc_mark_hook_fn); ++ ++ /* This function is called to initialise ELF file header info. ++ Customised versions can modify things like the OS and ABI version. */ ++ bfd_boolean (*elf_backend_init_file_header) ++ (bfd *, struct bfd_link_info *); ++ ++ /* This function, if defined, prints a symbol to file and returns the ++ name of the symbol to be printed. It should return NULL to fall ++ back to default symbol printing. */ ++ const char *(*elf_backend_print_symbol_all) ++ (bfd *, void *, asymbol *); ++ ++ /* This function, if defined, is called after all local symbols and ++ global symbols converted to locals are emitted into the symtab ++ section. It allows the backend to emit special local symbols ++ not handled in the hash table. */ ++ bfd_boolean (*elf_backend_output_arch_local_syms) ++ (bfd *, struct bfd_link_info *, void *, ++ bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, ++ struct elf_link_hash_entry *)); ++ ++ /* This function, if defined, is called after all symbols are emitted ++ into the symtab section. It allows the backend to emit special ++ global symbols not handled in the hash table. */ ++ bfd_boolean (*elf_backend_output_arch_syms) ++ (bfd *, struct bfd_link_info *, void *, ++ bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, ++ struct elf_link_hash_entry *)); ++ ++ /* Filter what symbols of the output file to include in the import ++ library if one is created. */ ++ unsigned int (*elf_backend_filter_implib_symbols) ++ (bfd *, struct bfd_link_info *, asymbol **, long); ++ ++ /* Copy any information related to dynamic linking from a pre-existing ++ symbol to a newly created symbol. Also called to copy flags and ++ other back-end info to a weakdef, in which case the symbol is not ++ newly created and plt/got refcounts and dynamic indices should not ++ be copied. */ ++ void (*elf_backend_copy_indirect_symbol) ++ (struct bfd_link_info *, struct elf_link_hash_entry *, ++ struct elf_link_hash_entry *); ++ ++ /* Modify any information related to dynamic linking such that the ++ symbol is not exported. */ ++ void (*elf_backend_hide_symbol) ++ (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); ++ ++ /* A function to do additional symbol fixup, called by ++ _bfd_elf_fix_symbol_flags. */ ++ bfd_boolean (*elf_backend_fixup_symbol) ++ (struct bfd_link_info *, struct elf_link_hash_entry *); ++ ++ /* Merge the backend specific symbol attribute. */ ++ void (*elf_backend_merge_symbol_attribute) ++ (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, ++ bfd_boolean); ++ ++ /* This function, if defined, will return a string containing the ++ name of a target-specific dynamic tag. */ ++ char *(*elf_backend_get_target_dtag) ++ (bfd_vma); ++ ++ /* Decide whether an undefined symbol is special and can be ignored. ++ This is the case for OPTIONAL symbols on IRIX. */ ++ bfd_boolean (*elf_backend_ignore_undef_symbol) ++ (struct elf_link_hash_entry *); ++ ++ /* Emit relocations. Overrides default routine for emitting relocs, ++ except during a relocatable link, or if all relocs are being emitted. */ ++ bfd_boolean (*elf_backend_emit_relocs) ++ (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, ++ struct elf_link_hash_entry **); ++ ++ /* Update relocations. It is allowed to change the number and the order. ++ In such a case hashes should be invalidated. */ ++ void (*elf_backend_update_relocs) ++ (asection *, struct bfd_elf_section_reloc_data *); ++ ++ /* Count relocations. Not called for relocatable links ++ or if all relocs are being preserved in the output. */ ++ unsigned int (*elf_backend_count_relocs) ++ (struct bfd_link_info *, asection *); ++ ++ /* Count additionals relocations. Called for relocatable links if ++ additional relocations needs to be created. */ ++ unsigned int (*elf_backend_count_additional_relocs) ++ (asection *); ++ ++ /* Say whether to sort relocs output by ld -r and ld --emit-relocs, ++ by r_offset. If NULL, default to true. */ ++ bfd_boolean (*sort_relocs_p) ++ (asection *); ++ ++ /* This function, if defined, is called when an NT_PRSTATUS note is found ++ in a core file. */ ++ bfd_boolean (*elf_backend_grok_prstatus) ++ (bfd *, Elf_Internal_Note *); ++ ++ /* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO ++ note is found in a core file. */ ++ bfd_boolean (*elf_backend_grok_psinfo) ++ (bfd *, Elf_Internal_Note *); ++ ++ /* This function, if defined, is called when a "FreeBSD" NT_PRSTATUS ++ note is found in a core file. */ ++ bfd_boolean (*elf_backend_grok_freebsd_prstatus) ++ (bfd *, Elf_Internal_Note *); ++ ++ /* This function, if defined, is called to write a note to a corefile. */ ++ char *(*elf_backend_write_core_note) ++ (bfd *abfd, char *buf, int *bufsiz, int note_type, ...); ++ ++ /* This function, if defined, is called to convert target-specific ++ section flag names into hex values. */ ++ flagword (*elf_backend_lookup_section_flags_hook) ++ (char *); ++ ++ /* This function returns class of a reloc type. */ ++ enum elf_reloc_type_class (*elf_backend_reloc_type_class) ++ (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *); ++ ++ /* This function, if defined, removes information about discarded functions ++ from other sections which mention them. */ ++ bfd_boolean (*elf_backend_discard_info) ++ (bfd *, struct elf_reloc_cookie *, struct bfd_link_info *); ++ ++ /* This function, if defined, signals that the function above has removed ++ the discarded relocations for this section. */ ++ bfd_boolean (*elf_backend_ignore_discarded_relocs) ++ (asection *); ++ ++ /* What to do when ld finds relocations against symbols defined in ++ discarded sections. */ ++ unsigned int (*action_discarded) ++ (asection *); ++ ++ /* This function returns the width of FDE pointers in bytes, or 0 if ++ that can't be determined for some reason. The default definition ++ goes by the bfd's EI_CLASS. */ ++ unsigned int (*elf_backend_eh_frame_address_size) ++ (bfd *, const asection *); ++ ++ /* These functions tell elf-eh-frame whether to attempt to turn ++ absolute or lsda encodings into pc-relative ones. The default ++ definition enables these transformations. */ ++ bfd_boolean (*elf_backend_can_make_relative_eh_frame) ++ (bfd *, struct bfd_link_info *, asection *); ++ bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame) ++ (bfd *, struct bfd_link_info *, asection *); ++ ++ /* This function returns an encoding after computing the encoded ++ value (and storing it in ENCODED) for the given OFFSET into OSEC, ++ to be stored in at LOC_OFFSET into the LOC_SEC input section. ++ The default definition chooses a 32-bit PC-relative encoding. */ ++ bfd_byte (*elf_backend_encode_eh_address) ++ (bfd *abfd, struct bfd_link_info *info, ++ asection *osec, bfd_vma offset, ++ asection *loc_sec, bfd_vma loc_offset, ++ bfd_vma *encoded); ++ ++ /* This function, if defined, may write out the given section. ++ Returns TRUE if it did so and FALSE if the caller should. */ ++ bfd_boolean (*elf_backend_write_section) ++ (bfd *, struct bfd_link_info *, asection *, bfd_byte *); ++ ++ /* This function, if defined, returns TRUE if it is section symbols ++ only that are considered local for the purpose of partitioning the ++ symbol table into local and global symbols. This should be NULL ++ for most targets, in which case the correct thing will be done. ++ MIPS ELF, at least on the Irix 5, has special requirements. */ ++ bfd_boolean (*elf_backend_elfsym_local_is_section) ++ (bfd *); ++ ++ /* The level of IRIX compatibility we're striving for. ++ MIPS ELF specific function. */ ++ irix_compat_t (*elf_backend_mips_irix_compat) ++ (bfd *); ++ ++ reloc_howto_type *(*elf_backend_mips_rtype_to_howto) ++ (bfd *, unsigned int, bfd_boolean); ++ ++ /* The swapping table to use when dealing with ECOFF information. ++ Used for the MIPS ELF .mdebug section. */ ++ const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap; ++ ++ /* This function implements `bfd_elf_bfd_from_remote_memory'; ++ see elf.c, elfcode.h. */ ++ bfd *(*elf_backend_bfd_from_remote_memory) ++ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, ++ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, ++ bfd_size_type len)); ++ ++ bfd_boolean (*elf_backend_core_find_build_id) (bfd *, bfd_vma); ++ ++ /* This function is used by `_bfd_elf_get_synthetic_symtab'; ++ see elf.c. */ ++ bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *); ++ ++ /* Is symbol defined in common section? */ ++ bfd_boolean (*common_definition) (Elf_Internal_Sym *); ++ ++ /* Return a common section index for section. */ ++ unsigned int (*common_section_index) (asection *); ++ ++ /* Return a common section for section. */ ++ asection *(*common_section) (asection *); ++ ++ /* Return TRUE if we can merge 2 definitions. */ ++ bfd_boolean (*merge_symbol) (struct elf_link_hash_entry *, ++ const Elf_Internal_Sym *, asection **, ++ bfd_boolean, bfd_boolean, ++ bfd *, const asection *); ++ ++ /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ ++ bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *); ++ ++ /* If non-NULL, called to register the location of XLAT_LOC within ++ .MIPS.xhash at which real final dynindx for H will be written. ++ If XLAT_LOC is zero, the symbol is not included in ++ .MIPS.xhash and no dynindx will be written. */ ++ void (*record_xhash_symbol) ++ (struct elf_link_hash_entry *h, bfd_vma xlat_loc); ++ ++ /* Return TRUE if type is a function symbol type. */ ++ bfd_boolean (*is_function_type) (unsigned int type); ++ ++ /* If the ELF symbol SYM might be a function in SEC, return the ++ function size and set *CODE_OFF to the function's entry point, ++ otherwise return zero. */ ++ bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec, ++ bfd_vma *code_off); ++ ++ /* Given NAME, the name of a relocation section stripped of its ++ .rel/.rela prefix, return the section in ABFD to which the ++ relocations apply. */ ++ asection *(*get_reloc_section) (bfd *abfd, const char *name); ++ ++ /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which ++ has a type >= SHT_LOOS. Returns TRUE if the fields were initialised, ++ FALSE otherwise. Can be called multiple times for a given section, ++ until it returns TRUE. Most of the times it is called ISECTION will be ++ set to an input section that might be associated with the output section. ++ The last time that it is called, ISECTION will be set to NULL. */ ++ bfd_boolean (*elf_backend_copy_special_section_fields) ++ (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection, ++ Elf_Internal_Shdr *osection); ++ ++ /* Used to handle bad SHF_LINK_ORDER input. */ ++ void (*link_order_error_handler) (const char *, ...); ++ ++ /* Name of the PLT relocation section. */ ++ const char *relplt_name; ++ ++ /* Alternate EM_xxxx machine codes for this backend. */ ++ int elf_machine_alt1; ++ int elf_machine_alt2; ++ ++ const struct elf_size_info *s; ++ ++ /* An array of target specific special sections. */ ++ const struct bfd_elf_special_section *special_sections; ++ ++ /* The size in bytes of the header for the GOT. This includes the ++ so-called reserved entries on some systems. */ ++ bfd_vma got_header_size; ++ ++ /* The size of the GOT entry for the symbol pointed to by H if non-NULL, ++ otherwise by the local symbol with index SYMNDX in IBFD. */ ++ bfd_vma (*got_elt_size) (bfd *, struct bfd_link_info *, ++ struct elf_link_hash_entry *h, ++ bfd *ibfd, unsigned long symndx); ++ ++ /* The vendor name to use for a processor-standard attributes section. */ ++ const char *obj_attrs_vendor; ++ ++ /* The section name to use for a processor-standard attributes section. */ ++ const char *obj_attrs_section; ++ ++ /* Return 1, 2 or 3 to indicate what type of arguments a ++ processor-specific tag takes. */ ++ int (*obj_attrs_arg_type) (int); ++ ++ /* The section type to use for an attributes section. */ ++ unsigned int obj_attrs_section_type; ++ ++ /* This function determines the order in which any attributes are ++ written. It must be defined for input in the range ++ LEAST_KNOWN_OBJ_ATTRIBUTE..NUM_KNOWN_OBJ_ATTRIBUTES-1 (this range ++ is used in order to make unity easy). The returned value is the ++ actual tag number to place in the input position. */ ++ int (*obj_attrs_order) (int); ++ ++ /* Handle merging unknown attributes; either warn and return TRUE, ++ or give an error and return FALSE. */ ++ bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int); ++ ++ /* Parse GNU properties. Return the property kind. If the property ++ is corrupt, issue an error message and return property_corrupt. */ ++ enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int, ++ bfd_byte *, ++ unsigned int); ++ ++ /* Merge GNU properties. Return TRUE if property is updated. */ ++ bfd_boolean (*merge_gnu_properties) (struct bfd_link_info *, bfd *, bfd *, ++ elf_property *, elf_property *); ++ ++ /* Set up GNU properties. */ ++ bfd *(*setup_gnu_properties) (struct bfd_link_info *); ++ ++ /* Fix up GNU properties. */ ++ void (*fixup_gnu_properties) (struct bfd_link_info *, ++ elf_property_list **); ++ ++ /* Encoding used for compact EH tables. */ ++ int (*compact_eh_encoding) (struct bfd_link_info *); ++ ++ /* Opcode representing no unwind. */ ++ int (*cant_unwind_opcode) (struct bfd_link_info *); ++ ++ /* Called when emitting an ELF symbol whoes input version had an ++ ST_SHNDX field set to a value in the range SHN_LOPROC..SHN_HIOS. ++ Returns the value to be installed in the ST_SHNDX field of the ++ emitted symbol. If not defined, the value is left unchanged. */ ++ unsigned int (*symbol_section_index) (bfd *, elf_symbol_type *); ++ ++ /* Called when a section has extra reloc sections. */ ++ bfd_boolean (*init_secondary_reloc_section) (bfd *, Elf_Internal_Shdr *, ++ const char *, unsigned int); ++ ++ /* Called when after loading the normal relocs for a section. */ ++ bfd_boolean (*slurp_secondary_relocs) (bfd *, asection *, asymbol **); ++ ++ /* Called after writing the normal relocs for a section. */ ++ bfd_boolean (*write_secondary_relocs) (bfd *, asection *); ++ ++ /* This is non-zero if static TLS segments require a special alignment. */ ++ unsigned static_tls_alignment; ++ ++ /* Alignment for the PT_GNU_STACK segment. */ ++ unsigned stack_align; ++ ++ /* Flag bits to assign to a section of type SHT_STRTAB. */ ++ unsigned long elf_strtab_flags; ++ ++ /* This is TRUE if the linker should act like collect and gather ++ global constructors and destructors by name. This is TRUE for ++ MIPS ELF because the Irix 5 tools can not handle the .init ++ section. */ ++ unsigned collect : 1; ++ ++ /* This is TRUE if the linker should ignore changes to the type of a ++ symbol. This is TRUE for MIPS ELF because some Irix 5 objects ++ record undefined functions as STT_OBJECT although the definitions ++ are STT_FUNC. */ ++ unsigned type_change_ok : 1; ++ ++ /* Whether the backend may use REL relocations. (Some backends use ++ both REL and RELA relocations, and this flag is set for those ++ backends.) */ ++ unsigned may_use_rel_p : 1; ++ ++ /* Whether the backend may use RELA relocations. (Some backends use ++ both REL and RELA relocations, and this flag is set for those ++ backends.) */ ++ unsigned may_use_rela_p : 1; ++ ++ /* Whether the default relocation type is RELA. If a backend with ++ this flag set wants REL relocations for a particular section, ++ it must note that explicitly. Similarly, if this flag is clear, ++ and the backend wants RELA relocations for a particular ++ section. */ ++ unsigned default_use_rela_p : 1; ++ ++ /* True if PLT and copy relocations should be RELA by default. */ ++ unsigned rela_plts_and_copies_p : 1; ++ ++ /* Set if RELA relocations for a relocatable link can be handled by ++ generic code. Backends that set this flag need do nothing in the ++ backend relocate_section routine for relocatable linking. */ ++ unsigned rela_normal : 1; ++ ++ /* Set if DT_REL/DT_RELA/DT_RELSZ/DT_RELASZ should not include PLT ++ relocations. */ ++ unsigned dtrel_excludes_plt : 1; ++ ++ /* TRUE if addresses "naturally" sign extend. This is used when ++ swapping in from Elf32 when BFD64. */ ++ unsigned sign_extend_vma : 1; ++ ++ unsigned want_got_plt : 1; ++ unsigned plt_readonly : 1; ++ unsigned want_plt_sym : 1; ++ unsigned plt_not_loaded : 1; ++ unsigned plt_alignment : 4; ++ unsigned can_gc_sections : 1; ++ unsigned can_refcount : 1; ++ unsigned want_got_sym : 1; ++ unsigned want_dynbss : 1; ++ unsigned want_dynrelro : 1; ++ ++ /* Targets which do not support physical addressing often require ++ that the p_paddr field in the section header to be set to zero. ++ This field indicates whether this behavior is required. */ ++ unsigned want_p_paddr_set_to_zero : 1; ++ ++ /* Target has broken hardware and/or kernel that requires pages not ++ to be mapped twice with different permissions. */ ++ unsigned no_page_alias : 1; ++ ++ /* True if an object file lacking a .note.GNU-stack section ++ should be assumed to be requesting exec stack. At least one ++ other file in the link needs to have a .note.GNU-stack section ++ for a PT_GNU_STACK segment to be created. */ ++ unsigned default_execstack : 1; ++ ++ /* True if elf_section_data(sec)->this_hdr.contents is sec->rawsize ++ in length rather than sec->size in length, if sec->rawsize is ++ non-zero and smaller than sec->size. */ ++ unsigned caches_rawsize : 1; ++ ++ /* Address of protected data defined in the shared library may be ++ external, i.e., due to copy relocation. */ ++ unsigned extern_protected_data : 1; ++ ++ /* True if `_bfd_elf_link_renumber_dynsyms' must be called even for ++ static binaries. */ ++ unsigned always_renumber_dynsyms : 1; ++ ++ /* True if the 32-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid' ++ members use a 16-bit data type. */ ++ unsigned linux_prpsinfo32_ugid16 : 1; ++ ++ /* True if the 64-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid' ++ members use a 16-bit data type. */ ++ unsigned linux_prpsinfo64_ugid16 : 1; ++}; ++ ++/* Information about reloc sections associated with a bfd_elf_section_data ++ structure. */ ++struct bfd_elf_section_reloc_data ++{ ++ /* The ELF header for the reloc section associated with this ++ section, if any. */ ++ Elf_Internal_Shdr *hdr; ++ /* The number of relocations currently assigned to HDR. */ ++ unsigned int count; ++ /* The ELF section number of the reloc section. Only used for an ++ output file. */ ++ int idx; ++ /* Used by the backend linker to store the symbol hash table entries ++ associated with relocs against global symbols. */ ++ struct elf_link_hash_entry **hashes; ++}; ++ ++/* Information stored for each BFD section in an ELF file. This ++ structure is allocated by elf_new_section_hook. */ ++ ++struct bfd_elf_section_data ++{ ++ /* The ELF header for this section. */ ++ Elf_Internal_Shdr this_hdr; ++ ++ /* INPUT_SECTION_FLAGS if specified in the linker script. */ ++ struct flag_info *section_flag_info; ++ ++ /* Information about the REL and RELA reloc sections associated ++ with this section, if any. */ ++ struct bfd_elf_section_reloc_data rel, rela; ++ ++ /* The ELF section number of this section. */ ++ int this_idx; ++ ++ /* Used by the backend linker when generating a shared library to ++ record the dynamic symbol index for a section symbol ++ corresponding to this section. A value of 0 means that there is ++ no dynamic symbol for this section. */ ++ int dynindx; ++ ++ /* A pointer to the linked-to section for SHF_LINK_ORDER. */ ++ asection *linked_to; ++ ++ /* A pointer to the swapped relocs. If the section uses REL relocs, ++ rather than RELA, all the r_addend fields will be zero. This ++ pointer may be NULL. It is used by the backend linker. */ ++ Elf_Internal_Rela *relocs; ++ ++ /* A pointer to a linked list tracking dynamic relocs copied for ++ local symbols. */ ++ void *local_dynrel; ++ ++ /* A pointer to the bfd section used for dynamic relocs. */ ++ asection *sreloc; ++ ++ union { ++ /* Group name, if this section is a member of a group. */ ++ const char *name; ++ ++ /* Group signature sym, if this is the SHT_GROUP section. */ ++ struct bfd_symbol *id; ++ } group; ++ ++ /* For a member of a group, points to the SHT_GROUP section. ++ NULL for the SHT_GROUP section itself and non-group sections. */ ++ asection *sec_group; ++ ++ /* A linked list of member sections in the group. Circular when used by ++ the linker. For the SHT_GROUP section, points at first member. */ ++ asection *next_in_group; ++ ++ /* The FDEs associated with this section. The u.fde.next_in_section ++ field acts as a chain pointer. */ ++ struct eh_cie_fde *fde_list; ++ ++ /* Link from a text section to its .eh_frame_entry section. */ ++ asection *eh_frame_entry; ++ ++ /* TRUE if the section has secondary reloc sections associated with it. ++ FIXME: In the future it might be better to change this into a list ++ of secondary reloc sections, making lookup easier and faster. */ ++ bfd_boolean has_secondary_relocs; ++ ++ /* A pointer used for various section optimizations. */ ++ void *sec_info; ++}; ++ ++#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd) ++#define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to) ++#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type) ++#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags) ++#define elf_section_info(sec) (elf_section_data(sec)->this_hdr.sh_info) ++#define elf_group_name(sec) (elf_section_data(sec)->group.name) ++#define elf_group_id(sec) (elf_section_data(sec)->group.id) ++#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group) ++#define elf_fde_list(sec) (elf_section_data(sec)->fde_list) ++#define elf_sec_group(sec) (elf_section_data(sec)->sec_group) ++#define elf_section_eh_frame_entry(sec) (elf_section_data(sec)->eh_frame_entry) ++ ++#define xvec_get_elf_backend_data(xvec) \ ++ ((const struct elf_backend_data *) (xvec)->backend_data) ++ ++#define get_elf_backend_data(abfd) \ ++ xvec_get_elf_backend_data ((abfd)->xvec) ++ ++/* The least object attributes (within an attributes subsection) known ++ for any target. Some code assumes that the value 0 is not used and ++ the field for that attribute can instead be used as a marker to ++ indicate that attributes have been initialized. */ ++#define LEAST_KNOWN_OBJ_ATTRIBUTE 2 ++ ++/* The maximum number of known object attributes for any target. */ ++#define NUM_KNOWN_OBJ_ATTRIBUTES 71 ++ ++/* The value of an object attribute. The type indicates whether the attribute ++ holds and integer, a string, or both. It can also indicate that there can ++ be no default (i.e. all values must be written to file, even zero), or ++ that the value is in error and should not be written to file. */ ++ ++typedef struct obj_attribute ++{ ++#define ATTR_TYPE_FLAG_INT_VAL (1 << 0) ++#define ATTR_TYPE_FLAG_STR_VAL (1 << 1) ++#define ATTR_TYPE_FLAG_NO_DEFAULT (1 << 2) ++#define ATTR_TYPE_FLAG_ERROR (1 << 3) ++ ++#define ATTR_TYPE_HAS_INT_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_INT_VAL) ++#define ATTR_TYPE_HAS_STR_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_STR_VAL) ++#define ATTR_TYPE_HAS_NO_DEFAULT(TYPE) ((TYPE) & ATTR_TYPE_FLAG_NO_DEFAULT) ++#define ATTR_TYPE_HAS_ERROR(TYPE) ((TYPE) & ATTR_TYPE_FLAG_ERROR) ++ ++ int type; ++ unsigned int i; ++ char *s; ++} obj_attribute; ++ ++typedef struct obj_attribute_list ++{ ++ struct obj_attribute_list *next; ++ unsigned int tag; ++ obj_attribute attr; ++} obj_attribute_list; ++ ++/* Object attributes may either be defined by the processor ABI, index ++ OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific ++ (and possibly also processor-specific), index OBJ_ATTR_GNU. */ ++#define OBJ_ATTR_PROC 0 ++#define OBJ_ATTR_GNU 1 ++#define OBJ_ATTR_FIRST OBJ_ATTR_PROC ++#define OBJ_ATTR_LAST OBJ_ATTR_GNU ++ ++/* The following object attribute tags are taken as generic, for all ++ targets and for "gnu" where there is no target standard. */ ++enum ++{ ++ Tag_NULL = 0, ++ Tag_File = 1, ++ Tag_Section = 2, ++ Tag_Symbol = 3, ++ Tag_compatibility = 32 ++}; ++ ++/* The following struct stores information about every SystemTap section ++ found in the object file. */ ++struct sdt_note ++{ ++ struct sdt_note *next; ++ bfd_size_type size; ++ bfd_byte data[1]; ++}; ++ ++/* tdata information grabbed from an elf core file. */ ++struct core_elf_obj_tdata ++{ ++ int signal; ++ int pid; ++ int lwpid; ++ char* program; ++ char* command; ++}; ++ ++/* Extra tdata information held for output ELF BFDs. */ ++struct output_elf_obj_tdata ++{ ++ struct elf_segment_map *seg_map; ++ struct elf_strtab_hash *strtab_ptr; ++ ++ /* STT_SECTION symbols for each section */ ++ asymbol **section_syms; ++ ++ /* Used to determine if PT_GNU_EH_FRAME segment header should be ++ created. */ ++ asection *eh_frame_hdr; ++ ++ /* NT_GNU_BUILD_ID note type info. */ ++ struct ++ { ++ bfd_boolean (*after_write_object_contents) (bfd *); ++ const char *style; ++ asection *sec; ++ } build_id; ++ ++ /* Records the result of `get_program_header_size'. */ ++ bfd_size_type program_header_size; ++ ++ /* Used when laying out sections. */ ++ file_ptr next_file_pos; ++ ++ int num_section_syms; ++ unsigned int shstrtab_section, strtab_section; ++ ++ /* Segment flags for the PT_GNU_STACK segment. */ ++ unsigned int stack_flags; ++ ++ /* Used to determine if the e_flags field has been initialized */ ++ bfd_boolean flags_init; ++}; ++ ++/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that ++ have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding. Used ++ to set the osabi field in the ELF header structure. */ ++enum elf_gnu_osabi ++{ ++ elf_gnu_osabi_mbind = 1 << 0, ++ elf_gnu_osabi_ifunc = 1 << 1, ++ elf_gnu_osabi_unique = 1 << 2, ++}; ++ ++typedef struct elf_section_list ++{ ++ Elf_Internal_Shdr hdr; ++ unsigned int ndx; ++ struct elf_section_list * next; ++} elf_section_list; ++ ++enum dynamic_lib_link_class { ++ DYN_NORMAL = 0, ++ DYN_AS_NEEDED = 1, ++ DYN_DT_NEEDED = 2, ++ DYN_NO_ADD_NEEDED = 4, ++ DYN_NO_NEEDED = 8 ++}; ++ ++/* Some private data is stashed away for future use using the tdata pointer ++ in the bfd structure. */ ++ ++struct elf_obj_tdata ++{ ++ Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */ ++ Elf_Internal_Shdr **elf_sect_ptr; ++ Elf_Internal_Phdr *phdr; ++ Elf_Internal_Shdr symtab_hdr; ++ Elf_Internal_Shdr shstrtab_hdr; ++ Elf_Internal_Shdr strtab_hdr; ++ Elf_Internal_Shdr dynsymtab_hdr; ++ Elf_Internal_Shdr dynstrtab_hdr; ++ Elf_Internal_Shdr dynversym_hdr; ++ Elf_Internal_Shdr dynverref_hdr; ++ Elf_Internal_Shdr dynverdef_hdr; ++ elf_section_list * symtab_shndx_list; ++ bfd_vma gp; /* The gp value */ ++ unsigned int gp_size; /* The gp size */ ++ unsigned int num_elf_sections; /* elf_sect_ptr size */ ++ ++ /* A mapping from external symbols to entries in the linker hash ++ table, used when linking. This is indexed by the symbol index ++ minus the sh_info field of the symbol table header. */ ++ struct elf_link_hash_entry **sym_hashes; ++ ++ /* Track usage and final offsets of GOT entries for local symbols. ++ This array is indexed by symbol index. Elements are used ++ identically to "got" in struct elf_link_hash_entry. */ ++ union ++ { ++ bfd_signed_vma *refcounts; ++ bfd_vma *offsets; ++ struct got_entry **ents; ++ } local_got; ++ ++ /* The linker ELF emulation code needs to let the backend ELF linker ++ know what filename should be used for a dynamic object if the ++ dynamic object is found using a search. The emulation code then ++ sometimes needs to know what name was actually used. Until the ++ file has been added to the linker symbol table, this field holds ++ the name the linker wants. After it has been added, it holds the ++ name actually used, which will be the DT_SONAME entry if there is ++ one. */ ++ const char *dt_name; ++ ++ /* The linker emulation needs to know what audit libs ++ are used by a dynamic object. */ ++ const char *dt_audit; ++ ++ /* Used by find_nearest_line entry point. */ ++ void *line_info; ++ ++ /* A place to stash dwarf1 info for this bfd. */ ++ struct dwarf1_debug *dwarf1_find_line_info; ++ ++ /* A place to stash dwarf2 info for this bfd. */ ++ void *dwarf2_find_line_info; ++ ++ /* Stash away info for yet another find line/function variant. */ ++ void *elf_find_function_cache; ++ ++ /* Number of symbol version definitions we are about to emit. */ ++ unsigned int cverdefs; ++ ++ /* Number of symbol version references we are about to emit. */ ++ unsigned int cverrefs; ++ ++ /* Symbol version definitions in external objects. */ ++ Elf_Internal_Verdef *verdef; ++ ++ /* Symbol version references to external objects. */ ++ Elf_Internal_Verneed *verref; ++ ++ /* A pointer to the .eh_frame section. */ ++ asection *eh_frame_section; ++ ++ /* Symbol buffer. */ ++ void *symbuf; ++ ++ /* List of GNU properties. Will be updated by setup_gnu_properties ++ after all input GNU properties are merged for output. */ ++ elf_property_list *properties; ++ ++ obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES]; ++ obj_attribute_list *other_obj_attributes[2]; ++ ++ /* Linked-list containing information about every Systemtap section ++ found in the object file. Each section corresponds to one entry ++ in the list. */ ++ struct sdt_note *sdt_note_head; ++ ++ Elf_Internal_Shdr **group_sect_ptr; ++ unsigned int num_group; ++ ++ /* Index into group_sect_ptr, updated by setup_group when finding a ++ section's group. Used to optimize subsequent group searches. */ ++ unsigned int group_search_offset; ++ ++ unsigned int symtab_section, dynsymtab_section; ++ unsigned int dynversym_section, dynverdef_section, dynverref_section; ++ ++ /* An identifier used to distinguish different target ++ specific extensions to this structure. */ ++ ENUM_BITFIELD (elf_target_id) object_id : 6; ++ ++ /* Whether a dyanmic object was specified normally on the linker ++ command line, or was specified when --as-needed was in effect, ++ or was found via a DT_NEEDED entry. */ ++ ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4; ++ ++ /* Whether the bfd uses OS specific bits that require ELFOSABI_GNU. */ ++ ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 3; ++ ++ /* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED ++ property. */ ++ unsigned int has_no_copy_on_protected : 1; ++ ++ /* Irix 5 often screws up the symbol table, sorting local symbols ++ after global symbols. This flag is set if the symbol table in ++ this BFD appears to be screwed up. If it is, we ignore the ++ sh_info field in the symbol table header, and always read all the ++ symbols. */ ++ unsigned int bad_symtab : 1; ++ ++ /* Information grabbed from an elf core file. */ ++ struct core_elf_obj_tdata *core; ++ ++ /* More information held for output ELF BFDs. */ ++ struct output_elf_obj_tdata *o; ++}; ++ ++#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) ++ ++#define elf_object_id(bfd) (elf_tdata(bfd) -> object_id) ++#define elf_program_header_size(bfd) (elf_tdata(bfd) -> o->program_header_size) ++#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) ++#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) ++#define elf_numsections(bfd) (elf_tdata(bfd) -> num_elf_sections) ++#define elf_seg_map(bfd) (elf_tdata(bfd) -> o->seg_map) ++#define elf_next_file_pos(bfd) (elf_tdata(bfd) -> o->next_file_pos) ++#define elf_eh_frame_hdr(bfd) (elf_tdata(bfd) -> o->eh_frame_hdr) ++#define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags) ++#define elf_shstrtab(bfd) (elf_tdata(bfd) -> o->strtab_ptr) ++#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) ++#define elf_symtab_shndx_list(bfd) (elf_tdata(bfd) -> symtab_shndx_list) ++#define elf_strtab_sec(bfd) (elf_tdata(bfd) -> o->strtab_section) ++#define elf_shstrtab_sec(bfd) (elf_tdata(bfd) -> o->shstrtab_section) ++#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr) ++#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section) ++#define elf_dynversym(bfd) (elf_tdata(bfd) -> dynversym_section) ++#define elf_dynverdef(bfd) (elf_tdata(bfd) -> dynverdef_section) ++#define elf_dynverref(bfd) (elf_tdata(bfd) -> dynverref_section) ++#define elf_eh_frame_section(bfd) \ ++ (elf_tdata(bfd) -> eh_frame_section) ++#define elf_section_syms(bfd) (elf_tdata(bfd) -> o->section_syms) ++#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_section_syms) ++#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) ++#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) ++#define elf_gp(bfd) (elf_tdata(bfd) -> gp) ++#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size) ++#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes) ++#define elf_local_got_refcounts(bfd) (elf_tdata(bfd) -> local_got.refcounts) ++#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets) ++#define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents) ++#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name) ++#define elf_dt_audit(bfd) (elf_tdata(bfd) -> dt_audit) ++#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class) ++#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) ++#define elf_flags_init(bfd) (elf_tdata(bfd) -> o->flags_init) ++#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes) ++#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes) ++#define elf_known_obj_attributes_proc(bfd) \ ++ (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC]) ++#define elf_other_obj_attributes_proc(bfd) \ ++ (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC]) ++#define elf_properties(bfd) (elf_tdata (bfd) -> properties) ++#define elf_has_no_copy_on_protected(bfd) \ ++ (elf_tdata(bfd) -> has_no_copy_on_protected) ++ ++extern void _bfd_elf_swap_verdef_in ++ (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *); ++extern void _bfd_elf_swap_verdef_out ++ (bfd *, const Elf_Internal_Verdef *, Elf_External_Verdef *); ++extern void _bfd_elf_swap_verdaux_in ++ (bfd *, const Elf_External_Verdaux *, Elf_Internal_Verdaux *); ++extern void _bfd_elf_swap_verdaux_out ++ (bfd *, const Elf_Internal_Verdaux *, Elf_External_Verdaux *); ++extern void _bfd_elf_swap_verneed_in ++ (bfd *, const Elf_External_Verneed *, Elf_Internal_Verneed *); ++extern void _bfd_elf_swap_verneed_out ++ (bfd *, const Elf_Internal_Verneed *, Elf_External_Verneed *); ++extern void _bfd_elf_swap_vernaux_in ++ (bfd *, const Elf_External_Vernaux *, Elf_Internal_Vernaux *); ++extern void _bfd_elf_swap_vernaux_out ++ (bfd *, const Elf_Internal_Vernaux *, Elf_External_Vernaux *); ++extern void _bfd_elf_swap_versym_in ++ (bfd *, const Elf_External_Versym *, Elf_Internal_Versym *); ++extern void _bfd_elf_swap_versym_out ++ (bfd *, const Elf_Internal_Versym *, Elf_External_Versym *); ++ ++extern unsigned int _bfd_elf_section_from_bfd_section ++ (bfd *, asection *); ++extern char *bfd_elf_string_from_elf_section ++ (bfd *, unsigned, unsigned); ++extern Elf_Internal_Sym *bfd_elf_get_elf_syms ++ (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *, ++ Elf_External_Sym_Shndx *); ++extern char * bfd_elf_get_str_section (bfd *, unsigned int); ++extern const char *bfd_elf_sym_name ++ (bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, asection *); ++ ++extern bfd_boolean _bfd_elf_copy_private_bfd_data ++ (bfd *, bfd *); ++extern bfd_boolean _bfd_elf_print_private_bfd_data ++ (bfd *, void *); ++const char * _bfd_elf_get_symbol_version_string ++ (bfd *, asymbol *, bfd_boolean, bfd_boolean *); ++extern void bfd_elf_print_symbol ++ (bfd *, void *, asymbol *, bfd_print_symbol_type); ++ ++extern unsigned int _bfd_elf_eh_frame_address_size ++ (bfd *, const asection *); ++extern bfd_byte _bfd_elf_encode_eh_address ++ (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset, ++ asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded); ++extern bfd_boolean _bfd_elf_can_make_relative ++ (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section); ++ ++extern enum elf_reloc_type_class _bfd_elf_reloc_type_class ++ (const struct bfd_link_info *, const asection *, ++ const Elf_Internal_Rela *); ++extern bfd_vma _bfd_elf_rela_local_sym ++ (bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *); ++extern bfd_vma _bfd_elf_rel_local_sym ++ (bfd *, Elf_Internal_Sym *, asection **, bfd_vma); ++extern bfd_vma _bfd_elf_section_offset ++ (bfd *, struct bfd_link_info *, asection *, bfd_vma); ++ ++extern unsigned long bfd_elf_hash ++ (const char *); ++extern unsigned long bfd_elf_gnu_hash ++ (const char *); ++ ++extern bfd_reloc_status_type bfd_elf_generic_reloc ++ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); ++extern bfd_boolean bfd_elf_allocate_object ++ (bfd *, size_t, enum elf_target_id); ++extern bfd_boolean bfd_elf_make_object ++ (bfd *); ++extern bfd_boolean bfd_elf_mkcorefile ++ (bfd *); ++extern bfd_boolean _bfd_elf_make_section_from_shdr ++ (bfd *, Elf_Internal_Shdr *, const char *, int); ++extern bfd_boolean _bfd_elf_make_section_from_phdr ++ (bfd *, Elf_Internal_Phdr *, int, const char *); ++extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc ++ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); ++extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create ++ (bfd *); ++extern void _bfd_elf_link_hash_table_free ++ (bfd *); ++extern void _bfd_elf_link_hash_copy_indirect ++ (struct bfd_link_info *, struct elf_link_hash_entry *, ++ struct elf_link_hash_entry *); ++extern void _bfd_elf_link_hash_hide_symbol ++ (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); ++extern void _bfd_elf_link_hide_symbol ++ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); ++extern bfd_boolean _bfd_elf_link_hash_fixup_symbol ++ (struct bfd_link_info *, struct elf_link_hash_entry *); ++extern bfd_boolean _bfd_elf_link_hash_table_init ++ (struct elf_link_hash_table *, bfd *, ++ struct bfd_hash_entry *(*) ++ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *), ++ unsigned int, enum elf_target_id); ++extern bfd_boolean _bfd_elf_slurp_version_tables ++ (bfd *, bfd_boolean); ++extern bfd_boolean _bfd_elf_merge_sections ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_match_sections_by_type ++ (bfd *, const asection *, bfd *, const asection *); ++extern bfd_boolean bfd_elf_is_group_section ++ (bfd *, const struct bfd_section *); ++extern const char *bfd_elf_group_name ++ (bfd *, const struct bfd_section *); ++extern bfd_boolean _bfd_elf_section_already_linked ++ (bfd *, asection *, struct bfd_link_info *); ++extern void bfd_elf_set_group_contents ++ (bfd *, asection *, void *); ++extern unsigned int _bfd_elf_filter_global_symbols ++ (bfd *, struct bfd_link_info *, asymbol **, long); ++extern asection *_bfd_elf_check_kept_section ++ (asection *, struct bfd_link_info *); ++#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms ++extern void _bfd_elf_copy_link_hash_symbol_type ++ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); ++extern bfd_boolean _bfd_elf_size_group_sections ++ (struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_fixup_group_sections ++(bfd *, asection *); ++extern bfd_boolean _bfd_elf_copy_private_header_data ++ (bfd *, bfd *); ++extern bfd_boolean _bfd_elf_copy_private_symbol_data ++ (bfd *, asymbol *, bfd *, asymbol *); ++#define _bfd_generic_init_private_section_data \ ++ _bfd_elf_init_private_section_data ++extern bfd_boolean _bfd_elf_init_private_section_data ++ (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_copy_private_section_data ++ (bfd *, asection *, bfd *, asection *); ++extern bfd_boolean _bfd_elf_write_object_contents ++ (bfd *); ++extern bfd_boolean _bfd_elf_write_corefile_contents ++ (bfd *); ++extern bfd_boolean _bfd_elf_set_section_contents ++ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); ++extern long _bfd_elf_get_symtab_upper_bound ++ (bfd *); ++extern long _bfd_elf_canonicalize_symtab ++ (bfd *, asymbol **); ++extern long _bfd_elf_get_dynamic_symtab_upper_bound ++ (bfd *); ++extern long _bfd_elf_canonicalize_dynamic_symtab ++ (bfd *, asymbol **); ++extern long _bfd_elf_get_synthetic_symtab ++ (bfd *, long, asymbol **, long, asymbol **, asymbol **); ++extern long _bfd_elf_get_reloc_upper_bound ++ (bfd *, sec_ptr); ++extern long _bfd_elf_canonicalize_reloc ++ (bfd *, sec_ptr, arelent **, asymbol **); ++extern asection * _bfd_elf_get_dynamic_reloc_section ++ (bfd *, asection *, bfd_boolean); ++extern asection * _bfd_elf_make_dynamic_reloc_section ++ (asection *, bfd *, unsigned int, bfd *, bfd_boolean); ++extern long _bfd_elf_get_dynamic_reloc_upper_bound ++ (bfd *); ++extern long _bfd_elf_canonicalize_dynamic_reloc ++ (bfd *, arelent **, asymbol **); ++extern asymbol *_bfd_elf_make_empty_symbol ++ (bfd *); ++extern void _bfd_elf_get_symbol_info ++ (bfd *, asymbol *, symbol_info *); ++extern bfd_boolean _bfd_elf_is_local_label_name ++ (bfd *, const char *); ++extern alent *_bfd_elf_get_lineno ++ (bfd *, asymbol *); ++extern bfd_boolean _bfd_elf_set_arch_mach ++ (bfd *, enum bfd_architecture, unsigned long); ++extern bfd_boolean _bfd_elf_find_nearest_line ++ (bfd *, asymbol **, asection *, bfd_vma, ++ const char **, const char **, unsigned int *, unsigned int *); ++extern bfd_boolean _bfd_elf_find_line ++ (bfd *, asymbol **, asymbol *, const char **, unsigned int *); ++extern bfd_boolean _bfd_elf_find_inliner_info ++ (bfd *, const char **, const char **, unsigned int *); ++extern asymbol *_bfd_elf_find_function ++ (bfd *, asymbol **, asection *, bfd_vma, const char **, const char **); ++#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols ++#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol ++extern int _bfd_elf_sizeof_headers ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_new_section_hook ++ (bfd *, asection *); ++extern const struct bfd_elf_special_section *_bfd_elf_get_special_section ++ (const char *, const struct bfd_elf_special_section *, unsigned int); ++extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr ++ (bfd *, asection *); ++ ++extern bfd_boolean _bfd_elf_link_hide_sym_by_version ++ (struct bfd_link_info *, struct elf_link_hash_entry *); ++ ++/* If the target doesn't have reloc handling written yet: */ ++extern bfd_boolean _bfd_elf_no_info_to_howto ++ (bfd *, arelent *, Elf_Internal_Rela *); ++ ++extern bfd_boolean bfd_section_from_shdr ++ (bfd *, unsigned int shindex); ++extern bfd_boolean bfd_section_from_phdr ++ (bfd *, Elf_Internal_Phdr *, int); ++ ++extern int _bfd_elf_symbol_from_bfd_symbol ++ (bfd *, asymbol **); ++ ++extern Elf_Internal_Sym *bfd_sym_from_r_symndx ++ (struct sym_cache *, bfd *, unsigned long); ++extern asection *bfd_section_from_elf_index ++ (bfd *, unsigned int); ++ ++extern struct elf_strtab_hash * _bfd_elf_strtab_init ++ (void); ++extern void _bfd_elf_strtab_free ++ (struct elf_strtab_hash *); ++extern size_t _bfd_elf_strtab_add ++ (struct elf_strtab_hash *, const char *, bfd_boolean); ++extern void _bfd_elf_strtab_addref ++ (struct elf_strtab_hash *, size_t); ++extern void _bfd_elf_strtab_delref ++ (struct elf_strtab_hash *, size_t); ++extern unsigned int _bfd_elf_strtab_refcount ++ (struct elf_strtab_hash *, size_t); ++extern void _bfd_elf_strtab_clear_all_refs ++ (struct elf_strtab_hash *); ++extern void *_bfd_elf_strtab_save ++ (struct elf_strtab_hash *); ++extern void _bfd_elf_strtab_restore ++ (struct elf_strtab_hash *, void *); ++extern bfd_size_type _bfd_elf_strtab_size ++ (struct elf_strtab_hash *); ++extern bfd_size_type _bfd_elf_strtab_len ++ (struct elf_strtab_hash *); ++extern bfd_size_type _bfd_elf_strtab_offset ++ (struct elf_strtab_hash *, size_t); ++extern const char * _bfd_elf_strtab_str ++ (struct elf_strtab_hash *, size_t idx, bfd_size_type *offset); ++extern bfd_boolean _bfd_elf_strtab_emit ++ (bfd *, struct elf_strtab_hash *); ++extern void _bfd_elf_strtab_finalize ++ (struct elf_strtab_hash *); ++ ++extern bfd_boolean bfd_elf_parse_eh_frame_entries ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_parse_eh_frame_entry ++ (struct bfd_link_info *, asection *, struct elf_reloc_cookie *); ++extern void _bfd_elf_parse_eh_frame ++ (bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *); ++extern bfd_boolean _bfd_elf_end_eh_frame_parsing ++ (struct bfd_link_info *info); ++ ++extern bfd_boolean _bfd_elf_discard_section_eh_frame ++ (bfd *, struct bfd_link_info *, asection *, ++ bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *); ++extern bfd_boolean _bfd_elf_adjust_eh_frame_global_symbol ++ (struct elf_link_hash_entry *, void *); ++extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr ++ (bfd *, struct bfd_link_info *); ++extern bfd_vma _bfd_elf_eh_frame_section_offset ++ (bfd *, struct bfd_link_info *, asection *, bfd_vma); ++extern bfd_boolean _bfd_elf_write_section_eh_frame ++ (bfd *, struct bfd_link_info *, asection *, bfd_byte *); ++bfd_boolean _bfd_elf_write_section_eh_frame_entry ++ (bfd *, struct bfd_link_info *, asection *, bfd_byte *); ++extern bfd_boolean _bfd_elf_fixup_eh_frame_hdr (struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_eh_frame_present ++ (struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_eh_frame_entry_present ++ (struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr ++ (struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *); ++ ++extern long _bfd_elf_link_lookup_local_dynindx ++ (struct bfd_link_info *, bfd *, long); ++extern bfd_boolean _bfd_elf_compute_section_file_positions ++ (bfd *, struct bfd_link_info *); ++extern file_ptr _bfd_elf_assign_file_position_for_section ++ (Elf_Internal_Shdr *, file_ptr, bfd_boolean); ++extern bfd_boolean _bfd_elf_modify_headers ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elf_validate_reloc ++ (bfd *, arelent *); ++ ++extern bfd_boolean bfd_elf_record_link_assignment ++ (bfd *, struct bfd_link_info *, const char *, bfd_boolean, ++ bfd_boolean); ++extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *, ++ const char *, bfd_vma); ++extern bfd_boolean bfd_elf_size_dynamic_sections ++ (bfd *, const char *, const char *, const char *, const char *, const char *, ++ const char * const *, struct bfd_link_info *, struct bfd_section **); ++extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean bfd_elf_get_bfd_needed_list ++ (bfd *, struct bfd_link_needed_list **); ++extern struct bfd_link_needed_list *bfd_elf_get_needed_list ++ (bfd *, struct bfd_link_info *); ++extern void bfd_elf_set_dt_needed_name ++ (bfd *, const char *); ++extern const char *bfd_elf_get_dt_soname ++ (bfd *); ++extern void bfd_elf_set_dyn_lib_class ++ (bfd *, enum dynamic_lib_link_class); ++extern int bfd_elf_get_dyn_lib_class ++ (bfd *); ++extern struct bfd_link_needed_list *bfd_elf_get_runpath_list ++ (bfd *, struct bfd_link_info *); ++extern int bfd_elf_discard_info ++ (bfd *, struct bfd_link_info *); ++extern unsigned int _bfd_elf_default_action_discarded ++ (struct bfd_section *); ++extern struct bfd_section *_bfd_elf_tls_setup ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elf_link_create_dynamic_sections ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_omit_section_dynsym_default ++ (bfd *, struct bfd_link_info *, asection *); ++extern bfd_boolean _bfd_elf_omit_section_dynsym_all ++ (bfd *, struct bfd_link_info *, asection *); ++extern bfd_boolean _bfd_elf_create_dynamic_sections ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_create_got_section ++ (bfd *, struct bfd_link_info *); ++extern asection *_bfd_elf_section_for_symbol ++ (struct elf_reloc_cookie *, unsigned long, bfd_boolean); ++extern struct elf_link_hash_entry *_bfd_elf_define_linkage_sym ++ (bfd *, struct bfd_link_info *, asection *, const char *); ++extern void _bfd_elf_init_1_index_section ++ (bfd *, struct bfd_link_info *); ++extern void _bfd_elf_init_2_index_sections ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elfcore_make_pseudosection ++ (bfd *, char *, size_t, ufile_ptr); ++extern char *_bfd_elfcore_strndup ++ (bfd *, char *, size_t); ++ ++extern Elf_Internal_Rela *_bfd_elf_link_read_relocs ++ (bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean); ++ ++extern bfd_boolean _bfd_elf_link_output_relocs ++ (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, ++ struct elf_link_hash_entry **); ++ ++extern bfd_boolean _bfd_elf_adjust_dynamic_copy ++ (struct bfd_link_info *, struct elf_link_hash_entry *, asection *); ++ ++extern bfd_boolean _bfd_elf_dynamic_symbol_p ++ (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); ++ ++extern bfd_boolean _bfd_elf_symbol_refs_local_p ++ (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); ++ ++extern bfd_reloc_status_type bfd_elf_perform_complex_relocation ++ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma); ++ ++extern bfd_boolean _bfd_elf_setup_sections ++ (bfd *); ++ ++extern struct bfd_link_hash_entry *bfd_elf_define_start_stop ++ (struct bfd_link_info *, const char *, asection *); ++ ++extern bfd_boolean _bfd_elf_init_file_header (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elf_final_write_processing (bfd *); ++ ++extern bfd_cleanup bfd_elf32_object_p ++ (bfd *); ++extern bfd_cleanup bfd_elf32_core_file_p ++ (bfd *); ++extern char *bfd_elf32_core_file_failing_command ++ (bfd *); ++extern int bfd_elf32_core_file_failing_signal ++ (bfd *); ++extern bfd_boolean bfd_elf32_core_file_matches_executable_p ++ (bfd *, bfd *); ++extern int bfd_elf32_core_file_pid ++ (bfd *); ++extern bfd_boolean _bfd_elf32_core_find_build_id ++ (bfd *, bfd_vma); ++ ++extern bfd_boolean bfd_elf32_swap_symbol_in ++ (bfd *, const void *, const void *, Elf_Internal_Sym *); ++extern void bfd_elf32_swap_symbol_out ++ (bfd *, const Elf_Internal_Sym *, void *, void *); ++extern void bfd_elf32_swap_reloc_in ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++extern void bfd_elf32_swap_reloc_out ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++extern void bfd_elf32_swap_reloca_in ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++extern void bfd_elf32_swap_reloca_out ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++extern void bfd_elf32_swap_phdr_in ++ (bfd *, const Elf32_External_Phdr *, Elf_Internal_Phdr *); ++extern void bfd_elf32_swap_phdr_out ++ (bfd *, const Elf_Internal_Phdr *, Elf32_External_Phdr *); ++extern void bfd_elf32_swap_dyn_in ++ (bfd *, const void *, Elf_Internal_Dyn *); ++extern void bfd_elf32_swap_dyn_out ++ (bfd *, const Elf_Internal_Dyn *, void *); ++extern long bfd_elf32_slurp_symbol_table ++ (bfd *, asymbol **, bfd_boolean); ++extern bfd_boolean bfd_elf32_write_shdrs_and_ehdr ++ (bfd *); ++extern int bfd_elf32_write_out_phdrs ++ (bfd *, const Elf_Internal_Phdr *, unsigned int); ++extern bfd_boolean bfd_elf32_checksum_contents ++ (bfd * , void (*) (const void *, size_t, void *), void *); ++extern void bfd_elf32_write_relocs ++ (bfd *, asection *, void *); ++extern bfd_boolean bfd_elf32_slurp_reloc_table ++ (bfd *, asection *, asymbol **, bfd_boolean); ++ ++extern bfd_cleanup bfd_elf64_object_p ++ (bfd *); ++extern bfd_cleanup bfd_elf64_core_file_p ++ (bfd *); ++extern char *bfd_elf64_core_file_failing_command ++ (bfd *); ++extern int bfd_elf64_core_file_failing_signal ++ (bfd *); ++extern bfd_boolean bfd_elf64_core_file_matches_executable_p ++ (bfd *, bfd *); ++extern int bfd_elf64_core_file_pid ++ (bfd *); ++extern bfd_boolean _bfd_elf64_core_find_build_id ++ (bfd *, bfd_vma); ++ ++extern bfd_boolean bfd_elf64_swap_symbol_in ++ (bfd *, const void *, const void *, Elf_Internal_Sym *); ++extern void bfd_elf64_swap_symbol_out ++ (bfd *, const Elf_Internal_Sym *, void *, void *); ++extern void bfd_elf64_swap_reloc_in ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++extern void bfd_elf64_swap_reloc_out ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++extern void bfd_elf64_swap_reloca_in ++ (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++extern void bfd_elf64_swap_reloca_out ++ (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++extern void bfd_elf64_swap_phdr_in ++ (bfd *, const Elf64_External_Phdr *, Elf_Internal_Phdr *); ++extern void bfd_elf64_swap_phdr_out ++ (bfd *, const Elf_Internal_Phdr *, Elf64_External_Phdr *); ++extern void bfd_elf64_swap_dyn_in ++ (bfd *, const void *, Elf_Internal_Dyn *); ++extern void bfd_elf64_swap_dyn_out ++ (bfd *, const Elf_Internal_Dyn *, void *); ++extern long bfd_elf64_slurp_symbol_table ++ (bfd *, asymbol **, bfd_boolean); ++extern bfd_boolean bfd_elf64_write_shdrs_and_ehdr ++ (bfd *); ++extern int bfd_elf64_write_out_phdrs ++ (bfd *, const Elf_Internal_Phdr *, unsigned int); ++extern bfd_boolean bfd_elf64_checksum_contents ++ (bfd * , void (*) (const void *, size_t, void *), void *); ++extern void bfd_elf64_write_relocs ++ (bfd *, asection *, void *); ++extern bfd_boolean bfd_elf64_slurp_reloc_table ++ (bfd *, asection *, asymbol **, bfd_boolean); ++ ++extern bfd_boolean _bfd_elf_default_relocs_compatible ++ (const bfd_target *, const bfd_target *); ++ ++extern bfd_boolean _bfd_elf_relocs_compatible ++ (const bfd_target *, const bfd_target *); ++extern bfd_boolean _bfd_elf_notice_as_needed ++ (bfd *, struct bfd_link_info *, enum notice_asneeded_action); ++ ++extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup ++ (bfd *, struct bfd_link_info *, const char *); ++extern bfd_boolean bfd_elf_link_add_symbols ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_add_dynamic_entry ++ (struct bfd_link_info *, bfd_vma, bfd_vma); ++extern bfd_boolean _bfd_elf_strip_zero_sized_dynamic_sections ++ (struct bfd_link_info *); ++extern int bfd_elf_add_dt_needed_tag ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_link_check_relocs ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean bfd_elf_link_record_dynamic_symbol ++ (struct bfd_link_info *, struct elf_link_hash_entry *); ++ ++extern int bfd_elf_link_record_local_dynamic_symbol ++ (struct bfd_link_info *, bfd *, long); ++ ++extern bfd_boolean _bfd_elf_close_and_cleanup ++ (bfd *); ++ ++extern bfd_boolean _bfd_elf_common_definition ++ (Elf_Internal_Sym *); ++ ++extern unsigned int _bfd_elf_common_section_index ++ (asection *); ++ ++extern asection *_bfd_elf_common_section ++ (asection *); ++ ++extern bfd_vma _bfd_elf_default_got_elt_size ++(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *, ++ unsigned long); ++ ++extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn ++ (bfd *, arelent *, struct bfd_symbol *, void *, ++ asection *, bfd *, char **); ++ ++extern bfd_boolean bfd_elf_final_link ++ (bfd *, struct bfd_link_info *); ++ ++extern void _bfd_elf_gc_keep ++ (struct bfd_link_info *info); ++ ++extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol ++ (struct elf_link_hash_entry *h, void *inf); ++ ++extern bfd_boolean bfd_elf_gc_sections ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean bfd_elf_gc_record_vtinherit ++ (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); ++ ++extern bfd_boolean bfd_elf_gc_record_vtentry ++ (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); ++ ++extern asection *_bfd_elf_gc_mark_hook ++ (asection *, struct bfd_link_info *, Elf_Internal_Rela *, ++ struct elf_link_hash_entry *, Elf_Internal_Sym *); ++ ++extern asection *_bfd_elf_gc_mark_rsec ++ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn, ++ struct elf_reloc_cookie *, bfd_boolean *); ++ ++extern bfd_boolean _bfd_elf_gc_mark_reloc ++ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn, ++ struct elf_reloc_cookie *); ++ ++extern bfd_boolean _bfd_elf_gc_mark_fdes ++ (struct bfd_link_info *, asection *, asection *, elf_gc_mark_hook_fn, ++ struct elf_reloc_cookie *); ++ ++extern bfd_boolean _bfd_elf_gc_mark ++ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn); ++ ++extern bfd_boolean _bfd_elf_gc_mark_extra_sections ++ (struct bfd_link_info *, elf_gc_mark_hook_fn); ++ ++extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean bfd_elf_gc_common_final_link ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean bfd_elf_reloc_symbol_deleted_p ++ (bfd_vma, void *); ++ ++extern struct elf_segment_map * _bfd_elf_make_dynamic_segment ++ (bfd *, asection *); ++ ++extern bfd_boolean _bfd_elf_map_sections_to_segments ++ (bfd *, struct bfd_link_info *); ++ ++extern bfd_boolean _bfd_elf_is_function_type (unsigned int); ++ ++extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *, ++ bfd_vma *); ++ ++extern asection *_bfd_elf_plt_get_reloc_section (bfd *, const char *); ++ ++extern int bfd_elf_get_default_section_type (flagword); ++ ++extern bfd_boolean bfd_elf_lookup_section_flags ++ (struct bfd_link_info *, struct flag_info *, asection *); ++ ++extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section ++ (bfd * abfd, asection * section); ++ ++/* PowerPC @tls opcode transform/validate. */ ++extern unsigned int _bfd_elf_ppc_at_tls_transform ++ (unsigned int, unsigned int); ++/* PowerPC @tprel opcode transform/validate. */ ++extern unsigned int _bfd_elf_ppc_at_tprel_transform ++ (unsigned int, unsigned int); ++/* PowerPC elf_object_p tweak. */ ++extern bfd_boolean _bfd_elf_ppc_set_arch (bfd *); ++/* PowerPC .gnu.attributes handling common to both 32-bit and 64-bit. */ ++extern bfd_boolean _bfd_elf_ppc_merge_fp_attributes ++ (bfd *, struct bfd_link_info *); ++ ++/* Return an upper bound on the number of bytes required to store a ++ copy of ABFD's program header table entries. Return -1 if an error ++ occurs; bfd_get_error will return an appropriate code. */ ++extern long bfd_get_elf_phdr_upper_bound ++ (bfd *abfd); ++ ++/* Copy ABFD's program header table entries to *PHDRS. The entries ++ will be stored as an array of Elf_Internal_Phdr structures, as ++ defined in include/elf/internal.h. To find out how large the ++ buffer needs to be, call bfd_get_elf_phdr_upper_bound. ++ ++ Return the number of program header table entries read, or -1 if an ++ error occurs; bfd_get_error will return an appropriate code. */ ++extern int bfd_get_elf_phdrs ++ (bfd *abfd, void *phdrs); ++ ++/* Exported interface for writing elf corefile notes. */ ++extern char *elfcore_write_note ++ (bfd *, char *, int *, const char *, int, const void *, int); ++extern char *elfcore_write_prpsinfo ++ (bfd *, char *, int *, const char *, const char *); ++extern char *elfcore_write_prstatus ++ (bfd *, char *, int *, long, int, const void *); ++extern char * elfcore_write_pstatus ++ (bfd *, char *, int *, long, int, const void *); ++extern char *elfcore_write_prfpreg ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_prxfpreg ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_xstatereg ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_vmx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_vsx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tar ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_ppr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_dscr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_ebb ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_pmu ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cgpr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cfpr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cvmx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cvsx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_spr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_ctar ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cppr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cdscr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_timer ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_todcmp ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_todpreg ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_ctrs ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_prefix ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_last_break ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_system_call ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_tdb ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_vxrs_low ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_vxrs_high ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_gs_cb ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_s390_gs_bc ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_arm_vfp ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_aarch_tls ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_aarch_hw_break ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_aarch_hw_watch ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_aarch_sve ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_aarch_pauth ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_arc_v2 ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_lwpstatus ++ (bfd *, char *, int *, long, int, const void *); ++extern char *elfcore_write_register_note ++ (bfd *, char *, int *, const char *, const void *, int); ++ ++/* Internal structure which holds information to be included in the ++ PRPSINFO section of Linux core files. ++ ++ This is an "internal" structure in the sense that it should be used ++ to pass information to BFD (via the `elfcore_write_linux_prpsinfo' ++ function), so things like endianess shouldn't be an issue. This ++ structure will eventually be converted in one of the ++ `elf_external_linux_*' structures and written out to an output bfd ++ by one of the functions declared below. */ ++ ++struct elf_internal_linux_prpsinfo ++ { ++ char pr_state; /* Numeric process state. */ ++ char pr_sname; /* Char for pr_state. */ ++ char pr_zomb; /* Zombie. */ ++ char pr_nice; /* Nice val. */ ++ unsigned long pr_flag; /* Flags. */ ++ unsigned int pr_uid; ++ unsigned int pr_gid; ++ int pr_pid, pr_ppid, pr_pgrp, pr_sid; ++ char pr_fname[16 + 1]; /* Filename of executable. */ ++ char pr_psargs[80 + 1]; /* Initial part of arg list. */ ++ }; ++ ++/* Linux/most 32-bit archs. */ ++extern char *elfcore_write_linux_prpsinfo32 ++ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *); ++ ++/* Linux/most 64-bit archs. */ ++extern char *elfcore_write_linux_prpsinfo64 ++ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *); ++ ++extern bfd *_bfd_elf32_bfd_from_remote_memory ++ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, ++ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); ++extern bfd *_bfd_elf64_bfd_from_remote_memory ++ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, ++ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); ++ ++extern bfd_vma bfd_elf_obj_attr_size (bfd *); ++extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma); ++extern int bfd_elf_get_obj_attr_int (bfd *, int, unsigned int); ++extern void bfd_elf_add_obj_attr_int (bfd *, int, unsigned int, unsigned int); ++#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \ ++ bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE)) ++extern void bfd_elf_add_obj_attr_string (bfd *, int, unsigned int, const char *); ++#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \ ++ bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE)) ++extern void bfd_elf_add_obj_attr_int_string (bfd *, int, unsigned int, ++ unsigned int, const char *); ++#define bfd_elf_add_proc_attr_int_string(BFD, TAG, INTVAL, STRVAL) \ ++ bfd_elf_add_obj_attr_int_string ((BFD), OBJ_ATTR_PROC, (TAG), \ ++ (INTVAL), (STRVAL)) ++ ++extern char *_bfd_elf_attr_strdup (bfd *, const char *); ++extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *); ++extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, unsigned int); ++extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *); ++extern bfd_boolean _bfd_elf_merge_object_attributes ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int); ++extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *); ++extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec); ++extern bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type, size_t); ++ ++extern bfd_boolean _bfd_elf_parse_gnu_properties ++ (bfd *, Elf_Internal_Note *); ++extern elf_property * _bfd_elf_get_property ++ (bfd *, unsigned int, unsigned int); ++extern bfd *_bfd_elf_link_setup_gnu_properties ++ (struct bfd_link_info *); ++extern bfd_size_type _bfd_elf_convert_gnu_property_size ++ (bfd *, bfd *); ++extern bfd_boolean _bfd_elf_convert_gnu_properties ++ (bfd *, asection *, bfd *, bfd_byte **, bfd_size_type *); ++ ++/* The linker may need to keep track of the number of relocs that it ++ decides to copy as dynamic relocs in check_relocs for each symbol. ++ This is so that it can later discard them if they are found to be ++ unnecessary. We can store the information in a field extending the ++ regular ELF linker hash table. */ ++ ++struct elf_dyn_relocs ++{ ++ struct elf_dyn_relocs *next; ++ ++ /* The input section of the reloc. */ ++ asection *sec; ++ ++ /* Total number of relocs copied for the input section. */ ++ bfd_size_type count; ++ ++ /* Number of pc-relative relocs copied for the input section. */ ++ bfd_size_type pc_count; ++}; ++ ++extern bfd_boolean _bfd_elf_create_ifunc_sections ++ (bfd *, struct bfd_link_info *); ++extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs ++ (struct bfd_link_info *, struct elf_link_hash_entry *, ++ struct elf_dyn_relocs **, unsigned int, unsigned int, ++ unsigned int, bfd_boolean); ++ ++extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *); ++extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *); ++ ++extern bfd_vma elf64_r_info (bfd_vma, bfd_vma); ++extern bfd_vma elf64_r_sym (bfd_vma); ++extern bfd_vma elf32_r_info (bfd_vma, bfd_vma); ++extern bfd_vma elf32_r_sym (bfd_vma); ++ ++extern bfd_boolean is_debuginfo_file (bfd *); ++ ++ ++extern bfd_boolean _bfd_elf_init_secondary_reloc_section ++ (bfd *, Elf_Internal_Shdr *, const char *, unsigned int); ++extern bfd_boolean _bfd_elf_slurp_secondary_reloc_section ++ (bfd *, asection *, asymbol **); ++extern bfd_boolean _bfd_elf_copy_special_section_fields ++ (const bfd *, bfd *, const Elf_Internal_Shdr *, Elf_Internal_Shdr *); ++extern bfd_boolean _bfd_elf_write_secondary_reloc_section ++ (bfd *, asection *); ++extern unsigned int _bfd_elf_symbol_section_index ++ (bfd *, elf_symbol_type *); ++ ++extern asection *_bfd_elf_readonly_dynrelocs ++ (struct elf_link_hash_entry *); ++extern bfd_boolean _bfd_elf_maybe_set_textrel ++ (struct elf_link_hash_entry *, void *); ++ ++extern bfd_boolean _bfd_elf_add_dynamic_tags ++ (bfd *, struct bfd_link_info *, bfd_boolean); ++ ++/* Large common section. */ ++extern asection _bfd_elf_large_com_section; ++ ++/* Hash for local symbol with the first section id, ID, in the input ++ file and the local symbol index, SYM. */ ++#define ELF_LOCAL_SYMBOL_HASH(ID, SYM) \ ++ (((((ID) & 0xffU) << 24) | (((ID) & 0xff00) << 8)) \ ++ ^ (SYM) ^ (((ID) & 0xffff0000U) >> 16)) ++ ++/* This is the condition under which finish_dynamic_symbol will be called. ++ If our finish_dynamic_symbol isn't called, we'll need to do something ++ about initializing any .plt and .got entries in relocate_section. */ ++#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ ++ ((DYN) \ ++ && ((SHARED) || !(H)->forced_local) \ ++ && ((H)->dynindx != -1 || (H)->forced_local)) ++ ++/* This macro is to avoid lots of duplicated code in the body ++ of xxx_relocate_section() in the various elfxx-xxxx.c files. */ ++#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \ ++ r_symndx, symtab_hdr, sym_hashes, \ ++ h, sec, relocation, \ ++ unresolved_reloc, warned, ignored) \ ++ do \ ++ { \ ++ /* It seems this can happen with erroneous or unsupported \ ++ input (mixing a.out and elf in an archive, for example.) */ \ ++ if (sym_hashes == NULL) \ ++ return FALSE; \ ++ \ ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; \ ++ \ ++ if (info->wrap_hash != NULL \ ++ && (input_section->flags & SEC_DEBUGGING) != 0) \ ++ h = ((struct elf_link_hash_entry *) \ ++ unwrap_hash_lookup (info, input_bfd, &h->root)); \ ++ \ ++ while (h->root.type == bfd_link_hash_indirect \ ++ || h->root.type == bfd_link_hash_warning) \ ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; \ ++ \ ++ warned = FALSE; \ ++ ignored = FALSE; \ ++ unresolved_reloc = FALSE; \ ++ relocation = 0; \ ++ if (h->root.type == bfd_link_hash_defined \ ++ || h->root.type == bfd_link_hash_defweak) \ ++ { \ ++ sec = h->root.u.def.section; \ ++ if (sec == NULL \ ++ || sec->output_section == NULL) \ ++ /* Set a flag that will be cleared later if we find a \ ++ relocation value for this symbol. output_section \ ++ is typically NULL for symbols satisfied by a shared \ ++ library. */ \ ++ unresolved_reloc = TRUE; \ ++ else \ ++ relocation = (h->root.u.def.value \ ++ + sec->output_section->vma \ ++ + sec->output_offset); \ ++ } \ ++ else if (h->root.type == bfd_link_hash_undefweak) \ ++ ; \ ++ else if (info->unresolved_syms_in_objects == RM_IGNORE \ ++ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \ ++ ignored = TRUE; \ ++ else if (!bfd_link_relocatable (info)) \ ++ { \ ++ bfd_boolean err; \ ++ err = (info->unresolved_syms_in_objects == RM_DIAGNOSE && \ ++ !info->warn_unresolved_syms) \ ++ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT; \ ++ (*info->callbacks->undefined_symbol) (info, \ ++ h->root.root.string, \ ++ input_bfd, \ ++ input_section, \ ++ rel->r_offset, err); \ ++ warned = TRUE; \ ++ } \ ++ (void) unresolved_reloc; \ ++ (void) warned; \ ++ (void) ignored; \ ++ } \ ++ while (0) ++ ++/* This macro is to avoid lots of duplicated code in the body of the ++ loop over relocations in xxx_relocate_section() in the various ++ elfxx-xxxx.c files. ++ ++ Handle relocations against symbols from removed linkonce sections, ++ or sections discarded by a linker script. When doing a relocatable ++ link, we remove such relocations. Otherwise, we just want the ++ section contents zeroed and avoid any special processing. */ ++#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \ ++ rel, count, relend, \ ++ howto, index, contents) \ ++ { \ ++ int i_; \ ++ _bfd_clear_contents (howto, input_bfd, input_section, \ ++ contents, rel[index].r_offset); \ ++ \ ++ if (bfd_link_relocatable (info) \ ++ && (input_section->flags & SEC_DEBUGGING)) \ ++ { \ ++ /* Only remove relocations in debug sections since other \ ++ sections may require relocations. */ \ ++ Elf_Internal_Shdr *rel_hdr; \ ++ \ ++ rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \ ++ \ ++ /* Avoid empty output section. */ \ ++ if (rel_hdr->sh_size > rel_hdr->sh_entsize) \ ++ { \ ++ rel_hdr->sh_size -= rel_hdr->sh_entsize; \ ++ rel_hdr = _bfd_elf_single_rel_hdr (input_section); \ ++ rel_hdr->sh_size -= rel_hdr->sh_entsize; \ ++ \ ++ memmove (rel, rel + count, \ ++ (relend - rel - count) * sizeof (*rel)); \ ++ \ ++ input_section->reloc_count -= count; \ ++ relend -= count; \ ++ rel--; \ ++ continue; \ ++ } \ ++ } \ ++ \ ++ for (i_ = 0; i_ < count; i_++) \ ++ { \ ++ rel[i_].r_info = 0; \ ++ rel[i_].r_addend = 0; \ ++ } \ ++ rel += count - 1; \ ++ continue; \ ++ } ++ ++/* Will a symbol be bound to the definition within the shared ++ library, if any. A unique symbol can never be bound locally. */ ++#define SYMBOLIC_BIND(INFO, H) \ ++ (!(H)->unique_global \ ++ && ((INFO)->symbolic \ ++ || (H)->start_stop \ ++ || ((INFO)->dynamic && !(H)->dynamic))) ++ ++/* Determine if a section contains CTF data, using its name. */ ++static inline bfd_boolean ++bfd_section_is_ctf (const asection *sec) ++{ ++ const char *name = bfd_section_name (sec); ++ return strncmp (name, ".ctf", 4) == 0 && (name[4] == 0 || name[4] == '.'); ++} ++ ++#ifdef __cplusplus ++} ++#endif ++#endif /* _LIBELF_H_ */ +diff -Nuar gdb-10.2/bfd/elf.c gdb-10.2/bfd/elf.c +--- gdb-10.2/bfd/elf.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/elf.c 2025-04-16 17:06:51.912086800 +0800 +@@ -10921,6 +10921,7 @@ + + case bfd_arch_aarch64: + case bfd_arch_alpha: ++ case bfd_arch_sw_64: + case bfd_arch_sparc: + switch (note->type) + { +diff -Nuar gdb-10.2/bfd/hosts/sw_64linux.h gdb-10.2/bfd/hosts/sw_64linux.h +--- gdb-10.2/bfd/hosts/sw_64linux.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/hosts/sw_64linux.h 2025-04-16 17:06:51.922086800 +0800 +@@ -0,0 +1,25 @@ ++/* Copyright (C) 2007-2019 Free Software Foundation, Inc. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/* Linux dumps "struct task_struct" at the end of the core-file. This ++ structure is currently 1080 bytes long, but we allow up to 4096 ++ bytes to allow for some future growth. */ ++#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096 ++#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ ++ ((abfd)->tdata.trad_core_data->u.signal) +diff -Nuar gdb-10.2/bfd/hosts/sw_64vms.h gdb-10.2/bfd/hosts/sw_64vms.h +--- gdb-10.2/bfd/hosts/sw_64vms.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/hosts/sw_64vms.h 2025-04-16 17:06:51.922086800 +0800 +@@ -0,0 +1,68 @@ ++/* alphavms.h -- BFD definitions for an openVMS host ++ Copyright (C) 1996-2019 Free Software Foundation, Inc. ++ Written by Klaus K?mpf (kkaempf@progis.de) ++ of proGIS Softwareentwicklung, Aachen, Germany ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifdef PACKAGE ++#error sysdep.h must be included in lieu of config.h ++#endif ++ ++#include "config.h" ++#include "ansidecl.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "filenames.h" ++#include "fopen-vms.h" ++ ++#define NO_FCNTL 1 ++ ++#ifndef O_ACCMODE ++#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) ++#endif ++ ++extern int getpagesize (void); ++extern char *stpcpy (char *, const char *); ++ ++/* No intl. */ ++#define gettext(Msgid) (Msgid) ++#define dgettext(Domainname, Msgid) (Msgid) ++#define dcgettext(Domainname, Msgid, Category) (Msgid) ++#define ngettext(Msgid1, Msgid2, n) \ ++ (n == 1 ? Msgid1 : Msgid2) ++#define dngettext(Domainname, Msgid1, Msgid2, n) \ ++ (n == 1 ? Msgid1 : Msgid2) ++#define dcngettext(Domainname, Msgid1, Msgid2, n, Category) \ ++ (n == 1 ? Msgid1 : Msgid2) ++#define textdomain(Domainname) do {} while (0) ++#define bindtextdomain(Domainname, Dirname) do {} while (0) ++#define _(String) (String) ++#define N_(String) (String) +diff -Nuar gdb-10.2/bfd/libaout.h gdb-10.2/bfd/libaout.h +--- gdb-10.2/bfd/libaout.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/libaout.h 2025-04-16 17:06:51.922086800 +0800 +@@ -268,6 +268,7 @@ + M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary. */ + M_VAX_NETBSD = 140, /* NetBSD/vax binary. */ + M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary. */ ++ M_SW_64_NETBSD = 142, /* NetBSD/sw_64 binary. */ + M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary. */ + M_SPARCLET_1 = 147, /* 0x93, reserved. */ + M_POWERPC_NETBSD = 149, /* NetBSD/powerpc (big-endian) binary. */ +diff -Nuar gdb-10.2/bfd/libbfd.h gdb-10.2/bfd/libbfd.h +--- gdb-10.2/bfd/libbfd.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/libbfd.h 2025-04-16 17:06:51.922086800 +0800 +@@ -433,10 +433,14 @@ + (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_cleanup _bfd_vms_lib_alpha_archive_p + (bfd *) ATTRIBUTE_HIDDEN; ++extern bfd_cleanup _bfd_vms_lib_sw_64_archive_p ++ (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_cleanup _bfd_vms_lib_ia64_archive_p + (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_boolean _bfd_vms_lib_alpha_mkarchive + (bfd *) ATTRIBUTE_HIDDEN; ++extern bfd_boolean _bfd_vms_lib_sw_64_mkarchive ++ (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_boolean _bfd_vms_lib_ia64_mkarchive + (bfd *) ATTRIBUTE_HIDDEN; + +@@ -1085,6 +1089,9 @@ + "BFD_RELOC_8_FFnn", + "BFD_RELOC_32_PCREL_S2", + "BFD_RELOC_16_PCREL_S2", ++#ifndef XWB20200308 ++ "BFD_RELOC_20_PCREL_S2", ++#endif + "BFD_RELOC_23_PCREL_S2", + "BFD_RELOC_HI22", + "BFD_RELOC_LO10", +@@ -1211,6 +1218,44 @@ + "BFD_RELOC_ALPHA_TPREL_HI16", + "BFD_RELOC_ALPHA_TPREL_LO16", + "BFD_RELOC_ALPHA_TPREL16", ++ "BFD_RELOC_SW_64_GPDISP_HI16", ++ "BFD_RELOC_SW_64_GPDISP_LO16", ++ "BFD_RELOC_SW_64_GPDISP", ++ "BFD_RELOC_SW_64_LITERAL", ++ "BFD_RELOC_SW_64_ELF_LITERAL", ++ "BFD_RELOC_SW_64_LITUSE", ++ "BFD_RELOC_SW_64_HINT", ++ "BFD_RELOC_SW_64_LINKAGE", ++ "BFD_RELOC_SW_64_CODEADDR", ++ "BFD_RELOC_SW_64_GPREL_HI16", ++ "BFD_RELOC_SW_64_GPREL_LO16", ++ "BFD_RELOC_SW_64_BRSGP", ++ "BFD_RELOC_SW_64_NOP", ++ "BFD_RELOC_SW_64_ELF_LITERAL", ++ "BFD_RELOC_SW_64_LITUSE", ++ "BFD_RELOC_SW_64_HINT", ++ "BFD_RELOC_SW_64_LINKAGE", ++ "BFD_RELOC_SW_64_CODEADDR", ++ "BFD_RELOC_SW_64_GPREL_HI16", ++ "BFD_RELOC_SW_64_GPREL_LO16", ++ "BFD_RELOC_SW_64_BRSGP", ++ "BFD_RELOC_SW_64_NOP", ++ "BFD_RELOC_SW_64_BSR", ++ "BFD_RELOC_SW_64_LDA", ++ "BFD_RELOC_SW_64_BOH", ++ "BFD_RELOC_SW_64_TLSGD", ++ "BFD_RELOC_SW_64_TLSLDM", ++ "BFD_RELOC_SW_64_DTPMOD64", ++ "BFD_RELOC_SW_64_GOTDTPREL16", ++ "BFD_RELOC_SW_64_DTPREL64", ++ "BFD_RELOC_SW_64_DTPREL_HI16", ++ "BFD_RELOC_SW_64_DTPREL_LO16", ++ "BFD_RELOC_SW_64_DTPREL16", ++ "BFD_RELOC_SW_64_GOTTPREL16", ++ "BFD_RELOC_SW_64_TPREL64", ++ "BFD_RELOC_SW_64_TPREL_HI16", ++ "BFD_RELOC_SW_64_TPREL_LO16", ++ "BFD_RELOC_SW_64_TPREL16", + "BFD_RELOC_MIPS_JMP", + "BFD_RELOC_MICROMIPS_JMP", + "BFD_RELOC_MIPS16_JMP", +diff -Nuar gdb-10.2/bfd/libbfd-in.h gdb-10.2/bfd/libbfd-in.h +--- gdb-10.2/bfd/libbfd-in.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/libbfd-in.h 2025-04-16 17:06:51.922086800 +0800 +@@ -428,10 +428,14 @@ + (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_cleanup _bfd_vms_lib_alpha_archive_p + (bfd *) ATTRIBUTE_HIDDEN; ++extern bfd_cleanup _bfd_vms_lib_sw_64_archive_p ++ (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_cleanup _bfd_vms_lib_ia64_archive_p + (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_boolean _bfd_vms_lib_alpha_mkarchive + (bfd *) ATTRIBUTE_HIDDEN; ++extern bfd_boolean _bfd_vms_lib_sw_64_mkarchive ++ (bfd *) ATTRIBUTE_HIDDEN; + extern bfd_boolean _bfd_vms_lib_ia64_mkarchive + (bfd *) ATTRIBUTE_HIDDEN; + +diff -Nuar gdb-10.2/bfd/mach-o.c gdb-10.2/bfd/mach-o.c +--- gdb-10.2/bfd/mach-o.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/mach-o.c 2025-04-16 17:06:51.922086800 +0800 +@@ -609,6 +609,7 @@ + case BFD_MACH_O_CPU_TYPE_SPARC: return "SPARC"; + case BFD_MACH_O_CPU_TYPE_I860: return "I860"; + case BFD_MACH_O_CPU_TYPE_ALPHA: return "ALPHA"; ++ case BFD_MACH_O_CPU_TYPE_SW_64: return "SW_64"; + case BFD_MACH_O_CPU_TYPE_POWERPC: return "PPC"; + case BFD_MACH_O_CPU_TYPE_POWERPC_64: return "PPC64"; + case BFD_MACH_O_CPU_TYPE_X86_64: return "X86_64"; +@@ -1181,6 +1182,9 @@ + case BFD_MACH_O_CPU_TYPE_ALPHA: + *type = bfd_arch_alpha; + break; ++ case BFD_MACH_O_CPU_TYPE_SW_64: ++ *type = bfd_arch_sw_64; ++ break; + case BFD_MACH_O_CPU_TYPE_POWERPC: + *type = bfd_arch_powerpc; + *subtype = bfd_mach_ppc; +diff -Nuar gdb-10.2/bfd/Makefile.am gdb-10.2/bfd/Makefile.am +--- gdb-10.2/bfd/Makefile.am 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/Makefile.am 2025-04-16 17:06:51.902086800 +0800 +@@ -92,6 +92,7 @@ + ALL_MACHINES = \ + cpu-aarch64.lo \ + cpu-alpha.lo \ ++ cpu-sw_64.lo \ + cpu-arc.lo \ + cpu-arm.lo \ + cpu-avr.lo \ +@@ -176,6 +177,7 @@ + ALL_MACHINES_CFILES = \ + cpu-aarch64.c \ + cpu-alpha.c \ ++ cpu-sw_64.c \ + cpu-arc.c \ + cpu-arm.c \ + cpu-avr.c \ +@@ -536,6 +538,7 @@ + aix5ppc-core.lo \ + aout64.lo \ + coff-alpha.lo \ ++ coff-sw_64.lo \ + coff-x86_64.lo \ + coff64-rs6000.lo \ + elf32-ia64.lo \ +@@ -543,6 +546,7 @@ + elf32-score.lo \ + elf32-score7.lo \ + elf64-alpha.lo \ ++ elf64-sw_64.lo \ + elf64-gen.lo \ + elf64-hppa.lo \ + elf64-ia64.lo \ +@@ -572,18 +576,21 @@ + pei-x86_64.lo \ + pepigen.lo \ + pex64igen.lo \ +- vms-alpha.lo ++ vms-alpha.lo \ ++ vms-sw_64.lo + + BFD64_BACKENDS_CFILES = \ + aix5ppc-core.c \ + aout64.c \ + coff-alpha.c \ ++ coff-sw_64.c \ + coff-x86_64.c \ + coff64-rs6000.c \ + elf32-mips.c \ + elf32-score.c \ + elf32-score7.c \ + elf64-alpha.c \ ++ elf64-sw_64.c \ + elf64-gen.c \ + elf64-hppa.c \ + elf64-ia64-vms.c \ +@@ -609,7 +616,8 @@ + pe-x86_64.c \ + pei-ia64.c \ + pei-x86_64.c \ +- vms-alpha.c ++ vms-alpha.c \ ++ vms-sw_64.c + + OPTIONAL_BACKENDS = \ + aix386-core.lo \ +diff -Nuar gdb-10.2/bfd/Makefile.in gdb-10.2/bfd/Makefile.in +--- gdb-10.2/bfd/Makefile.in 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/Makefile.in 2025-04-16 17:06:51.902086800 +0800 +@@ -517,6 +517,7 @@ + ALL_MACHINES = \ + cpu-aarch64.lo \ + cpu-alpha.lo \ ++ cpu-sw_64.lo \ + cpu-arc.lo \ + cpu-arm.lo \ + cpu-avr.lo \ +@@ -601,6 +602,7 @@ + ALL_MACHINES_CFILES = \ + cpu-aarch64.c \ + cpu-alpha.c \ ++ cpu-sw_64.c \ + cpu-arc.c \ + cpu-arm.c \ + cpu-avr.c \ +@@ -963,6 +965,7 @@ + aix5ppc-core.lo \ + aout64.lo \ + coff-alpha.lo \ ++ coff-sw_64.lo \ + coff-x86_64.lo \ + coff64-rs6000.lo \ + elf32-ia64.lo \ +@@ -970,6 +973,7 @@ + elf32-score.lo \ + elf32-score7.lo \ + elf64-alpha.lo \ ++ elf64-sw_64.lo \ + elf64-gen.lo \ + elf64-hppa.lo \ + elf64-ia64.lo \ +@@ -999,18 +1003,20 @@ + pei-x86_64.lo \ + pepigen.lo \ + pex64igen.lo \ +- vms-alpha.lo +- ++ vms-alpha.lo \ ++ vms-sw_64.lo + BFD64_BACKENDS_CFILES = \ + aix5ppc-core.c \ + aout64.c \ + coff-alpha.c \ ++ coff-sw_64.c \ + coff-x86_64.c \ + coff64-rs6000.c \ + elf32-mips.c \ + elf32-score.c \ + elf32-score7.c \ + elf64-alpha.c \ ++ elf64-sw_64.c \ + elf64-gen.c \ + elf64-hppa.c \ + elf64-ia64-vms.c \ +@@ -1036,8 +1042,8 @@ + pe-x86_64.c \ + pei-ia64.c \ + pei-x86_64.c \ +- vms-alpha.c +- ++ vms-alpha.c \ ++ vms-sw_64.c + OPTIONAL_BACKENDS = \ + aix386-core.lo \ + cisco-core.lo \ +@@ -1303,6 +1309,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-i386lynx.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cisco-core.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-alpha.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-sw_64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-bfd.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-go32.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-i386.Plo@am__quote@ +@@ -1323,6 +1330,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corefile.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-aarch64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-alpha.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-sw_64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arc.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arm.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-avr.Plo@am__quote@ +@@ -1487,6 +1495,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-aarch64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-alpha.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sw_64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-bpf.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-gen.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-hppa.Plo@am__quote@ +@@ -1574,6 +1583,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vaxnetbsd.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verilog.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-alpha.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-sw_64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-lib.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-misc.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wasm-module.Plo@am__quote@ +diff -Nuar gdb-10.2/bfd/makefile.vms gdb-10.2/bfd/makefile.vms +--- gdb-10.2/bfd/makefile.vms 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/makefile.vms 2025-04-16 17:06:51.922086800 +0800 +@@ -35,7 +35,11 @@ + OBJS:=vms-alpha.obj,vms-lib.obj,vms-misc.obj,cpu-alpha.obj + DEFS=SELECT_VECS="&alpha_vms_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch" + endif +- ++ifeq ($(ARCH),SW_64) ++HOSTFILE=sw_64vms.h ++OBJS:=vms-sw_64.obj,vms-lib.obj,vms-misc.obj,cpu-sw_64.obj ++DEFS=SELECT_VECS="&sw_64_vms_vec",SELECT_ARCHITECTURES="&bfd_sw_64_arch" ++endif + OBJS:=$(OBJS),archive.obj,archive64.obj,archures.obj,bfd.obj,bfdio.obj,\ + binary.obj,cache.obj,coffgen.obj,compress.obj,corefile.obj,dwarf2.obj,\ + elf.obj,format.obj,hash.obj,ihex.obj,init.obj,libbfd.obj,linker.obj,\ +diff -Nuar gdb-10.2/bfd/netbsd-core.c gdb-10.2/bfd/netbsd-core.c +--- gdb-10.2/bfd/netbsd-core.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/netbsd-core.c 2025-04-16 17:06:51.922086800 +0800 +@@ -180,7 +180,9 @@ + case M_ALPHA_NETBSD: + bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0); + break; +- ++ case M_SW_64_NETBSD: ++ bfd_default_set_arch_mach (abfd, bfd_arch_sw_64, 0); ++ break; + case M_ARM6_NETBSD: + bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3); + break; +diff -Nuar gdb-10.2/bfd/targets.c gdb-10.2/bfd/targets.c +--- gdb-10.2/bfd/targets.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/targets.c 2025-04-16 17:06:51.922086800 +0800 +@@ -673,6 +673,11 @@ + extern const bfd_target alpha_elf64_fbsd_vec; + extern const bfd_target alpha_vms_vec; + extern const bfd_target alpha_vms_lib_txt_vec; ++extern const bfd_target sw_64_ecoff_le_vec; ++extern const bfd_target sw_64_elf64_vec; ++extern const bfd_target sw_64_elf64_fbsd_vec; ++extern const bfd_target sw_64_vms_vec; ++extern const bfd_target sw_64_vms_lib_txt_vec; + extern const bfd_target am33_elf32_linux_vec; + extern const bfd_target aout_vec; + extern const bfd_target arc_elf32_be_vec; +@@ -986,9 +991,14 @@ + &alpha_elf64_vec, + &alpha_elf64_fbsd_vec, + &alpha_vms_vec, ++ ++ &sw_64_ecoff_le_vec, ++ &sw_64_elf64_vec, ++ &sw_64_elf64_fbsd_vec, ++ &sw_64_vms_vec, + #endif + &alpha_vms_lib_txt_vec, +- ++ &sw_64_vms_lib_txt_vec, + &am33_elf32_linux_vec, + + #if 0 +diff -Nuar gdb-10.2/bfd/vms-lib.c gdb-10.2/bfd/vms-lib.c +--- gdb-10.2/bfd/vms-lib.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/bfd/vms-lib.c 2025-04-16 17:06:51.922086800 +0800 +@@ -56,6 +56,7 @@ + { + vms_lib_vax, + vms_lib_alpha, ++ vms_lib_sw_64, + vms_lib_ia64, + vms_lib_txt + }; +@@ -533,6 +534,15 @@ + return NULL; + } + break; ++ case vms_lib_sw_64: ++ if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB) ++ || majorid != LBR_MAJORID ++ || lhd.nindex != 2) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return NULL; ++ } ++ break; + case vms_lib_ia64: + if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB) + || majorid != LBR_ELFMAJORID +@@ -710,7 +720,13 @@ + { + return _bfd_vms_lib_archive_p (abfd, vms_lib_alpha); + } ++/* Standard function for sw_64 libraries. */ + ++const bfd_target * ++_bfd_vms_lib_sw_64_archive_p (bfd *abfd) ++{ ++ return _bfd_vms_lib_archive_p (abfd, vms_lib_sw_64); ++} + /* Standard function for ia64 libraries. */ + + bfd_cleanup +@@ -749,6 +765,11 @@ + tdata->mhd_size = offsetof (struct vms_mhd, pad1); + tdata->type = LBR__C_TYP_EOBJ; + break; ++ case vms_lib_sw_64: ++ tdata->ver = LBR_MAJORID; ++ tdata->mhd_size = offsetof (struct vms_mhd, pad1); ++ tdata->type = LBR__C_TYP_EOBJ; ++ break; + case vms_lib_ia64: + tdata->ver = LBR_ELFMAJORID; + tdata->mhd_size = sizeof (struct vms_mhd); +@@ -774,6 +795,12 @@ + } + + bfd_boolean ++_bfd_vms_lib_sw_64_mkarchive (bfd *abfd) ++{ ++ return _bfd_vms_lib_mkarchive (abfd, vms_lib_sw_64); ++} ++ ++bfd_boolean + _bfd_vms_lib_ia64_mkarchive (bfd *abfd) + { + return _bfd_vms_lib_mkarchive (abfd, vms_lib_ia64); +@@ -2326,6 +2353,9 @@ + case vms_lib_alpha: + saneid = LHD_SANEID3; + break; ++ case vms_lib_sw_64: ++ saneid = LHD_SANEID3; ++ break; + case vms_lib_ia64: + saneid = LHD_SANEID6; + break; +@@ -2425,6 +2455,59 @@ + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error ++ }, ++ BFD_JUMP_TABLE_GENERIC (_bfd_generic), ++ BFD_JUMP_TABLE_COPY (_bfd_generic), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib), ++ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), ++ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), ++ BFD_JUMP_TABLE_WRITE (_bfd_nowrite), ++ BFD_JUMP_TABLE_LINK (_bfd_nolink), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ NULL ++}; ++/* Add sw_64 target for text library. This costs almost nothing and is useful to ++ read VMS library on the host. */ ++ ++const bfd_target sw_64_vms_lib_txt_vec = ++{ ++ "vms-libtxt", /* Name. */ ++ bfd_target_unknown_flavour, ++ BFD_ENDIAN_UNKNOWN, /* byteorder */ ++ BFD_ENDIAN_UNKNOWN, /* header_byteorder */ ++ 0, /* Object flags. */ ++ 0, /* Sect flags. */ ++ 0, /* symbol_leading_char. */ ++ ' ', /* ar_pad_char. */ ++ 15, /* ar_max_namelen. */ ++ 0, /* match priority. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, ++ { /* bfd_check_format. */ ++ _bfd_dummy_target, ++ _bfd_dummy_target, ++ _bfd_vms_lib_txt_archive_p, ++ _bfd_dummy_target ++ }, ++ { /* bfd_set_format. */ ++ _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error ++ }, ++ { /* bfd_write_contents. */ ++ _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error, ++ _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error + }, + BFD_JUMP_TABLE_GENERIC (_bfd_generic), +diff -Nuar gdb-10.2/bfd/vms-sw_64.c gdb-10.2/bfd/vms-sw_64.c +--- gdb-10.2/bfd/vms-sw_64.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/bfd/vms-sw_64.c 2025-04-16 17:06:51.922086800 +0800 +@@ -0,0 +1,9625 @@ ++/* vms.c -- BFD back-end for EVAX (openVMS/Sw_64) files. ++ Copyright (C) 1996-2018 Free Software Foundation, Inc. ++ ++ Initial version written by Klaus Kaempf (kkaempf@rmi.de) ++ Major rewrite by Adacore. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/* TODO: ++ o overlayed sections ++ o PIC ++ o Generation of shared image ++ o Relocation optimizations ++ o EISD for the stack ++ o Vectors isect ++ o 64 bits sections ++ o Entry point ++ o LIB$INITIALIZE ++ o protected sections (for messages) ++ ... ++*/ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdlink.h" ++#include "libbfd.h" ++#include "bfdver.h" ++ ++#include "vms.h" ++#include "vms/eihd.h" ++#include "vms/eiha.h" ++#include "vms/eihi.h" ++#include "vms/eihs.h" ++#include "vms/eisd.h" ++#include "vms/dmt.h" ++#include "vms/dst.h" ++#include "vms/eihvn.h" ++#include "vms/eobjrec.h" ++#include "vms/egsd.h" ++#include "vms/egps.h" ++#include "vms/esgps.h" ++#include "vms/eeom.h" ++#include "vms/emh.h" ++#include "vms/eiaf.h" ++#include "vms/shl.h" ++#include "vms/eicp.h" ++#include "vms/etir.h" ++#include "vms/egsy.h" ++#include "vms/esdf.h" ++#include "vms/esdfm.h" ++#include "vms/esdfv.h" ++#include "vms/esrf.h" ++#include "vms/egst.h" ++#include "vms/eidc.h" ++#include "vms/dsc.h" ++#include "vms/prt.h" ++#include "vms/internal.h" ++ ++ ++#define MIN(a,b) ((a) < (b) ? (a) : (b)) ++ ++/* The r_type field in a reloc is one of the following values. */ ++#define SW_64_R_IGNORE 0 ++#define SW_64_R_REFQUAD 1 ++#define SW_64_R_BRADDR 2 ++#define SW_64_R_HINT 3 ++#define SW_64_R_SREL16 4 ++#define SW_64_R_SREL32 5 ++#define SW_64_R_SREL64 6 ++#define SW_64_R_OP_PUSH 7 ++#define SW_64_R_OP_STORE 8 ++#define SW_64_R_OP_PSUB 9 ++#define SW_64_R_OP_PRSHIFT 10 ++#define SW_64_R_LINKAGE 11 ++#define SW_64_R_REFLONG 12 ++#define SW_64_R_CODEADDR 13 ++#define SW_64_R_NOP 14 ++#define SW_64_R_BSR 15 ++#define SW_64_R_LDA 16 ++#define SW_64_R_BOH 17 ++ ++/* These are used with DST_S_C_LINE_NUM. */ ++#define DST_S_C_LINE_NUM_HEADER_SIZE 4 ++ ++/* These are used with DST_S_C_SOURCE */ ++ ++#define DST_S_B_PCLINE_UNSBYTE 1 ++#define DST_S_W_PCLINE_UNSWORD 1 ++#define DST_S_L_PCLINE_UNSLONG 1 ++ ++#define DST_S_B_MODBEG_NAME 14 ++#define DST_S_L_RTNBEG_ADDRESS 5 ++#define DST_S_B_RTNBEG_NAME 13 ++#define DST_S_L_RTNEND_SIZE 5 ++ ++/* These are used with DST_S_C_SOURCE. */ ++#define DST_S_C_SOURCE_HEADER_SIZE 4 ++ ++#define DST_S_B_SRC_DF_LENGTH 1 ++#define DST_S_W_SRC_DF_FILEID 3 ++#define DST_S_B_SRC_DF_FILENAME 20 ++#define DST_S_B_SRC_UNSBYTE 1 ++#define DST_S_W_SRC_UNSWORD 1 ++#define DST_S_L_SRC_UNSLONG 1 ++ ++/* Debugger symbol definitions. */ ++ ++#define DBG_S_L_DMT_MODBEG 0 ++#define DBG_S_L_DST_SIZE 4 ++#define DBG_S_W_DMT_PSECT_COUNT 8 ++#define DBG_S_C_DMT_HEADER_SIZE 12 ++ ++#define DBG_S_L_DMT_PSECT_START 0 ++#define DBG_S_L_DMT_PSECT_LENGTH 4 ++#define DBG_S_C_DMT_PSECT_SIZE 8 ++ ++/* VMS module header. */ ++ ++struct hdr_struct ++{ ++ char hdr_b_strlvl; ++ int hdr_l_arch1; ++ int hdr_l_arch2; ++ int hdr_l_recsiz; ++ char *hdr_t_name; ++ char *hdr_t_version; ++ char *hdr_t_date; ++ char *hdr_c_lnm; ++ char *hdr_c_src; ++ char *hdr_c_ttl; ++}; ++ ++#define EMH_DATE_LENGTH 17 ++ ++/* VMS End-Of-Module records (EOM/EEOM). */ ++ ++struct eom_struct ++{ ++ unsigned int eom_l_total_lps; ++ unsigned short eom_w_comcod; ++ bfd_boolean eom_has_transfer; ++ unsigned char eom_b_tfrflg; ++ unsigned int eom_l_psindx; ++ unsigned int eom_l_tfradr; ++}; ++ ++struct vms_symbol_entry ++{ ++ bfd *owner; ++ ++ /* Common fields. */ ++ unsigned char typ; ++ unsigned char data_type; ++ unsigned short flags; ++ ++ /* Section and offset/value of the symbol. */ ++ unsigned int value; ++ asection *section; ++ ++ /* Section and offset/value for the entry point (only for subprg). */ ++ asection *code_section; ++ unsigned int code_value; ++ ++ /* Symbol vector offset. */ ++ unsigned int symbol_vector; ++ ++ /* Length of the name. */ ++ unsigned char namelen; ++ ++ char name[1]; ++}; ++ ++/* Stack value for push/pop commands. */ ++ ++struct stack_struct ++{ ++ bfd_vma value; ++ unsigned int reloc; ++}; ++ ++#define STACKSIZE 128 ++ ++/* A minimal decoding of DST compilation units. We only decode ++ what's needed to get to the line number information. */ ++ ++struct fileinfo ++{ ++ char *name; ++ unsigned int srec; ++}; ++ ++struct srecinfo ++{ ++ struct srecinfo *next; ++ unsigned int line; ++ unsigned int sfile; ++ unsigned int srec; ++}; ++ ++struct lineinfo ++{ ++ struct lineinfo *next; ++ bfd_vma address; ++ unsigned int line; ++}; ++ ++struct funcinfo ++{ ++ struct funcinfo *next; ++ char *name; ++ bfd_vma low; ++ bfd_vma high; ++}; ++ ++struct module ++{ ++ /* Chain the previously read compilation unit. */ ++ struct module *next; ++ ++ /* The module name. */ ++ char *name; ++ ++ /* The start offset and size of debug info in the DST section. */ ++ unsigned int modbeg; ++ unsigned int size; ++ ++ /* The lowest and highest addresses contained in this compilation ++ unit as specified in the compilation unit header. */ ++ bfd_vma low; ++ bfd_vma high; ++ ++ /* The listing line table. */ ++ struct lineinfo *line_table; ++ ++ /* The source record table. */ ++ struct srecinfo *srec_table; ++ ++ /* A list of the functions found in this module. */ ++ struct funcinfo *func_table; ++ ++ /* Current allocation of file_table. */ ++ unsigned int file_table_count; ++ ++ /* An array of the files making up this module. */ ++ struct fileinfo *file_table; ++}; ++ ++/* BFD private data for sw_64-vms. */ ++ ++struct vms_private_data_struct ++{ ++ /* If true, relocs have been read. */ ++ bfd_boolean reloc_done; ++ ++ /* Record input buffer. */ ++ struct vms_rec_rd recrd; ++ struct vms_rec_wr recwr; ++ ++ struct hdr_struct hdr_data; /* data from HDR/EMH record */ ++ struct eom_struct eom_data; /* data from EOM/EEOM record */ ++ ++ /* Transfer addresses (entry points). */ ++ bfd_vma transfer_address[4]; ++ ++ /* Array of GSD sections to get the correspond BFD one. */ ++ unsigned int section_max; /* Size of the sections array. */ ++ unsigned int section_count; /* Number of GSD sections. */ ++ asection **sections; ++ ++ /* Array of raw symbols. */ ++ struct vms_symbol_entry **syms; ++ ++ /* Canonicalized symbols. */ ++ asymbol **csymbols; ++ ++ /* Number of symbols. */ ++ unsigned int gsd_sym_count; ++ /* Size of the syms array. */ ++ unsigned int max_sym_count; ++ /* Number of procedure symbols. */ ++ unsigned int norm_sym_count; ++ ++ /* Stack used to evaluate TIR/ETIR commands. */ ++ struct stack_struct *stack; ++ int stackptr; ++ ++ /* Content reading. */ ++ asection *image_section; /* section for image_ptr */ ++ file_ptr image_offset; /* Offset for image_ptr. */ ++ ++ struct module *modules; /* list of all compilation units */ ++ ++ /* The DST section. */ ++ asection *dst_section; ++ ++ unsigned int dst_ptr_offsets_count; /* # of offsets in following array */ ++ unsigned int *dst_ptr_offsets; /* array of saved image_ptr offsets */ ++ ++ /* Shared library support */ ++ bfd_vma symvva; /* relative virtual address of symbol vector */ ++ unsigned int ident; ++ unsigned char matchctl; ++ ++ /* Shared library index. This is used for input bfd while linking. */ ++ unsigned int shr_index; ++ ++ /* Used to place structures in the file. */ ++ file_ptr file_pos; ++ ++ /* Simply linked list of eisd. */ ++ struct vms_internal_eisd_map *eisd_head; ++ struct vms_internal_eisd_map *eisd_tail; ++ ++ /* Simply linked list of eisd for shared libraries. */ ++ struct vms_internal_eisd_map *gbl_eisd_head; ++ struct vms_internal_eisd_map *gbl_eisd_tail; ++ ++ /* linkage index counter used by conditional store commands */ ++ unsigned int vms_linkage_index; ++}; ++ ++#define PRIV2(abfd, name) \ ++ (((struct vms_private_data_struct *)(abfd)->tdata.any)->name) ++#define PRIV(name) PRIV2(abfd,name) ++ ++ ++/* Used to keep extra VMS specific information for a given section. ++ ++ reloc_size holds the size of the relocation stream, note this ++ is very different from the number of relocations as VMS relocations ++ are variable length. ++ ++ reloc_stream is the actual stream of relocation entries. */ ++ ++struct vms_section_data_struct ++{ ++ /* Maximnum number of entries in sec->relocation. */ ++ unsigned reloc_max; ++ ++ /* Corresponding eisd. Used only while generating executables. */ ++ struct vms_internal_eisd_map *eisd; ++ ++ /* PSC flags to be clear. */ ++ flagword no_flags; ++ ++ /* PSC flags to be set. */ ++ flagword flags; ++}; ++ ++#define vms_section_data(sec) \ ++ ((struct vms_section_data_struct *)sec->used_by_bfd) ++ ++/* To be called from the debugger. */ ++struct vms_private_data_struct *bfd_vms_get_data (bfd *); ++ ++static int vms_get_remaining_object_record (bfd *, unsigned int); ++static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd); ++static void sw_64_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *); ++static void sw_64_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *); ++static void sw_64_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *, ++ bfd_vma); ++static void sw_64_vms_add_fixup_lr (struct bfd_link_info *, unsigned int, ++ bfd_vma); ++static void sw_64_vms_add_lw_reloc (struct bfd_link_info *); ++static void sw_64_vms_add_qw_reloc (struct bfd_link_info *); ++ ++struct vector_type ++{ ++ unsigned int max_el; ++ unsigned int nbr_el; ++ void *els; ++}; ++ ++/* Number of elements in VEC. */ ++ ++#define VEC_COUNT(VEC) ((VEC).nbr_el) ++ ++/* Get the address of the Nth element. */ ++ ++#define VEC_EL(VEC, TYPE, N) (((TYPE *)((VEC).els))[N]) ++ ++#define VEC_INIT(VEC) \ ++ do { \ ++ (VEC).max_el = 0; \ ++ (VEC).nbr_el = 0; \ ++ (VEC).els = NULL; \ ++ } while (0) ++ ++/* Be sure there is room for a new element. */ ++ ++static void vector_grow1 (struct vector_type *vec, size_t elsz); ++ ++/* Allocate room for a new element and return its address. */ ++ ++#define VEC_APPEND(VEC, TYPE) \ ++ (vector_grow1 (&VEC, sizeof (TYPE)), &VEC_EL(VEC, TYPE, (VEC).nbr_el++)) ++ ++/* Append an element. */ ++ ++#define VEC_APPEND_EL(VEC, TYPE, EL) \ ++ (*(VEC_APPEND (VEC, TYPE)) = EL) ++ ++struct sw_64_vms_vma_ref ++{ ++ bfd_vma vma; /* Vma in the output. */ ++ bfd_vma ref; /* Reference in the input. */ ++}; ++ ++struct sw_64_vms_shlib_el ++{ ++ bfd *abfd; ++ bfd_boolean has_fixups; ++ ++ struct vector_type lp; /* Vector of bfd_vma. */ ++ struct vector_type ca; /* Vector of bfd_vma. */ ++ struct vector_type qr; /* Vector of struct sw_64_vms_vma_ref. */ ++}; ++ ++/* Sw_64 VMS linker hash table. */ ++ ++struct sw_64_vms_link_hash_table ++{ ++ struct bfd_link_hash_table root; ++ ++ /* Vector of shared libraries. */ ++ struct vector_type shrlibs; ++ ++ /* Fixup section. */ ++ asection *fixup; ++ ++ /* Base address. Used by fixups. */ ++ bfd_vma base_addr; ++}; ++ ++#define sw_64_vms_link_hash(INFO) \ ++ ((struct sw_64_vms_link_hash_table *)(INFO->hash)) ++ ++/* Sw_64 VMS linker hash table entry. */ ++ ++struct sw_64_vms_link_hash_entry ++{ ++ struct bfd_link_hash_entry root; ++ ++ /* Pointer to the original vms symbol. */ ++ struct vms_symbol_entry *sym; ++}; ++ ++/* Image reading. */ ++ ++/* Read & process EIHD record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset, ++ unsigned int *eihs_offset) ++{ ++ unsigned int imgtype, size; ++ bfd_vma symvva; ++ struct vms_eihd *eihd = (struct vms_eihd *)PRIV (recrd.rec); ++ ++ vms_debug2 ((8, "_bfd_vms_slurp_eihd\n")); ++ ++ /* PR 21813: Check for an undersized record. */ ++ if (PRIV (recrd.buf_size) < sizeof (* eihd)) ++ { ++ _bfd_error_handler (_("corrupt EIHD record - size is too small")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ size = bfd_getl32 (eihd->size); ++ imgtype = bfd_getl32 (eihd->imgtype); ++ ++ if (imgtype == EIHD__K_EXE || imgtype == EIHD__K_LIM) ++ abfd->flags |= EXEC_P; ++ ++ symvva = bfd_getl64 (eihd->symvva); ++ if (symvva != 0) ++ { ++ PRIV (symvva) = symvva; ++ abfd->flags |= DYNAMIC; ++ } ++ ++ PRIV (ident) = bfd_getl32 (eihd->ident); ++ PRIV (matchctl) = eihd->matchctl; ++ ++ *eisd_offset = bfd_getl32 (eihd->isdoff); ++ *eihs_offset = bfd_getl32 (eihd->symdbgoff); ++ ++ vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n", ++ size, imgtype, (unsigned long)symvva, ++ *eisd_offset, *eihs_offset)); ++ ++ return TRUE; ++} ++ ++/* Read & process EISD record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) ++{ ++ int section_count = 0; ++ ++ vms_debug2 ((8, "_bfd_vms_slurp_eisd\n")); ++ ++ while (1) ++ { ++ struct vms_eisd *eisd; ++ unsigned int rec_size; ++ unsigned int size; ++ bfd_uint64_t vaddr; ++ unsigned int flags; ++ unsigned int vbn; ++ char *name = NULL; ++ asection *section; ++ flagword bfd_flags; ++ ++ /* PR 17512: file: 3d9e9fe9. ++ 12 is the offset of the eisdsize field from the start of the record (8) ++ plus the size of the eisdsize field (4). */ ++ if (offset >= PRIV (recrd.rec_size) - 12) ++ return FALSE; ++ eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset); ++ rec_size = bfd_getl32 (eisd->eisdsize); ++ if (rec_size == 0) ++ break; ++ ++ /* Skip to next block if pad. */ ++ if (rec_size == 0xffffffff) ++ { ++ offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1); ++ continue; ++ } ++ ++ /* Make sure that there is enough data present in the record. */ ++ /* FIXME: Should we use sizeof (struct vms_eisd) rather than just 32 here ? */ ++ if (rec_size < 32) ++ return FALSE; ++ /* Make sure that the record is not too big either. */ ++ if (offset + rec_size >= PRIV (recrd.rec_size)) ++ return FALSE; ++ ++ offset += rec_size; ++ ++ size = bfd_getl32 (eisd->secsize); ++ vaddr = bfd_getl64 (eisd->virt_addr); ++ flags = bfd_getl32 (eisd->flags); ++ vbn = bfd_getl32 (eisd->vbn); ++ ++ vms_debug2 ((4, "EISD at 0x%x size 0x%x addr 0x%lx flags 0x%x blk %d\n", ++ offset, size, (unsigned long)vaddr, flags, vbn)); ++ ++ /* VMS combines psects from .obj files into isects in the .exe. This ++ process doesn't preserve enough information to reliably determine ++ what's in each section without examining the data. This is ++ especially true of DWARF debug sections. */ ++ bfd_flags = SEC_ALLOC; ++ if (vbn != 0) ++ bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD; ++ ++ if (flags & EISD__M_EXE) ++ bfd_flags |= SEC_CODE; ++ ++ if (flags & EISD__M_NONSHRADR) ++ bfd_flags |= SEC_DATA; ++ ++ if (!(flags & EISD__M_WRT)) ++ bfd_flags |= SEC_READONLY; ++ ++ if (flags & EISD__M_DZRO) ++ bfd_flags |= SEC_DATA; ++ ++ if (flags & EISD__M_FIXUPVEC) ++ bfd_flags |= SEC_DATA; ++ ++ if (flags & EISD__M_CRF) ++ bfd_flags |= SEC_DATA; ++ ++ if (flags & EISD__M_GBL) ++ { ++ if (rec_size < offsetof (struct vms_eisd, gblnam)) ++ return FALSE; ++ else if (rec_size < sizeof (struct vms_eisd)) ++ name = _bfd_vms_save_counted_string (eisd->gblnam, ++ rec_size - offsetof (struct vms_eisd, gblnam)); ++ else ++ name = _bfd_vms_save_counted_string (eisd->gblnam, EISD__K_GBLNAMLEN); ++ bfd_flags |= SEC_COFF_SHARED_LIBRARY; ++ bfd_flags &= ~(SEC_ALLOC | SEC_LOAD); ++ } ++ else if (flags & EISD__M_FIXUPVEC) ++ name = "$FIXUPVEC$"; ++ else if (eisd->type == EISD__K_USRSTACK) ++ name = "$STACK$"; ++ else ++ { ++ const char *pfx; ++ ++ name = (char*) bfd_alloc (abfd, 32); ++ if (flags & EISD__M_DZRO) ++ pfx = "BSS"; ++ else if (flags & EISD__M_EXE) ++ pfx = "CODE"; ++ else if (!(flags & EISD__M_WRT)) ++ pfx = "RO"; ++ else ++ pfx = "LOCAL"; ++ BFD_ASSERT (section_count < 999); ++ sprintf (name, "$%s_%03d$", pfx, section_count++); ++ } ++ ++ section = bfd_make_section (abfd, name); ++ ++ if (!section) ++ return FALSE; ++ ++ section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : 0; ++ section->size = size; ++ section->vma = vaddr; ++ ++ if (!bfd_set_section_flags (abfd, section, bfd_flags)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Read & process EIHS record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) ++{ ++ unsigned char *p = PRIV (recrd.rec) + offset; ++ unsigned int gstvbn; ++ unsigned int gstsize ATTRIBUTE_UNUSED; ++ unsigned int dstvbn; ++ unsigned int dstsize; ++ unsigned int dmtvbn; ++ unsigned int dmtbytes; ++ asection *section; ++ ++ /* PR 21611: Check that offset is valid. */ ++ if (offset > PRIV (recrd.rec_size) - (EIHS__L_DMTBYTES + 4)) ++ { ++ _bfd_error_handler (_("unable to read EIHS record at offset %#x"), ++ offset); ++ bfd_set_error (bfd_error_file_truncated); ++ return FALSE; ++ } ++ ++ gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN); ++ gstsize = bfd_getl32 (p + EIHS__L_GSTSIZE); ++ dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN); ++ dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE); ++ dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN); ++ dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES); ++ ++#if VMS_DEBUG ++ vms_debug (8, "_bfd_vms_slurp_ihs\n"); ++ vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n", ++ gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes); ++#endif ++ ++ if (dstvbn) ++ { ++ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING; ++ ++ section = bfd_make_section (abfd, "$DST$"); ++ if (!section) ++ return FALSE; ++ ++ section->size = dstsize; ++ section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1); ++ ++ if (!bfd_set_section_flags (abfd, section, bfd_flags)) ++ return FALSE; ++ ++ PRIV (dst_section) = section; ++ abfd->flags |= (HAS_DEBUG | HAS_LINENO); ++ } ++ ++ if (dmtvbn) ++ { ++ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING; ++ ++ section = bfd_make_section (abfd, "$DMT$"); ++ if (!section) ++ return FALSE; ++ ++ section->size = dmtbytes; ++ section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1); ++ ++ if (!bfd_set_section_flags (abfd, section, bfd_flags)) ++ return FALSE; ++ } ++ ++ if (gstvbn) ++ { ++ if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET)) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return FALSE; ++ } ++ ++ if (!_bfd_vms_slurp_object_records (abfd)) ++ return FALSE; ++ ++ abfd->flags |= HAS_SYMS; ++ } ++ ++ return TRUE; ++} ++ ++/* Object file reading. */ ++ ++/* Object file input functions. */ ++ ++/* Get next record from object file to vms_buf. ++ Set PRIV(buf_size) and return it ++ ++ This is a little tricky since it should be portable. ++ ++ The openVMS object file has 'variable length' which means that ++ read() returns data in chunks of (hopefully) correct and expected ++ size. The linker (and other tools on VMS) depend on that. Unix ++ doesn't know about 'formatted' files, so reading and writing such ++ an object file in a Unix environment is not trivial. ++ ++ With the tool 'file' (available on all VMS FTP sites), one ++ can view and change the attributes of a file. Changing from ++ 'variable length' to 'fixed length, 512 bytes' reveals the ++ record size at the first 2 bytes of every record. The same ++ may happen during the transfer of object files from VMS to Unix, ++ at least with UCX, the DEC implementation of TCP/IP. ++ ++ The VMS format repeats the size at bytes 2 & 3 of every record. ++ ++ On the first call (file_format == FF_UNKNOWN) we check if ++ the first and the third byte pair (!) of the record match. ++ If they do it's an object file in an Unix environment or with ++ wrong attributes (FF_FOREIGN), else we should be in a VMS ++ environment where read() returns the record size (FF_NATIVE). ++ ++ Reading is always done in 2 steps: ++ 1. first just the record header is read and the size extracted, ++ 2. then the read buffer is adjusted and the remaining bytes are ++ read in. ++ ++ All file I/O is done on even file positions. */ ++ ++#define VMS_OBJECT_ADJUSTMENT 2 ++ ++static void ++maybe_adjust_record_pointer_for_object (bfd *abfd) ++{ ++ /* Set the file format once for all on the first invocation. */ ++ if (PRIV (recrd.file_format) == FF_UNKNOWN) ++ { ++ if (PRIV (recrd.rec)[0] == PRIV (recrd.rec)[4] ++ && PRIV (recrd.rec)[1] == PRIV (recrd.rec)[5]) ++ PRIV (recrd.file_format) = FF_FOREIGN; ++ else ++ PRIV (recrd.file_format) = FF_NATIVE; ++ } ++ ++ /* The adjustment is needed only in an Unix environment. */ ++ if (PRIV (recrd.file_format) == FF_FOREIGN) ++ PRIV (recrd.rec) += VMS_OBJECT_ADJUSTMENT; ++} ++ ++/* Implement step #1 of the object record reading procedure. ++ Return the record type or -1 on failure. */ ++ ++static int ++_bfd_vms_get_object_record (bfd *abfd) ++{ ++ unsigned int test_len = 6; ++ int type; ++ ++ vms_debug2 ((8, "_bfd_vms_get_obj_record\n")); ++ ++ /* Skip alignment byte if the current position is odd. */ ++ if (PRIV (recrd.file_format) == FF_FOREIGN && (bfd_tell (abfd) & 1)) ++ { ++ if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ } ++ ++ /* Read the record header */ ++ if (bfd_bread (PRIV (recrd.buf), test_len, abfd) != test_len) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ ++ /* Reset the record pointer. */ ++ PRIV (recrd.rec) = PRIV (recrd.buf); ++ maybe_adjust_record_pointer_for_object (abfd); ++ ++ if (vms_get_remaining_object_record (abfd, test_len) <= 0) ++ return -1; ++ ++ type = bfd_getl16 (PRIV (recrd.rec)); ++ ++ vms_debug2 ((8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n", ++ PRIV (recrd.rec), PRIV (recrd.rec_size), type)); ++ ++ return type; ++} ++ ++/* Implement step #2 of the object record reading procedure. ++ Return the size of the record or 0 on failure. */ ++ ++static int ++vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far) ++{ ++ unsigned int to_read; ++ ++ vms_debug2 ((8, "vms_get_remaining_obj_record\n")); ++ ++ /* Extract record size. */ ++ PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2); ++ ++ if (PRIV (recrd.rec_size) == 0) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return 0; ++ } ++ ++ /* That's what the linker manual says. */ ++ if (PRIV (recrd.rec_size) > EOBJ__C_MAXRECSIZ) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return 0; ++ } ++ ++ /* Take into account object adjustment. */ ++ to_read = PRIV (recrd.rec_size); ++ if (PRIV (recrd.file_format) == FF_FOREIGN) ++ to_read += VMS_OBJECT_ADJUSTMENT; ++ ++ /* Adjust the buffer. */ ++ if (to_read > PRIV (recrd.buf_size)) ++ { ++ PRIV (recrd.buf) ++ = (unsigned char *) bfd_realloc (PRIV (recrd.buf), to_read); ++ if (PRIV (recrd.buf) == NULL) ++ return 0; ++ PRIV (recrd.buf_size) = to_read; ++ } ++ /* PR 17512: file: 025-1974-0.004. */ ++ else if (to_read <= read_so_far) ++ return 0; ++ ++ /* Read the remaining record. */ ++ to_read -= read_so_far; ++ ++ vms_debug2 ((8, "vms_get_remaining_obj_record: to_read %d\n", to_read)); ++ ++ if (bfd_bread (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return 0; ++ } ++ ++ /* Reset the record pointer. */ ++ PRIV (recrd.rec) = PRIV (recrd.buf); ++ maybe_adjust_record_pointer_for_object (abfd); ++ ++ vms_debug2 ((8, "vms_get_remaining_obj_record: size %d\n", ++ PRIV (recrd.rec_size))); ++ ++ return PRIV (recrd.rec_size); ++} ++ ++/* Read and process emh record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_ehdr (bfd *abfd) ++{ ++ unsigned char *ptr; ++ unsigned char *vms_rec; ++ unsigned char *end; ++ int subtype; ++ ++ vms_rec = PRIV (recrd.rec); ++ /* PR 17512: file: 62736583. */ ++ end = PRIV (recrd.buf) + PRIV (recrd.buf_size); ++ ++ vms_debug2 ((2, "HDR/EMH\n")); ++ ++ subtype = bfd_getl16 (vms_rec + 4); ++ ++ vms_debug2 ((3, "subtype %d\n", subtype)); ++ ++ switch (subtype) ++ { ++ case EMH__C_MHD: ++ /* Module header. */ ++ if (vms_rec + 21 >= end) ++ goto fail; ++ PRIV (hdr_data).hdr_b_strlvl = vms_rec[6]; ++ PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8); ++ PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12); ++ PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16); ++ if ((vms_rec + 20 + vms_rec[20] + 1) >= end) ++ goto fail; ++ PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20, vms_rec[20]); ++ ptr = vms_rec + 20 + vms_rec[20] + 1; ++ if ((ptr + *ptr + 1) >= end) ++ goto fail; ++ PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr, *ptr); ++ ptr += *ptr + 1; ++ if (ptr + 17 >= end) ++ goto fail; ++ PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17); ++ break; ++ ++ case EMH__C_LNM: ++ if (vms_rec + PRIV (recrd.rec_size - 6) > end) ++ goto fail; ++ PRIV (hdr_data).hdr_c_lnm = ++ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); ++ break; ++ ++ case EMH__C_SRC: ++ if (vms_rec + PRIV (recrd.rec_size - 6) > end) ++ goto fail; ++ PRIV (hdr_data).hdr_c_src = ++ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); ++ break; ++ ++ case EMH__C_TTL: ++ if (vms_rec + PRIV (recrd.rec_size - 6) > end) ++ goto fail; ++ PRIV (hdr_data).hdr_c_ttl = ++ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); ++ break; ++ ++ case EMH__C_CPR: ++ case EMH__C_MTC: ++ case EMH__C_GTX: ++ break; ++ ++ default: ++ fail: ++ bfd_set_error (bfd_error_wrong_format); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Typical sections for evax object files. */ ++ ++#define EVAX_ABS_NAME "$ABS$" ++#define EVAX_CODE_NAME "$CODE$" ++#define EVAX_LINK_NAME "$LINK$" ++#define EVAX_DATA_NAME "$DATA$" ++#define EVAX_BSS_NAME "$BSS$" ++#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$" ++#define EVAX_READONLY_NAME "$READONLY$" ++#define EVAX_LITERAL_NAME "$LITERAL$" ++#define EVAX_LITERALS_NAME "$LITERALS" ++#define EVAX_COMMON_NAME "$COMMON$" ++#define EVAX_LOCAL_NAME "$LOCAL$" ++ ++struct sec_flags_struct ++{ ++ const char *name; /* Name of section. */ ++ int vflags_always; ++ flagword flags_always; /* Flags we set always. */ ++ int vflags_hassize; ++ flagword flags_hassize; /* Flags we set if the section has a size > 0. */ ++}; ++ ++/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Sw_64) compatible. */ ++ ++static const struct sec_flags_struct evax_section_flags[] = ++ { ++ { EVAX_ABS_NAME, ++ EGPS__V_SHR, ++ 0, ++ EGPS__V_SHR, ++ 0 }, ++ { EVAX_CODE_NAME, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE, ++ SEC_CODE | SEC_READONLY, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE, ++ SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_LITERAL_NAME, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD, ++ SEC_DATA | SEC_READONLY, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_LINK_NAME, ++ EGPS__V_REL | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY, ++ EGPS__V_REL | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_DATA_NAME, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, ++ SEC_DATA, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, ++ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_BSS_NAME, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, ++ SEC_NO_FLAGS, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, ++ SEC_ALLOC }, ++ { EVAX_READONLYADDR_NAME, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_READONLY_NAME, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD, ++ SEC_DATA | SEC_READONLY, ++ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD, ++ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_LOCAL_NAME, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, ++ SEC_DATA, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, ++ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { EVAX_LITERALS_NAME, ++ EGPS__V_PIC | EGPS__V_OVR, ++ SEC_DATA | SEC_READONLY, ++ EGPS__V_PIC | EGPS__V_OVR, ++ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, ++ { NULL, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, ++ SEC_DATA, ++ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, ++ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD } ++ }; ++ ++/* Retrieve BFD section flags by name and size. */ ++ ++static flagword ++vms_secflag_by_name (const struct sec_flags_struct *section_flags, ++ const char *name, ++ int hassize) ++{ ++ int i = 0; ++ ++ while (section_flags[i].name != NULL) ++ { ++ if (strcmp (name, section_flags[i].name) == 0) ++ { ++ if (hassize) ++ return section_flags[i].flags_hassize; ++ else ++ return section_flags[i].flags_always; ++ } ++ i++; ++ } ++ if (hassize) ++ return section_flags[i].flags_hassize; ++ return section_flags[i].flags_always; ++} ++ ++/* Retrieve VMS section flags by name and size. */ ++ ++static flagword ++vms_esecflag_by_name (const struct sec_flags_struct *section_flags, ++ const char *name, ++ int hassize) ++{ ++ int i = 0; ++ ++ while (section_flags[i].name != NULL) ++ { ++ if (strcmp (name, section_flags[i].name) == 0) ++ { ++ if (hassize) ++ return section_flags[i].vflags_hassize; ++ else ++ return section_flags[i].vflags_always; ++ } ++ i++; ++ } ++ if (hassize) ++ return section_flags[i].vflags_hassize; ++ return section_flags[i].vflags_always; ++} ++ ++/* Add SYM to the symbol table of ABFD. ++ Return FALSE in case of error. */ ++ ++static bfd_boolean ++add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym) ++{ ++ if (PRIV (gsd_sym_count) >= PRIV (max_sym_count)) ++ { ++ if (PRIV (max_sym_count) == 0) ++ { ++ PRIV (max_sym_count) = 128; ++ PRIV (syms) = bfd_malloc ++ (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)); ++ } ++ else ++ { ++ PRIV (max_sym_count) *= 2; ++ PRIV (syms) = bfd_realloc ++ (PRIV (syms), ++ (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *))); ++ } ++ if (PRIV (syms) == NULL) ++ return FALSE; ++ } ++ ++ PRIV (syms)[PRIV (gsd_sym_count)++] = sym; ++ return TRUE; ++} ++ ++/* Create a symbol whose name is ASCIC and add it to ABFD. ++ Return NULL in case of error. */ ++ ++static struct vms_symbol_entry * ++add_symbol (bfd *abfd, const unsigned char *ascic) ++{ ++ struct vms_symbol_entry *entry; ++ int len; ++ ++ len = *ascic++; ++ entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len); ++ if (entry == NULL) ++ return NULL; ++ entry->namelen = len; ++ memcpy (entry->name, ascic, len); ++ entry->name[len] = 0; ++ entry->owner = abfd; ++ ++ if (!add_symbol_entry (abfd, entry)) ++ return NULL; ++ return entry; ++} ++ ++/* Read and process EGSD. Return FALSE on failure. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_egsd (bfd *abfd) ++{ ++ int gsd_type; ++ unsigned int gsd_size; ++ unsigned char *vms_rec; ++ unsigned long base_addr; ++ ++ vms_debug2 ((2, "EGSD\n")); ++ ++ if (PRIV (recrd.rec_size) < 8) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: its size (%#x) is too small"), ++ PRIV (recrd.rec_size)); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ PRIV (recrd.rec) += 8; /* Skip type, size, align pad. */ ++ PRIV (recrd.rec_size) -= 8; ++ ++ /* Calculate base address for each section. */ ++ base_addr = 0L; ++ ++ while (PRIV (recrd.rec_size) > 4) ++ { ++ vms_rec = PRIV (recrd.rec); ++ ++ gsd_type = bfd_getl16 (vms_rec); ++ gsd_size = bfd_getl16 (vms_rec + 2); ++ ++ vms_debug2 ((3, "egsd_type %d\n", gsd_type)); ++ ++ /* PR 21615: Check for size overflow. */ ++ if (PRIV (recrd.rec_size) < gsd_size) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: size (%#x) is larger than remaining space (%#x)"), ++ gsd_size, PRIV (recrd.rec_size)); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ if (gsd_size < 4) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: size (%#x) is too small"), ++ gsd_size); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ switch (gsd_type) ++ { ++ case EGSD__C_PSC: ++ /* Program section definition. */ ++ { ++ struct vms_egps *egps = (struct vms_egps *)vms_rec; ++ flagword new_flags, vms_flags; ++ asection *section; ++ ++ vms_flags = bfd_getl16 (egps->flags); ++ ++ if ((vms_flags & EGPS__V_REL) == 0) ++ { ++ /* Use the global absolute section for all ++ absolute sections. */ ++ section = bfd_abs_section_ptr; ++ } ++ else ++ { ++ char *name; ++ unsigned long align_addr; ++ ++ name = _bfd_vms_save_counted_string (&egps->namlng, gsd_size - 4); ++ ++ section = bfd_make_section (abfd, name); ++ if (!section) ++ return FALSE; ++ ++ section->filepos = 0; ++ section->size = bfd_getl32 (egps->alloc); ++ section->alignment_power = egps->align; ++ ++ vms_section_data (section)->flags = vms_flags; ++ vms_section_data (section)->no_flags = 0; ++ ++ new_flags = vms_secflag_by_name (evax_section_flags, name, ++ section->size > 0); ++ if (section->size > 0) ++ new_flags |= SEC_LOAD; ++ if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0) ++ { ++ /* Set RELOC and HAS_CONTENTS if the section is not ++ demand-zero and not empty. */ ++ new_flags |= SEC_HAS_CONTENTS; ++ if (vms_flags & EGPS__V_REL) ++ new_flags |= SEC_RELOC; ++ } ++ if (vms_flags & EGPS__V_EXE) ++ { ++ /* Set CODE if section is executable. */ ++ new_flags |= SEC_CODE; ++ new_flags &= ~SEC_DATA; ++ } ++ if (!bfd_set_section_flags (abfd, section, new_flags)) ++ return FALSE; ++ ++ /* Give a non-overlapping vma to non absolute sections. */ ++ align_addr = (1 << section->alignment_power); ++ if ((base_addr % align_addr) != 0) ++ base_addr += (align_addr - (base_addr % align_addr)); ++ section->vma = (bfd_vma)base_addr; ++ base_addr += section->size; ++ } ++ ++ /* Append it to the section array. */ ++ if (PRIV (section_count) >= PRIV (section_max)) ++ { ++ if (PRIV (section_max) == 0) ++ PRIV (section_max) = 16; ++ else ++ PRIV (section_max) *= 2; ++ PRIV (sections) = bfd_realloc_or_free ++ (PRIV (sections), PRIV (section_max) * sizeof (asection *)); ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ } ++ ++ PRIV (sections)[PRIV (section_count)] = section; ++ PRIV (section_count)++; ++ } ++ break; ++ ++ case EGSD__C_SYM: ++ { ++ int nameoff; ++ struct vms_symbol_entry *entry; ++ struct vms_egsy *egsy = (struct vms_egsy *) vms_rec; ++ flagword old_flags; ++ ++ old_flags = bfd_getl16 (egsy->flags); ++ if (old_flags & EGSY__V_DEF) ++ nameoff = ESDF__B_NAMLNG; ++ else ++ nameoff = ESRF__B_NAMLNG; ++ ++ entry = add_symbol (abfd, vms_rec + nameoff); ++ if (entry == NULL) ++ return FALSE; ++ ++ /* Allow only duplicate reference. */ ++ if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF)) ++ abort (); ++ ++ if (entry->typ == 0) ++ { ++ entry->typ = gsd_type; ++ entry->data_type = egsy->datyp; ++ entry->flags = old_flags; ++ } ++ ++ if (old_flags & EGSY__V_DEF) ++ { ++ struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; ++ long psindx; ++ ++ entry->value = bfd_getl64 (esdf->value); ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ ++ psindx = bfd_getl32 (esdf->psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->section = PRIV (sections)[psindx]; ++ ++ if (old_flags & EGSY__V_NORM) ++ { ++ PRIV (norm_sym_count)++; ++ ++ entry->code_value = bfd_getl64 (esdf->code_address); ++ psindx = bfd_getl32 (esdf->ca_psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->code_section = PRIV (sections)[psindx]; ++ } ++ } ++ } ++ break; ++ ++ case EGSD__C_SYMG: ++ { ++ struct vms_symbol_entry *entry; ++ struct vms_egst *egst = (struct vms_egst *)vms_rec; ++ flagword old_flags; ++ ++ old_flags = bfd_getl16 (egst->header.flags); ++ ++ entry = add_symbol (abfd, &egst->namlng); ++ ++ if (entry == NULL) ++ return FALSE; ++ ++ entry->typ = gsd_type; ++ entry->data_type = egst->header.datyp; ++ entry->flags = old_flags; ++ ++ entry->symbol_vector = bfd_getl32 (egst->value); ++ ++ if (old_flags & EGSY__V_REL) ++ { ++ long psindx; ++ ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ psindx = bfd_getl32 (egst->psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->section = PRIV (sections)[psindx]; ++ } ++ else ++ entry->section = bfd_abs_section_ptr; ++ ++ entry->value = bfd_getl64 (egst->lp_2); ++ ++ if (old_flags & EGSY__V_NORM) ++ { ++ PRIV (norm_sym_count)++; ++ ++ entry->code_value = bfd_getl64 (egst->lp_1); ++ entry->code_section = bfd_abs_section_ptr; ++ } ++ } ++ break; ++ ++ case EGSD__C_SPSC: ++ case EGSD__C_IDC: ++ /* Currently ignored. */ ++ break; ++ case EGSD__C_SYMM: ++ case EGSD__C_SYMV: ++ default: ++ _bfd_error_handler (_("unknown EGSD subtype %d"), gsd_type); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ PRIV (recrd.rec_size) -= gsd_size; ++ PRIV (recrd.rec) += gsd_size; ++ } ++ ++ /* FIXME: Should we complain if PRIV (recrd.rec_size) is not zero ? */ ++ ++ if (PRIV (gsd_sym_count) > 0) ++ abfd->flags |= HAS_SYMS; ++ ++ return TRUE; ++} ++ ++/* Stack routines for vms ETIR commands. */ ++ ++/* Push value and section index. */ ++ ++static void ++_bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc) ++{ ++ vms_debug2 ((4, "\n", ++ (unsigned long)val, reloc, PRIV (stackptr))); ++ ++ PRIV (stack[PRIV (stackptr)]).value = val; ++ PRIV (stack[PRIV (stackptr)]).reloc = reloc; ++ PRIV (stackptr)++; ++ if (PRIV (stackptr) >= STACKSIZE) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ _bfd_error_handler (_("stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); ++ exit (1); ++ } ++} ++ ++/* Pop value and section index. */ ++ ++static void ++_bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel) ++{ ++ if (PRIV (stackptr) == 0) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ _bfd_error_handler (_("stack underflow in _bfd_vms_pop")); ++ exit (1); ++ } ++ PRIV (stackptr)--; ++ *val = PRIV (stack[PRIV (stackptr)]).value; ++ *rel = PRIV (stack[PRIV (stackptr)]).reloc; ++ ++ vms_debug2 ((4, "\n", (unsigned long)*val, *rel)); ++} ++ ++/* Routines to fill sections contents during tir/etir read. */ ++ ++/* Initialize image buffer pointer to be filled. */ ++ ++static void ++image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info) ++{ ++ asection *sec; ++ ++ vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect)); ++ ++ if (PRIV (sections) == NULL) ++ return; ++ if (sect < 0 || sect >= (int) PRIV (section_count)) ++ return; ++ ++ sec = PRIV (sections)[sect]; ++ ++ if (info) ++ { ++ /* Reading contents to an output bfd. */ ++ ++ if (sec->output_section == NULL) ++ { ++ /* Section discarded. */ ++ vms_debug2 ((5, " section %s discarded\n", sec->name)); ++ ++ /* This is not used. */ ++ PRIV (image_section) = NULL; ++ PRIV (image_offset) = 0; ++ return; ++ } ++ PRIV (image_offset) = sec->output_offset + vma; ++ PRIV (image_section) = sec->output_section; ++ } ++ else ++ { ++ PRIV (image_offset) = vma; ++ PRIV (image_section) = sec; ++ } ++} ++ ++/* Increment image buffer pointer by offset. */ ++ ++static void ++image_inc_ptr (bfd *abfd, bfd_vma offset) ++{ ++ vms_debug2 ((4, "image_inc_ptr (%u)\n", (unsigned)offset)); ++ ++ PRIV (image_offset) += offset; ++} ++ ++/* Save current DST location counter under specified index. */ ++ ++static void ++dst_define_location (bfd *abfd, unsigned int loc) ++{ ++ vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc)); ++ ++ /* Grow the ptr offset table if necessary. */ ++ if (loc + 1 > PRIV (dst_ptr_offsets_count)) ++ { ++ PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets), ++ (loc + 1) * sizeof (unsigned int)); ++ PRIV (dst_ptr_offsets_count) = loc + 1; ++ } ++ ++ PRIV (dst_ptr_offsets)[loc] = PRIV (image_offset); ++} ++ ++/* Restore saved DST location counter from specified index. */ ++ ++static void ++dst_restore_location (bfd *abfd, unsigned int loc) ++{ ++ vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc)); ++ ++ PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc]; ++} ++ ++/* Retrieve saved DST location counter from specified index. */ ++ ++static unsigned int ++dst_retrieve_location (bfd *abfd, unsigned int loc) ++{ ++ vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc)); ++ ++ return PRIV (dst_ptr_offsets)[loc]; ++} ++ ++/* Write multiple bytes to section image. */ ++ ++static bfd_boolean ++image_write (bfd *abfd, unsigned char *ptr, unsigned int size) ++{ ++#if VMS_DEBUG ++ _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size, ++ (long)PRIV (image_offset)); ++ _bfd_hexdump (9, ptr, size, 0); ++#endif ++ ++ if (PRIV (image_section)->contents != NULL) ++ { ++ asection *sec = PRIV (image_section); ++ file_ptr off = PRIV (image_offset); ++ ++ /* Check bounds. */ ++ if (off > (file_ptr)sec->size ++ || size > (file_ptr)sec->size ++ || off + size > (file_ptr)sec->size) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ memcpy (sec->contents + off, ptr, size); ++ } ++ ++ PRIV (image_offset) += size; ++ return TRUE; ++} ++ ++/* Write byte to section image. */ ++ ++static bfd_boolean ++image_write_b (bfd * abfd, unsigned int value) ++{ ++ unsigned char data[1]; ++ ++ vms_debug2 ((6, "image_write_b (%02x)\n", (int) value)); ++ ++ *data = value; ++ ++ return image_write (abfd, data, sizeof (data)); ++} ++ ++/* Write 2-byte word to image. */ ++ ++static bfd_boolean ++image_write_w (bfd * abfd, unsigned int value) ++{ ++ unsigned char data[2]; ++ ++ vms_debug2 ((6, "image_write_w (%04x)\n", (int) value)); ++ ++ bfd_putl16 (value, data); ++ return image_write (abfd, data, sizeof (data)); ++} ++ ++/* Write 4-byte long to image. */ ++ ++static bfd_boolean ++image_write_l (bfd * abfd, unsigned long value) ++{ ++ unsigned char data[4]; ++ ++ vms_debug2 ((6, "image_write_l (%08lx)\n", value)); ++ ++ bfd_putl32 (value, data); ++ return image_write (abfd, data, sizeof (data)); ++} ++ ++/* Write 8-byte quad to image. */ ++ ++static bfd_boolean ++image_write_q (bfd * abfd, bfd_vma value) ++{ ++ unsigned char data[8]; ++ ++ vms_debug2 ((6, "image_write_q (%08lx)\n", (unsigned long)value)); ++ ++ bfd_putl64 (value, data); ++ return image_write (abfd, data, sizeof (data)); ++} ++ ++static const char * ++_bfd_vms_etir_name (int cmd) ++{ ++ switch (cmd) ++ { ++ case ETIR__C_STA_GBL: return "ETIR__C_STA_GBL"; ++ case ETIR__C_STA_LW: return "ETIR__C_STA_LW"; ++ case ETIR__C_STA_QW: return "ETIR__C_STA_QW"; ++ case ETIR__C_STA_PQ: return "ETIR__C_STA_PQ"; ++ case ETIR__C_STA_LI: return "ETIR__C_STA_LI"; ++ case ETIR__C_STA_MOD: return "ETIR__C_STA_MOD"; ++ case ETIR__C_STA_CKARG: return "ETIR__C_STA_CKARG"; ++ case ETIR__C_STO_B: return "ETIR__C_STO_B"; ++ case ETIR__C_STO_W: return "ETIR__C_STO_W"; ++ case ETIR__C_STO_GBL: return "ETIR__C_STO_GBL"; ++ case ETIR__C_STO_CA: return "ETIR__C_STO_CA"; ++ case ETIR__C_STO_RB: return "ETIR__C_STO_RB"; ++ case ETIR__C_STO_AB: return "ETIR__C_STO_AB"; ++ case ETIR__C_STO_OFF: return "ETIR__C_STO_OFF"; ++ case ETIR__C_STO_IMM: return "ETIR__C_STO_IMM"; ++ case ETIR__C_STO_IMMR: return "ETIR__C_STO_IMMR"; ++ case ETIR__C_STO_LW: return "ETIR__C_STO_LW"; ++ case ETIR__C_STO_QW: return "ETIR__C_STO_QW"; ++ case ETIR__C_STO_GBL_LW: return "ETIR__C_STO_GBL_LW"; ++ case ETIR__C_STO_LP_PSB: return "ETIR__C_STO_LP_PSB"; ++ case ETIR__C_STO_HINT_GBL: return "ETIR__C_STO_HINT_GBL"; ++ case ETIR__C_STO_HINT_PS: return "ETIR__C_STO_HINT_PS"; ++ case ETIR__C_OPR_ADD: return "ETIR__C_OPR_ADD"; ++ case ETIR__C_OPR_SUB: return "ETIR__C_OPR_SUB"; ++ case ETIR__C_OPR_INSV: return "ETIR__C_OPR_INSV"; ++ case ETIR__C_OPR_USH: return "ETIR__C_OPR_USH"; ++ case ETIR__C_OPR_ROT: return "ETIR__C_OPR_ROT"; ++ case ETIR__C_OPR_REDEF: return "ETIR__C_OPR_REDEF"; ++ case ETIR__C_OPR_DFLIT: return "ETIR__C_OPR_DFLIT"; ++ case ETIR__C_STC_LP: return "ETIR__C_STC_LP"; ++ case ETIR__C_STC_GBL: return "ETIR__C_STC_GBL"; ++ case ETIR__C_STC_GCA: return "ETIR__C_STC_GCA"; ++ case ETIR__C_STC_PS: return "ETIR__C_STC_PS"; ++ case ETIR__C_STC_NBH_PS: return "ETIR__C_STC_NBH_PS"; ++ case ETIR__C_STC_NOP_GBL: return "ETIR__C_STC_NOP_GBL"; ++ case ETIR__C_STC_NOP_PS: return "ETIR__C_STC_NOP_PS"; ++ case ETIR__C_STC_BSR_GBL: return "ETIR__C_STC_BSR_GBL"; ++ case ETIR__C_STC_BSR_PS: return "ETIR__C_STC_BSR_PS"; ++ case ETIR__C_STC_LDA_GBL: return "ETIR__C_STC_LDA_GBL"; ++ case ETIR__C_STC_LDA_PS: return "ETIR__C_STC_LDA_PS"; ++ case ETIR__C_STC_BOH_GBL: return "ETIR__C_STC_BOH_GBL"; ++ case ETIR__C_STC_BOH_PS: return "ETIR__C_STC_BOH_PS"; ++ case ETIR__C_STC_NBH_GBL: return "ETIR__C_STC_NBH_GBL"; ++ case ETIR__C_STC_LP_PSB: return "ETIR__C_STC_LP_PSB"; ++ case ETIR__C_CTL_SETRB: return "ETIR__C_CTL_SETRB"; ++ case ETIR__C_CTL_AUGRB: return "ETIR__C_CTL_AUGRB"; ++ case ETIR__C_CTL_DFLOC: return "ETIR__C_CTL_DFLOC"; ++ case ETIR__C_CTL_STLOC: return "ETIR__C_CTL_STLOC"; ++ case ETIR__C_CTL_STKDL: return "ETIR__C_CTL_STKDL"; ++ ++ default: ++ /* These names have not yet been added to this switch statement. */ ++ _bfd_error_handler (_("unknown ETIR command %d"), cmd); ++ } ++ ++ return NULL; ++} ++#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L) ++ ++static void ++_bfd_vms_get_value (bfd *abfd, ++ const unsigned char *ascic, ++ const unsigned char *max_ascic, ++ struct bfd_link_info *info, ++ bfd_vma *vma, ++ struct sw_64_vms_link_hash_entry **hp) ++{ ++ char name[257]; ++ unsigned int len; ++ unsigned int i; ++ struct sw_64_vms_link_hash_entry *h; ++ ++ /* Not linking. Do not try to resolve the symbol. */ ++ if (info == NULL) ++ { ++ *vma = 0; ++ *hp = NULL; ++ return; ++ } ++ ++ len = *ascic; ++ if (ascic + len >= max_ascic) ++ { ++ _bfd_error_handler (_("corrupt vms value")); ++ *vma = 0; ++ *hp = NULL; ++ return; ++ } ++ ++ for (i = 0; i < len; i++) ++ name[i] = ascic[i + 1]; ++ name[i] = 0; ++ ++ h = (struct sw_64_vms_link_hash_entry *) ++ bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); ++ ++ *hp = h; ++ ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak)) ++ *vma = h->root.u.def.value ++ + h->root.u.def.section->output_offset ++ + h->root.u.def.section->output_section->vma; ++ else if (h && h->root.type == bfd_link_hash_undefweak) ++ *vma = 0; ++ else ++ { ++ (*info->callbacks->undefined_symbol) ++ (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE); ++ *vma = 0; ++ } ++} ++ ++#define RELC_NONE 0 ++#define RELC_REL 1 ++#define RELC_SHR_BASE 0x10000 ++#define RELC_SEC_BASE 0x20000 ++#define RELC_MASK 0x0ffff ++ ++static unsigned int ++sw_64_vms_sym_to_ctxt (struct sw_64_vms_link_hash_entry *h) ++{ ++ /* Handle undefined symbols. */ ++ if (h == NULL || h->sym == NULL) ++ return RELC_NONE; ++ ++ if (h->sym->typ == EGSD__C_SYMG) ++ { ++ if (h->sym->flags & EGSY__V_REL) ++ return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index); ++ else ++ { ++ /* Can this happen (non-relocatable symg) ? I'd like to see ++ an example. */ ++ abort (); ++ } ++ } ++ if (h->sym->typ == EGSD__C_SYM) ++ { ++ if (h->sym->flags & EGSY__V_REL) ++ return RELC_REL; ++ else ++ return RELC_NONE; ++ } ++ abort (); ++} ++ ++static bfd_vma ++sw_64_vms_get_sym_value (asection *sect, bfd_vma addr) ++{ ++ return sect->output_section->vma + sect->output_offset + addr; ++} ++ ++static bfd_vma ++sw_64_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info, ++ unsigned int rel, bfd_vma vma) ++{ ++ asection *sec; ++ ++ if (PRIV (sections) == NULL) ++ return 0; ++ ++ sec = PRIV (sections)[rel & RELC_MASK]; ++ ++ if (info) ++ { ++ if (sec->output_section == NULL) ++ abort (); ++ return vma + sec->output_section->vma + sec->output_offset; ++ } ++ else ++ return vma + sec->vma; ++} ++ ++/* Read an ETIR record from ABFD. If INFO is not null, put the content into ++ the output section (used during linking). ++ Return FALSE in case of error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) ++{ ++ unsigned char *ptr; ++ unsigned int length; ++ unsigned char *maxptr; ++ bfd_vma op1; ++ bfd_vma op2; ++ unsigned int rel1; ++ unsigned int rel2; ++ struct sw_64_vms_link_hash_entry *h; ++ ++ PRIV (recrd.rec) += ETIR__C_HEADER_SIZE; ++ PRIV (recrd.rec_size) -= ETIR__C_HEADER_SIZE; ++ ++ ptr = PRIV (recrd.rec); ++ length = PRIV (recrd.rec_size); ++ maxptr = ptr + length; ++ ++ vms_debug2 ((2, "ETIR: %d bytes\n", length)); ++ ++ while (ptr < maxptr) ++ { ++ int cmd = bfd_getl16 (ptr); ++ int cmd_length = bfd_getl16 (ptr + 2); ++ ++ ptr += 4; ++ ++ /* PR 21589 and 21579: Check for a corrupt ETIR record. */ ++ if (cmd_length < 4 || (ptr + cmd_length > maxptr + 4)) ++ { ++ corrupt_etir: ++ _bfd_error_handler (_("corrupt ETIR record encountered")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++#if VMS_DEBUG ++ _bfd_vms_debug (4, "etir: %s(%d)\n", ++ _bfd_vms_etir_name (cmd), cmd); ++ _bfd_hexdump (8, ptr, cmd_length - 4, 0); ++#endif ++ ++ switch (cmd) ++ { ++ /* Stack global ++ arg: cs symbol name ++ ++ stack 32 bit value of symbol (high bits set to 0). */ ++ case ETIR__C_STA_GBL: ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); ++ _bfd_vms_push (abfd, op1, sw_64_vms_sym_to_ctxt (h)); ++ break; ++ ++ /* Stack longword ++ arg: lw value ++ ++ stack 32 bit value, sign extend to 64 bit. */ ++ case ETIR__C_STA_LW: ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; ++ _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE); ++ break; ++ ++ /* Stack quadword ++ arg: qw value ++ ++ stack 64 bit value of symbol. */ ++ case ETIR__C_STA_QW: ++ if (ptr + 8 >= maxptr) ++ goto corrupt_etir; ++ _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE); ++ break; ++ ++ /* Stack psect base plus quadword offset ++ arg: lw section index ++ qw signed quadword offset (low 32 bits) ++ ++ Stack qw argument and section index ++ (see ETIR__C_STO_OFF, ETIR__C_CTL_SETRB). */ ++ case ETIR__C_STA_PQ: ++ { ++ int psect; ++ ++ if (ptr + 12 >= maxptr) ++ goto corrupt_etir; ++ psect = bfd_getl32 (ptr); ++ if ((unsigned int) psect >= PRIV (section_count)) ++ { ++ _bfd_error_handler (_("bad section index in %s"), ++ _bfd_vms_etir_name (cmd)); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ op1 = bfd_getl64 (ptr + 4); ++ _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE); ++ } ++ break; ++ ++ case ETIR__C_STA_LI: ++ case ETIR__C_STA_MOD: ++ case ETIR__C_STA_CKARG: ++ _bfd_error_handler (_("unsupported STA cmd %s"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ ++ /* Store byte: pop stack, write byte ++ arg: -. */ ++ case ETIR__C_STO_B: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ image_write_b (abfd, (unsigned int) op1 & 0xff); ++ break; ++ ++ /* Store word: pop stack, write word ++ arg: -. */ ++ case ETIR__C_STO_W: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ image_write_w (abfd, (unsigned int) op1 & 0xffff); ++ break; ++ ++ /* Store longword: pop stack, write longword ++ arg: -. */ ++ case ETIR__C_STO_LW: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 & RELC_SEC_BASE) ++ { ++ op1 = sw_64_vms_fix_sec_rel (abfd, info, rel1, op1); ++ rel1 = RELC_REL; ++ } ++ else if (rel1 & RELC_SHR_BASE) ++ { ++ sw_64_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1); ++ rel1 = RELC_NONE; ++ } ++ if (rel1 != RELC_NONE) ++ { ++ if (rel1 != RELC_REL) ++ abort (); ++ sw_64_vms_add_lw_reloc (info); ++ } ++ image_write_l (abfd, op1); ++ break; ++ ++ /* Store quadword: pop stack, write quadword ++ arg: -. */ ++ case ETIR__C_STO_QW: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 & RELC_SEC_BASE) ++ { ++ op1 = sw_64_vms_fix_sec_rel (abfd, info, rel1, op1); ++ rel1 = RELC_REL; ++ } ++ else if (rel1 & RELC_SHR_BASE) ++ abort (); ++ if (rel1 != RELC_NONE) ++ { ++ if (rel1 != RELC_REL) ++ abort (); ++ sw_64_vms_add_qw_reloc (info); ++ } ++ image_write_q (abfd, op1); ++ break; ++ ++ /* Store immediate repeated: pop stack for repeat count ++ arg: lw byte count ++ da data. */ ++ case ETIR__C_STO_IMMR: ++ { ++ int size; ++ ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; ++ size = bfd_getl32 (ptr); ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ while (op1-- > 0) ++ image_write (abfd, ptr + 4, size); ++ } ++ break; ++ ++ /* Store global: write symbol value ++ arg: cs global symbol name. */ ++ case ETIR__C_STO_GBL: ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); ++ if (h && h->sym) ++ { ++ if (h->sym->typ == EGSD__C_SYMG) ++ { ++ sw_64_vms_add_fixup_qr ++ (info, abfd, h->sym->owner, h->sym->symbol_vector); ++ op1 = 0; ++ } ++ else ++ { ++ op1 = sw_64_vms_get_sym_value (h->sym->section, ++ h->sym->value); ++ sw_64_vms_add_qw_reloc (info); ++ } ++ } ++ image_write_q (abfd, op1); ++ break; ++ ++ /* Store code address: write address of entry point ++ arg: cs global symbol name (procedure). */ ++ case ETIR__C_STO_CA: ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); ++ if (h && h->sym) ++ { ++ if (h->sym->flags & EGSY__V_NORM) ++ { ++ /* That's really a procedure. */ ++ if (h->sym->typ == EGSD__C_SYMG) ++ { ++ sw_64_vms_add_fixup_ca (info, abfd, h->sym->owner); ++ op1 = h->sym->symbol_vector; ++ } ++ else ++ { ++ op1 = sw_64_vms_get_sym_value (h->sym->code_section, ++ h->sym->code_value); ++ sw_64_vms_add_qw_reloc (info); ++ } ++ } ++ else ++ { ++ /* Symbol is not a procedure. */ ++ abort (); ++ } ++ } ++ image_write_q (abfd, op1); ++ break; ++ ++ /* Store offset to psect: pop stack, add low 32 bits to base of psect ++ arg: none. */ ++ case ETIR__C_STO_OFF: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ ++ if (!(rel1 & RELC_SEC_BASE)) ++ abort (); ++ ++ op1 = sw_64_vms_fix_sec_rel (abfd, info, rel1, op1); ++ rel1 = RELC_REL; ++ image_write_q (abfd, op1); ++ break; ++ ++ /* Store immediate ++ arg: lw count of bytes ++ da data. */ ++ case ETIR__C_STO_IMM: ++ { ++ unsigned int size; ++ ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; ++ size = bfd_getl32 (ptr); ++ image_write (abfd, ptr + 4, size); ++ } ++ break; ++ ++ /* This code is 'reserved to digital' according to the openVMS ++ linker manual, however it is generated by the DEC C compiler ++ and defined in the include file. ++ FIXME, since the following is just a guess ++ store global longword: store 32bit value of symbol ++ arg: cs symbol name. */ ++ case ETIR__C_STO_GBL_LW: ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); ++#if 0 ++ abort (); ++#endif ++ image_write_l (abfd, op1); ++ break; ++ ++ case ETIR__C_STO_RB: ++ case ETIR__C_STO_AB: ++ case ETIR__C_STO_LP_PSB: ++ _bfd_error_handler (_("%s: not supported"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ case ETIR__C_STO_HINT_GBL: ++ case ETIR__C_STO_HINT_PS: ++ _bfd_error_handler (_("%s: not implemented"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ ++ /* 200 Store-conditional Linkage Pair ++ arg: none. */ ++ case ETIR__C_STC_LP: ++ ++ /* 202 Store-conditional Address at global address ++ lw linkage index ++ cs global name. */ ++ ++ case ETIR__C_STC_GBL: ++ ++ /* 203 Store-conditional Code Address at global address ++ lw linkage index ++ cs procedure name. */ ++ case ETIR__C_STC_GCA: ++ ++ /* 204 Store-conditional Address at psect + offset ++ lw linkage index ++ lw psect index ++ qw offset. */ ++ case ETIR__C_STC_PS: ++ _bfd_error_handler (_("%s: not supported"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ ++ /* 201 Store-conditional Linkage Pair with Procedure Signature ++ lw linkage index ++ cs procedure name ++ by signature length ++ da signature. */ ++ ++ case ETIR__C_STC_LP_PSB: ++ _bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h); ++ if (h && h->sym) ++ { ++ if (h->sym->typ == EGSD__C_SYMG) ++ { ++ sw_64_vms_add_fixup_lp (info, abfd, h->sym->owner); ++ op1 = h->sym->symbol_vector; ++ op2 = 0; ++ } ++ else ++ { ++ op1 = sw_64_vms_get_sym_value (h->sym->code_section, ++ h->sym->code_value); ++ op2 = sw_64_vms_get_sym_value (h->sym->section, ++ h->sym->value); ++ } ++ } ++ else ++ { ++ /* Undefined symbol. */ ++ op1 = 0; ++ op2 = 0; ++ } ++ image_write_q (abfd, op1); ++ image_write_q (abfd, op2); ++ break; ++ ++ /* 205 Store-conditional NOP at address of global ++ arg: none. */ ++ case ETIR__C_STC_NOP_GBL: ++ /* SW_64_R_NOP */ ++ ++ /* 207 Store-conditional BSR at global address ++ arg: none. */ ++ ++ case ETIR__C_STC_BSR_GBL: ++ /* SW_64_R_BSR */ ++ ++ /* 209 Store-conditional LDA at global address ++ arg: none. */ ++ ++ case ETIR__C_STC_LDA_GBL: ++ /* SW_64_R_LDA */ ++ ++ /* 211 Store-conditional BSR or Hint at global address ++ arg: none. */ ++ ++ case ETIR__C_STC_BOH_GBL: ++ /* Currentl ignored. */ ++ break; ++ ++ /* 213 Store-conditional NOP,BSR or HINT at global address ++ arg: none. */ ++ ++ case ETIR__C_STC_NBH_GBL: ++ ++ /* 206 Store-conditional NOP at pect + offset ++ arg: none. */ ++ ++ case ETIR__C_STC_NOP_PS: ++ ++ /* 208 Store-conditional BSR at pect + offset ++ arg: none. */ ++ ++ case ETIR__C_STC_BSR_PS: ++ ++ /* 210 Store-conditional LDA at psect + offset ++ arg: none. */ ++ ++ case ETIR__C_STC_LDA_PS: ++ ++ /* 212 Store-conditional BSR or Hint at pect + offset ++ arg: none. */ ++ ++ case ETIR__C_STC_BOH_PS: ++ ++ /* 214 Store-conditional NOP, BSR or HINT at psect + offset ++ arg: none. */ ++ case ETIR__C_STC_NBH_PS: ++ _bfd_error_handler (_("%s: not supported"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ ++ /* Det relocation base: pop stack, set image location counter ++ arg: none. */ ++ case ETIR__C_CTL_SETRB: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (!(rel1 & RELC_SEC_BASE)) ++ abort (); ++ image_set_ptr (abfd, op1, rel1 & RELC_MASK, info); ++ break; ++ ++ /* Augment relocation base: increment image location counter by offset ++ arg: lw offset value. */ ++ case ETIR__C_CTL_AUGRB: ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; ++ op1 = bfd_getl32 (ptr); ++ image_inc_ptr (abfd, op1); ++ break; ++ ++ /* Define location: pop index, save location counter under index ++ arg: none. */ ++ case ETIR__C_CTL_DFLOC: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ dst_define_location (abfd, op1); ++ break; ++ ++ /* Set location: pop index, restore location counter from index ++ arg: none. */ ++ case ETIR__C_CTL_STLOC: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ dst_restore_location (abfd, op1); ++ break; ++ ++ /* Stack defined location: pop index, push location counter from index ++ arg: none. */ ++ case ETIR__C_CTL_STKDL: ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_NOP: /* No-op. */ ++ break; ++ ++ case ETIR__C_OPR_ADD: /* Add. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 == RELC_NONE && rel2 != RELC_NONE) ++ rel1 = rel2; ++ else if (rel1 != RELC_NONE && rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op1 + op2, rel1); ++ break; ++ ++ case ETIR__C_OPR_SUB: /* Subtract. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 == RELC_NONE && rel2 != RELC_NONE) ++ rel1 = rel2; ++ else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE)) ++ { ++ op1 = sw_64_vms_fix_sec_rel (abfd, info, rel1, op1); ++ op2 = sw_64_vms_fix_sec_rel (abfd, info, rel2, op2); ++ rel1 = RELC_NONE; ++ } ++ else if (rel1 != RELC_NONE && rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op2 - op1, rel1); ++ break; ++ ++ case ETIR__C_OPR_MUL: /* Multiply. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op1 * op2, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_DIV: /* Divide. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ goto bad_context; ++ if (op2 == 0) ++ _bfd_vms_push (abfd, 0, RELC_NONE); ++ else ++ _bfd_vms_push (abfd, op2 / op1, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_AND: /* Logical AND. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op1 & op2, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_IOR: /* Logical inclusive OR. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op1 | op2, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_EOR: /* Logical exclusive OR. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_NEG: /* Negate. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, -op1, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_COM: /* Complement. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (rel1 != RELC_NONE) ++ goto bad_context; ++ _bfd_vms_push (abfd, ~op1, RELC_NONE); ++ break; ++ ++ case ETIR__C_OPR_ASH: /* Arithmetic shift. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ if (rel1 != RELC_NONE || rel2 != RELC_NONE) ++ { ++ bad_context: ++ _bfd_error_handler (_("invalid use of %s with contexts"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ } ++ if ((int)op2 < 0) /* Shift right. */ ++ op1 >>= -(int)op2; ++ else /* Shift left. */ ++ op1 <<= (int)op2; ++ _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym. */ ++ break; ++ ++ case ETIR__C_OPR_INSV: /* Insert field. */ ++ case ETIR__C_OPR_USH: /* Unsigned shift. */ ++ case ETIR__C_OPR_ROT: /* Rotate. */ ++ case ETIR__C_OPR_REDEF: /* Redefine symbol to current location. */ ++ case ETIR__C_OPR_DFLIT: /* Define a literal. */ ++ _bfd_error_handler (_("%s: not supported"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ break; ++ ++ case ETIR__C_OPR_SEL: /* Select. */ ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ if (op1 & 0x01L) ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ else ++ { ++ _bfd_vms_pop (abfd, &op1, &rel1); ++ _bfd_vms_pop (abfd, &op2, &rel2); ++ _bfd_vms_push (abfd, op1, rel1); ++ } ++ break; ++ ++ default: ++ _bfd_error_handler (_("reserved cmd %d"), cmd); ++ return FALSE; ++ break; ++ } ++ ++ ptr += cmd_length - 4; ++ } ++ ++ return TRUE; ++} ++ ++/* Process EDBG/ETBT record. ++ Return TRUE on success, FALSE on error */ ++ ++static bfd_boolean ++vms_slurp_debug (bfd *abfd) ++{ ++ asection *section = PRIV (dst_section); ++ ++ if (section == NULL) ++ { ++ /* We have no way to find out beforehand how much debug info there ++ is in an object file, so pick an initial amount and grow it as ++ needed later. */ ++ flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC ++ | SEC_IN_MEMORY; ++ ++ section = bfd_make_section (abfd, "$DST$"); ++ if (!section) ++ return FALSE; ++ if (!bfd_set_section_flags (abfd, section, flags)) ++ return FALSE; ++ PRIV (dst_section) = section; ++ } ++ ++ PRIV (image_section) = section; ++ PRIV (image_offset) = section->size; ++ ++ if (!_bfd_vms_slurp_etir (abfd, NULL)) ++ return FALSE; ++ ++ section->size = PRIV (image_offset); ++ return TRUE; ++} ++ ++/* Process EDBG record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_edbg (bfd *abfd) ++{ ++ vms_debug2 ((2, "EDBG\n")); ++ ++ abfd->flags |= HAS_DEBUG | HAS_LINENO; ++ ++ return vms_slurp_debug (abfd); ++} ++ ++/* Process ETBT record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_etbt (bfd *abfd) ++{ ++ vms_debug2 ((2, "ETBT\n")); ++ ++ abfd->flags |= HAS_LINENO; ++ ++ return vms_slurp_debug (abfd); ++} ++ ++/* Process EEOM record. ++ Return TRUE on success, FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_eeom (bfd *abfd) ++{ ++ struct vms_eeom *eeom = (struct vms_eeom *) PRIV (recrd.rec); ++ ++ vms_debug2 ((2, "EEOM\n")); ++ ++ /* PR 21813: Check for an undersized record. */ ++ if (PRIV (recrd.buf_size) < sizeof (* eeom)) ++ { ++ _bfd_error_handler (_("corrupt EEOM record - size is too small")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps); ++ PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod); ++ if (PRIV (eom_data).eom_w_comcod > 1) ++ { ++ _bfd_error_handler (_("object module not error-free !")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ PRIV (eom_data).eom_has_transfer = FALSE; ++ if (PRIV (recrd.rec_size) > 10) ++ { ++ PRIV (eom_data).eom_has_transfer = TRUE; ++ PRIV (eom_data).eom_b_tfrflg = eeom->tfrflg; ++ PRIV (eom_data).eom_l_psindx = bfd_getl32 (eeom->psindx); ++ PRIV (eom_data).eom_l_tfradr = bfd_getl32 (eeom->tfradr); ++ ++ abfd->start_address = PRIV (eom_data).eom_l_tfradr; ++ } ++ return TRUE; ++} ++ ++/* Slurp an ordered set of VMS object records. Return FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_slurp_object_records (bfd * abfd) ++{ ++ bfd_boolean err; ++ int type; ++ ++ do ++ { ++ vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd))); ++ ++ type = _bfd_vms_get_object_record (abfd); ++ if (type < 0) ++ { ++ vms_debug2 ((2, "next_record failed\n")); ++ return FALSE; ++ } ++ ++ switch (type) ++ { ++ case EOBJ__C_EMH: ++ err = _bfd_vms_slurp_ehdr (abfd); ++ break; ++ case EOBJ__C_EEOM: ++ err = _bfd_vms_slurp_eeom (abfd); ++ break; ++ case EOBJ__C_EGSD: ++ err = _bfd_vms_slurp_egsd (abfd); ++ break; ++ case EOBJ__C_ETIR: ++ err = TRUE; /* _bfd_vms_slurp_etir (abfd); */ ++ break; ++ case EOBJ__C_EDBG: ++ err = _bfd_vms_slurp_edbg (abfd); ++ break; ++ case EOBJ__C_ETBT: ++ err = _bfd_vms_slurp_etbt (abfd); ++ break; ++ default: ++ err = FALSE; ++ } ++ if (!err) ++ { ++ vms_debug2 ((2, "slurp type %d failed\n", type)); ++ return FALSE; ++ } ++ } ++ while (type != EOBJ__C_EEOM); ++ ++ return TRUE; ++} ++ ++/* Initialize private data */ ++static bfd_boolean ++vms_initialize (bfd * abfd) ++{ ++ bfd_size_type amt; ++ ++ amt = sizeof (struct vms_private_data_struct); ++ abfd->tdata.any = bfd_zalloc (abfd, amt); ++ if (abfd->tdata.any == NULL) ++ return FALSE; ++ ++ PRIV (recrd.file_format) = FF_UNKNOWN; ++ ++ amt = sizeof (struct stack_struct) * STACKSIZE; ++ PRIV (stack) = bfd_alloc (abfd, amt); ++ if (PRIV (stack) == NULL) ++ goto error_ret1; ++ ++ return TRUE; ++ ++ error_ret1: ++ bfd_release (abfd, abfd->tdata.any); ++ abfd->tdata.any = NULL; ++ return FALSE; ++} ++ ++/* Check the format for a file being read. ++ Return a (bfd_target *) if it's an object file or zero if not. */ ++ ++static const struct bfd_target * ++sw_64_vms_object_p (bfd *abfd) ++{ ++ void *tdata_save = abfd->tdata.any; ++ unsigned int test_len; ++ unsigned char *buf; ++ ++ vms_debug2 ((1, "vms_object_p(%p)\n", abfd)); ++ ++ /* Allocate sw_64-vms specific data. */ ++ if (!vms_initialize (abfd)) ++ goto error_ret; ++ ++ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)) ++ goto err_wrong_format; ++ ++ /* The first challenge with VMS is to discover the kind of the file. ++ ++ Image files (executable or shared images) are stored as a raw ++ stream of bytes (like on UNIX), but there is no magic number. ++ ++ Object files are written with RMS (record management service), ie ++ each records are preceeded by its length (on a word - 2 bytes), and ++ padded for word-alignment. That would be simple but when files ++ are transfered to a UNIX filesystem (using ftp), records are lost. ++ Only the raw content of the records are transfered. Fortunately, ++ the Sw_64 Object file format also store the length of the record ++ in the records. Is that clear ? */ ++ ++ /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id, ++ 2 bytes size repeated) and 12 bytes for images (4 bytes major id, ++ 4 bytes minor id, 4 bytes length). */ ++ test_len = 12; ++ ++ /* Size the main buffer. */ ++ buf = (unsigned char *) bfd_malloc (test_len); ++ if (buf == NULL) ++ goto error_ret; ++ PRIV (recrd.buf) = buf; ++ PRIV (recrd.buf_size) = test_len; ++ ++ /* Initialize the record pointer. */ ++ PRIV (recrd.rec) = buf; ++ ++ if (bfd_bread (buf, test_len, abfd) != test_len) ++ goto err_wrong_format; ++ ++ /* Is it an image? */ ++ if ((bfd_getl32 (buf) == EIHD__K_MAJORID) ++ && (bfd_getl32 (buf + 4) == EIHD__K_MINORID)) ++ { ++ unsigned int to_read; ++ unsigned int read_so_far; ++ unsigned int remaining; ++ unsigned int eisd_offset, eihs_offset; ++ ++ /* Extract the header size. */ ++ PRIV (recrd.rec_size) = bfd_getl32 (buf + EIHD__L_SIZE); ++ ++ /* The header size is 0 for DSF files. */ ++ if (PRIV (recrd.rec_size) == 0) ++ PRIV (recrd.rec_size) = sizeof (struct vms_eihd); ++ ++ if (PRIV (recrd.rec_size) > PRIV (recrd.buf_size)) ++ { ++ buf = bfd_realloc_or_free (buf, PRIV (recrd.rec_size)); ++ ++ if (buf == NULL) ++ { ++ PRIV (recrd.buf) = NULL; ++ goto error_ret; ++ } ++ PRIV (recrd.buf) = buf; ++ PRIV (recrd.buf_size) = PRIV (recrd.rec_size); ++ } ++ ++ /* PR 21813: Check for a truncated record. */ ++ if (PRIV (recrd.rec_size < test_len)) ++ goto error_ret; ++ /* Read the remaining record. */ ++ remaining = PRIV (recrd.rec_size) - test_len; ++ to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining); ++ read_so_far = test_len; ++ ++ while (remaining > 0) ++ { ++ if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read) ++ goto err_wrong_format; ++ ++ read_so_far += to_read; ++ remaining -= to_read; ++ ++ to_read = MIN (VMS_BLOCK_SIZE, remaining); ++ } ++ ++ /* Reset the record pointer. */ ++ PRIV (recrd.rec) = buf; ++ ++ /* PR 17512: file: 7d7c57c2. */ ++ if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd)) ++ goto error_ret; ++ vms_debug2 ((2, "file type is image\n")); ++ ++ if (!_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset)) ++ goto err_wrong_format; ++ ++ if (!_bfd_vms_slurp_eisd (abfd, eisd_offset)) ++ goto err_wrong_format; ++ ++ /* EIHS is optional. */ ++ if (eihs_offset != 0 && !_bfd_vms_slurp_eihs (abfd, eihs_offset)) ++ goto err_wrong_format; ++ } ++ else ++ { ++ int type; ++ ++ /* Assume it's a module and adjust record pointer if necessary. */ ++ maybe_adjust_record_pointer_for_object (abfd); ++ ++ /* But is it really a module? */ ++ if (bfd_getl16 (PRIV (recrd.rec)) <= EOBJ__C_MAXRECTYP ++ && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ) ++ { ++ if (vms_get_remaining_object_record (abfd, test_len) <= 0) ++ goto err_wrong_format; ++ ++ vms_debug2 ((2, "file type is module\n")); ++ ++ type = bfd_getl16 (PRIV (recrd.rec)); ++ if (type != EOBJ__C_EMH || !_bfd_vms_slurp_ehdr (abfd)) ++ goto err_wrong_format; ++ ++ if (!_bfd_vms_slurp_object_records (abfd)) ++ goto err_wrong_format; ++ } ++ else ++ goto err_wrong_format; ++ } ++ ++ /* Set arch_info to sw_64. */ ++ ++ if (! bfd_default_set_arch_mach (abfd, bfd_arch_sw_64, 0)) ++ goto err_wrong_format; ++ ++ return abfd->xvec; ++ ++ err_wrong_format: ++ bfd_set_error (bfd_error_wrong_format); ++ ++ error_ret: ++ if (PRIV (recrd.buf)) ++ free (PRIV (recrd.buf)); ++ if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) ++ bfd_release (abfd, abfd->tdata.any); ++ abfd->tdata.any = tdata_save; ++ return NULL; ++} ++ ++/* Image write. */ ++ ++/* Write an EMH/MHD record. */ ++ ++static void ++_bfd_vms_write_emh (bfd *abfd) ++{ ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ _bfd_vms_output_alignment (recwr, 2); ++ ++ /* EMH. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); ++ _bfd_vms_output_short (recwr, EMH__C_MHD); ++ _bfd_vms_output_short (recwr, EOBJ__C_STRLVL); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE); ++ ++ /* Create module name from filename. */ ++ if (bfd_get_filename (abfd) != 0) ++ { ++ char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE); ++ _bfd_vms_output_counted (recwr, module); ++ free (module); ++ } ++ else ++ _bfd_vms_output_counted (recwr, "NONAME"); ++ ++ _bfd_vms_output_counted (recwr, BFD_VERSION_STRING); ++ _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH); ++ _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH); ++ _bfd_vms_output_end (abfd, recwr); ++} ++ ++/* Write an EMH/LMN record. */ ++ ++static void ++_bfd_vms_write_lmn (bfd *abfd, const char *name) ++{ ++ char version [64]; ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ unsigned int ver = BFD_VERSION / 10000; ++ ++ /* LMN. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); ++ _bfd_vms_output_short (recwr, EMH__C_LNM); ++ snprintf (version, sizeof (version), "%s %d.%d.%d", name, ++ ver / 10000, (ver / 100) % 100, ver % 100); ++ _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version)); ++ _bfd_vms_output_end (abfd, recwr); ++} ++ ++ ++/* Write eom record for bfd abfd. Return FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_write_eeom (bfd *abfd) ++{ ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ vms_debug2 ((2, "vms_write_eeom\n")); ++ ++ _bfd_vms_output_alignment (recwr, 2); ++ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EEOM); ++ _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1); ++ _bfd_vms_output_byte (recwr, 0); /* Completion code. */ ++ _bfd_vms_output_byte (recwr, 0); /* Fill byte. */ ++ ++ if ((abfd->flags & EXEC_P) == 0 ++ && bfd_get_start_address (abfd) != (bfd_vma)-1) ++ { ++ asection *section; ++ ++ section = bfd_get_section_by_name (abfd, ".link"); ++ if (section == 0) ++ { ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ return FALSE; ++ } ++ _bfd_vms_output_short (recwr, 0); ++ _bfd_vms_output_long (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_long (recwr, ++ (unsigned long) bfd_get_start_address (abfd)); ++ _bfd_vms_output_long (recwr, 0); ++ } ++ ++ _bfd_vms_output_end (abfd, recwr); ++ return TRUE; ++} ++ ++static void ++vector_grow1 (struct vector_type *vec, size_t elsz) ++{ ++ if (vec->nbr_el + 1 < vec->max_el) ++ return; ++ ++ if (vec->max_el == 0) ++ { ++ vec->max_el = 16; ++ vec->els = bfd_malloc2 (vec->max_el, elsz); ++ } ++ else ++ { ++ vec->max_el *= 2; ++ vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz); ++ } ++} ++ ++/* Bump ABFD file position to next block. */ ++ ++static void ++sw_64_vms_file_position_block (bfd *abfd) ++{ ++ /* Next block. */ ++ PRIV (file_pos) += VMS_BLOCK_SIZE - 1; ++ PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE); ++} ++ ++/* Convert from internal structure SRC to external structure DST. */ ++ ++static void ++sw_64_vms_swap_eisd_out (struct vms_internal_eisd_map *src, ++ struct vms_eisd *dst) ++{ ++ bfd_putl32 (src->u.eisd.majorid, dst->majorid); ++ bfd_putl32 (src->u.eisd.minorid, dst->minorid); ++ bfd_putl32 (src->u.eisd.eisdsize, dst->eisdsize); ++ if (src->u.eisd.eisdsize <= EISD__K_LENEND) ++ return; ++ bfd_putl32 (src->u.eisd.secsize, dst->secsize); ++ bfd_putl64 (src->u.eisd.virt_addr, dst->virt_addr); ++ bfd_putl32 (src->u.eisd.flags, dst->flags); ++ bfd_putl32 (src->u.eisd.vbn, dst->vbn); ++ dst->pfc = src->u.eisd.pfc; ++ dst->matchctl = src->u.eisd.matchctl; ++ dst->type = src->u.eisd.type; ++ dst->fill_1 = 0; ++ if (src->u.eisd.flags & EISD__M_GBL) ++ { ++ bfd_putl32 (src->u.gbl_eisd.ident, dst->ident); ++ memcpy (dst->gblnam, src->u.gbl_eisd.gblnam, ++ src->u.gbl_eisd.gblnam[0] + 1); ++ } ++} ++ ++/* Append EISD to the list of extra eisd for ABFD. */ ++ ++static void ++sw_64_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd) ++{ ++ eisd->next = NULL; ++ if (PRIV (gbl_eisd_head) == NULL) ++ PRIV (gbl_eisd_head) = eisd; ++ else ++ PRIV (gbl_eisd_tail)->next = eisd; ++ PRIV (gbl_eisd_tail) = eisd; ++} ++ ++/* Create an EISD for shared image SHRIMG. ++ Return FALSE in case of error. */ ++ ++static bfd_boolean ++sw_64_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg) ++{ ++ struct vms_internal_eisd_map *eisd; ++ int namlen; ++ ++ namlen = strlen (PRIV2 (shrimg, hdr_data.hdr_t_name)); ++ if (namlen + 5 > EISD__K_GBLNAMLEN) ++ { ++ /* Won't fit. */ ++ return FALSE; ++ } ++ ++ eisd = bfd_alloc (abfd, sizeof (*eisd)); ++ if (eisd == NULL) ++ return FALSE; ++ ++ /* Fill the fields. */ ++ eisd->u.gbl_eisd.common.majorid = EISD__K_MAJORID; ++ eisd->u.gbl_eisd.common.minorid = EISD__K_MINORID; ++ eisd->u.gbl_eisd.common.eisdsize = (EISD__K_LEN + 4 + namlen + 5 + 3) & ~3; ++ eisd->u.gbl_eisd.common.secsize = VMS_BLOCK_SIZE; /* Must not be 0. */ ++ eisd->u.gbl_eisd.common.virt_addr = 0; ++ eisd->u.gbl_eisd.common.flags = EISD__M_GBL; ++ eisd->u.gbl_eisd.common.vbn = 0; ++ eisd->u.gbl_eisd.common.pfc = 0; ++ eisd->u.gbl_eisd.common.matchctl = PRIV2 (shrimg, matchctl); ++ eisd->u.gbl_eisd.common.type = EISD__K_SHRPIC; ++ ++ eisd->u.gbl_eisd.ident = PRIV2 (shrimg, ident); ++ eisd->u.gbl_eisd.gblnam[0] = namlen + 4; ++ memcpy (eisd->u.gbl_eisd.gblnam + 1, PRIV2 (shrimg, hdr_data.hdr_t_name), ++ namlen); ++ memcpy (eisd->u.gbl_eisd.gblnam + 1 + namlen, "_001", 4); ++ ++ /* Append it to the list. */ ++ sw_64_vms_append_extra_eisd (abfd, eisd); ++ ++ return TRUE; ++} ++ ++/* Create an EISD for section SEC. ++ Return FALSE in case of failure. */ ++ ++static bfd_boolean ++sw_64_vms_create_eisd_for_section (bfd *abfd, asection *sec) ++{ ++ struct vms_internal_eisd_map *eisd; ++ ++ /* Only for allocating section. */ ++ if (!(sec->flags & SEC_ALLOC)) ++ return TRUE; ++ ++ BFD_ASSERT (vms_section_data (sec)->eisd == NULL); ++ eisd = bfd_alloc (abfd, sizeof (*eisd)); ++ if (eisd == NULL) ++ return FALSE; ++ vms_section_data (sec)->eisd = eisd; ++ ++ /* Fill the fields. */ ++ eisd->u.eisd.majorid = EISD__K_MAJORID; ++ eisd->u.eisd.minorid = EISD__K_MINORID; ++ eisd->u.eisd.eisdsize = EISD__K_LEN; ++ eisd->u.eisd.secsize = ++ (sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1); ++ eisd->u.eisd.virt_addr = sec->vma; ++ eisd->u.eisd.flags = 0; ++ eisd->u.eisd.vbn = 0; /* To be later defined. */ ++ eisd->u.eisd.pfc = 0; /* Default. */ ++ eisd->u.eisd.matchctl = EISD__K_MATALL; ++ eisd->u.eisd.type = EISD__K_NORMAL; ++ ++ if (sec->flags & SEC_CODE) ++ eisd->u.eisd.flags |= EISD__M_EXE; ++ if (!(sec->flags & SEC_READONLY)) ++ eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF; ++ ++ /* If relocations or fixup will be applied, make this isect writeable. */ ++ if (sec->flags & SEC_RELOC) ++ eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF; ++ ++ if (!(sec->flags & SEC_HAS_CONTENTS)) ++ { ++ eisd->u.eisd.flags |= EISD__M_DZRO; ++ eisd->u.eisd.flags &= ~EISD__M_CRF; ++ } ++ if (sec->flags & SEC_LINKER_CREATED) ++ { ++ if (strcmp (sec->name, "$FIXUP$") == 0) ++ eisd->u.eisd.flags |= EISD__M_FIXUPVEC; ++ } ++ ++ /* Append it to the list. */ ++ eisd->next = NULL; ++ if (PRIV (eisd_head) == NULL) ++ PRIV (eisd_head) = eisd; ++ else ++ PRIV (eisd_tail)->next = eisd; ++ PRIV (eisd_tail) = eisd; ++ ++ return TRUE; ++} ++ ++/* Layout executable ABFD and write it to the disk. ++ Return FALSE in case of failure. */ ++ ++static bfd_boolean ++sw_64_vms_write_exec (bfd *abfd) ++{ ++ struct vms_eihd eihd; ++ struct vms_eiha *eiha; ++ struct vms_eihi *eihi; ++ struct vms_eihs *eihs = NULL; ++ asection *sec; ++ struct vms_internal_eisd_map *first_eisd; ++ struct vms_internal_eisd_map *eisd; ++ asection *dst; ++ asection *dmt; ++ file_ptr gst_filepos = 0; ++ unsigned int lnkflags = 0; ++ ++ /* Build the EIHD. */ ++ PRIV (file_pos) = EIHD__C_LENGTH; ++ ++ memset (&eihd, 0, sizeof (eihd)); ++ memset (eihd.fill_2, 0xff, sizeof (eihd.fill_2)); ++ ++ bfd_putl32 (EIHD__K_MAJORID, eihd.majorid); ++ bfd_putl32 (EIHD__K_MINORID, eihd.minorid); ++ ++ bfd_putl32 (sizeof (eihd), eihd.size); ++ bfd_putl32 (0, eihd.isdoff); ++ bfd_putl32 (0, eihd.activoff); ++ bfd_putl32 (0, eihd.symdbgoff); ++ bfd_putl32 (0, eihd.imgidoff); ++ bfd_putl32 (0, eihd.patchoff); ++ bfd_putl64 (0, eihd.iafva); ++ bfd_putl32 (0, eihd.version_array_off); ++ ++ bfd_putl32 (EIHD__K_EXE, eihd.imgtype); ++ bfd_putl32 (0, eihd.subtype); ++ ++ bfd_putl32 (0, eihd.imgiocnt); ++ bfd_putl32 (-1, eihd.privreqs); ++ bfd_putl32 (-1, eihd.privreqs + 4); ++ ++ bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE, ++ eihd.hdrblkcnt); ++ bfd_putl32 (0, eihd.ident); ++ bfd_putl32 (0, eihd.sysver); ++ ++ eihd.matchctl = 0; ++ bfd_putl32 (0, eihd.symvect_size); ++ bfd_putl32 (16, eihd.virt_mem_block_size); ++ bfd_putl32 (0, eihd.ext_fixup_off); ++ bfd_putl32 (0, eihd.noopt_psect_off); ++ bfd_putl32 (-1, eihd.alias); ++ ++ /* Alloc EIHA. */ ++ eiha = (struct vms_eiha *)((char *) &eihd + PRIV (file_pos)); ++ bfd_putl32 (PRIV (file_pos), eihd.activoff); ++ PRIV (file_pos) += sizeof (struct vms_eiha); ++ ++ bfd_putl32 (sizeof (struct vms_eiha), eiha->size); ++ bfd_putl32 (0, eiha->spare); ++ bfd_putl64 (PRIV (transfer_address[0]), eiha->tfradr1); ++ bfd_putl64 (PRIV (transfer_address[1]), eiha->tfradr2); ++ bfd_putl64 (PRIV (transfer_address[2]), eiha->tfradr3); ++ bfd_putl64 (PRIV (transfer_address[3]), eiha->tfradr4); ++ bfd_putl64 (0, eiha->inishr); ++ ++ /* Alloc EIHI. */ ++ eihi = (struct vms_eihi *)((char *) &eihd + PRIV (file_pos)); ++ bfd_putl32 (PRIV (file_pos), eihd.imgidoff); ++ PRIV (file_pos) += sizeof (struct vms_eihi); ++ ++ bfd_putl32 (EIHI__K_MAJORID, eihi->majorid); ++ bfd_putl32 (EIHI__K_MINORID, eihi->minorid); ++ { ++ char *module; ++ unsigned int len; ++ ++ /* Set module name. */ ++ module = vms_get_module_name (bfd_get_filename (abfd), TRUE); ++ len = strlen (module); ++ if (len > sizeof (eihi->imgnam) - 1) ++ len = sizeof (eihi->imgnam) - 1; ++ eihi->imgnam[0] = len; ++ memcpy (eihi->imgnam + 1, module, len); ++ free (module); ++ } ++ { ++ unsigned int lo; ++ unsigned int hi; ++ ++ /* Set time. */ ++ vms_get_time (&hi, &lo); ++ bfd_putl32 (lo, eihi->linktime + 0); ++ bfd_putl32 (hi, eihi->linktime + 4); ++ } ++ eihi->imgid[0] = 0; ++ eihi->linkid[0] = 0; ++ eihi->imgbid[0] = 0; ++ ++ /* Alloc EIHS. */ ++ dst = PRIV (dst_section); ++ dmt = bfd_get_section_by_name (abfd, "$DMT$"); ++ if (dst != NULL && dst->size != 0) ++ { ++ eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos)); ++ bfd_putl32 (PRIV (file_pos), eihd.symdbgoff); ++ PRIV (file_pos) += sizeof (struct vms_eihs); ++ ++ bfd_putl32 (EIHS__K_MAJORID, eihs->majorid); ++ bfd_putl32 (EIHS__K_MINORID, eihs->minorid); ++ bfd_putl32 (0, eihs->dstvbn); ++ bfd_putl32 (0, eihs->dstsize); ++ bfd_putl32 (0, eihs->gstvbn); ++ bfd_putl32 (0, eihs->gstsize); ++ bfd_putl32 (0, eihs->dmtvbn); ++ bfd_putl32 (0, eihs->dmtsize); ++ } ++ ++ /* One EISD per section. */ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ if (!sw_64_vms_create_eisd_for_section (abfd, sec)) ++ return FALSE; ++ } ++ ++ /* Merge section EIDS which extra ones. */ ++ if (PRIV (eisd_tail)) ++ PRIV (eisd_tail)->next = PRIV (gbl_eisd_head); ++ else ++ PRIV (eisd_head) = PRIV (gbl_eisd_head); ++ if (PRIV (gbl_eisd_tail)) ++ PRIV (eisd_tail) = PRIV (gbl_eisd_tail); ++ ++ first_eisd = PRIV (eisd_head); ++ ++ /* Add end of eisd. */ ++ if (first_eisd) ++ { ++ eisd = bfd_zalloc (abfd, sizeof (*eisd)); ++ if (eisd == NULL) ++ return FALSE; ++ eisd->u.eisd.majorid = 0; ++ eisd->u.eisd.minorid = 0; ++ eisd->u.eisd.eisdsize = 0; ++ sw_64_vms_append_extra_eisd (abfd, eisd); ++ } ++ ++ /* Place EISD in the file. */ ++ for (eisd = first_eisd; eisd; eisd = eisd->next) ++ { ++ file_ptr room = VMS_BLOCK_SIZE - (PRIV (file_pos) % VMS_BLOCK_SIZE); ++ ++ /* First block is a little bit special: there is a word at the end. */ ++ if (PRIV (file_pos) < VMS_BLOCK_SIZE && room > 2) ++ room -= 2; ++ if (room < eisd->u.eisd.eisdsize + EISD__K_LENEND) ++ sw_64_vms_file_position_block (abfd); ++ ++ eisd->file_pos = PRIV (file_pos); ++ PRIV (file_pos) += eisd->u.eisd.eisdsize; ++ ++ if (eisd->u.eisd.flags & EISD__M_FIXUPVEC) ++ bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva); ++ } ++ ++ if (first_eisd != NULL) ++ { ++ bfd_putl32 (first_eisd->file_pos, eihd.isdoff); ++ /* Real size of end of eisd marker. */ ++ PRIV (file_pos) += EISD__K_LENEND; ++ } ++ ++ bfd_putl32 (PRIV (file_pos), eihd.size); ++ bfd_putl32 ((PRIV (file_pos) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE, ++ eihd.hdrblkcnt); ++ ++ /* Place sections. */ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ if (!(sec->flags & SEC_HAS_CONTENTS)) ++ continue; ++ ++ eisd = vms_section_data (sec)->eisd; ++ ++ /* Align on a block. */ ++ sw_64_vms_file_position_block (abfd); ++ sec->filepos = PRIV (file_pos); ++ ++ if (eisd != NULL) ++ eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1; ++ ++ PRIV (file_pos) += sec->size; ++ } ++ ++ /* Update EIHS. */ ++ if (eihs != NULL && dst != NULL) ++ { ++ bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn); ++ bfd_putl32 (dst->size, eihs->dstsize); ++ ++ if (dmt != NULL) ++ { ++ lnkflags |= EIHD__M_DBGDMT; ++ bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn); ++ bfd_putl32 (dmt->size, eihs->dmtsize); ++ } ++ if (PRIV (gsd_sym_count) != 0) ++ { ++ sw_64_vms_file_position_block (abfd); ++ gst_filepos = PRIV (file_pos); ++ bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn); ++ bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize); ++ } ++ } ++ ++ /* Write EISD in hdr. */ ++ for (eisd = first_eisd; eisd && eisd->file_pos < VMS_BLOCK_SIZE; ++ eisd = eisd->next) ++ sw_64_vms_swap_eisd_out ++ (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos)); ++ ++ /* Write first block. */ ++ bfd_putl32 (lnkflags, eihd.lnkflags); ++ if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd)) ++ return FALSE; ++ ++ /* Write remaining eisd. */ ++ if (eisd != NULL) ++ { ++ unsigned char blk[VMS_BLOCK_SIZE]; ++ struct vms_internal_eisd_map *next_eisd; ++ ++ memset (blk, 0xff, sizeof (blk)); ++ while (eisd != NULL) ++ { ++ sw_64_vms_swap_eisd_out ++ (eisd, ++ (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE))); ++ ++ next_eisd = eisd->next; ++ if (next_eisd == NULL ++ || (next_eisd->file_pos / VMS_BLOCK_SIZE ++ != eisd->file_pos / VMS_BLOCK_SIZE)) ++ { ++ if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk)) ++ return FALSE; ++ ++ memset (blk, 0xff, sizeof (blk)); ++ } ++ eisd = next_eisd; ++ } ++ } ++ ++ /* Write sections. */ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ unsigned char blk[VMS_BLOCK_SIZE]; ++ bfd_size_type len; ++ ++ if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS)) ++ continue; ++ if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size) ++ return FALSE; ++ ++ /* Pad. */ ++ len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE; ++ if (len != VMS_BLOCK_SIZE) ++ { ++ memset (blk, 0, len); ++ if (bfd_bwrite (blk, len, abfd) != len) ++ return FALSE; ++ } ++ } ++ ++ /* Write GST. */ ++ if (gst_filepos != 0) ++ { ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ unsigned int i; ++ ++ _bfd_vms_write_emh (abfd); ++ _bfd_vms_write_lmn (abfd, "GNU LD"); ++ ++ /* PSC for the absolute section. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); ++ _bfd_vms_output_short (recwr, 0); ++ _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_counted (recwr, ".$$ABS$$."); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_end (abfd, recwr); ++ ++ for (i = 0; i < PRIV (gsd_sym_count); i++) ++ { ++ struct vms_symbol_entry *sym = PRIV (syms)[i]; ++ bfd_vma val; ++ bfd_vma ep; ++ ++ if ((i % 5) == 0) ++ { ++ _bfd_vms_output_alignment (recwr, 8); ++ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); ++ _bfd_vms_output_long (recwr, 0); ++ } ++ _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG); ++ _bfd_vms_output_short (recwr, 0); /* Data type, alignment. */ ++ _bfd_vms_output_short (recwr, sym->flags); ++ ++ if (sym->code_section) ++ ep = sw_64_vms_get_sym_value (sym->code_section, sym->code_value); ++ else ++ { ++ BFD_ASSERT (sym->code_value == 0); ++ ep = 0; ++ } ++ val = sw_64_vms_get_sym_value (sym->section, sym->value); ++ _bfd_vms_output_quad ++ (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val); ++ _bfd_vms_output_quad (recwr, ep); ++ _bfd_vms_output_quad (recwr, val); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ if ((i % 5) == 4) ++ _bfd_vms_output_end (abfd, recwr); ++ } ++ if ((i % 5) != 0) ++ _bfd_vms_output_end (abfd, recwr); ++ ++ if (!_bfd_vms_write_eeom (abfd)) ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/* Object write. */ ++ ++/* Write section and symbol directory of bfd abfd. Return FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_write_egsd (bfd *abfd) ++{ ++ asection *section; ++ asymbol *symbol; ++ unsigned int symnum; ++ const char *sname; ++ flagword new_flags, old_flags; ++ int abs_section_index = -1; ++ unsigned int target_index = 0; ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ vms_debug2 ((2, "vms_write_egsd\n")); ++ ++ /* Egsd is quadword aligned. */ ++ _bfd_vms_output_alignment (recwr, 8); ++ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); ++ _bfd_vms_output_long (recwr, 0); ++ ++ /* Number sections. */ ++ for (section = abfd->sections; section != NULL; section = section->next) ++ { ++ if (section->flags & SEC_DEBUGGING) ++ continue; ++ if (!strcmp (section->name, ".vmsdebug")) ++ { ++ section->flags |= SEC_DEBUGGING; ++ continue; ++ } ++ section->target_index = target_index++; ++ } ++ ++ for (section = abfd->sections; section != NULL; section = section->next) ++ { ++ vms_debug2 ((3, "Section #%d %s, %d bytes\n", ++ section->target_index, section->name, (int)section->size)); ++ ++ /* Don't write out the VMS debug info section since it is in the ++ ETBT and EDBG sections in etir. */ ++ if (section->flags & SEC_DEBUGGING) ++ continue; ++ ++ /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */ ++ if (_bfd_vms_output_check (recwr, 64) < 0) ++ { ++ _bfd_vms_output_end (abfd, recwr); ++ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); ++ _bfd_vms_output_long (recwr, 0); ++ } ++ ++ /* Don't know if this is necessary for the linker but for now it keeps ++ vms_slurp_gsd happy. */ ++ sname = section->name; ++ if (*sname == '.') ++ { ++ /* Remove leading dot. */ ++ sname++; ++ if ((*sname == 't') && (strcmp (sname, "text") == 0)) ++ sname = EVAX_CODE_NAME; ++ else if ((*sname == 'd') && (strcmp (sname, "data") == 0)) ++ sname = EVAX_DATA_NAME; ++ else if ((*sname == 'b') && (strcmp (sname, "bss") == 0)) ++ sname = EVAX_BSS_NAME; ++ else if ((*sname == 'l') && (strcmp (sname, "link") == 0)) ++ sname = EVAX_LINK_NAME; ++ else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0)) ++ sname = EVAX_READONLY_NAME; ++ else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) ++ sname = EVAX_LITERAL_NAME; ++ else if ((*sname == 'l') && (strcmp (sname, "literals") == 0)) ++ sname = EVAX_LITERALS_NAME; ++ else if ((*sname == 'c') && (strcmp (sname, "comm") == 0)) ++ sname = EVAX_COMMON_NAME; ++ else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) ++ sname = EVAX_LOCAL_NAME; ++ } ++ ++ if (bfd_is_com_section (section)) ++ new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD ++ | EGPS__V_WRT | EGPS__V_NOMOD | EGPS__V_COM); ++ else ++ new_flags = vms_esecflag_by_name (evax_section_flags, sname, ++ section->size > 0); ++ ++ /* Modify them as directed. */ ++ if (section->flags & SEC_READONLY) ++ new_flags &= ~EGPS__V_WRT; ++ ++ new_flags &= ~vms_section_data (section)->no_flags; ++ new_flags |= vms_section_data (section)->flags; ++ ++ vms_debug2 ((3, "sec flags %x\n", section->flags)); ++ vms_debug2 ((3, "new_flags %x, _raw_size %lu\n", ++ new_flags, (unsigned long)section->size)); ++ ++ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); ++ _bfd_vms_output_short (recwr, section->alignment_power & 0xff); ++ _bfd_vms_output_short (recwr, new_flags); ++ _bfd_vms_output_long (recwr, (unsigned long) section->size); ++ _bfd_vms_output_counted (recwr, sname); ++ _bfd_vms_output_end_subrec (recwr); ++ ++ /* If the section is an obsolute one, remind its index as it will be ++ used later for absolute symbols. */ ++ if ((new_flags & EGPS__V_REL) == 0 && abs_section_index < 0) ++ abs_section_index = section->target_index; ++ } ++ ++ /* Output symbols. */ ++ vms_debug2 ((3, "%d symbols found\n", abfd->symcount)); ++ ++ bfd_set_start_address (abfd, (bfd_vma) -1); ++ ++ for (symnum = 0; symnum < abfd->symcount; symnum++) ++ { ++ symbol = abfd->outsymbols[symnum]; ++ old_flags = symbol->flags; ++ ++ /* Work-around a missing feature: consider __main as the main entry ++ point. */ ++ if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0) ++ bfd_set_start_address (abfd, (bfd_vma)symbol->value); ++ ++ /* Only put in the GSD the global and the undefined symbols. */ ++ if (old_flags & BSF_FILE) ++ continue; ++ ++ if ((old_flags & BSF_GLOBAL) == 0 && !bfd_is_und_section (symbol->section)) ++ { ++ /* If the LIB$INITIIALIZE section is present, add a reference to ++ LIB$INITIALIZE symbol. FIXME: this should be done explicitely ++ in the assembly file. */ ++ if (!((old_flags & BSF_SECTION_SYM) != 0 ++ && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0)) ++ continue; ++ } ++ ++ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. Add 16 more ++ bytes for a possible ABS section. */ ++ if (_bfd_vms_output_check (recwr, 80 + 16) < 0) ++ { ++ _bfd_vms_output_end (abfd, recwr); ++ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); ++ _bfd_vms_output_long (recwr, 0); ++ } ++ ++ if ((old_flags & BSF_GLOBAL) != 0 ++ && bfd_is_abs_section (symbol->section) ++ && abs_section_index <= 0) ++ { ++ /* Create an absolute section if none was defined. It is highly ++ unlikely that the name $ABS$ clashes with a user defined ++ non-absolute section name. */ ++ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); ++ _bfd_vms_output_short (recwr, 4); ++ _bfd_vms_output_short (recwr, EGPS__V_SHR); ++ _bfd_vms_output_long (recwr, 0); ++ _bfd_vms_output_counted (recwr, "$ABS$"); ++ _bfd_vms_output_end_subrec (recwr); ++ ++ abs_section_index = target_index++; ++ } ++ ++ _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM); ++ ++ /* Data type, alignment. */ ++ _bfd_vms_output_short (recwr, 0); ++ ++ new_flags = 0; ++ ++ if (old_flags & BSF_WEAK) ++ new_flags |= EGSY__V_WEAK; ++ if (bfd_is_com_section (symbol->section)) /* .comm */ ++ new_flags |= (EGSY__V_WEAK | EGSY__V_COMM); ++ ++ if (old_flags & BSF_FUNCTION) ++ { ++ new_flags |= EGSY__V_NORM; ++ new_flags |= EGSY__V_REL; ++ } ++ if (old_flags & BSF_GLOBAL) ++ { ++ new_flags |= EGSY__V_DEF; ++ if (!bfd_is_abs_section (symbol->section)) ++ new_flags |= EGSY__V_REL; ++ } ++ _bfd_vms_output_short (recwr, new_flags); ++ ++ if (old_flags & BSF_GLOBAL) ++ { ++ /* Symbol definition. */ ++ bfd_vma code_address = 0; ++ unsigned long ca_psindx = 0; ++ unsigned long psindx; ++ ++ if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL) ++ { ++ asymbol *sym; ++ ++ sym = ++ ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym; ++ code_address = sym->value; ++ ca_psindx = sym->section->target_index; ++ } ++ if (bfd_is_abs_section (symbol->section)) ++ psindx = abs_section_index; ++ else ++ psindx = symbol->section->target_index; ++ ++ _bfd_vms_output_quad (recwr, symbol->value); ++ _bfd_vms_output_quad (recwr, code_address); ++ _bfd_vms_output_long (recwr, ca_psindx); ++ _bfd_vms_output_long (recwr, psindx); ++ } ++ _bfd_vms_output_counted (recwr, symbol->name); ++ ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ ++ _bfd_vms_output_alignment (recwr, 8); ++ _bfd_vms_output_end (abfd, recwr); ++ ++ return TRUE; ++} ++ ++/* Write object header for bfd abfd. Return FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_write_ehdr (bfd *abfd) ++{ ++ asymbol *symbol; ++ unsigned int symnum; ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd)); ++ ++ _bfd_vms_output_alignment (recwr, 2); ++ ++ _bfd_vms_write_emh (abfd); ++ _bfd_vms_write_lmn (abfd, "GNU AS"); ++ ++ /* SRC. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); ++ _bfd_vms_output_short (recwr, EMH__C_SRC); ++ ++ for (symnum = 0; symnum < abfd->symcount; symnum++) ++ { ++ symbol = abfd->outsymbols[symnum]; ++ ++ if (symbol->flags & BSF_FILE) ++ { ++ _bfd_vms_output_dump (recwr, (unsigned char *) symbol->name, ++ (int) strlen (symbol->name)); ++ break; ++ } ++ } ++ ++ if (symnum == abfd->symcount) ++ _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname")); ++ ++ _bfd_vms_output_end (abfd, recwr); ++ ++ /* TTL. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); ++ _bfd_vms_output_short (recwr, EMH__C_TTL); ++ _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL")); ++ _bfd_vms_output_end (abfd, recwr); ++ ++ /* CPR. */ ++ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); ++ _bfd_vms_output_short (recwr, EMH__C_CPR); ++ _bfd_vms_output_dump (recwr, ++ (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996", ++ 39); ++ _bfd_vms_output_end (abfd, recwr); ++ ++ return TRUE; ++} ++ ++/* Part 4.6, relocations. */ ++ ++ ++/* WRITE ETIR SECTION ++ ++ This is still under construction and therefore not documented. */ ++ ++/* Close the etir/etbt record. */ ++ ++static void ++end_etir_record (bfd * abfd) ++{ ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ _bfd_vms_output_end (abfd, recwr); ++} ++ ++static void ++start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset) ++{ ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ if (section->flags & SEC_DEBUGGING) ++ { ++ _bfd_vms_output_begin (recwr, EOBJ__C_ETBT); ++ ++ if (offset == 0) ++ { ++ /* Push start offset. */ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW); ++ _bfd_vms_output_long (recwr, (unsigned long) 0); ++ _bfd_vms_output_end_subrec (recwr); ++ ++ /* Set location. */ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ } ++ else ++ { ++ _bfd_vms_output_begin (recwr, EOBJ__C_ETIR); ++ ++ if (offset == 0) ++ { ++ /* Push start offset. */ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); ++ _bfd_vms_output_long (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, offset); ++ _bfd_vms_output_end_subrec (recwr); ++ ++ /* Start = pop (). */ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ } ++} ++ ++/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual ++ address VADDR in section specified by SEC_INDEX and NAME. */ ++ ++static void ++sto_imm (bfd *abfd, asection *section, ++ bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr) ++{ ++ bfd_size_type size; ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++#if VMS_DEBUG ++ _bfd_vms_debug (8, "sto_imm %d bytes\n", (int) ssize); ++ _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr); ++#endif ++ ++ while (ssize > 0) ++ { ++ /* Try all the rest. */ ++ size = ssize; ++ ++ if (_bfd_vms_output_check (recwr, size) < 0) ++ { ++ /* Doesn't fit, split ! */ ++ end_etir_record (abfd); ++ ++ start_etir_or_etbt_record (abfd, section, vaddr); ++ ++ size = _bfd_vms_output_check (recwr, 0); /* get max size */ ++ if (size > ssize) /* more than what's left ? */ ++ size = ssize; ++ } ++ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_IMM); ++ _bfd_vms_output_long (recwr, (unsigned long) (size)); ++ _bfd_vms_output_dump (recwr, cptr, size); ++ _bfd_vms_output_end_subrec (recwr); ++ ++#if VMS_DEBUG ++ _bfd_vms_debug (10, "dumped %d bytes\n", (int) size); ++ _bfd_hexdump (10, cptr, (int) size, (int) vaddr); ++#endif ++ ++ vaddr += size; ++ cptr += size; ++ ssize -= size; ++ } ++} ++ ++static void ++etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen) ++{ ++ if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0) ++ { ++ /* Not enough room in this record. Close it and open a new one. */ ++ end_etir_record (abfd); ++ start_etir_or_etbt_record (abfd, section, vaddr); ++ } ++} ++ ++/* Return whether RELOC must be deferred till the end. */ ++ ++static bfd_boolean ++defer_reloc_p (arelent *reloc) ++{ ++ switch (reloc->howto->type) ++ { ++ case SW_64_R_NOP: ++ case SW_64_R_LDA: ++ case SW_64_R_BSR: ++ case SW_64_R_BOH: ++ return TRUE; ++ ++ default: ++ return FALSE; ++ } ++} ++ ++/* Write section contents for bfd abfd. Return FALSE on error. */ ++ ++static bfd_boolean ++_bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) ++{ ++ asection *section; ++ struct vms_rec_wr *recwr = &PRIV (recwr); ++ ++ vms_debug2 ((2, "vms_write_tir (%p, %d)\n", abfd, objtype)); ++ ++ _bfd_vms_output_alignment (recwr, 4); ++ ++ PRIV (vms_linkage_index) = 0; ++ ++ for (section = abfd->sections; section; section = section->next) ++ { ++ vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n", ++ section->target_index, section->name, (int) (section->size))); ++ ++ if (!(section->flags & SEC_HAS_CONTENTS) ++ || bfd_is_com_section (section)) ++ continue; ++ ++ if (!section->contents) ++ { ++ bfd_set_error (bfd_error_no_contents); ++ return FALSE; ++ } ++ ++ start_etir_or_etbt_record (abfd, section, 0); ++ ++ if (section->flags & SEC_RELOC) ++ { ++ bfd_vma curr_addr = 0; ++ unsigned char *curr_data = section->contents; ++ bfd_size_type size; ++ int pass2_needed = 0; ++ int pass2_in_progress = 0; ++ unsigned int irel; ++ ++ if (section->reloc_count == 0) ++ _bfd_error_handler ++ (_("SEC_RELOC with no relocs in section %pA"), section); ++ ++#if VMS_DEBUG ++ else ++ { ++ int i = section->reloc_count; ++ arelent **rptr = section->orelocation; ++ _bfd_vms_debug (4, "%d relocations:\n", i); ++ while (i-- > 0) ++ { ++ _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, " ++ "addr %08lx, off %08lx, len %d: %s\n", ++ (*(*rptr)->sym_ptr_ptr)->name, ++ (*(*rptr)->sym_ptr_ptr)->section->name, ++ (long) (*(*rptr)->sym_ptr_ptr)->value, ++ (unsigned long)(*rptr)->address, ++ (unsigned long)(*rptr)->addend, ++ bfd_get_reloc_size ((*rptr)->howto), ++ ( *rptr)->howto->name); ++ rptr++; ++ } ++ } ++#endif ++ ++ new_pass: ++ for (irel = 0; irel < section->reloc_count; irel++) ++ { ++ struct evax_private_udata_struct *udata; ++ arelent *rptr = section->orelocation [irel]; ++ bfd_vma addr = rptr->address; ++ asymbol *sym = *rptr->sym_ptr_ptr; ++ asection *sec = sym->section; ++ bfd_boolean defer = defer_reloc_p (rptr); ++ unsigned int slen; ++ ++ if (pass2_in_progress) ++ { ++ /* Non-deferred relocs have already been output. */ ++ if (!defer) ++ continue; ++ } ++ else ++ { ++ /* Deferred relocs must be output at the very end. */ ++ if (defer) ++ { ++ pass2_needed = 1; ++ continue; ++ } ++ ++ /* Regular relocs are intertwined with binary data. */ ++ if (curr_addr > addr) ++ _bfd_error_handler (_("size error in section %pA"), ++ section); ++ size = addr - curr_addr; ++ sto_imm (abfd, section, size, curr_data, curr_addr); ++ curr_data += size; ++ curr_addr += size; ++ } ++ ++ size = bfd_get_reloc_size (rptr->howto); ++ ++ switch (rptr->howto->type) ++ { ++ case SW_64_R_IGNORE: ++ break; ++ ++ case SW_64_R_REFLONG: ++ if (bfd_is_und_section (sym->section)) ++ { ++ bfd_vma addend = rptr->addend; ++ slen = strlen ((char *) sym->name); ++ etir_output_check (abfd, section, curr_addr, slen); ++ if (addend) ++ { ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW); ++ _bfd_vms_output_long (recwr, (unsigned long) addend); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ else ++ { ++ _bfd_vms_output_begin_subrec ++ (recwr, ETIR__C_STO_GBL_LW); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ } ++ else if (bfd_is_abs_section (sym->section)) ++ { ++ etir_output_check (abfd, section, curr_addr, 16); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW); ++ _bfd_vms_output_long (recwr, (unsigned long) sym->value); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ else ++ { ++ etir_output_check (abfd, section, curr_addr, 32); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); ++ _bfd_vms_output_long (recwr, ++ (unsigned long) sec->target_index); ++ _bfd_vms_output_quad (recwr, rptr->addend + sym->value); ++ _bfd_vms_output_end_subrec (recwr); ++ /* ??? Table B-8 of the OpenVMS Linker Utilily Manual ++ says that we should have a ETIR__C_STO_OFF here. ++ But the relocation would not be BFD_RELOC_32 then. ++ This case is very likely unreachable. */ ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ break; ++ ++ case SW_64_R_REFQUAD: ++ if (bfd_is_und_section (sym->section)) ++ { ++ bfd_vma addend = rptr->addend; ++ slen = strlen ((char *) sym->name); ++ etir_output_check (abfd, section, curr_addr, slen); ++ if (addend) ++ { ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW); ++ _bfd_vms_output_quad (recwr, addend); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ else ++ { ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ } ++ else if (bfd_is_abs_section (sym->section)) ++ { ++ etir_output_check (abfd, section, curr_addr, 16); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW); ++ _bfd_vms_output_quad (recwr, sym->value); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ else ++ { ++ etir_output_check (abfd, section, curr_addr, 32); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); ++ _bfd_vms_output_long (recwr, ++ (unsigned long) sec->target_index); ++ _bfd_vms_output_quad (recwr, rptr->addend + sym->value); ++ _bfd_vms_output_end_subrec (recwr); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF); ++ _bfd_vms_output_end_subrec (recwr); ++ } ++ break; ++ ++ case SW_64_R_HINT: ++ sto_imm (abfd, section, size, curr_data, curr_addr); ++ break; ++ ++ case SW_64_R_LINKAGE: ++ etir_output_check (abfd, section, curr_addr, 64); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) rptr->addend); ++ if (rptr->addend > PRIV (vms_linkage_index)) ++ PRIV (vms_linkage_index) = rptr->addend; ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_byte (recwr, 0); ++ _bfd_vms_output_end_subrec (recwr); ++ break; ++ ++ case SW_64_R_CODEADDR: ++ slen = strlen ((char *) sym->name); ++ etir_output_check (abfd, section, curr_addr, slen); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA); ++ _bfd_vms_output_counted (recwr, sym->name); ++ _bfd_vms_output_end_subrec (recwr); ++ break; ++ ++ case SW_64_R_NOP: ++ udata ++ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; ++ etir_output_check (abfd, section, curr_addr, ++ 32 + 1 + strlen (udata->origname)); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL); ++ _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->address); ++ _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->addend); ++ _bfd_vms_output_counted (recwr, udata->origname); ++ _bfd_vms_output_end_subrec (recwr); ++ break; ++ ++ case SW_64_R_BSR: ++ _bfd_error_handler (_("spurious SW_64_R_BSR reloc")); ++ break; ++ ++ case SW_64_R_LDA: ++ udata ++ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; ++ etir_output_check (abfd, section, curr_addr, ++ 32 + 1 + strlen (udata->origname)); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LDA_GBL); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) udata->lkindex + 1); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->address); ++ _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) udata->bsym->section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->addend); ++ _bfd_vms_output_counted (recwr, udata->origname); ++ _bfd_vms_output_end_subrec (recwr); ++ break; ++ ++ case SW_64_R_BOH: ++ udata ++ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; ++ etir_output_check (abfd, section, curr_addr, ++ 32 + 1 + strlen (udata->origname)); ++ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL); ++ _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->address); ++ _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000); ++ _bfd_vms_output_long ++ (recwr, (unsigned long) section->target_index); ++ _bfd_vms_output_quad (recwr, rptr->addend); ++ _bfd_vms_output_counted (recwr, udata->origname); ++ _bfd_vms_output_end_subrec (recwr); ++ break; ++ ++ default: ++ _bfd_error_handler (_("unhandled relocation %s"), ++ rptr->howto->name); ++ break; ++ } ++ ++ curr_data += size; ++ curr_addr += size; ++ } /* End of relocs loop. */ ++ ++ if (!pass2_in_progress) ++ { ++ /* Output rest of section. */ ++ if (curr_addr > section->size) ++ _bfd_error_handler (_("size error in section %pA"), section); ++ size = section->size - curr_addr; ++ sto_imm (abfd, section, size, curr_data, curr_addr); ++ curr_data += size; ++ curr_addr += size; ++ ++ if (pass2_needed) ++ { ++ pass2_in_progress = 1; ++ goto new_pass; ++ } ++ } ++ } ++ ++ else /* (section->flags & SEC_RELOC) */ ++ sto_imm (abfd, section, section->size, section->contents, 0); ++ ++ end_etir_record (abfd); ++ } ++ ++ _bfd_vms_output_alignment (recwr, 2); ++ return TRUE; ++} ++ ++/* Write cached information into a file being written, at bfd_close. */ ++ ++static bfd_boolean ++sw_64_vms_write_object_contents (bfd *abfd) ++{ ++ vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd)); ++ ++ if (abfd->flags & (EXEC_P | DYNAMIC)) ++ { ++ return sw_64_vms_write_exec (abfd); ++ } ++ else ++ { ++ if (abfd->section_count > 0) /* we have sections */ ++ { ++ if (!_bfd_vms_write_ehdr (abfd)) ++ return FALSE; ++ if (!_bfd_vms_write_egsd (abfd)) ++ return FALSE; ++ if (!_bfd_vms_write_etir (abfd, EOBJ__C_ETIR)) ++ return FALSE; ++ if (!_bfd_vms_write_eeom (abfd)) ++ return FALSE; ++ } ++ } ++ return TRUE; ++} ++ ++/* Debug stuff: nearest line. */ ++ ++#define SET_MODULE_PARSED(m) \ ++ do { if ((m)->name == NULL) (m)->name = ""; } while (0) ++#define IS_MODULE_PARSED(m) ((m)->name != NULL) ++ ++/* Build a new module for the specified BFD. */ ++ ++static struct module * ++new_module (bfd *abfd) ++{ ++ struct module *module ++ = (struct module *) bfd_zalloc (abfd, sizeof (struct module)); ++ module->file_table_count = 16; /* Arbitrary. */ ++ module->file_table ++ = bfd_malloc (module->file_table_count * sizeof (struct fileinfo)); ++ return module; ++} ++ ++/* Parse debug info for a module and internalize it. */ ++ ++static void ++parse_module (bfd *abfd, struct module *module, unsigned char *ptr, ++ int length) ++{ ++ unsigned char *maxptr = ptr + length; ++ unsigned char *src_ptr, *pcl_ptr; ++ unsigned int prev_linum = 0, curr_linenum = 0; ++ bfd_vma prev_pc = 0, curr_pc = 0; ++ struct srecinfo *curr_srec, *srec; ++ struct lineinfo *curr_line, *line; ++ struct funcinfo *funcinfo; ++ ++ /* Initialize tables with zero element. */ ++ curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo)); ++ module->srec_table = curr_srec; ++ ++ curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo)); ++ module->line_table = curr_line; ++ ++ while (length == -1 || ptr < maxptr) ++ { ++ /* The first byte is not counted in the recorded length. */ ++ int rec_length = bfd_getl16 (ptr) + 1; ++ int rec_type = bfd_getl16 (ptr + 2); ++ ++ vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type)); ++ ++ if (length == -1 && rec_type == DST__K_MODEND) ++ break; ++ ++ switch (rec_type) ++ { ++ case DST__K_MODBEG: ++ module->name ++ = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME, ++ maxptr - (ptr + DST_S_B_MODBEG_NAME)); ++ ++ curr_pc = 0; ++ prev_pc = 0; ++ curr_linenum = 0; ++ prev_linum = 0; ++ ++ vms_debug2 ((3, "module: %s\n", module->name)); ++ break; ++ ++ case DST__K_MODEND: ++ break; ++ ++ case DST__K_RTNBEG: ++ funcinfo = (struct funcinfo *) ++ bfd_zalloc (abfd, sizeof (struct funcinfo)); ++ funcinfo->name ++ = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME, ++ maxptr - (ptr + DST_S_B_RTNBEG_NAME)); ++ funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS); ++ funcinfo->next = module->func_table; ++ module->func_table = funcinfo; ++ ++ vms_debug2 ((3, "routine: %s at 0x%lx\n", ++ funcinfo->name, (unsigned long) funcinfo->low)); ++ break; ++ ++ case DST__K_RTNEND: ++ module->func_table->high = module->func_table->low ++ + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1; ++ ++ if (module->func_table->high > module->high) ++ module->high = module->func_table->high; ++ ++ vms_debug2 ((3, "end routine\n")); ++ break; ++ ++ case DST__K_PROLOG: ++ vms_debug2 ((3, "prologue\n")); ++ break; ++ ++ case DST__K_EPILOG: ++ vms_debug2 ((3, "epilog\n")); ++ break; ++ ++ case DST__K_BLKBEG: ++ vms_debug2 ((3, "block\n")); ++ break; ++ ++ case DST__K_BLKEND: ++ vms_debug2 ((3, "end block\n")); ++ break; ++ ++ case DST__K_SOURCE: ++ src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE; ++ ++ vms_debug2 ((3, "source info\n")); ++ ++ while (src_ptr < ptr + rec_length) ++ { ++ int cmd = src_ptr[0], cmd_length, data; ++ ++ switch (cmd) ++ { ++ case DST__K_SRC_DECLFILE: ++ { ++ unsigned int fileid ++ = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID); ++ char *filename ++ = _bfd_vms_save_counted_string (src_ptr + DST_S_B_SRC_DF_FILENAME, ++ (ptr + rec_length) - ++ (src_ptr + DST_S_B_SRC_DF_FILENAME) ++ ); ++ ++ while (fileid >= module->file_table_count) ++ { ++ module->file_table_count *= 2; ++ module->file_table ++ = bfd_realloc (module->file_table, ++ module->file_table_count ++ * sizeof (struct fileinfo)); ++ } ++ ++ module->file_table [fileid].name = filename; ++ module->file_table [fileid].srec = 1; ++ cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2; ++ vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n", ++ fileid, module->file_table [fileid].name)); ++ } ++ break; ++ ++ case DST__K_SRC_DEFLINES_B: ++ /* Perform the association and set the next higher index ++ to the limit. */ ++ data = src_ptr[DST_S_B_SRC_UNSBYTE]; ++ srec = (struct srecinfo *) ++ bfd_zalloc (abfd, sizeof (struct srecinfo)); ++ srec->line = curr_srec->line + data; ++ srec->srec = curr_srec->srec + data; ++ srec->sfile = curr_srec->sfile; ++ curr_srec->next = srec; ++ curr_srec = srec; ++ cmd_length = 2; ++ vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_B: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_DEFLINES_W: ++ /* Perform the association and set the next higher index ++ to the limit. */ ++ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD); ++ srec = (struct srecinfo *) ++ bfd_zalloc (abfd, sizeof (struct srecinfo)); ++ srec->line = curr_srec->line + data; ++ srec->srec = curr_srec->srec + data, ++ srec->sfile = curr_srec->sfile; ++ curr_srec->next = srec; ++ curr_srec = srec; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_W: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_INCRLNUM_B: ++ data = src_ptr[DST_S_B_SRC_UNSBYTE]; ++ curr_srec->line += data; ++ cmd_length = 2; ++ vms_debug2 ((4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_SETFILE: ++ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD); ++ curr_srec->sfile = data; ++ curr_srec->srec = module->file_table[data].srec; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_SETLNUM_L: ++ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG); ++ curr_srec->line = data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_L: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_SETLNUM_W: ++ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD); ++ curr_srec->line = data; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_W: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_SETREC_L: ++ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG); ++ curr_srec->srec = data; ++ module->file_table[curr_srec->sfile].srec = data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST_S_C_SRC_SETREC_L: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_SETREC_W: ++ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD); ++ curr_srec->srec = data; ++ module->file_table[curr_srec->sfile].srec = data; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST_S_C_SRC_SETREC_W: %d\n", data)); ++ break; ++ ++ case DST__K_SRC_FORMFEED: ++ cmd_length = 1; ++ vms_debug2 ((4, "DST_S_C_SRC_FORMFEED\n")); ++ break; ++ ++ default: ++ _bfd_error_handler (_("unknown source command %d"), ++ cmd); ++ cmd_length = 2; ++ break; ++ } ++ ++ src_ptr += cmd_length; ++ } ++ break; ++ ++ case DST__K_LINE_NUM: ++ pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE; ++ ++ vms_debug2 ((3, "line info\n")); ++ ++ while (pcl_ptr < ptr + rec_length) ++ { ++ /* The command byte is signed so we must sign-extend it. */ ++ int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data; ++ ++ switch (cmd) ++ { ++ case DST__K_DELTA_PC_W: ++ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD); ++ curr_pc += data; ++ curr_linenum += 1; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST__K_DELTA_PC_W: %d\n", data)); ++ break; ++ ++ case DST__K_DELTA_PC_L: ++ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG); ++ curr_pc += data; ++ curr_linenum += 1; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST__K_DELTA_PC_L: %d\n", data)); ++ break; ++ ++ case DST__K_INCR_LINUM: ++ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE]; ++ curr_linenum += data; ++ cmd_length = 2; ++ vms_debug2 ((4, "DST__K_INCR_LINUM: %d\n", data)); ++ break; ++ ++ case DST__K_INCR_LINUM_W: ++ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD); ++ curr_linenum += data; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST__K_INCR_LINUM_W: %d\n", data)); ++ break; ++ ++ case DST__K_INCR_LINUM_L: ++ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG); ++ curr_linenum += data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST__K_INCR_LINUM_L: %d\n", data)); ++ break; ++ ++ case DST__K_SET_LINUM_INCR: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_LINUM_INCR"); ++ cmd_length = 2; ++ break; ++ ++ case DST__K_SET_LINUM_INCR_W: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_LINUM_INCR_W"); ++ cmd_length = 3; ++ break; ++ ++ case DST__K_RESET_LINUM_INCR: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_RESET_LINUM_INCR"); ++ cmd_length = 1; ++ break; ++ ++ case DST__K_BEG_STMT_MODE: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_BEG_STMT_MODE"); ++ cmd_length = 1; ++ break; ++ ++ case DST__K_END_STMT_MODE: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_END_STMT_MODE"); ++ cmd_length = 1; ++ break; ++ ++ case DST__K_SET_LINUM_B: ++ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE]; ++ curr_linenum = data; ++ cmd_length = 2; ++ vms_debug2 ((4, "DST__K_SET_LINUM_B: %d\n", data)); ++ break; ++ ++ case DST__K_SET_LINUM: ++ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD); ++ curr_linenum = data; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST__K_SET_LINE_NUM: %d\n", data)); ++ break; ++ ++ case DST__K_SET_LINUM_L: ++ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG); ++ curr_linenum = data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST__K_SET_LINUM_L: %d\n", data)); ++ break; ++ ++ case DST__K_SET_PC: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_PC"); ++ cmd_length = 2; ++ break; ++ ++ case DST__K_SET_PC_W: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_PC_W"); ++ cmd_length = 3; ++ break; ++ ++ case DST__K_SET_PC_L: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_PC_L"); ++ cmd_length = 5; ++ break; ++ ++ case DST__K_SET_STMTNUM: ++ _bfd_error_handler ++ (_("%s not implemented"), "DST__K_SET_STMTNUM"); ++ cmd_length = 2; ++ break; ++ ++ case DST__K_TERM: ++ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE]; ++ curr_pc += data; ++ cmd_length = 2; ++ vms_debug2 ((4, "DST__K_TERM: %d\n", data)); ++ break; ++ ++ case DST__K_TERM_W: ++ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD); ++ curr_pc += data; ++ cmd_length = 3; ++ vms_debug2 ((4, "DST__K_TERM_W: %d\n", data)); ++ break; ++ ++ case DST__K_TERM_L: ++ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG); ++ curr_pc += data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST__K_TERM_L: %d\n", data)); ++ break; ++ ++ case DST__K_SET_ABS_PC: ++ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG); ++ curr_pc = data; ++ cmd_length = 5; ++ vms_debug2 ((4, "DST__K_SET_ABS_PC: 0x%x\n", data)); ++ break; ++ ++ default: ++ if (cmd <= 0) ++ { ++ curr_pc -= cmd; ++ curr_linenum += 1; ++ cmd_length = 1; ++ vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n", ++ (unsigned long)curr_pc, curr_linenum)); ++ } ++ else ++ { ++ _bfd_error_handler (_("unknown line command %d"), cmd); ++ cmd_length = 2; ++ } ++ break; ++ } ++ ++ if ((curr_linenum != prev_linum && curr_pc != prev_pc) ++ || cmd <= 0 ++ || cmd == DST__K_DELTA_PC_L ++ || cmd == DST__K_DELTA_PC_W) ++ { ++ line = (struct lineinfo *) ++ bfd_zalloc (abfd, sizeof (struct lineinfo)); ++ line->address = curr_pc; ++ line->line = curr_linenum; ++ ++ curr_line->next = line; ++ curr_line = line; ++ ++ prev_linum = curr_linenum; ++ prev_pc = curr_pc; ++ vms_debug2 ((4, "-> correlate pc 0x%lx with line %d\n", ++ (unsigned long)curr_pc, curr_linenum)); ++ } ++ ++ pcl_ptr += cmd_length; ++ } ++ break; ++ ++ case 0x17: /* Undocumented type used by DEC C to declare equates. */ ++ vms_debug2 ((3, "undocumented type 0x17\n")); ++ break; ++ ++ default: ++ vms_debug2 ((3, "ignoring record\n")); ++ break; ++ ++ } ++ ++ ptr += rec_length; ++ } ++ ++ /* Finalize tables with EOL marker. */ ++ srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo)); ++ srec->line = (unsigned int) -1; ++ srec->srec = (unsigned int) -1; ++ curr_srec->next = srec; ++ ++ line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo)); ++ line->line = (unsigned int) -1; ++ line->address = (bfd_vma) -1; ++ curr_line->next = line; ++ ++ /* Advertise that this module has been parsed. This is needed ++ because parsing can be either performed at module creation ++ or deferred until debug info is consumed. */ ++ SET_MODULE_PARSED (module); ++} ++ ++/* Build the list of modules for the specified BFD. */ ++ ++static struct module * ++build_module_list (bfd *abfd) ++{ ++ struct module *module, *list = NULL; ++ asection *dmt; ++ ++ if ((dmt = bfd_get_section_by_name (abfd, "$DMT$"))) ++ { ++ /* We have a DMT section so this must be an image. Parse the ++ section and build the list of modules. This is sufficient ++ since we can compute the start address and the end address ++ of every module from the section contents. */ ++ bfd_size_type size = bfd_get_section_size (dmt); ++ unsigned char *ptr, *end; ++ ++ ptr = (unsigned char *) bfd_alloc (abfd, size); ++ if (! ptr) ++ return NULL; ++ ++ if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size)) ++ return NULL; ++ ++ vms_debug2 ((2, "DMT\n")); ++ ++ end = ptr + size; ++ ++ while (ptr < end) ++ { ++ /* Each header declares a module with its start offset and size ++ of debug info in the DST section, as well as the count of ++ program sections (i.e. address spans) it contains. */ ++ int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG); ++ int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE); ++ int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT); ++ ptr += DBG_S_C_DMT_HEADER_SIZE; ++ ++ vms_debug2 ((3, "module: modbeg = %d, size = %d, count = %d\n", ++ modbeg, msize, count)); ++ ++ /* We create a 'module' structure for each program section since ++ we only support contiguous addresses in a 'module' structure. ++ As a consequence, the actual debug info in the DST section is ++ shared and can be parsed multiple times; that doesn't seem to ++ cause problems in practice. */ ++ while (count-- > 0) ++ { ++ int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START); ++ int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH); ++ module = new_module (abfd); ++ module->modbeg = modbeg; ++ module->size = msize; ++ module->low = start; ++ module->high = start + length; ++ module->next = list; ++ list = module; ++ ptr += DBG_S_C_DMT_PSECT_SIZE; ++ ++ vms_debug2 ((4, "section: start = 0x%x, length = %d\n", ++ start, length)); ++ } ++ } ++ } ++ else ++ { ++ /* We don't have a DMT section so this must be an object. Parse ++ the module right now in order to compute its start address and ++ end address. */ ++ void *dst = PRIV (dst_section)->contents; ++ ++ if (dst == NULL) ++ return NULL; ++ ++ module = new_module (abfd); ++ parse_module (abfd, module, PRIV (dst_section)->contents, -1); ++ list = module; ++ } ++ ++ return list; ++} ++ ++/* Calculate and return the name of the source file and the line nearest ++ to the wanted location in the specified module. */ ++ ++static bfd_boolean ++module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, ++ const char **file, const char **func, ++ unsigned int *line) ++{ ++ struct funcinfo *funcinfo; ++ struct lineinfo *lineinfo; ++ struct srecinfo *srecinfo; ++ bfd_boolean ret = FALSE; ++ ++ /* Parse this module if that was not done at module creation. */ ++ if (! IS_MODULE_PARSED (module)) ++ { ++ unsigned int size = module->size; ++ unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg; ++ unsigned char *buffer = (unsigned char *) bfd_malloc (module->size); ++ ++ if (bfd_seek (abfd, modbeg, SEEK_SET) != 0 ++ || bfd_bread (buffer, size, abfd) != size) ++ { ++ bfd_set_error (bfd_error_no_debug_section); ++ return FALSE; ++ } ++ ++ parse_module (abfd, module, buffer, size); ++ free (buffer); ++ } ++ ++ /* Find out the function (if any) that contains the address. */ ++ for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next) ++ if (addr >= funcinfo->low && addr <= funcinfo->high) ++ { ++ *func = funcinfo->name; ++ ret = TRUE; ++ break; ++ } ++ ++ /* Find out the source file and the line nearest to the address. */ ++ for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next) ++ if (lineinfo->next && addr < lineinfo->next->address) ++ { ++ for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next) ++ if (srecinfo->next && lineinfo->line < srecinfo->next->line) ++ { ++ if (srecinfo->sfile > 0) ++ { ++ *file = module->file_table[srecinfo->sfile].name; ++ *line = srecinfo->srec + lineinfo->line - srecinfo->line; ++ } ++ else ++ { ++ *file = module->name; ++ *line = lineinfo->line; ++ } ++ return TRUE; ++ } ++ ++ break; ++ } ++ ++ return ret; ++} ++ ++/* Provided a BFD, a section and an offset into the section, calculate and ++ return the name of the source file and the line nearest to the wanted ++ location. */ ++ ++static bfd_boolean ++_bfd_vms_find_nearest_line (bfd *abfd, ++ asymbol **symbols ATTRIBUTE_UNUSED, ++ asection *section, ++ bfd_vma offset, ++ const char **file, ++ const char **func, ++ unsigned int *line, ++ unsigned int *discriminator) ++{ ++ struct module *module; ++ ++ /* What address are we looking for? */ ++ bfd_vma addr = section->vma + offset; ++ ++ *file = NULL; ++ *func = NULL; ++ *line = 0; ++ if (discriminator) ++ *discriminator = 0; ++ ++ /* We can't do anything if there is no DST (debug symbol table). */ ++ if (PRIV (dst_section) == NULL) ++ return FALSE; ++ ++ /* Create the module list - if not already done. */ ++ if (PRIV (modules) == NULL) ++ { ++ PRIV (modules) = build_module_list (abfd); ++ if (PRIV (modules) == NULL) ++ return FALSE; ++ } ++ ++ for (module = PRIV (modules); module; module = module->next) ++ if (addr >= module->low && addr <= module->high) ++ return module_find_nearest_line (abfd, module, addr, file, func, line); ++ ++ return FALSE; ++} ++ ++/* Canonicalizations. */ ++/* Set name, value, section and flags of SYM from E. */ ++ ++static bfd_boolean ++sw_64_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym) ++{ ++ flagword flags; ++ symvalue value; ++ asection *sec; ++ const char *name; ++ ++ name = e->name; ++ value = 0; ++ flags = BSF_NO_FLAGS; ++ sec = NULL; ++ ++ switch (e->typ) ++ { ++ case EGSD__C_SYM: ++ if (e->flags & EGSY__V_WEAK) ++ flags |= BSF_WEAK; ++ ++ if (e->flags & EGSY__V_DEF) ++ { ++ /* Symbol definition. */ ++ flags |= BSF_GLOBAL; ++ if (e->flags & EGSY__V_NORM) ++ flags |= BSF_FUNCTION; ++ value = e->value; ++ sec = e->section; ++ } ++ else ++ { ++ /* Symbol reference. */ ++ sec = bfd_und_section_ptr; ++ } ++ break; ++ ++ case EGSD__C_SYMG: ++ /* A universal symbol is by definition global... */ ++ flags |= BSF_GLOBAL; ++ ++ /* ...and dynamic in shared libraries. */ ++ if (abfd->flags & DYNAMIC) ++ flags |= BSF_DYNAMIC; ++ ++ if (e->flags & EGSY__V_WEAK) ++ flags |= BSF_WEAK; ++ ++ if (!(e->flags & EGSY__V_DEF)) ++ abort (); ++ ++ if (e->flags & EGSY__V_NORM) ++ flags |= BSF_FUNCTION; ++ ++ value = e->value; ++ /* sec = e->section; */ ++ sec = bfd_abs_section_ptr; ++ break; ++ ++ default: ++ return FALSE; ++ } ++ ++ sym->name = name; ++ sym->section = sec; ++ sym->flags = flags; ++ sym->value = value; ++ return TRUE; ++} ++ ++ ++/* Return the number of bytes required to store a vector of pointers ++ to asymbols for all the symbols in the BFD abfd, including a ++ terminal NULL pointer. If there are no symbols in the BFD, ++ then return 0. If an error occurs, return -1. */ ++ ++static long ++sw_64_vms_get_symtab_upper_bound (bfd *abfd) ++{ ++ vms_debug2 ((1, "sw_64_vms_get_symtab_upper_bound (%p), %d symbols\n", ++ abfd, PRIV (gsd_sym_count))); ++ ++ return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *); ++} ++ ++/* Read the symbols from the BFD abfd, and fills in the vector ++ location with pointers to the symbols and a trailing NULL. ++ ++ Return number of symbols read. */ ++ ++static long ++sw_64_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols) ++{ ++ unsigned int i; ++ ++ vms_debug2 ((1, "sw_64_vms_canonicalize_symtab (%p, )\n", abfd)); ++ ++ if (PRIV (csymbols) == NULL) ++ { ++ PRIV (csymbols) = (asymbol **) bfd_alloc ++ (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *)); ++ ++ /* Traverse table and fill symbols vector. */ ++ for (i = 0; i < PRIV (gsd_sym_count); i++) ++ { ++ struct vms_symbol_entry *e = PRIV (syms)[i]; ++ asymbol *sym; ++ ++ sym = bfd_make_empty_symbol (abfd); ++ if (sym == NULL || !sw_64_vms_convert_symbol (abfd, e, sym)) ++ { ++ bfd_release (abfd, PRIV (csymbols)); ++ PRIV (csymbols) = NULL; ++ return -1; ++ } ++ ++ PRIV (csymbols)[i] = sym; ++ } ++ } ++ ++ if (symbols != NULL) ++ { ++ for (i = 0; i < PRIV (gsd_sym_count); i++) ++ symbols[i] = PRIV (csymbols)[i]; ++ symbols[i] = NULL; ++ } ++ ++ return PRIV (gsd_sym_count); ++} ++ ++/* Read and convert relocations from ETIR. We do it once for all sections. */ ++ ++static bfd_boolean ++sw_64_vms_slurp_relocs (bfd *abfd) ++{ ++ int cur_psect = -1; ++ ++ vms_debug2 ((3, "sw_64_vms_slurp_relocs\n")); ++ ++ /* We slurp relocs only once, for all sections. */ ++ if (PRIV (reloc_done)) ++ return TRUE; ++ PRIV (reloc_done) = TRUE; ++ ++ if (sw_64_vms_canonicalize_symtab (abfd, NULL) < 0) ++ return FALSE; ++ ++ if (bfd_seek (abfd, 0, SEEK_SET) != 0) ++ return FALSE; ++ ++ while (1) ++ { ++ unsigned char *begin; ++ unsigned char *end; ++ unsigned char *ptr; ++ bfd_reloc_code_real_type reloc_code; ++ int type; ++ bfd_vma vaddr = 0; ++ ++ int length; ++ ++ bfd_vma cur_address; ++ int cur_psidx = -1; ++ unsigned char *cur_sym = NULL; ++ int prev_cmd = -1; ++ bfd_vma cur_addend = 0; ++ ++ /* Skip non-ETIR records. */ ++ type = _bfd_vms_get_object_record (abfd); ++ if (type == EOBJ__C_EEOM) ++ break; ++ if (type != EOBJ__C_ETIR) ++ continue; ++ ++ begin = PRIV (recrd.rec) + 4; ++ end = PRIV (recrd.rec) + PRIV (recrd.rec_size); ++ ++ for (ptr = begin; ptr < end; ptr += length) ++ { ++ int cmd; ++ ++ cmd = bfd_getl16 (ptr); ++ length = bfd_getl16 (ptr + 2); ++ ++ cur_address = vaddr; ++ ++ vms_debug2 ((4, "sw_64_vms_slurp_relocs: etir %s\n", ++ _bfd_vms_etir_name (cmd))); ++ ++ switch (cmd) ++ { ++ case ETIR__C_STA_GBL: /* SW_64_R_REFLONG und_section, step 1 */ ++ /* SW_64_R_REFQUAD und_section, step 1 */ ++ cur_sym = ptr + 4; ++ prev_cmd = cmd; ++ continue; ++ ++ case ETIR__C_STA_PQ: /* SW_64_R_REF{LONG|QUAD}, others part 1 */ ++ cur_psidx = bfd_getl32 (ptr + 4); ++ cur_addend = bfd_getl64 (ptr + 8); ++ prev_cmd = cmd; ++ continue; ++ ++ case ETIR__C_CTL_SETRB: ++ if (prev_cmd != ETIR__C_STA_PQ) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ } ++ cur_psect = cur_psidx; ++ vaddr = cur_addend; ++ cur_psidx = -1; ++ cur_addend = 0; ++ continue; ++ ++ case ETIR__C_STA_LW: /* SW_64_R_REFLONG abs_section, step 1 */ ++ /* SW_64_R_REFLONG und_section, step 2 */ ++ if (prev_cmd != -1) ++ { ++ if (prev_cmd != ETIR__C_STA_GBL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), ++ _bfd_vms_etir_name (ETIR__C_STA_LW)); ++ return FALSE; ++ } ++ } ++ cur_addend = bfd_getl32 (ptr + 4); ++ prev_cmd = cmd; ++ continue; ++ ++ case ETIR__C_STA_QW: /* SW_64_R_REFQUAD abs_section, step 1 */ ++ /* SW_64_R_REFQUAD und_section, step 2 */ ++ if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), ++ _bfd_vms_etir_name (ETIR__C_STA_QW)); ++ return FALSE; ++ } ++ cur_addend = bfd_getl64 (ptr + 4); ++ prev_cmd = cmd; ++ continue; ++ ++ case ETIR__C_STO_LW: /* SW_64_R_REFLONG und_section, step 4 */ ++ /* SW_64_R_REFLONG abs_section, step 2 */ ++ /* SW_64_R_REFLONG others, step 2 */ ++ if (prev_cmd != ETIR__C_OPR_ADD ++ && prev_cmd != ETIR__C_STA_LW ++ && prev_cmd != ETIR__C_STA_PQ) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("unknown reloc %s + %s"), ++ _bfd_vms_etir_name (prev_cmd), ++ _bfd_vms_etir_name (ETIR__C_STO_LW)); ++ return FALSE; ++ } ++ reloc_code = BFD_RELOC_32; ++ break; ++ ++ case ETIR__C_STO_QW: /* SW_64_R_REFQUAD und_section, step 4 */ ++ /* SW_64_R_REFQUAD abs_section, step 2 */ ++ if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("unknown reloc %s + %s"), ++ _bfd_vms_etir_name (prev_cmd), ++ _bfd_vms_etir_name (ETIR__C_STO_QW)); ++ return FALSE; ++ } ++ reloc_code = BFD_RELOC_64; ++ break; ++ ++ case ETIR__C_STO_OFF: /* SW_64_R_REFQUAD others, step 2 */ ++ if (prev_cmd != ETIR__C_STA_PQ) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("unknown reloc %s + %s"), ++ _bfd_vms_etir_name (prev_cmd), ++ _bfd_vms_etir_name (ETIR__C_STO_OFF)); ++ return FALSE; ++ } ++ reloc_code = BFD_RELOC_64; ++ break; ++ ++ case ETIR__C_OPR_ADD: /* SW_64_R_REFLONG und_section, step 3 */ ++ /* SW_64_R_REFQUAD und_section, step 3 */ ++ if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("unknown reloc %s + %s"), ++ _bfd_vms_etir_name (prev_cmd), ++ _bfd_vms_etir_name (ETIR__C_OPR_ADD)); ++ return FALSE; ++ } ++ prev_cmd = ETIR__C_OPR_ADD; ++ continue; ++ ++ case ETIR__C_STO_CA: /* SW_64_R_CODEADDR */ ++ reloc_code = BFD_RELOC_SW_64_CODEADDR; ++ cur_sym = ptr + 4; ++ break; ++ ++ case ETIR__C_STO_GBL: /* SW_64_R_REFQUAD und_section */ ++ reloc_code = BFD_RELOC_64; ++ cur_sym = ptr + 4; ++ break; ++ ++ case ETIR__C_STO_GBL_LW: /* SW_64_R_REFLONG und_section */ ++ reloc_code = BFD_RELOC_32; ++ cur_sym = ptr + 4; ++ break; ++ ++ case ETIR__C_STC_LP_PSB: /* SW_64_R_LINKAGE */ ++ reloc_code = BFD_RELOC_SW_64_LINKAGE; ++ cur_sym = ptr + 8; ++ break; ++ ++ case ETIR__C_STC_NOP_GBL: /* SW_64_R_NOP */ ++ reloc_code = BFD_RELOC_SW_64_NOP; ++ goto call_reloc; ++ ++ case ETIR__C_STC_BSR_GBL: /* SW_64_R_BSR */ ++ reloc_code = BFD_RELOC_SW_64_BSR; ++ goto call_reloc; ++ ++ case ETIR__C_STC_LDA_GBL: /* SW_64_R_LDA */ ++ reloc_code = BFD_RELOC_SW_64_LDA; ++ goto call_reloc; ++ ++ case ETIR__C_STC_BOH_GBL: /* SW_64_R_BOH */ ++ reloc_code = BFD_RELOC_SW_64_BOH; ++ goto call_reloc; ++ ++ call_reloc: ++ cur_sym = ptr + 4 + 32; ++ cur_address = bfd_getl64 (ptr + 4 + 8); ++ cur_addend = bfd_getl64 (ptr + 4 + 24); ++ break; ++ ++ case ETIR__C_STO_IMM: ++ vaddr += bfd_getl32 (ptr + 4); ++ continue; ++ ++ default: ++ _bfd_error_handler (_("unknown reloc %s"), ++ _bfd_vms_etir_name (cmd)); ++ return FALSE; ++ } ++ ++ { ++ asection *sec; ++ struct vms_section_data_struct *vms_sec; ++ arelent *reloc; ++ ++ /* Get section to which the relocation applies. */ ++ if (cur_psect < 0 || cur_psect > (int)PRIV (section_count)) ++ { ++ _bfd_error_handler (_("invalid section index in ETIR")); ++ return FALSE; ++ } ++ ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ sec = PRIV (sections)[cur_psect]; ++ if (sec == bfd_abs_section_ptr) ++ { ++ _bfd_error_handler (_("relocation for non-REL psect")); ++ return FALSE; ++ } ++ ++ vms_sec = vms_section_data (sec); ++ ++ /* Allocate a reloc entry. */ ++ if (sec->reloc_count >= vms_sec->reloc_max) ++ { ++ if (vms_sec->reloc_max == 0) ++ { ++ vms_sec->reloc_max = 64; ++ sec->relocation = bfd_zmalloc ++ (vms_sec->reloc_max * sizeof (arelent)); ++ } ++ else ++ { ++ vms_sec->reloc_max *= 2; ++ sec->relocation = bfd_realloc ++ (sec->relocation, vms_sec->reloc_max * sizeof (arelent)); ++ } ++ } ++ reloc = &sec->relocation[sec->reloc_count]; ++ sec->reloc_count++; ++ ++ reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code); ++ ++ if (cur_sym != NULL) ++ { ++ unsigned int j; ++ unsigned int symlen = *cur_sym; ++ asymbol **sym; ++ ++ /* Linear search. */ ++ symlen = *cur_sym; ++ cur_sym++; ++ sym = NULL; ++ ++ for (j = 0; j < PRIV (gsd_sym_count); j++) ++ if (PRIV (syms)[j]->namelen == symlen ++ && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0) ++ { ++ sym = &PRIV (csymbols)[j]; ++ break; ++ } ++ if (sym == NULL) ++ { ++ _bfd_error_handler (_("unknown symbol in command %s"), ++ _bfd_vms_etir_name (cmd)); ++ reloc->sym_ptr_ptr = NULL; ++ } ++ else ++ reloc->sym_ptr_ptr = sym; ++ } ++ else if (cur_psidx >= 0) ++ { ++ if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count)) ++ return FALSE; ++ reloc->sym_ptr_ptr = ++ PRIV (sections)[cur_psidx]->symbol_ptr_ptr; ++ } ++ else ++ reloc->sym_ptr_ptr = NULL; ++ ++ reloc->address = cur_address; ++ reloc->addend = cur_addend; ++ ++ vaddr += bfd_get_reloc_size (reloc->howto); ++ } ++ ++ cur_addend = 0; ++ prev_cmd = -1; ++ cur_sym = NULL; ++ cur_psidx = -1; ++ } ++ } ++ vms_debug2 ((3, "sw_64_vms_slurp_relocs: result = TRUE\n")); ++ ++ return TRUE; ++} ++ ++/* Return the number of bytes required to store the relocation ++ information associated with the given section. */ ++ ++static long ++sw_64_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section) ++{ ++ sw_64_vms_slurp_relocs (abfd); ++ ++ return (section->reloc_count + 1) * sizeof (arelent *); ++} ++ ++/* Convert relocations from VMS (external) form into BFD internal ++ form. Return the number of relocations. */ ++ ++static long ++sw_64_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr, ++ asymbol **symbols ATTRIBUTE_UNUSED) ++{ ++ arelent *tblptr; ++ int count; ++ ++ if (!sw_64_vms_slurp_relocs (abfd)) ++ return -1; ++ ++ count = section->reloc_count; ++ tblptr = section->relocation; ++ ++ while (count--) ++ *relptr++ = tblptr++; ++ ++ *relptr = (arelent *) NULL; ++ return section->reloc_count; ++} ++ ++/* Install a new set of internal relocs. */ ++ ++#define sw_64_vms_set_reloc _bfd_generic_set_reloc ++ ++ ++/* This is just copied from ecoff-sw_64, needs to be fixed probably. */ ++ ++/* How to process the various reloc types. */ ++ ++static bfd_reloc_status_type ++reloc_nil (bfd * abfd ATTRIBUTE_UNUSED, ++ arelent *reloc ATTRIBUTE_UNUSED, ++ asymbol *sym ATTRIBUTE_UNUSED, ++ void * data ATTRIBUTE_UNUSED, ++ asection *sec ATTRIBUTE_UNUSED, ++ bfd *output_bfd ATTRIBUTE_UNUSED, ++ char **error_message ATTRIBUTE_UNUSED) ++{ ++#if VMS_DEBUG ++ vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd); ++ vms_debug (2, "In section %s, symbol %s\n", ++ sec->name, sym->name); ++ vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n", ++ reloc->sym_ptr_ptr[0]->name, ++ (unsigned long)reloc->address, ++ (unsigned long)reloc->addend, reloc->howto->name); ++ vms_debug (2, "data at %p\n", data); ++ /* _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */ ++#endif ++ ++ return bfd_reloc_ok; ++} ++ ++/* In case we're on a 32-bit machine, construct a 64-bit "-1" value ++ from smaller values. Start with zero, widen, *then* decrement. */ ++#define MINUS_ONE (((bfd_vma)0) - 1) ++ ++static reloc_howto_type sw_64_howto_table[] = ++{ ++ HOWTO (SW_64_R_IGNORE, /* Type. */ ++ 0, /* Rightshift. */ ++ 0, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 8, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "IGNORE", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0, /* Source mask */ ++ 0, /* Dest mask. */ ++ TRUE), /* PC rel offset. */ ++ ++ /* A 64 bit reference to a symbol. */ ++ HOWTO (SW_64_R_REFQUAD, /* Type. */ ++ 0, /* Rightshift. */ ++ 4, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 64, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_bitfield, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "REFQUAD", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ MINUS_ONE, /* Source mask. */ ++ MINUS_ONE, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* A 21 bit branch. The native assembler generates these for ++ branches within the text segment, and also fills in the PC ++ relative offset in the instruction. */ ++ HOWTO (SW_64_R_BRADDR, /* Type. */ ++ 2, /* Rightshift. */ ++ 2, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 21, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_signed, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "BRADDR", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0x1fffff, /* Source mask. */ ++ 0x1fffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* A hint for a jump to a register. */ ++ HOWTO (SW_64_R_HINT, /* Type. */ ++ 2, /* Rightshift. */ ++ 1, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 14, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "HINT", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0x3fff, /* Source mask. */ ++ 0x3fff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* 16 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL16, /* Type. */ ++ 0, /* Rightshift. */ ++ 1, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 16, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_signed, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "SREL16", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0xffff, /* Source mask. */ ++ 0xffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* 32 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL32, /* Type. */ ++ 0, /* Rightshift. */ ++ 2, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 32, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_signed, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "SREL32", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* A 64 bit PC relative offset. */ ++ HOWTO (SW_64_R_SREL64, /* Type. */ ++ 0, /* Rightshift. */ ++ 4, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 64, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_signed, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "SREL64", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ MINUS_ONE, /* Source mask. */ ++ MINUS_ONE, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* Push a value on the reloc evaluation stack. */ ++ HOWTO (SW_64_R_OP_PUSH, /* Type. */ ++ 0, /* Rightshift. */ ++ 0, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "OP_PUSH", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0, /* Source mask. */ ++ 0, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* Store the value from the stack at the given address. Store it in ++ a bitfield of size r_size starting at bit position r_offset. */ ++ HOWTO (SW_64_R_OP_STORE, /* Type. */ ++ 0, /* Rightshift. */ ++ 4, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 64, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "OP_STORE", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0, /* Source mask. */ ++ MINUS_ONE, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* Subtract the reloc address from the value on the top of the ++ relocation stack. */ ++ HOWTO (SW_64_R_OP_PSUB, /* Type. */ ++ 0, /* Rightshift. */ ++ 0, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "OP_PSUB", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0, /* Source mask. */ ++ 0, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* Shift the value on the top of the relocation stack right by the ++ given value. */ ++ HOWTO (SW_64_R_OP_PRSHIFT, /* Type. */ ++ 0, /* Rightshift. */ ++ 0, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "OP_PRSHIFT", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0, /* Source mask. */ ++ 0, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* Hack. Linkage is done by linker. */ ++ HOWTO (SW_64_R_LINKAGE, /* Type. */ ++ 0, /* Rightshift. */ ++ 8, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 256, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "LINKAGE", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0, /* Source mask. */ ++ 0, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* A 32 bit reference to a symbol. */ ++ HOWTO (SW_64_R_REFLONG, /* Type. */ ++ 0, /* Rightshift. */ ++ 2, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 32, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_bitfield, /* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "REFLONG", /* Name. */ ++ TRUE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ /* A 64 bit reference to a procedure, written as 32 bit value. */ ++ HOWTO (SW_64_R_CODEADDR, /* Type. */ ++ 0, /* Rightshift. */ ++ 4, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 64, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_signed,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "CODEADDR", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ HOWTO (SW_64_R_NOP, /* Type. */ ++ 0, /* Rightshift. */ ++ 3, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ /* The following value must match that of SW_64_R_BSR/SW_64_R_BOH ++ because the calculations for the 3 relocations are the same. ++ See B.4.5.2 of the OpenVMS Linker Utility Manual. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "NOP", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ HOWTO (SW_64_R_BSR, /* Type. */ ++ 0, /* Rightshift. */ ++ 3, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "BSR", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ HOWTO (SW_64_R_LDA, /* Type. */ ++ 0, /* Rightshift. */ ++ 3, /* Size (0 = byte, 1 = short, 2 = long). */ ++ 0, /* Bitsize. */ ++ FALSE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "LDA", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++ ++ HOWTO (SW_64_R_BOH, /* Type. */ ++ 0, /* Rightshift. */ ++ 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */ ++ 0, /* Bitsize. */ ++ TRUE, /* PC relative. */ ++ 0, /* Bitpos. */ ++ complain_overflow_dont,/* Complain_on_overflow. */ ++ reloc_nil, /* Special_function. */ ++ "BOH", /* Name. */ ++ FALSE, /* Partial_inplace. */ ++ 0xffffffff, /* Source mask. */ ++ 0xffffffff, /* Dest mask. */ ++ FALSE), /* PC rel offset. */ ++}; ++ ++/* Return a pointer to a howto structure which, when invoked, will perform ++ the relocation code on data from the architecture noted. */ ++ ++static const struct reloc_howto_struct * ++sw_64_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, ++ bfd_reloc_code_real_type code) ++{ ++ int sw_64_type; ++ ++ vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code)); ++ ++ switch (code) ++ { ++ case BFD_RELOC_16: sw_64_type = SW_64_R_SREL16; break; ++ case BFD_RELOC_32: sw_64_type = SW_64_R_REFLONG; break; ++ case BFD_RELOC_64: sw_64_type = SW_64_R_REFQUAD; break; ++ case BFD_RELOC_CTOR: sw_64_type = SW_64_R_REFQUAD; break; ++#ifndef XWB20200308 ++ case BFD_RELOC_20_PCREL_S2: alpha_type = SW_64_R_BR18ADDR; break; ++#endif ++ case BFD_RELOC_23_PCREL_S2: sw_64_type = SW_64_R_BRADDR; break; ++ case BFD_RELOC_SW_64_HINT: sw_64_type = SW_64_R_HINT; break; ++ case BFD_RELOC_16_PCREL: sw_64_type = SW_64_R_SREL16; break; ++ case BFD_RELOC_32_PCREL: sw_64_type = SW_64_R_SREL32; break; ++ case BFD_RELOC_64_PCREL: sw_64_type = SW_64_R_SREL64; break; ++ case BFD_RELOC_SW_64_LINKAGE: sw_64_type = SW_64_R_LINKAGE; break; ++ case BFD_RELOC_SW_64_CODEADDR: sw_64_type = SW_64_R_CODEADDR; break; ++ case BFD_RELOC_SW_64_NOP: sw_64_type = SW_64_R_NOP; break; ++ case BFD_RELOC_SW_64_BSR: sw_64_type = SW_64_R_BSR; break; ++ case BFD_RELOC_SW_64_LDA: sw_64_type = SW_64_R_LDA; break; ++ case BFD_RELOC_SW_64_BOH: sw_64_type = SW_64_R_BOH; break; ++ default: ++ _bfd_error_handler (_("reloc (%d) is *UNKNOWN*"), code); ++ return NULL; ++ } ++ vms_debug2 ((2, "reloc is %s\n", sw_64_howto_table[sw_64_type].name)); ++ return & sw_64_howto_table[sw_64_type]; ++} ++ ++static reloc_howto_type * ++sw_64_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ const char *r_name) ++{ ++ unsigned int i; ++ ++ for (i = 0; ++ i < sizeof (sw_64_howto_table) / sizeof (sw_64_howto_table[0]); ++ i++) ++ if (sw_64_howto_table[i].name != NULL ++ && strcasecmp (sw_64_howto_table[i].name, r_name) == 0) ++ return &sw_64_howto_table[i]; ++ ++ return NULL; ++} ++ ++static long ++sw_64_vms_get_synthetic_symtab (bfd *abfd, ++ long symcount ATTRIBUTE_UNUSED, ++ asymbol **usyms ATTRIBUTE_UNUSED, ++ long dynsymcount ATTRIBUTE_UNUSED, ++ asymbol **dynsyms ATTRIBUTE_UNUSED, ++ asymbol **ret) ++{ ++ asymbol *syms; ++ unsigned int i; ++ unsigned int n = 0; ++ ++ syms = (asymbol *) bfd_malloc (PRIV (norm_sym_count) * sizeof (asymbol)); ++ *ret = syms; ++ if (syms == NULL) ++ return -1; ++ ++ for (i = 0; i < PRIV (gsd_sym_count); i++) ++ { ++ struct vms_symbol_entry *e = PRIV (syms)[i]; ++ asymbol *sym; ++ flagword flags; ++ symvalue value; ++ asection *sec; ++ const char *name; ++ char *sname; ++ int l; ++ ++ name = e->name; ++ value = 0; ++ flags = BSF_LOCAL | BSF_SYNTHETIC; ++ sec = NULL; ++ ++ switch (e->typ) ++ { ++ case EGSD__C_SYM: ++ case EGSD__C_SYMG: ++ if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM)) ++ { ++ value = e->code_value; ++ sec = e->code_section; ++ } ++ else ++ continue; ++ break; ++ ++ default: ++ continue; ++ } ++ ++ l = strlen (name); ++ sname = bfd_alloc (abfd, l + 5); ++ if (sname == NULL) ++ return FALSE; ++ memcpy (sname, name, l); ++ memcpy (sname + l, "..en", 5); ++ ++ sym = &syms[n++]; ++ sym->name = sname; ++ sym->section = sec; ++ sym->flags = flags; ++ sym->value = value; ++ sym->udata.p = NULL; ++ } ++ ++ return n; ++} ++ ++/* Private dump. */ ++ ++static const char * ++vms_time_to_str (unsigned char *buf) ++{ ++ time_t t = vms_rawtime_to_time_t (buf); ++ char *res = ctime (&t); ++ ++ if (!res) ++ res = "*invalid time*"; ++ else ++ res[24] = 0; ++ return res; ++} ++ ++static void ++evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len) ++{ ++ struct vms_emh_common *emh = (struct vms_emh_common *)rec; ++ unsigned int subtype; ++ int extra; ++ ++ subtype = (unsigned) bfd_getl16 (emh->subtyp); ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); ++ ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* emh)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EMH record\n")); ++ return; ++ } ++ extra = rec_len - sizeof (struct vms_emh_common); ++ ++ switch (subtype) ++ { ++ case EMH__C_MHD: ++ { ++ struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec; ++ const char * name; ++ const char * nextname; ++ const char * maxname; ++ ++ /* PR 21840: Check for invalid lengths. */ ++ if (rec_len < sizeof (* mhd)) ++ { ++ fprintf (file, _(" Error: The record length is less than the size of an EMH_MHD record\n")); ++ return; ++ } ++ fprintf (file, _("Module header\n")); ++ fprintf (file, _(" structure level: %u\n"), mhd->strlvl); ++ fprintf (file, _(" max record size: %u\n"), ++ (unsigned) bfd_getl32 (mhd->recsiz)); ++ name = (char *)(mhd + 1); ++ maxname = (char *) rec + rec_len; ++ if (name > maxname - 2) ++ { ++ fprintf (file, _(" Error: The module name is missing\n")); ++ return; ++ } ++ nextname = name + name[0] + 1; ++ if (nextname >= maxname) ++ { ++ fprintf (file, _(" Error: The module name is too long\n")); ++ return; ++ } ++ fprintf (file, _(" module name : %.*s\n"), name[0], name + 1); ++ name = nextname; ++ if (name > maxname - 2) ++ { ++ fprintf (file, _(" Error: The module version is missing\n")); ++ return; ++ } ++ nextname = name + name[0] + 1; ++ if (nextname >= maxname) ++ { ++ fprintf (file, _(" Error: The module version is too long\n")); ++ return; ++ } ++ fprintf (file, _(" module version : %.*s\n"), name[0], name + 1); ++ name = nextname; ++ if ((maxname - name) < 17 && maxname[-1] != 0) ++ fprintf (file, _(" Error: The compile date is truncated\n")); ++ else ++ fprintf (file, _(" compile date : %.17s\n"), name); ++ } ++ break; ++ ++ case EMH__C_LNM: ++ fprintf (file, _("Language Processor Name\n")); ++ fprintf (file, _(" language name: %.*s\n"), extra, (char *)(emh + 1)); ++ break; ++ ++ case EMH__C_SRC: ++ fprintf (file, _("Source Files Header\n")); ++ fprintf (file, _(" file: %.*s\n"), extra, (char *)(emh + 1)); ++ break; ++ ++ case EMH__C_TTL: ++ fprintf (file, _("Title Text Header\n")); ++ fprintf (file, _(" title: %.*s\n"), extra, (char *)(emh + 1)); ++ break; ++ ++ case EMH__C_CPR: ++ fprintf (file, _("Copyright Header\n")); ++ fprintf (file, _(" copyright: %.*s\n"), extra, (char *)(emh + 1)); ++ break; ++ ++ default: ++ fprintf (file, _("unhandled emh subtype %u\n"), subtype); ++ break; ++ } ++} ++ ++static void ++evax_bfd_print_eeom (FILE *file, unsigned char *rec, unsigned int rec_len) ++{ ++ struct vms_eeom *eeom = (struct vms_eeom *)rec; ++ ++ fprintf (file, _(" EEOM (len=%u):\n"), rec_len); ++ ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* eeom)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EEOM record\n")); ++ return; ++ } ++ ++ fprintf (file, _(" number of cond linkage pairs: %u\n"), ++ (unsigned)bfd_getl32 (eeom->total_lps)); ++ fprintf (file, _(" completion code: %u\n"), ++ (unsigned)bfd_getl16 (eeom->comcod)); ++ if (rec_len > 10) ++ { ++ fprintf (file, _(" transfer addr flags: 0x%02x\n"), eeom->tfrflg); ++ fprintf (file, _(" transfer addr psect: %u\n"), ++ (unsigned)bfd_getl32 (eeom->psindx)); ++ fprintf (file, _(" transfer address : 0x%08x\n"), ++ (unsigned)bfd_getl32 (eeom->tfradr)); ++ } ++} ++ ++static void ++exav_bfd_print_egsy_flags (unsigned int flags, FILE *file) ++{ ++ if (flags & EGSY__V_WEAK) ++ fputs (_(" WEAK"), file); ++ if (flags & EGSY__V_DEF) ++ fputs (_(" DEF"), file); ++ if (flags & EGSY__V_UNI) ++ fputs (_(" UNI"), file); ++ if (flags & EGSY__V_REL) ++ fputs (_(" REL"), file); ++ if (flags & EGSY__V_COMM) ++ fputs (_(" COMM"), file); ++ if (flags & EGSY__V_VECEP) ++ fputs (_(" VECEP"), file); ++ if (flags & EGSY__V_NORM) ++ fputs (_(" NORM"), file); ++ if (flags & EGSY__V_QUAD_VAL) ++ fputs (_(" QVAL"), file); ++} ++ ++static void ++evax_bfd_print_egsd_flags (FILE *file, unsigned int flags) ++{ ++ if (flags & EGPS__V_PIC) ++ fputs (_(" PIC"), file); ++ if (flags & EGPS__V_LIB) ++ fputs (_(" LIB"), file); ++ if (flags & EGPS__V_OVR) ++ fputs (_(" OVR"), file); ++ if (flags & EGPS__V_REL) ++ fputs (_(" REL"), file); ++ if (flags & EGPS__V_GBL) ++ fputs (_(" GBL"), file); ++ if (flags & EGPS__V_SHR) ++ fputs (_(" SHR"), file); ++ if (flags & EGPS__V_EXE) ++ fputs (_(" EXE"), file); ++ if (flags & EGPS__V_RD) ++ fputs (_(" RD"), file); ++ if (flags & EGPS__V_WRT) ++ fputs (_(" WRT"), file); ++ if (flags & EGPS__V_VEC) ++ fputs (_(" VEC"), file); ++ if (flags & EGPS__V_NOMOD) ++ fputs (_(" NOMOD"), file); ++ if (flags & EGPS__V_COM) ++ fputs (_(" COM"), file); ++ if (flags & EGPS__V_ALLOC_64BIT) ++ fputs (_(" 64B"), file); ++} ++ ++static void ++evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len) ++{ ++ unsigned int off = sizeof (struct vms_egsd); ++ unsigned int n; ++ ++ fprintf (file, _(" EGSD (len=%u):\n"), rec_len); ++ ++ n = 0; ++ for (off = sizeof (struct vms_egsd); off < rec_len; ) ++ { ++ struct vms_egsd_entry *e = (struct vms_egsd_entry *)(rec + off); ++ unsigned int type; ++ unsigned int len; ++ ++ type = (unsigned)bfd_getl16 (e->gsdtyp); ++ len = (unsigned)bfd_getl16 (e->gsdsiz); ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" EGSD entry %2u (type: %u, len: %u): "), ++ n, type, len); ++ n++; ++ ++ if (off + len > rec_len || off + len < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ ++ switch (type) ++ { ++ case EGSD__C_PSC: ++ { ++ struct vms_egps *egps = (struct vms_egps *)e; ++ unsigned int flags = bfd_getl16 (egps->flags); ++ unsigned int l; ++ ++ fprintf (file, _("PSC - Program section definition\n")); ++ fprintf (file, _(" alignment : 2**%u\n"), egps->align); ++ fprintf (file, _(" flags : 0x%04x"), flags); ++ evax_bfd_print_egsd_flags (file, flags); ++ fputc ('\n', file); ++ l = bfd_getl32 (egps->alloc); ++ fprintf (file, _(" alloc (len): %u (0x%08x)\n"), l, l); ++ fprintf (file, _(" name : %.*s\n"), ++ egps->namlng, egps->name); ++ } ++ break; ++ case EGSD__C_SPSC: ++ { ++ struct vms_esgps *esgps = (struct vms_esgps *)e; ++ unsigned int flags = bfd_getl16 (esgps->flags); ++ unsigned int l; ++ ++ fprintf (file, _("SPSC - Shared Image Program section def\n")); ++ fprintf (file, _(" alignment : 2**%u\n"), esgps->align); ++ fprintf (file, _(" flags : 0x%04x"), flags); ++ evax_bfd_print_egsd_flags (file, flags); ++ fputc ('\n', file); ++ l = bfd_getl32 (esgps->alloc); ++ fprintf (file, _(" alloc (len) : %u (0x%08x)\n"), l, l); ++ fprintf (file, _(" image offset : 0x%08x\n"), ++ (unsigned int)bfd_getl32 (esgps->base)); ++ fprintf (file, _(" symvec offset : 0x%08x\n"), ++ (unsigned int)bfd_getl32 (esgps->value)); ++ fprintf (file, _(" name : %.*s\n"), ++ esgps->namlng, esgps->name); ++ } ++ break; ++ case EGSD__C_SYM: ++ { ++ struct vms_egsy *egsy = (struct vms_egsy *)e; ++ unsigned int flags = bfd_getl16 (egsy->flags); ++ ++ if (flags & EGSY__V_DEF) ++ { ++ struct vms_esdf *esdf = (struct vms_esdf *)e; ++ ++ fprintf (file, _("SYM - Global symbol definition\n")); ++ fprintf (file, _(" flags: 0x%04x"), flags); ++ exav_bfd_print_egsy_flags (flags, file); ++ fputc ('\n', file); ++ fprintf (file, _(" psect offset: 0x%08x\n"), ++ (unsigned)bfd_getl32 (esdf->value)); ++ if (flags & EGSY__V_NORM) ++ { ++ fprintf (file, _(" code address: 0x%08x\n"), ++ (unsigned)bfd_getl32 (esdf->code_address)); ++ fprintf (file, _(" psect index for entry point : %u\n"), ++ (unsigned)bfd_getl32 (esdf->ca_psindx)); ++ } ++ fprintf (file, _(" psect index : %u\n"), ++ (unsigned)bfd_getl32 (esdf->psindx)); ++ fprintf (file, _(" name : %.*s\n"), ++ esdf->namlng, esdf->name); ++ } ++ else ++ { ++ struct vms_esrf *esrf = (struct vms_esrf *)e; ++ ++ fprintf (file, _("SYM - Global symbol reference\n")); ++ fprintf (file, _(" name : %.*s\n"), ++ esrf->namlng, esrf->name); ++ } ++ } ++ break; ++ case EGSD__C_IDC: ++ { ++ struct vms_eidc *eidc = (struct vms_eidc *)e; ++ unsigned int flags = bfd_getl32 (eidc->flags); ++ unsigned char *p; ++ ++ fprintf (file, _("IDC - Ident Consistency check\n")); ++ fprintf (file, _(" flags : 0x%08x"), flags); ++ if (flags & EIDC__V_BINIDENT) ++ fputs (" BINDENT", file); ++ fputc ('\n', file); ++ fprintf (file, _(" id match : %x\n"), ++ (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK); ++ fprintf (file, _(" error severity: %x\n"), ++ (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK); ++ p = eidc->name; ++ fprintf (file, _(" entity name : %.*s\n"), p[0], p + 1); ++ p += 1 + p[0]; ++ fprintf (file, _(" object name : %.*s\n"), p[0], p + 1); ++ p += 1 + p[0]; ++ if (flags & EIDC__V_BINIDENT) ++ fprintf (file, _(" binary ident : 0x%08x\n"), ++ (unsigned)bfd_getl32 (p + 1)); ++ else ++ fprintf (file, _(" ascii ident : %.*s\n"), p[0], p + 1); ++ } ++ break; ++ case EGSD__C_SYMG: ++ { ++ struct vms_egst *egst = (struct vms_egst *)e; ++ unsigned int flags = bfd_getl16 (egst->header.flags); ++ ++ fprintf (file, _("SYMG - Universal symbol definition\n")); ++ fprintf (file, _(" flags: 0x%04x"), flags); ++ exav_bfd_print_egsy_flags (flags, file); ++ fputc ('\n', file); ++ fprintf (file, _(" symbol vector offset: 0x%08x\n"), ++ (unsigned)bfd_getl32 (egst->value)); ++ fprintf (file, _(" entry point: 0x%08x\n"), ++ (unsigned)bfd_getl32 (egst->lp_1)); ++ fprintf (file, _(" proc descr : 0x%08x\n"), ++ (unsigned)bfd_getl32 (egst->lp_2)); ++ fprintf (file, _(" psect index: %u\n"), ++ (unsigned)bfd_getl32 (egst->psindx)); ++ fprintf (file, _(" name : %.*s\n"), ++ egst->namlng, egst->name); ++ } ++ break; ++ case EGSD__C_SYMV: ++ { ++ struct vms_esdfv *esdfv = (struct vms_esdfv *)e; ++ unsigned int flags = bfd_getl16 (esdfv->flags); ++ ++ fprintf (file, _("SYMV - Vectored symbol definition\n")); ++ fprintf (file, _(" flags: 0x%04x"), flags); ++ exav_bfd_print_egsy_flags (flags, file); ++ fputc ('\n', file); ++ fprintf (file, _(" vector : 0x%08x\n"), ++ (unsigned)bfd_getl32 (esdfv->vector)); ++ fprintf (file, _(" psect offset: %u\n"), ++ (unsigned)bfd_getl32 (esdfv->value)); ++ fprintf (file, _(" psect index : %u\n"), ++ (unsigned)bfd_getl32 (esdfv->psindx)); ++ fprintf (file, _(" name : %.*s\n"), ++ esdfv->namlng, esdfv->name); ++ } ++ break; ++ case EGSD__C_SYMM: ++ { ++ struct vms_esdfm *esdfm = (struct vms_esdfm *)e; ++ unsigned int flags = bfd_getl16 (esdfm->flags); ++ ++ fprintf (file, _("SYMM - Global symbol definition with version\n")); ++ fprintf (file, _(" flags: 0x%04x"), flags); ++ exav_bfd_print_egsy_flags (flags, file); ++ fputc ('\n', file); ++ fprintf (file, _(" version mask: 0x%08x\n"), ++ (unsigned)bfd_getl32 (esdfm->version_mask)); ++ fprintf (file, _(" psect offset: %u\n"), ++ (unsigned)bfd_getl32 (esdfm->value)); ++ fprintf (file, _(" psect index : %u\n"), ++ (unsigned)bfd_getl32 (esdfm->psindx)); ++ fprintf (file, _(" name : %.*s\n"), ++ esdfm->namlng, esdfm->name); ++ } ++ break; ++ default: ++ fprintf (file, _("unhandled egsd entry type %u\n"), type); ++ break; ++ } ++ off += len; ++ } ++} ++ ++static void ++evax_bfd_print_hex (FILE *file, const char *pfx, ++ const unsigned char *buf, unsigned int len) ++{ ++ unsigned int i; ++ unsigned int n; ++ ++ n = 0; ++ for (i = 0; i < len; i++) ++ { ++ if (n == 0) ++ fputs (pfx, file); ++ fprintf (file, " %02x", buf[i]); ++ n++; ++ if (n == 16) ++ { ++ n = 0; ++ fputc ('\n', file); ++ } ++ } ++ if (n != 0) ++ fputc ('\n', file); ++} ++ ++static void ++evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps) ++{ ++ /* xgettext:c-format */ ++ fprintf (file, _(" linkage index: %u, replacement insn: 0x%08x\n"), ++ (unsigned)bfd_getl32 (buf), ++ (unsigned)bfd_getl32 (buf + 16)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" psect idx 1: %u, offset 1: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf + 4), ++ (unsigned)bfd_getl32 (buf + 12), ++ (unsigned)bfd_getl32 (buf + 8)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" psect idx 2: %u, offset 2: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf + 20), ++ (unsigned)bfd_getl32 (buf + 28), ++ (unsigned)bfd_getl32 (buf + 24)); ++ if (is_ps) ++ /* xgettext:c-format */ ++ fprintf (file, _(" psect idx 3: %u, offset 3: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf + 32), ++ (unsigned)bfd_getl32 (buf + 40), ++ (unsigned)bfd_getl32 (buf + 36)); ++ else ++ fprintf (file, _(" global name: %.*s\n"), buf[32], buf + 33); ++} ++ ++static void ++evax_bfd_print_etir (FILE *file, const char *name, ++ unsigned char *rec, unsigned int rec_len) ++{ ++ unsigned int off = sizeof (struct vms_egsd); ++ unsigned int sec_len = 0; ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" %s (len=%u+%u):\n"), name, ++ (unsigned)(rec_len - sizeof (struct vms_eobjrec)), ++ (unsigned)sizeof (struct vms_eobjrec)); ++ ++ for (off = sizeof (struct vms_eobjrec); off < rec_len; ) ++ { ++ struct vms_etir *etir = (struct vms_etir *)(rec + off); ++ unsigned char *buf; ++ unsigned int type; ++ unsigned int size; ++ ++ type = bfd_getl16 (etir->rectyp); ++ size = bfd_getl16 (etir->size); ++ buf = rec + off + sizeof (struct vms_etir); ++ ++ if (off + size > rec_len || off + size < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4); ++ switch (type) ++ { ++ case ETIR__C_STA_GBL: ++ fprintf (file, _("STA_GBL (stack global) %.*s\n"), ++ buf[0], buf + 1); ++ break; ++ case ETIR__C_STA_LW: ++ fprintf (file, _("STA_LW (stack longword) 0x%08x\n"), ++ (unsigned)bfd_getl32 (buf)); ++ break; ++ case ETIR__C_STA_QW: ++ fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf + 4), ++ (unsigned)bfd_getl32 (buf + 0)); ++ break; ++ case ETIR__C_STA_PQ: ++ fprintf (file, _("STA_PQ (stack psect base + offset)\n")); ++ /* xgettext:c-format */ ++ fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf + 0), ++ (unsigned)bfd_getl32 (buf + 8), ++ (unsigned)bfd_getl32 (buf + 4)); ++ break; ++ case ETIR__C_STA_LI: ++ fprintf (file, _("STA_LI (stack literal)\n")); ++ break; ++ case ETIR__C_STA_MOD: ++ fprintf (file, _("STA_MOD (stack module)\n")); ++ break; ++ case ETIR__C_STA_CKARG: ++ fprintf (file, _("STA_CKARG (compare procedure argument)\n")); ++ break; ++ ++ case ETIR__C_STO_B: ++ fprintf (file, _("STO_B (store byte)\n")); ++ break; ++ case ETIR__C_STO_W: ++ fprintf (file, _("STO_W (store word)\n")); ++ break; ++ case ETIR__C_STO_LW: ++ fprintf (file, _("STO_LW (store longword)\n")); ++ break; ++ case ETIR__C_STO_QW: ++ fprintf (file, _("STO_QW (store quadword)\n")); ++ break; ++ case ETIR__C_STO_IMMR: ++ { ++ unsigned int len = bfd_getl32 (buf); ++ fprintf (file, ++ _("STO_IMMR (store immediate repeat) %u bytes\n"), ++ len); ++ evax_bfd_print_hex (file, " ", buf + 4, len); ++ sec_len += len; ++ } ++ break; ++ case ETIR__C_STO_GBL: ++ fprintf (file, _("STO_GBL (store global) %.*s\n"), ++ buf[0], buf + 1); ++ break; ++ case ETIR__C_STO_CA: ++ fprintf (file, _("STO_CA (store code address) %.*s\n"), ++ buf[0], buf + 1); ++ break; ++ case ETIR__C_STO_RB: ++ fprintf (file, _("STO_RB (store relative branch)\n")); ++ break; ++ case ETIR__C_STO_AB: ++ fprintf (file, _("STO_AB (store absolute branch)\n")); ++ break; ++ case ETIR__C_STO_OFF: ++ fprintf (file, _("STO_OFF (store offset to psect)\n")); ++ break; ++ case ETIR__C_STO_IMM: ++ { ++ unsigned int len = bfd_getl32 (buf); ++ fprintf (file, ++ _("STO_IMM (store immediate) %u bytes\n"), ++ len); ++ evax_bfd_print_hex (file, " ", buf + 4, len); ++ sec_len += len; ++ } ++ break; ++ case ETIR__C_STO_GBL_LW: ++ fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"), ++ buf[0], buf + 1); ++ break; ++ case ETIR__C_STO_LP_PSB: ++ fprintf (file, _("STO_OFF (store LP with procedure signature)\n")); ++ break; ++ case ETIR__C_STO_HINT_GBL: ++ fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n")); ++ break; ++ case ETIR__C_STO_HINT_PS: ++ fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n")); ++ break; ++ ++ case ETIR__C_OPR_NOP: ++ fprintf (file, _("OPR_NOP (no-operation)\n")); ++ break; ++ case ETIR__C_OPR_ADD: ++ fprintf (file, _("OPR_ADD (add)\n")); ++ break; ++ case ETIR__C_OPR_SUB: ++ fprintf (file, _("OPR_SUB (subtract)\n")); ++ break; ++ case ETIR__C_OPR_MUL: ++ fprintf (file, _("OPR_MUL (multiply)\n")); ++ break; ++ case ETIR__C_OPR_DIV: ++ fprintf (file, _("OPR_DIV (divide)\n")); ++ break; ++ case ETIR__C_OPR_AND: ++ fprintf (file, _("OPR_AND (logical and)\n")); ++ break; ++ case ETIR__C_OPR_IOR: ++ fprintf (file, _("OPR_IOR (logical inclusive or)\n")); ++ break; ++ case ETIR__C_OPR_EOR: ++ fprintf (file, _("OPR_EOR (logical exclusive or)\n")); ++ break; ++ case ETIR__C_OPR_NEG: ++ fprintf (file, _("OPR_NEG (negate)\n")); ++ break; ++ case ETIR__C_OPR_COM: ++ fprintf (file, _("OPR_COM (complement)\n")); ++ break; ++ case ETIR__C_OPR_INSV: ++ fprintf (file, _("OPR_INSV (insert field)\n")); ++ break; ++ case ETIR__C_OPR_ASH: ++ fprintf (file, _("OPR_ASH (arithmetic shift)\n")); ++ break; ++ case ETIR__C_OPR_USH: ++ fprintf (file, _("OPR_USH (unsigned shift)\n")); ++ break; ++ case ETIR__C_OPR_ROT: ++ fprintf (file, _("OPR_ROT (rotate)\n")); ++ break; ++ case ETIR__C_OPR_SEL: ++ fprintf (file, _("OPR_SEL (select)\n")); ++ break; ++ case ETIR__C_OPR_REDEF: ++ fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n")); ++ break; ++ case ETIR__C_OPR_DFLIT: ++ fprintf (file, _("OPR_REDEF (define a literal)\n")); ++ break; ++ ++ case ETIR__C_STC_LP: ++ fprintf (file, _("STC_LP (store cond linkage pair)\n")); ++ break; ++ case ETIR__C_STC_LP_PSB: ++ fprintf (file, ++ _("STC_LP_PSB (store cond linkage pair + signature)\n")); ++ /* xgettext:c-format */ ++ fprintf (file, _(" linkage index: %u, procedure: %.*s\n"), ++ (unsigned)bfd_getl32 (buf), buf[4], buf + 5); ++ buf += 4 + 1 + buf[4]; ++ fprintf (file, _(" signature: %.*s\n"), buf[0], buf + 1); ++ break; ++ case ETIR__C_STC_GBL: ++ fprintf (file, _("STC_GBL (store cond global)\n")); ++ /* xgettext:c-format */ ++ fprintf (file, _(" linkage index: %u, global: %.*s\n"), ++ (unsigned)bfd_getl32 (buf), buf[4], buf + 5); ++ break; ++ case ETIR__C_STC_GCA: ++ fprintf (file, _("STC_GCA (store cond code address)\n")); ++ /* xgettext:c-format */ ++ fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"), ++ (unsigned)bfd_getl32 (buf), buf[4], buf + 5); ++ break; ++ case ETIR__C_STC_PS: ++ fprintf (file, _("STC_PS (store cond psect + offset)\n")); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (buf), ++ (unsigned)bfd_getl32 (buf + 4), ++ (unsigned)bfd_getl32 (buf + 12), ++ (unsigned)bfd_getl32 (buf + 8)); ++ break; ++ case ETIR__C_STC_NOP_GBL: ++ fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 0); ++ break; ++ case ETIR__C_STC_NOP_PS: ++ fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 1); ++ break; ++ case ETIR__C_STC_BSR_GBL: ++ fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 0); ++ break; ++ case ETIR__C_STC_BSR_PS: ++ fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 1); ++ break; ++ case ETIR__C_STC_LDA_GBL: ++ fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 0); ++ break; ++ case ETIR__C_STC_LDA_PS: ++ fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 1); ++ break; ++ case ETIR__C_STC_BOH_GBL: ++ fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 0); ++ break; ++ case ETIR__C_STC_BOH_PS: ++ fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n")); ++ evax_bfd_print_etir_stc_ir (file, buf, 1); ++ break; ++ case ETIR__C_STC_NBH_GBL: ++ fprintf (file, ++ _("STC_NBH_GBL (store cond or hint at global addr)\n")); ++ break; ++ case ETIR__C_STC_NBH_PS: ++ fprintf (file, ++ _("STC_NBH_PS (store cond or hint at psect + offset)\n")); ++ break; ++ ++ case ETIR__C_CTL_SETRB: ++ fprintf (file, _("CTL_SETRB (set relocation base)\n")); ++ sec_len += 4; ++ break; ++ case ETIR__C_CTL_AUGRB: ++ { ++ unsigned int val = bfd_getl32 (buf); ++ fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val); ++ } ++ break; ++ case ETIR__C_CTL_DFLOC: ++ fprintf (file, _("CTL_DFLOC (define location)\n")); ++ break; ++ case ETIR__C_CTL_STLOC: ++ fprintf (file, _("CTL_STLOC (set location)\n")); ++ break; ++ case ETIR__C_CTL_STKDL: ++ fprintf (file, _("CTL_STKDL (stack defined location)\n")); ++ break; ++ default: ++ fprintf (file, _("*unhandled*\n")); ++ break; ++ } ++ off += size; ++ } ++} ++ ++static void ++evax_bfd_print_eobj (struct bfd *abfd, FILE *file) ++{ ++ bfd_boolean is_first = TRUE; ++ bfd_boolean has_records = FALSE; ++ ++ while (1) ++ { ++ unsigned int rec_len; ++ unsigned int pad_len; ++ unsigned char *rec; ++ unsigned int hdr_size; ++ unsigned int type; ++ ++ if (is_first) ++ { ++ unsigned char buf[6]; ++ ++ is_first = FALSE; ++ ++ /* Read 6 bytes. */ ++ if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf)) ++ { ++ fprintf (file, _("cannot read GST record length\n")); ++ return; ++ } ++ rec_len = bfd_getl16 (buf + 0); ++ if (rec_len == bfd_getl16 (buf + 4) ++ && bfd_getl16 (buf + 2) == EOBJ__C_EMH) ++ { ++ /* The format is raw: record-size, type, record-size. */ ++ has_records = TRUE; ++ pad_len = (rec_len + 1) & ~1U; ++ hdr_size = 4; ++ } ++ else if (rec_len == EOBJ__C_EMH) ++ { ++ has_records = FALSE; ++ pad_len = bfd_getl16 (buf + 2); ++ hdr_size = 6; ++ } ++ else ++ { ++ /* Ill-formed. */ ++ fprintf (file, _("cannot find EMH in first GST record\n")); ++ return; ++ } ++ rec = bfd_malloc (pad_len); ++ memcpy (rec, buf + sizeof (buf) - hdr_size, hdr_size); ++ } ++ else ++ { ++ unsigned int rec_len2 = 0; ++ unsigned char hdr[4]; ++ ++ if (has_records) ++ { ++ unsigned char buf_len[2]; ++ ++ if (bfd_bread (buf_len, sizeof (buf_len), abfd) ++ != sizeof (buf_len)) ++ { ++ fprintf (file, _("cannot read GST record length\n")); ++ return; ++ } ++ rec_len2 = (unsigned)bfd_getl16 (buf_len); ++ } ++ ++ if (bfd_bread (hdr, sizeof (hdr), abfd) != sizeof (hdr)) ++ { ++ fprintf (file, _("cannot read GST record header\n")); ++ return; ++ } ++ rec_len = (unsigned)bfd_getl16 (hdr + 2); ++ if (has_records) ++ pad_len = (rec_len + 1) & ~1U; ++ else ++ pad_len = rec_len; ++ rec = bfd_malloc (pad_len); ++ memcpy (rec, hdr, sizeof (hdr)); ++ hdr_size = sizeof (hdr); ++ if (has_records && rec_len2 != rec_len) ++ { ++ fprintf (file, _(" corrupted GST\n")); ++ break; ++ } ++ } ++ ++ if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd) ++ != pad_len - hdr_size) ++ { ++ fprintf (file, _("cannot read GST record\n")); ++ return; ++ } ++ ++ type = (unsigned)bfd_getl16 (rec); ++ ++ switch (type) ++ { ++ case EOBJ__C_EMH: ++ evax_bfd_print_emh (file, rec, rec_len); ++ break; ++ case EOBJ__C_EGSD: ++ evax_bfd_print_egsd (file, rec, rec_len); ++ break; ++ case EOBJ__C_EEOM: ++ evax_bfd_print_eeom (file, rec, rec_len); ++ free (rec); ++ return; ++ break; ++ case EOBJ__C_ETIR: ++ evax_bfd_print_etir (file, "ETIR", rec, rec_len); ++ break; ++ case EOBJ__C_EDBG: ++ evax_bfd_print_etir (file, "EDBG", rec, rec_len); ++ break; ++ case EOBJ__C_ETBT: ++ evax_bfd_print_etir (file, "ETBT", rec, rec_len); ++ break; ++ default: ++ fprintf (file, _(" unhandled EOBJ record type %u\n"), type); ++ break; ++ } ++ free (rec); ++ } ++} ++ ++static void ++evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel, ++ unsigned int stride) ++{ ++ while (1) ++ { ++ unsigned int base; ++ unsigned int count; ++ unsigned int j; ++ ++ count = bfd_getl32 (rel + 0); ++ ++ if (count == 0) ++ break; ++ base = bfd_getl32 (rel + 4); ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" bitcount: %u, base addr: 0x%08x\n"), ++ count, base); ++ ++ rel += 8; ++ for (j = 0; count > 0; j += 4, count -= 32) ++ { ++ unsigned int k; ++ unsigned int n = 0; ++ unsigned int val; ++ ++ val = bfd_getl32 (rel); ++ rel += 4; ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" bitmap: 0x%08x (count: %u):\n"), val, count); ++ ++ for (k = 0; k < 32; k++) ++ if (val & (1 << k)) ++ { ++ if (n == 0) ++ fputs (" ", file); ++ fprintf (file, _(" %08x"), base + (j * 8 + k) * stride); ++ n++; ++ if (n == 8) ++ { ++ fputs ("\n", file); ++ n = 0; ++ } ++ } ++ if (n) ++ fputs ("\n", file); ++ } ++ } ++} ++ ++static void ++evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel) ++{ ++ while (1) ++ { ++ unsigned int j; ++ unsigned int count; ++ ++ count = bfd_getl32 (rel + 0); ++ if (count == 0) ++ return; ++ /* xgettext:c-format */ ++ fprintf (file, _(" image %u (%u entries)\n"), ++ (unsigned)bfd_getl32 (rel + 4), count); ++ rel += 8; ++ for (j = 0; j < count; j++) ++ { ++ /* xgettext:c-format */ ++ fprintf (file, _(" offset: 0x%08x, val: 0x%08x\n"), ++ (unsigned)bfd_getl32 (rel + 0), ++ (unsigned)bfd_getl32 (rel + 4)); ++ rel += 8; ++ } ++ } ++} ++ ++static void ++evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel) ++{ ++ unsigned int count; ++ ++ while (1) ++ { ++ unsigned int j; ++ unsigned int n = 0; ++ ++ count = bfd_getl32 (rel + 0); ++ if (count == 0) ++ break; ++ /* xgettext:c-format */ ++ fprintf (file, _(" image %u (%u entries), offsets:\n"), ++ (unsigned)bfd_getl32 (rel + 4), count); ++ rel += 8; ++ for (j = 0; j < count; j++) ++ { ++ if (n == 0) ++ fputs (" ", file); ++ fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel)); ++ n++; ++ if (n == 7) ++ { ++ fputs ("\n", file); ++ n = 0; ++ } ++ rel += 4; ++ } ++ if (n) ++ fputs ("\n", file); ++ } ++} ++ ++static void ++evax_bfd_print_indent (int indent, FILE *file) ++{ ++ for (; indent; indent--) ++ fputc (' ', file); ++} ++ ++static const char * ++evax_bfd_get_dsc_name (unsigned int v) ++{ ++ switch (v) ++ { ++ case DSC__K_DTYPE_Z: ++ return "Z (Unspecified)"; ++ case DSC__K_DTYPE_V: ++ return "V (Bit)"; ++ case DSC__K_DTYPE_BU: ++ return "BU (Byte logical)"; ++ case DSC__K_DTYPE_WU: ++ return "WU (Word logical)"; ++ case DSC__K_DTYPE_LU: ++ return "LU (Longword logical)"; ++ case DSC__K_DTYPE_QU: ++ return "QU (Quadword logical)"; ++ case DSC__K_DTYPE_B: ++ return "B (Byte integer)"; ++ case DSC__K_DTYPE_W: ++ return "W (Word integer)"; ++ case DSC__K_DTYPE_L: ++ return "L (Longword integer)"; ++ case DSC__K_DTYPE_Q: ++ return "Q (Quadword integer)"; ++ case DSC__K_DTYPE_F: ++ return "F (Single-precision floating)"; ++ case DSC__K_DTYPE_D: ++ return "D (Double-precision floating)"; ++ case DSC__K_DTYPE_FC: ++ return "FC (Complex)"; ++ case DSC__K_DTYPE_DC: ++ return "DC (Double-precision Complex)"; ++ case DSC__K_DTYPE_T: ++ return "T (ASCII text string)"; ++ case DSC__K_DTYPE_NU: ++ return "NU (Numeric string, unsigned)"; ++ case DSC__K_DTYPE_NL: ++ return "NL (Numeric string, left separate sign)"; ++ case DSC__K_DTYPE_NLO: ++ return "NLO (Numeric string, left overpunched sign)"; ++ case DSC__K_DTYPE_NR: ++ return "NR (Numeric string, right separate sign)"; ++ case DSC__K_DTYPE_NRO: ++ return "NRO (Numeric string, right overpunched sig)"; ++ case DSC__K_DTYPE_NZ: ++ return "NZ (Numeric string, zoned sign)"; ++ case DSC__K_DTYPE_P: ++ return "P (Packed decimal string)"; ++ case DSC__K_DTYPE_ZI: ++ return "ZI (Sequence of instructions)"; ++ case DSC__K_DTYPE_ZEM: ++ return "ZEM (Procedure entry mask)"; ++ case DSC__K_DTYPE_DSC: ++ return "DSC (Descriptor, used for arrays of dyn strings)"; ++ case DSC__K_DTYPE_OU: ++ return "OU (Octaword logical)"; ++ case DSC__K_DTYPE_O: ++ return "O (Octaword integer)"; ++ case DSC__K_DTYPE_G: ++ return "G (Double precision G floating, 64 bit)"; ++ case DSC__K_DTYPE_H: ++ return "H (Quadruple precision floating, 128 bit)"; ++ case DSC__K_DTYPE_GC: ++ return "GC (Double precision complex, G floating)"; ++ case DSC__K_DTYPE_HC: ++ return "HC (Quadruple precision complex, H floating)"; ++ case DSC__K_DTYPE_CIT: ++ return "CIT (COBOL intermediate temporary)"; ++ case DSC__K_DTYPE_BPV: ++ return "BPV (Bound Procedure Value)"; ++ case DSC__K_DTYPE_BLV: ++ return "BLV (Bound Label Value)"; ++ case DSC__K_DTYPE_VU: ++ return "VU (Bit Unaligned)"; ++ case DSC__K_DTYPE_ADT: ++ return "ADT (Absolute Date-Time)"; ++ case DSC__K_DTYPE_VT: ++ return "VT (Varying Text)"; ++ case DSC__K_DTYPE_T2: ++ return "T2 (16-bit char)"; ++ case DSC__K_DTYPE_VT2: ++ return "VT2 (16-bit varying char)"; ++ default: ++ return "?? (unknown)"; ++ } ++} ++ ++static void ++evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) ++{ ++ unsigned char bclass = buf[3]; ++ unsigned char dtype = buf[2]; ++ unsigned int len = (unsigned)bfd_getl16 (buf); ++ unsigned int pointer = (unsigned)bfd_getl32 (buf + 4); ++ ++ evax_bfd_print_indent (indent, file); ++ ++ if (len == 1 && pointer == 0xffffffffUL) ++ { ++ /* 64 bits. */ ++ fprintf (file, _("64 bits *unhandled*\n")); ++ } ++ else ++ { ++ /* xgettext:c-format */ ++ fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"), ++ bclass, dtype, len, pointer); ++ switch (bclass) ++ { ++ case DSC__K_CLASS_NCA: ++ { ++ const struct vms_dsc_nca *dsc = (const void *)buf; ++ unsigned int i; ++ const unsigned char *b; ++ ++ evax_bfd_print_indent (indent, file); ++ fprintf (file, _("non-contiguous array of %s\n"), ++ evax_bfd_get_dsc_name (dsc->dtype)); ++ evax_bfd_print_indent (indent + 1, file); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"), ++ dsc->dimct, dsc->aflags, dsc->digits, dsc->scale); ++ evax_bfd_print_indent (indent + 1, file); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _("arsize: %u, a0: 0x%08x\n"), ++ (unsigned)bfd_getl32 (dsc->arsize), ++ (unsigned)bfd_getl32 (dsc->a0)); ++ evax_bfd_print_indent (indent + 1, file); ++ fprintf (file, _("Strides:\n")); ++ b = buf + sizeof (*dsc); ++ for (i = 0; i < dsc->dimct; i++) ++ { ++ evax_bfd_print_indent (indent + 2, file); ++ fprintf (file, "[%u]: %u\n", i + 1, ++ (unsigned)bfd_getl32 (b)); ++ b += 4; ++ } ++ evax_bfd_print_indent (indent + 1, file); ++ fprintf (file, _("Bounds:\n")); ++ b = buf + sizeof (*dsc); ++ for (i = 0; i < dsc->dimct; i++) ++ { ++ evax_bfd_print_indent (indent + 2, file); ++ /* xgettext:c-format */ ++ fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1, ++ (unsigned)bfd_getl32 (b + 0), ++ (unsigned)bfd_getl32 (b + 4)); ++ b += 8; ++ } ++ } ++ break; ++ case DSC__K_CLASS_UBS: ++ { ++ const struct vms_dsc_ubs *ubs = (const void *)buf; ++ ++ evax_bfd_print_indent (indent, file); ++ fprintf (file, _("unaligned bit-string of %s\n"), ++ evax_bfd_get_dsc_name (ubs->dtype)); ++ evax_bfd_print_indent (indent + 1, file); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _("base: %u, pos: %u\n"), ++ (unsigned)bfd_getl32 (ubs->base), ++ (unsigned)bfd_getl32 (ubs->pos)); ++ } ++ break; ++ default: ++ fprintf (file, _("*unhandled*\n")); ++ break; ++ } ++ } ++} ++ ++static unsigned int ++evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) ++{ ++ unsigned int vflags = buf[0]; ++ unsigned int value = (unsigned)bfd_getl32 (buf + 1); ++ unsigned int len = 5; ++ ++ evax_bfd_print_indent (indent, file); ++ /* xgettext:c-format */ ++ fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value); ++ buf += 5; ++ ++ switch (vflags) ++ { ++ case DST__K_VFLAGS_NOVAL: ++ fprintf (file, _("(no value)\n")); ++ break; ++ case DST__K_VFLAGS_NOTACTIVE: ++ fprintf (file, _("(not active)\n")); ++ break; ++ case DST__K_VFLAGS_UNALLOC: ++ fprintf (file, _("(not allocated)\n")); ++ break; ++ case DST__K_VFLAGS_DSC: ++ fprintf (file, _("(descriptor)\n")); ++ evax_bfd_print_desc (buf + value, indent + 1, file); ++ break; ++ case DST__K_VFLAGS_TVS: ++ fprintf (file, _("(trailing value)\n")); ++ break; ++ case DST__K_VS_FOLLOWS: ++ fprintf (file, _("(value spec follows)\n")); ++ break; ++ case DST__K_VFLAGS_BITOFFS: ++ fprintf (file, _("(at bit offset %u)\n"), value); ++ break; ++ default: ++ /* xgettext:c-format */ ++ fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "), ++ (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT, ++ vflags & DST__K_DISP ? 1 : 0, ++ vflags & DST__K_INDIR ? 1 : 0); ++ switch (vflags & DST__K_VALKIND_MASK) ++ { ++ case DST__K_VALKIND_LITERAL: ++ fputs (_("literal"), file); ++ break; ++ case DST__K_VALKIND_ADDR: ++ fputs (_("address"), file); ++ break; ++ case DST__K_VALKIND_DESC: ++ fputs (_("desc"), file); ++ break; ++ case DST__K_VALKIND_REG: ++ fputs (_("reg"), file); ++ break; ++ } ++ fputs (")\n", file); ++ break; ++ } ++ return len; ++} ++ ++static void ++evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file) ++{ ++ unsigned char kind = buf[2]; ++ unsigned int len = (unsigned)bfd_getl16 (buf); ++ ++ evax_bfd_print_indent (indent, file); ++ /* xgettext:c-format */ ++ fprintf (file, _("len: %2u, kind: %2u "), len, kind); ++ buf += 3; ++ switch (kind) ++ { ++ case DST__K_TS_ATOM: ++ /* xgettext:c-format */ ++ fprintf (file, _("atomic, type=0x%02x %s\n"), ++ buf[0], evax_bfd_get_dsc_name (buf[0])); ++ break; ++ case DST__K_TS_IND: ++ fprintf (file, _("indirect, defined at 0x%08x\n"), ++ (unsigned)bfd_getl32 (buf)); ++ break; ++ case DST__K_TS_TPTR: ++ fprintf (file, _("typed pointer\n")); ++ evax_bfd_print_typspec (buf, indent + 1, file); ++ break; ++ case DST__K_TS_PTR: ++ fprintf (file, _("pointer\n")); ++ break; ++ case DST__K_TS_ARRAY: ++ { ++ const unsigned char *vs; ++ unsigned int vec_len; ++ unsigned int i; ++ ++ fprintf (file, _("array, dim: %u, bitmap: "), buf[0]); ++ vec_len = (buf[0] + 1 + 7) / 8; ++ for (i = 0; i < vec_len; i++) ++ fprintf (file, " %02x", buf[i + 1]); ++ fputc ('\n', file); ++ vs = buf + 1 + vec_len; ++ evax_bfd_print_indent (indent, file); ++ fprintf (file, _("array descriptor:\n")); ++ vs += evax_bfd_print_valspec (vs, indent + 1, file); ++ for (i = 0; i < buf[0] + 1U; i++) ++ if (buf[1 + i / 8] & (1 << (i % 8))) ++ { ++ evax_bfd_print_indent (indent, file); ++ if (i == 0) ++ fprintf (file, _("type spec for element:\n")); ++ else ++ fprintf (file, _("type spec for subscript %u:\n"), i); ++ evax_bfd_print_typspec (vs, indent + 1, file); ++ vs += bfd_getl16 (vs); ++ } ++ } ++ break; ++ default: ++ fprintf (file, _("*unhandled*\n")); ++ } ++} ++ ++static void ++evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) ++{ ++ unsigned int off = 0; ++ unsigned int pc = 0; ++ unsigned int line = 0; ++ ++ fprintf (file, _("Debug symbol table:\n")); ++ ++ while (dst_size > 0) ++ { ++ struct vms_dst_header dsth; ++ unsigned int len; ++ unsigned int type; ++ unsigned char *buf; ++ ++ if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth)) ++ { ++ fprintf (file, _("cannot read DST header\n")); ++ return; ++ } ++ len = bfd_getl16 (dsth.length); ++ type = bfd_getl16 (dsth.type); ++ /* xgettext:c-format */ ++ fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "), ++ type, len, off); ++ if (len == 0) ++ { ++ fputc ('\n', file); ++ break; ++ } ++ len++; ++ dst_size -= len; ++ off += len; ++ len -= sizeof (dsth); ++ buf = bfd_malloc (len); ++ if (bfd_bread (buf, len, abfd) != len) ++ { ++ fprintf (file, _("cannot read DST symbol\n")); ++ return; ++ } ++ switch (type) ++ { ++ case DSC__K_DTYPE_V: ++ case DSC__K_DTYPE_BU: ++ case DSC__K_DTYPE_WU: ++ case DSC__K_DTYPE_LU: ++ case DSC__K_DTYPE_QU: ++ case DSC__K_DTYPE_B: ++ case DSC__K_DTYPE_W: ++ case DSC__K_DTYPE_L: ++ case DSC__K_DTYPE_Q: ++ case DSC__K_DTYPE_F: ++ case DSC__K_DTYPE_D: ++ case DSC__K_DTYPE_FC: ++ case DSC__K_DTYPE_DC: ++ case DSC__K_DTYPE_T: ++ case DSC__K_DTYPE_NU: ++ case DSC__K_DTYPE_NL: ++ case DSC__K_DTYPE_NLO: ++ case DSC__K_DTYPE_NR: ++ case DSC__K_DTYPE_NRO: ++ case DSC__K_DTYPE_NZ: ++ case DSC__K_DTYPE_P: ++ case DSC__K_DTYPE_ZI: ++ case DSC__K_DTYPE_ZEM: ++ case DSC__K_DTYPE_DSC: ++ case DSC__K_DTYPE_OU: ++ case DSC__K_DTYPE_O: ++ case DSC__K_DTYPE_G: ++ case DSC__K_DTYPE_H: ++ case DSC__K_DTYPE_GC: ++ case DSC__K_DTYPE_HC: ++ case DSC__K_DTYPE_CIT: ++ case DSC__K_DTYPE_BPV: ++ case DSC__K_DTYPE_BLV: ++ case DSC__K_DTYPE_VU: ++ case DSC__K_DTYPE_ADT: ++ case DSC__K_DTYPE_VT: ++ case DSC__K_DTYPE_T2: ++ case DSC__K_DTYPE_VT2: ++ fprintf (file, _("standard data: %s\n"), ++ evax_bfd_get_dsc_name (type)); ++ evax_bfd_print_valspec (buf, 4, file); ++ fprintf (file, _(" name: %.*s\n"), buf[5], buf + 6); ++ break; ++ case DST__K_MODBEG: ++ { ++ struct vms_dst_modbeg *dst = (void *)buf; ++ const char *name = (const char *)buf + sizeof (*dst); ++ ++ fprintf (file, _("modbeg\n")); ++ /* xgettext:c-format */ ++ fprintf (file, _(" flags: %d, language: %u, " ++ "major: %u, minor: %u\n"), ++ dst->flags, ++ (unsigned)bfd_getl32 (dst->language), ++ (unsigned)bfd_getl16 (dst->major), ++ (unsigned)bfd_getl16 (dst->minor)); ++ fprintf (file, _(" module name: %.*s\n"), ++ name[0], name + 1); ++ name += name[0] + 1; ++ fprintf (file, _(" compiler : %.*s\n"), ++ name[0], name + 1); ++ } ++ break; ++ case DST__K_MODEND: ++ fprintf (file, _("modend\n")); ++ break; ++ case DST__K_RTNBEG: ++ { ++ struct vms_dst_rtnbeg *dst = (void *)buf; ++ const char *name = (const char *)buf + sizeof (*dst); ++ ++ fputs (_("rtnbeg\n"), file); ++ /* xgettext:c-format */ ++ fprintf (file, _(" flags: %u, address: 0x%08x, " ++ "pd-address: 0x%08x\n"), ++ dst->flags, ++ (unsigned)bfd_getl32 (dst->address), ++ (unsigned)bfd_getl32 (dst->pd_address)); ++ fprintf (file, _(" routine name: %.*s\n"), ++ name[0], name + 1); ++ } ++ break; ++ case DST__K_RTNEND: ++ { ++ struct vms_dst_rtnend *dst = (void *)buf; ++ ++ fprintf (file, _("rtnend: size 0x%08x\n"), ++ (unsigned)bfd_getl32 (dst->size)); ++ } ++ break; ++ case DST__K_PROLOG: ++ { ++ struct vms_dst_prolog *dst = (void *)buf; ++ ++ fprintf (file, _("prolog: bkpt address 0x%08x\n"), ++ (unsigned)bfd_getl32 (dst->bkpt_addr)); ++ } ++ break; ++ case DST__K_EPILOG: ++ { ++ struct vms_dst_epilog *dst = (void *)buf; ++ ++ /* xgettext:c-format */ ++ fprintf (file, _("epilog: flags: %u, count: %u\n"), ++ dst->flags, (unsigned)bfd_getl32 (dst->count)); ++ } ++ break; ++ case DST__K_BLKBEG: ++ { ++ struct vms_dst_blkbeg *dst = (void *)buf; ++ const char *name = (const char *)buf + sizeof (*dst); ++ ++ /* xgettext:c-format */ ++ fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"), ++ (unsigned)bfd_getl32 (dst->address), ++ name[0], name + 1); ++ } ++ break; ++ case DST__K_BLKEND: ++ { ++ struct vms_dst_blkend *dst = (void *)buf; ++ ++ fprintf (file, _("blkend: size: 0x%08x\n"), ++ (unsigned)bfd_getl32 (dst->size)); ++ } ++ break; ++ case DST__K_TYPSPEC: ++ { ++ fprintf (file, _("typspec (len: %u)\n"), len); ++ fprintf (file, _(" name: %.*s\n"), buf[0], buf + 1); ++ evax_bfd_print_typspec (buf + 1 + buf[0], 5, file); ++ } ++ break; ++ case DST__K_SEPTYP: ++ { ++ fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6); ++ evax_bfd_print_valspec (buf, 4, file); ++ } ++ break; ++ case DST__K_RECBEG: ++ { ++ struct vms_dst_recbeg *recbeg = (void *)buf; ++ const char *name = (const char *)buf + sizeof (*recbeg); ++ ++ fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1); ++ evax_bfd_print_valspec (buf, 4, file); ++ fprintf (file, _(" len: %u bits\n"), ++ (unsigned)bfd_getl32 (name + 1 + name[0])); ++ } ++ break; ++ case DST__K_RECEND: ++ fprintf (file, _("recend\n")); ++ break; ++ case DST__K_ENUMBEG: ++ /* xgettext:c-format */ ++ fprintf (file, _("enumbeg, len: %u, name: %.*s\n"), ++ buf[0], buf[1], buf + 2); ++ break; ++ case DST__K_ENUMELT: ++ fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6); ++ evax_bfd_print_valspec (buf, 4, file); ++ break; ++ case DST__K_ENUMEND: ++ fprintf (file, _("enumend\n")); ++ break; ++ case DST__K_LABEL: ++ { ++ struct vms_dst_label *lab = (void *)buf; ++ fprintf (file, _("label, name: %.*s\n"), ++ lab->name[0], lab->name + 1); ++ fprintf (file, _(" address: 0x%08x\n"), ++ (unsigned)bfd_getl32 (lab->value)); ++ } ++ break; ++ case DST__K_DIS_RANGE: ++ { ++ unsigned int cnt = bfd_getl32 (buf); ++ unsigned char *rng = buf + 4; ++ unsigned int i; ++ ++ fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt); ++ for (i = 0; i < cnt; i++, rng += 8) ++ /* xgettext:c-format */ ++ fprintf (file, _(" address: 0x%08x, size: %u\n"), ++ (unsigned)bfd_getl32 (rng), ++ (unsigned)bfd_getl32 (rng + 4)); ++ ++ } ++ break; ++ case DST__K_LINE_NUM: ++ { ++ unsigned char *buf_orig = buf; ++ ++ fprintf (file, _("line num (len: %u)\n"), len); ++ ++ while (len > 0) ++ { ++ signed char cmd; ++ unsigned char cmdlen; ++ unsigned int val; ++ ++ cmd = buf[0]; ++ cmdlen = 0; ++ ++ fputs (" ", file); ++ ++ switch (cmd) ++ { ++ case DST__K_DELTA_PC_W: ++ val = bfd_getl16 (buf + 1); ++ fprintf (file, _("delta_pc_w %u\n"), val); ++ pc += val; ++ line++; ++ cmdlen = 3; ++ break; ++ case DST__K_INCR_LINUM: ++ val = buf[1]; ++ fprintf (file, _("incr_linum(b): +%u\n"), val); ++ line += val; ++ cmdlen = 2; ++ break; ++ case DST__K_INCR_LINUM_W: ++ val = bfd_getl16 (buf + 1); ++ fprintf (file, _("incr_linum_w: +%u\n"), val); ++ line += val; ++ cmdlen = 3; ++ break; ++ case DST__K_INCR_LINUM_L: ++ val = bfd_getl32 (buf + 1); ++ fprintf (file, _("incr_linum_l: +%u\n"), val); ++ line += val; ++ cmdlen = 5; ++ break; ++ case DST__K_SET_LINUM: ++ line = bfd_getl16 (buf + 1); ++ fprintf (file, _("set_line_num(w) %u\n"), line); ++ cmdlen = 3; ++ break; ++ case DST__K_SET_LINUM_B: ++ line = buf[1]; ++ fprintf (file, _("set_line_num_b %u\n"), line); ++ cmdlen = 2; ++ break; ++ case DST__K_SET_LINUM_L: ++ line = bfd_getl32 (buf + 1); ++ fprintf (file, _("set_line_num_l %u\n"), line); ++ cmdlen = 5; ++ break; ++ case DST__K_SET_ABS_PC: ++ pc = bfd_getl32 (buf + 1); ++ fprintf (file, _("set_abs_pc: 0x%08x\n"), pc); ++ cmdlen = 5; ++ break; ++ case DST__K_DELTA_PC_L: ++ fprintf (file, _("delta_pc_l: +0x%08x\n"), ++ (unsigned)bfd_getl32 (buf + 1)); ++ cmdlen = 5; ++ break; ++ case DST__K_TERM: ++ fprintf (file, _("term(b): 0x%02x"), buf[1]); ++ pc += buf[1]; ++ fprintf (file, _(" pc: 0x%08x\n"), pc); ++ cmdlen = 2; ++ break; ++ case DST__K_TERM_W: ++ val = bfd_getl16 (buf + 1); ++ fprintf (file, _("term_w: 0x%04x"), val); ++ pc += val; ++ fprintf (file, _(" pc: 0x%08x\n"), pc); ++ cmdlen = 3; ++ break; ++ default: ++ if (cmd <= 0) ++ { ++ fprintf (file, _("delta pc +%-4d"), -cmd); ++ line++; /* FIXME: curr increment. */ ++ pc += -cmd; ++ /* xgettext:c-format */ ++ fprintf (file, _(" pc: 0x%08x line: %5u\n"), ++ pc, line); ++ cmdlen = 1; ++ } ++ else ++ fprintf (file, _(" *unhandled* cmd %u\n"), cmd); ++ break; ++ } ++ if (cmdlen == 0) ++ break; ++ len -= cmdlen; ++ buf += cmdlen; ++ } ++ buf = buf_orig; ++ } ++ break; ++ case DST__K_SOURCE: ++ { ++ unsigned char *buf_orig = buf; ++ ++ fprintf (file, _("source (len: %u)\n"), len); ++ ++ while (len > 0) ++ { ++ signed char cmd = buf[0]; ++ unsigned char cmdlen = 0; ++ ++ switch (cmd) ++ { ++ case DST__K_SRC_DECLFILE: ++ { ++ struct vms_dst_src_decl_src *src = (void *)(buf + 1); ++ const char *name; ++ ++ /* xgettext:c-format */ ++ fprintf (file, _(" declfile: len: %u, flags: %u, " ++ "fileid: %u\n"), ++ src->length, src->flags, ++ (unsigned)bfd_getl16 (src->fileid)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" rms: cdt: 0x%08x %08x, " ++ "ebk: 0x%08x, ffb: 0x%04x, " ++ "rfo: %u\n"), ++ (unsigned)bfd_getl32 (src->rms_cdt + 4), ++ (unsigned)bfd_getl32 (src->rms_cdt + 0), ++ (unsigned)bfd_getl32 (src->rms_ebk), ++ (unsigned)bfd_getl16 (src->rms_ffb), ++ src->rms_rfo); ++ name = (const char *)buf + 1 + sizeof (*src); ++ fprintf (file, _(" filename : %.*s\n"), ++ name[0], name + 1); ++ name += name[0] + 1; ++ fprintf (file, _(" module name: %.*s\n"), ++ name[0], name + 1); ++ cmdlen = 2 + src->length; ++ } ++ break; ++ case DST__K_SRC_SETFILE: ++ fprintf (file, _(" setfile %u\n"), ++ (unsigned)bfd_getl16 (buf + 1)); ++ cmdlen = 3; ++ break; ++ case DST__K_SRC_SETREC_W: ++ fprintf (file, _(" setrec %u\n"), ++ (unsigned)bfd_getl16 (buf + 1)); ++ cmdlen = 3; ++ break; ++ case DST__K_SRC_SETREC_L: ++ fprintf (file, _(" setrec %u\n"), ++ (unsigned)bfd_getl32 (buf + 1)); ++ cmdlen = 5; ++ break; ++ case DST__K_SRC_SETLNUM_W: ++ fprintf (file, _(" setlnum %u\n"), ++ (unsigned)bfd_getl16 (buf + 1)); ++ cmdlen = 3; ++ break; ++ case DST__K_SRC_SETLNUM_L: ++ fprintf (file, _(" setlnum %u\n"), ++ (unsigned)bfd_getl32 (buf + 1)); ++ cmdlen = 5; ++ break; ++ case DST__K_SRC_DEFLINES_W: ++ fprintf (file, _(" deflines %u\n"), ++ (unsigned)bfd_getl16 (buf + 1)); ++ cmdlen = 3; ++ break; ++ case DST__K_SRC_DEFLINES_B: ++ fprintf (file, _(" deflines %u\n"), buf[1]); ++ cmdlen = 2; ++ break; ++ case DST__K_SRC_FORMFEED: ++ fprintf (file, _(" formfeed\n")); ++ cmdlen = 1; ++ break; ++ default: ++ fprintf (file, _(" *unhandled* cmd %u\n"), cmd); ++ break; ++ } ++ if (cmdlen == 0) ++ break; ++ len -= cmdlen; ++ buf += cmdlen; ++ } ++ buf = buf_orig; ++ } ++ break; ++ default: ++ fprintf (file, _("*unhandled* dst type %u\n"), type); ++ break; ++ } ++ free (buf); ++ } ++} ++ ++static void ++evax_bfd_print_image (bfd *abfd, FILE *file) ++{ ++ struct vms_eihd eihd; ++ const char *name; ++ unsigned int val; ++ unsigned int eiha_off; ++ unsigned int eihi_off; ++ unsigned int eihs_off; ++ unsigned int eisd_off; ++ unsigned int eihef_off = 0; ++ unsigned int eihnp_off = 0; ++ unsigned int dmt_vbn = 0; ++ unsigned int dmt_size = 0; ++ unsigned int dst_vbn = 0; ++ unsigned int dst_size = 0; ++ unsigned int gst_vbn = 0; ++ unsigned int gst_size = 0; ++ unsigned int eiaf_vbn = 0; ++ unsigned int eiaf_size = 0; ++ unsigned int eihvn_off; ++ ++ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) ++ || bfd_bread (&eihd, sizeof (eihd), abfd) != sizeof (eihd)) ++ { ++ fprintf (file, _("cannot read EIHD\n")); ++ return; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"), ++ (unsigned)bfd_getl32 (eihd.size), ++ (unsigned)bfd_getl32 (eihd.hdrblkcnt)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" majorid: %u, minorid: %u\n"), ++ (unsigned)bfd_getl32 (eihd.majorid), ++ (unsigned)bfd_getl32 (eihd.minorid)); ++ ++ val = (unsigned)bfd_getl32 (eihd.imgtype); ++ switch (val) ++ { ++ case EIHD__K_EXE: ++ name = _("executable"); ++ break; ++ case EIHD__K_LIM: ++ name = _("linkable image"); ++ break; ++ default: ++ name = _("unknown"); ++ break; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _(" image type: %u (%s)"), val, name); ++ ++ val = (unsigned)bfd_getl32 (eihd.subtype); ++ switch (val) ++ { ++ case EIHD__C_NATIVE: ++ name = _("native"); ++ break; ++ case EIHD__C_CLI: ++ name = _("CLI"); ++ break; ++ default: ++ name = _("unknown"); ++ break; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _(", subtype: %u (%s)\n"), val, name); ++ ++ eisd_off = bfd_getl32 (eihd.isdoff); ++ eiha_off = bfd_getl32 (eihd.activoff); ++ eihi_off = bfd_getl32 (eihd.imgidoff); ++ eihs_off = bfd_getl32 (eihd.symdbgoff); ++ /* xgettext:c-format */ ++ fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, " ++ "imgid: %u, patch: %u\n"), ++ eisd_off, eiha_off, eihs_off, eihi_off, ++ (unsigned)bfd_getl32 (eihd.patchoff)); ++ fprintf (file, _(" fixup info rva: ")); ++ bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.iafva)); ++ fprintf (file, _(", symbol vector rva: ")); ++ bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.symvva)); ++ eihvn_off = bfd_getl32 (eihd.version_array_off); ++ fprintf (file, _("\n" ++ " version array off: %u\n"), ++ eihvn_off); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"), ++ (unsigned)bfd_getl32 (eihd.imgiocnt), ++ (unsigned)bfd_getl32 (eihd.iochancnt), ++ (unsigned)bfd_getl32 (eihd.privreqs + 4), ++ (unsigned)bfd_getl32 (eihd.privreqs + 0)); ++ val = (unsigned)bfd_getl32 (eihd.lnkflags); ++ fprintf (file, _(" linker flags: %08x:"), val); ++ if (val & EIHD__M_LNKDEBUG) ++ fprintf (file, " LNKDEBUG"); ++ if (val & EIHD__M_LNKNOTFR) ++ fprintf (file, " LNKNOTFR"); ++ if (val & EIHD__M_NOP0BUFS) ++ fprintf (file, " NOP0BUFS"); ++ if (val & EIHD__M_PICIMG) ++ fprintf (file, " PICIMG"); ++ if (val & EIHD__M_P0IMAGE) ++ fprintf (file, " P0IMAGE"); ++ if (val & EIHD__M_DBGDMT) ++ fprintf (file, " DBGDMT"); ++ if (val & EIHD__M_INISHR) ++ fprintf (file, " INISHR"); ++ if (val & EIHD__M_XLATED) ++ fprintf (file, " XLATED"); ++ if (val & EIHD__M_BIND_CODE_SEC) ++ fprintf (file, " BIND_CODE_SEC"); ++ if (val & EIHD__M_BIND_DATA_SEC) ++ fprintf (file, " BIND_DATA_SEC"); ++ if (val & EIHD__M_MKTHREADS) ++ fprintf (file, " MKTHREADS"); ++ if (val & EIHD__M_UPCALLS) ++ fprintf (file, " UPCALLS"); ++ if (val & EIHD__M_OMV_READY) ++ fprintf (file, " OMV_READY"); ++ if (val & EIHD__M_EXT_BIND_SECT) ++ fprintf (file, " EXT_BIND_SECT"); ++ fprintf (file, "\n"); ++ /* xgettext:c-format */ ++ fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, " ++ "match ctrl: %u, symvect_size: %u\n"), ++ (unsigned)bfd_getl32 (eihd.ident), ++ (unsigned)bfd_getl32 (eihd.sysver), ++ eihd.matchctl, ++ (unsigned)bfd_getl32 (eihd.symvect_size)); ++ fprintf (file, _(" BPAGE: %u"), ++ (unsigned)bfd_getl32 (eihd.virt_mem_block_size)); ++ if (val & (EIHD__M_OMV_READY | EIHD__M_EXT_BIND_SECT)) ++ { ++ eihef_off = bfd_getl32 (eihd.ext_fixup_off); ++ eihnp_off = bfd_getl32 (eihd.noopt_psect_off); ++ /* xgettext:c-format */ ++ fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"), ++ eihef_off, eihnp_off); ++ } ++ fprintf (file, _(", alias: %u\n"), (unsigned)bfd_getl16 (eihd.alias)); ++ ++ if (eihvn_off != 0) ++ { ++ struct vms_eihvn eihvn; ++ unsigned int mask; ++ unsigned int j; ++ ++ fprintf (file, _("system version array information:\n")); ++ if (bfd_seek (abfd, (file_ptr) eihvn_off, SEEK_SET) ++ || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn)) ++ { ++ fprintf (file, _("cannot read EIHVN header\n")); ++ return; ++ } ++ mask = bfd_getl32 (eihvn.subsystem_mask); ++ for (j = 0; j < 32; j++) ++ if (mask & (1 << j)) ++ { ++ struct vms_eihvn_subversion ver; ++ if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver)) ++ { ++ fprintf (file, _("cannot read EIHVN version\n")); ++ return; ++ } ++ fprintf (file, _(" %02u "), j); ++ switch (j) ++ { ++ case EIHVN__BASE_IMAGE_BIT: ++ fputs (_("BASE_IMAGE "), file); ++ break; ++ case EIHVN__MEMORY_MANAGEMENT_BIT: ++ fputs (_("MEMORY_MANAGEMENT"), file); ++ break; ++ case EIHVN__IO_BIT: ++ fputs (_("IO "), file); ++ break; ++ case EIHVN__FILES_VOLUMES_BIT: ++ fputs (_("FILES_VOLUMES "), file); ++ break; ++ case EIHVN__PROCESS_SCHED_BIT: ++ fputs (_("PROCESS_SCHED "), file); ++ break; ++ case EIHVN__SYSGEN_BIT: ++ fputs (_("SYSGEN "), file); ++ break; ++ case EIHVN__CLUSTERS_LOCKMGR_BIT: ++ fputs (_("CLUSTERS_LOCKMGR "), file); ++ break; ++ case EIHVN__LOGICAL_NAMES_BIT: ++ fputs (_("LOGICAL_NAMES "), file); ++ break; ++ case EIHVN__SECURITY_BIT: ++ fputs (_("SECURITY "), file); ++ break; ++ case EIHVN__IMAGE_ACTIVATOR_BIT: ++ fputs (_("IMAGE_ACTIVATOR "), file); ++ break; ++ case EIHVN__NETWORKS_BIT: ++ fputs (_("NETWORKS "), file); ++ break; ++ case EIHVN__COUNTERS_BIT: ++ fputs (_("COUNTERS "), file); ++ break; ++ case EIHVN__STABLE_BIT: ++ fputs (_("STABLE "), file); ++ break; ++ case EIHVN__MISC_BIT: ++ fputs (_("MISC "), file); ++ break; ++ case EIHVN__CPU_BIT: ++ fputs (_("CPU "), file); ++ break; ++ case EIHVN__VOLATILE_BIT: ++ fputs (_("VOLATILE "), file); ++ break; ++ case EIHVN__SHELL_BIT: ++ fputs (_("SHELL "), file); ++ break; ++ case EIHVN__POSIX_BIT: ++ fputs (_("POSIX "), file); ++ break; ++ case EIHVN__MULTI_PROCESSING_BIT: ++ fputs (_("MULTI_PROCESSING "), file); ++ break; ++ case EIHVN__GALAXY_BIT: ++ fputs (_("GALAXY "), file); ++ break; ++ default: ++ fputs (_("*unknown* "), file); ++ break; ++ } ++ fprintf (file, ": %u.%u\n", ++ (unsigned)bfd_getl16 (ver.major), ++ (unsigned)bfd_getl16 (ver.minor)); ++ } ++ } ++ ++ if (eiha_off != 0) ++ { ++ struct vms_eiha eiha; ++ ++ if (bfd_seek (abfd, (file_ptr) eiha_off, SEEK_SET) ++ || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha)) ++ { ++ fprintf (file, _("cannot read EIHA\n")); ++ return; ++ } ++ fprintf (file, _("Image activation: (size=%u)\n"), ++ (unsigned)bfd_getl32 (eiha.size)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" First address : 0x%08x 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiha.tfradr1_h), ++ (unsigned)bfd_getl32 (eiha.tfradr1)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" Second address: 0x%08x 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiha.tfradr2_h), ++ (unsigned)bfd_getl32 (eiha.tfradr2)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" Third address : 0x%08x 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiha.tfradr3_h), ++ (unsigned)bfd_getl32 (eiha.tfradr3)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiha.tfradr4_h), ++ (unsigned)bfd_getl32 (eiha.tfradr4)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" Shared image : 0x%08x 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiha.inishr_h), ++ (unsigned)bfd_getl32 (eiha.inishr)); ++ } ++ if (eihi_off != 0) ++ { ++ struct vms_eihi eihi; ++ ++ if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET) ++ || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi)) ++ { ++ fprintf (file, _("cannot read EIHI\n")); ++ return; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _("Image identification: (major: %u, minor: %u)\n"), ++ (unsigned)bfd_getl32 (eihi.majorid), ++ (unsigned)bfd_getl32 (eihi.minorid)); ++ fprintf (file, _(" image name : %.*s\n"), ++ eihi.imgnam[0], eihi.imgnam + 1); ++ fprintf (file, _(" link time : %s\n"), ++ vms_time_to_str (eihi.linktime)); ++ fprintf (file, _(" image ident : %.*s\n"), ++ eihi.imgid[0], eihi.imgid + 1); ++ fprintf (file, _(" linker ident : %.*s\n"), ++ eihi.linkid[0], eihi.linkid + 1); ++ fprintf (file, _(" image build ident: %.*s\n"), ++ eihi.imgbid[0], eihi.imgbid + 1); ++ } ++ if (eihs_off != 0) ++ { ++ struct vms_eihs eihs; ++ ++ if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET) ++ || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs)) ++ { ++ fprintf (file, _("cannot read EIHS\n")); ++ return; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"), ++ (unsigned)bfd_getl32 (eihs.majorid), ++ (unsigned)bfd_getl32 (eihs.minorid)); ++ dst_vbn = bfd_getl32 (eihs.dstvbn); ++ dst_size = bfd_getl32 (eihs.dstsize); ++ /* xgettext:c-format */ ++ fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"), ++ dst_vbn, dst_size, dst_size); ++ gst_vbn = bfd_getl32 (eihs.gstvbn); ++ gst_size = bfd_getl32 (eihs.gstsize); ++ /* xgettext:c-format */ ++ fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"), ++ gst_vbn, gst_size); ++ dmt_vbn = bfd_getl32 (eihs.dmtvbn); ++ dmt_size = bfd_getl32 (eihs.dmtsize); ++ /* xgettext:c-format */ ++ fprintf (file, _(" debug module table : vbn: %u, size: %u\n"), ++ dmt_vbn, dmt_size); ++ } ++ while (eisd_off != 0) ++ { ++ struct vms_eisd eisd; ++ unsigned int len; ++ ++ while (1) ++ { ++ if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET) ++ || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd)) ++ { ++ fprintf (file, _("cannot read EISD\n")); ++ return; ++ } ++ len = (unsigned)bfd_getl32 (eisd.eisdsize); ++ if (len != (unsigned)-1) ++ break; ++ ++ /* Next block. */ ++ eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1); ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _("Image section descriptor: (major: %u, minor: %u, " ++ "size: %u, offset: %u)\n"), ++ (unsigned)bfd_getl32 (eisd.majorid), ++ (unsigned)bfd_getl32 (eisd.minorid), ++ len, eisd_off); ++ if (len == 0) ++ break; ++ /* xgettext:c-format */ ++ fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"), ++ (unsigned)bfd_getl32 (eisd.virt_addr + 4), ++ (unsigned)bfd_getl32 (eisd.virt_addr + 0), ++ (unsigned)bfd_getl32 (eisd.secsize)); ++ val = (unsigned)bfd_getl32 (eisd.flags); ++ fprintf (file, _(" flags: 0x%04x"), val); ++ if (val & EISD__M_GBL) ++ fprintf (file, " GBL"); ++ if (val & EISD__M_CRF) ++ fprintf (file, " CRF"); ++ if (val & EISD__M_DZRO) ++ fprintf (file, " DZRO"); ++ if (val & EISD__M_WRT) ++ fprintf (file, " WRT"); ++ if (val & EISD__M_INITALCODE) ++ fprintf (file, " INITALCODE"); ++ if (val & EISD__M_BASED) ++ fprintf (file, " BASED"); ++ if (val & EISD__M_FIXUPVEC) ++ fprintf (file, " FIXUPVEC"); ++ if (val & EISD__M_RESIDENT) ++ fprintf (file, " RESIDENT"); ++ if (val & EISD__M_VECTOR) ++ fprintf (file, " VECTOR"); ++ if (val & EISD__M_PROTECT) ++ fprintf (file, " PROTECT"); ++ if (val & EISD__M_LASTCLU) ++ fprintf (file, " LASTCLU"); ++ if (val & EISD__M_EXE) ++ fprintf (file, " EXE"); ++ if (val & EISD__M_NONSHRADR) ++ fprintf (file, " NONSHRADR"); ++ if (val & EISD__M_QUAD_LENGTH) ++ fprintf (file, " QUAD_LENGTH"); ++ if (val & EISD__M_ALLOC_64BIT) ++ fprintf (file, " ALLOC_64BIT"); ++ fprintf (file, "\n"); ++ if (val & EISD__M_FIXUPVEC) ++ { ++ eiaf_vbn = bfd_getl32 (eisd.vbn); ++ eiaf_size = bfd_getl32 (eisd.secsize); ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("), ++ (unsigned)bfd_getl32 (eisd.vbn), ++ eisd.pfc, eisd.matchctl, eisd.type); ++ switch (eisd.type) ++ { ++ case EISD__K_NORMAL: ++ fputs (_("NORMAL"), file); ++ break; ++ case EISD__K_SHRFXD: ++ fputs (_("SHRFXD"), file); ++ break; ++ case EISD__K_PRVFXD: ++ fputs (_("PRVFXD"), file); ++ break; ++ case EISD__K_SHRPIC: ++ fputs (_("SHRPIC"), file); ++ break; ++ case EISD__K_PRVPIC: ++ fputs (_("PRVPIC"), file); ++ break; ++ case EISD__K_USRSTACK: ++ fputs (_("USRSTACK"), file); ++ break; ++ default: ++ fputs (_("*unknown*"), file); ++ break; ++ } ++ fputs (_(")\n"), file); ++ if (val & EISD__M_GBL) ++ /* xgettext:c-format */ ++ fprintf (file, _(" ident: 0x%08x, name: %.*s\n"), ++ (unsigned)bfd_getl32 (eisd.ident), ++ eisd.gblnam[0], eisd.gblnam + 1); ++ eisd_off += len; ++ } ++ ++ if (dmt_vbn != 0) ++ { ++ if (bfd_seek (abfd, (file_ptr) (dmt_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)) ++ { ++ fprintf (file, _("cannot read DMT\n")); ++ return; ++ } ++ ++ fprintf (file, _("Debug module table:\n")); ++ ++ while (dmt_size > 0) ++ { ++ struct vms_dmt_header dmth; ++ unsigned int count; ++ ++ if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth)) ++ { ++ fprintf (file, _("cannot read DMT header\n")); ++ return; ++ } ++ count = bfd_getl16 (dmth.psect_count); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _(" module offset: 0x%08x, size: 0x%08x, (%u psects)\n"), ++ (unsigned)bfd_getl32 (dmth.modbeg), ++ (unsigned)bfd_getl32 (dmth.size), count); ++ dmt_size -= sizeof (dmth); ++ while (count > 0) ++ { ++ struct vms_dmt_psect dmtp; ++ ++ if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp)) ++ { ++ fprintf (file, _("cannot read DMT psect\n")); ++ return; ++ } ++ /* xgettext:c-format */ ++ fprintf (file, _(" psect start: 0x%08x, length: %u\n"), ++ (unsigned)bfd_getl32 (dmtp.start), ++ (unsigned)bfd_getl32 (dmtp.length)); ++ count--; ++ dmt_size -= sizeof (dmtp); ++ } ++ } ++ } ++ ++ if (dst_vbn != 0) ++ { ++ if (bfd_seek (abfd, (file_ptr) (dst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)) ++ { ++ fprintf (file, _("cannot read DST\n")); ++ return; ++ } ++ ++ evax_bfd_print_dst (abfd, dst_size, file); ++ } ++ if (gst_vbn != 0) ++ { ++ if (bfd_seek (abfd, (file_ptr) (gst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)) ++ { ++ fprintf (file, _("cannot read GST\n")); ++ return; ++ } ++ ++ fprintf (file, _("Global symbol table:\n")); ++ evax_bfd_print_eobj (abfd, file); ++ } ++ if (eiaf_vbn != 0) ++ { ++ unsigned char *buf; ++ struct vms_eiaf *eiaf; ++ unsigned int qrelfixoff; ++ unsigned int lrelfixoff; ++ unsigned int qdotadroff; ++ unsigned int ldotadroff; ++ unsigned int shrimgcnt; ++ unsigned int shlstoff; ++ unsigned int codeadroff; ++ unsigned int lpfixoff; ++ unsigned int chgprtoff; ++ ++ buf = bfd_malloc (eiaf_size); ++ ++ if (bfd_seek (abfd, (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) ++ || bfd_bread (buf, eiaf_size, abfd) != eiaf_size) ++ { ++ fprintf (file, _("cannot read EIHA\n")); ++ free (buf); ++ return; ++ } ++ eiaf = (struct vms_eiaf *)buf; ++ fprintf (file, ++ /* xgettext:c-format */ ++ _("Image activator fixup: (major: %u, minor: %u)\n"), ++ (unsigned)bfd_getl32 (eiaf->majorid), ++ (unsigned)bfd_getl32 (eiaf->minorid)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" iaflink : 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (eiaf->iaflink + 0), ++ (unsigned)bfd_getl32 (eiaf->iaflink + 4)); ++ /* xgettext:c-format */ ++ fprintf (file, _(" fixuplnk: 0x%08x %08x\n"), ++ (unsigned)bfd_getl32 (eiaf->fixuplnk + 0), ++ (unsigned)bfd_getl32 (eiaf->fixuplnk + 4)); ++ fprintf (file, _(" size : %u\n"), ++ (unsigned)bfd_getl32 (eiaf->size)); ++ fprintf (file, _(" flags: 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiaf->flags)); ++ qrelfixoff = bfd_getl32 (eiaf->qrelfixoff); ++ lrelfixoff = bfd_getl32 (eiaf->lrelfixoff); ++ /* xgettext:c-format */ ++ fprintf (file, _(" qrelfixoff: %5u, lrelfixoff: %5u\n"), ++ qrelfixoff, lrelfixoff); ++ qdotadroff = bfd_getl32 (eiaf->qdotadroff); ++ ldotadroff = bfd_getl32 (eiaf->ldotadroff); ++ /* xgettext:c-format */ ++ fprintf (file, _(" qdotadroff: %5u, ldotadroff: %5u\n"), ++ qdotadroff, ldotadroff); ++ codeadroff = bfd_getl32 (eiaf->codeadroff); ++ lpfixoff = bfd_getl32 (eiaf->lpfixoff); ++ /* xgettext:c-format */ ++ fprintf (file, _(" codeadroff: %5u, lpfixoff : %5u\n"), ++ codeadroff, lpfixoff); ++ chgprtoff = bfd_getl32 (eiaf->chgprtoff); ++ fprintf (file, _(" chgprtoff : %5u\n"), chgprtoff); ++ shrimgcnt = bfd_getl32 (eiaf->shrimgcnt); ++ shlstoff = bfd_getl32 (eiaf->shlstoff); ++ /* xgettext:c-format */ ++ fprintf (file, _(" shlstoff : %5u, shrimgcnt : %5u\n"), ++ shlstoff, shrimgcnt); ++ /* xgettext:c-format */ ++ fprintf (file, _(" shlextra : %5u, permctx : %5u\n"), ++ (unsigned)bfd_getl32 (eiaf->shlextra), ++ (unsigned)bfd_getl32 (eiaf->permctx)); ++ fprintf (file, _(" base_va : 0x%08x\n"), ++ (unsigned)bfd_getl32 (eiaf->base_va)); ++ fprintf (file, _(" lppsbfixoff: %5u\n"), ++ (unsigned)bfd_getl32 (eiaf->lppsbfixoff)); ++ ++ if (shlstoff) ++ { ++ struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff); ++ unsigned int j; ++ ++ fprintf (file, _(" Shareable images:\n")); ++ for (j = 0; j < shrimgcnt; j++, shl++) ++ { ++ fprintf (file, ++ /* xgettext:c-format */ ++ _(" %u: size: %u, flags: 0x%02x, name: %.*s\n"), ++ j, shl->size, shl->flags, ++ shl->imgnam[0], shl->imgnam + 1); ++ } ++ } ++ if (qrelfixoff != 0) ++ { ++ fprintf (file, _(" quad-word relocation fixups:\n")); ++ evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8); ++ } ++ if (lrelfixoff != 0) ++ { ++ fprintf (file, _(" long-word relocation fixups:\n")); ++ evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4); ++ } ++ if (qdotadroff != 0) ++ { ++ fprintf (file, _(" quad-word .address reference fixups:\n")); ++ evax_bfd_print_address_fixups (file, buf + qdotadroff); ++ } ++ if (ldotadroff != 0) ++ { ++ fprintf (file, _(" long-word .address reference fixups:\n")); ++ evax_bfd_print_address_fixups (file, buf + ldotadroff); ++ } ++ if (codeadroff != 0) ++ { ++ fprintf (file, _(" Code Address Reference Fixups:\n")); ++ evax_bfd_print_reference_fixups (file, buf + codeadroff); ++ } ++ if (lpfixoff != 0) ++ { ++ fprintf (file, _(" Linkage Pairs Reference Fixups:\n")); ++ evax_bfd_print_reference_fixups (file, buf + lpfixoff); ++ } ++ if (chgprtoff) ++ { ++ unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff); ++ struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4); ++ unsigned int j; ++ ++ fprintf (file, _(" Change Protection (%u entries):\n"), count); ++ for (j = 0; j < count; j++, eicp++) ++ { ++ unsigned int prot = bfd_getl32 (eicp->newprt); ++ fprintf (file, ++ /* xgettext:c-format */ ++ _(" base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "), ++ (unsigned)bfd_getl32 (eicp->baseva + 4), ++ (unsigned)bfd_getl32 (eicp->baseva + 0), ++ (unsigned)bfd_getl32 (eicp->size), ++ (unsigned)bfd_getl32 (eicp->newprt)); ++ switch (prot) ++ { ++ case PRT__C_NA: ++ fprintf (file, "NA"); ++ break; ++ case PRT__C_RESERVED: ++ fprintf (file, "RES"); ++ break; ++ case PRT__C_KW: ++ fprintf (file, "KW"); ++ break; ++ case PRT__C_KR: ++ fprintf (file, "KR"); ++ break; ++ case PRT__C_UW: ++ fprintf (file, "UW"); ++ break; ++ case PRT__C_EW: ++ fprintf (file, "EW"); ++ break; ++ case PRT__C_ERKW: ++ fprintf (file, "ERKW"); ++ break; ++ case PRT__C_ER: ++ fprintf (file, "ER"); ++ break; ++ case PRT__C_SW: ++ fprintf (file, "SW"); ++ break; ++ case PRT__C_SREW: ++ fprintf (file, "SREW"); ++ break; ++ case PRT__C_SRKW: ++ fprintf (file, "SRKW"); ++ break; ++ case PRT__C_SR: ++ fprintf (file, "SR"); ++ break; ++ case PRT__C_URSW: ++ fprintf (file, "URSW"); ++ break; ++ case PRT__C_UREW: ++ fprintf (file, "UREW"); ++ break; ++ case PRT__C_URKW: ++ fprintf (file, "URKW"); ++ break; ++ case PRT__C_UR: ++ fprintf (file, "UR"); ++ break; ++ default: ++ fputs ("??", file); ++ break; ++ } ++ fputc ('\n', file); ++ } ++ } ++ free (buf); ++ } ++} ++ ++static bfd_boolean ++vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr) ++{ ++ FILE *file = (FILE *)ptr; ++ ++ if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) ++ evax_bfd_print_image (abfd, file); ++ else ++ { ++ if (bfd_seek (abfd, 0, SEEK_SET)) ++ return FALSE; ++ evax_bfd_print_eobj (abfd, file); ++ } ++ return TRUE; ++} ++ ++/* Linking. */ ++ ++/* Slurp ETIR/EDBG/ETBT VMS object records. */ ++ ++static bfd_boolean ++sw_64_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) ++{ ++ asection *cur_section; ++ file_ptr cur_offset; ++ asection *dst_section; ++ file_ptr dst_offset; ++ ++ if (bfd_seek (abfd, 0, SEEK_SET) != 0) ++ return FALSE; ++ ++ cur_section = NULL; ++ cur_offset = 0; ++ ++ dst_section = PRIV (dst_section); ++ dst_offset = 0; ++ if (info) ++ { ++ if (info->strip == strip_all || info->strip == strip_debugger) ++ { ++ /* Discard the DST section. */ ++ dst_offset = 0; ++ dst_section = NULL; ++ } ++ else if (dst_section) ++ { ++ dst_offset = dst_section->output_offset; ++ dst_section = dst_section->output_section; ++ } ++ } ++ ++ while (1) ++ { ++ int type; ++ bfd_boolean res; ++ ++ type = _bfd_vms_get_object_record (abfd); ++ if (type < 0) ++ { ++ vms_debug2 ((2, "next_record failed\n")); ++ return FALSE; ++ } ++ switch (type) ++ { ++ case EOBJ__C_ETIR: ++ PRIV (image_section) = cur_section; ++ PRIV (image_offset) = cur_offset; ++ res = _bfd_vms_slurp_etir (abfd, info); ++ cur_section = PRIV (image_section); ++ cur_offset = PRIV (image_offset); ++ break; ++ case EOBJ__C_EDBG: ++ case EOBJ__C_ETBT: ++ if (dst_section == NULL) ++ continue; ++ PRIV (image_section) = dst_section; ++ PRIV (image_offset) = dst_offset; ++ res = _bfd_vms_slurp_etir (abfd, info); ++ dst_offset = PRIV (image_offset); ++ break; ++ case EOBJ__C_EEOM: ++ return TRUE; ++ default: ++ continue; ++ } ++ if (!res) ++ { ++ vms_debug2 ((2, "slurp eobj type %d failed\n", type)); ++ return FALSE; ++ } ++ } ++} ++ ++static int ++sw_64_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++/* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */ ++ ++static void ++sw_64_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib) ++{ ++ struct sw_64_vms_shlib_el *sl; ++ asection *sect = PRIV2 (src, image_section); ++ file_ptr offset = PRIV2 (src, image_offset); ++ ++ sl = &VEC_EL (sw_64_vms_link_hash (info)->shrlibs, ++ struct sw_64_vms_shlib_el, PRIV2 (shlib, shr_index)); ++ sl->has_fixups = TRUE; ++ VEC_APPEND_EL (sl->lp, bfd_vma, ++ sect->output_section->vma + sect->output_offset + offset); ++ sect->output_section->flags |= SEC_RELOC; ++} ++ ++/* Add a code address fixup at address SECT + OFFSET to SHLIB. */ ++ ++static void ++sw_64_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib) ++{ ++ struct sw_64_vms_shlib_el *sl; ++ asection *sect = PRIV2 (src, image_section); ++ file_ptr offset = PRIV2 (src, image_offset); ++ ++ sl = &VEC_EL (sw_64_vms_link_hash (info)->shrlibs, ++ struct sw_64_vms_shlib_el, PRIV2 (shlib, shr_index)); ++ sl->has_fixups = TRUE; ++ VEC_APPEND_EL (sl->ca, bfd_vma, ++ sect->output_section->vma + sect->output_offset + offset); ++ sect->output_section->flags |= SEC_RELOC; ++} ++ ++/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */ ++ ++static void ++sw_64_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src, ++ bfd *shlib, bfd_vma vec) ++{ ++ struct sw_64_vms_shlib_el *sl; ++ struct sw_64_vms_vma_ref *r; ++ asection *sect = PRIV2 (src, image_section); ++ file_ptr offset = PRIV2 (src, image_offset); ++ ++ sl = &VEC_EL (sw_64_vms_link_hash (info)->shrlibs, ++ struct sw_64_vms_shlib_el, PRIV2 (shlib, shr_index)); ++ sl->has_fixups = TRUE; ++ r = VEC_APPEND (sl->qr, struct sw_64_vms_vma_ref); ++ r->vma = sect->output_section->vma + sect->output_offset + offset; ++ r->ref = vec; ++ sect->output_section->flags |= SEC_RELOC; ++} ++ ++static void ++sw_64_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ unsigned int shr ATTRIBUTE_UNUSED, ++ bfd_vma vec ATTRIBUTE_UNUSED) ++{ ++ /* Not yet supported. */ ++ abort (); ++} ++ ++/* Add relocation. FIXME: Not yet emitted. */ ++ ++static void ++sw_64_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED) ++{ ++} ++ ++static void ++sw_64_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED) ++{ ++} ++ ++static struct bfd_hash_entry * ++sw_64_vms_link_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct sw_64_vms_link_hash_entry *ret = ++ (struct sw_64_vms_link_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == NULL) ++ ret = ((struct sw_64_vms_link_hash_entry *) ++ bfd_hash_allocate (table, ++ sizeof (struct sw_64_vms_link_hash_entry))); ++ if (ret == NULL) ++ return NULL; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = ((struct sw_64_vms_link_hash_entry *) ++ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, ++ table, string)); ++ ++ ret->sym = NULL; ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++/* Create an Sw_64/VMS link hash table. */ ++ ++static struct bfd_link_hash_table * ++sw_64_vms_bfd_link_hash_table_create (bfd *abfd) ++{ ++ struct sw_64_vms_link_hash_table *ret; ++ bfd_size_type amt = sizeof (struct sw_64_vms_link_hash_table); ++ ++ ret = (struct sw_64_vms_link_hash_table *) bfd_malloc (amt); ++ if (ret == NULL) ++ return NULL; ++ if (!_bfd_link_hash_table_init (&ret->root, abfd, ++ sw_64_vms_link_hash_newfunc, ++ sizeof (struct sw_64_vms_link_hash_entry))) ++ { ++ free (ret); ++ return NULL; ++ } ++ ++ VEC_INIT (ret->shrlibs); ++ ret->fixup = NULL; ++ ++ return &ret->root; ++} ++ ++static bfd_boolean ++sw_64_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < PRIV (gsd_sym_count); i++) ++ { ++ struct vms_symbol_entry *e = PRIV (syms)[i]; ++ struct sw_64_vms_link_hash_entry *h; ++ struct bfd_link_hash_entry *h_root; ++ asymbol sym; ++ ++ if (!sw_64_vms_convert_symbol (abfd, e, &sym)) ++ return FALSE; ++ ++ if ((e->flags & EGSY__V_DEF) && abfd->selective_search) ++ { ++ /* In selective_search mode, only add definition that are ++ required. */ ++ h = (struct sw_64_vms_link_hash_entry *)bfd_link_hash_lookup ++ (info->hash, sym.name, FALSE, FALSE, FALSE); ++ if (h == NULL || h->root.type != bfd_link_hash_undefined) ++ continue; ++ } ++ else ++ h = NULL; ++ ++ h_root = (struct bfd_link_hash_entry *) h; ++ if (!_bfd_generic_link_add_one_symbol (info, abfd, sym.name, sym.flags, ++ sym.section, sym.value, NULL, ++ FALSE, FALSE, &h_root)) ++ return FALSE; ++ h = (struct sw_64_vms_link_hash_entry *) h_root; ++ ++ if ((e->flags & EGSY__V_DEF) ++ && h->sym == NULL ++ && abfd->xvec == info->output_bfd->xvec) ++ h->sym = e; ++ } ++ ++ if (abfd->flags & DYNAMIC) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ ++ /* We do not want to include any of the sections in a dynamic ++ object in the output file. See comment in elflink.c. */ ++ bfd_section_list_clear (abfd); ++ ++ shlib = VEC_APPEND (sw_64_vms_link_hash (info)->shrlibs, ++ struct sw_64_vms_shlib_el); ++ shlib->abfd = abfd; ++ VEC_INIT (shlib->ca); ++ VEC_INIT (shlib->lp); ++ VEC_INIT (shlib->qr); ++ PRIV (shr_index) = VEC_COUNT (sw_64_vms_link_hash (info)->shrlibs) - 1; ++ } ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++sw_64_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ int pass; ++ struct bfd_link_hash_entry **pundef; ++ struct bfd_link_hash_entry **next_pundef; ++ ++ /* We only accept VMS libraries. */ ++ if (info->output_bfd->xvec != abfd->xvec) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return FALSE; ++ } ++ ++ /* The archive_pass field in the archive itself is used to ++ initialize PASS, since we may search the same archive multiple ++ times. */ ++ pass = ++abfd->archive_pass; ++ ++ /* Look through the list of undefined symbols. */ ++ for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef) ++ { ++ struct bfd_link_hash_entry *h; ++ symindex symidx; ++ bfd *element; ++ bfd *orig_element; ++ ++ h = *pundef; ++ next_pundef = &(*pundef)->u.undef.next; ++ ++ /* When a symbol is defined, it is not necessarily removed from ++ the list. */ ++ if (h->type != bfd_link_hash_undefined ++ && h->type != bfd_link_hash_common) ++ { ++ /* Remove this entry from the list, for general cleanliness ++ and because we are going to look through the list again ++ if we search any more libraries. We can't remove the ++ entry if it is the tail, because that would lose any ++ entries we add to the list later on. */ ++ if (*pundef != info->hash->undefs_tail) ++ { ++ *pundef = *next_pundef; ++ next_pundef = pundef; ++ } ++ continue; ++ } ++ ++ /* Look for this symbol in the archive hash table. */ ++ symidx = _bfd_vms_lib_find_symbol (abfd, h->root.string); ++ if (symidx == BFD_NO_MORE_SYMBOLS) ++ { ++ /* Nothing in this slot. */ ++ continue; ++ } ++ ++ element = bfd_get_elt_at_index (abfd, symidx); ++ if (element == NULL) ++ return FALSE; ++ ++ if (element->archive_pass == -1 || element->archive_pass == pass) ++ { ++ /* Next symbol if this archive is wrong or already handled. */ ++ continue; ++ } ++ ++ if (! bfd_check_format (element, bfd_object)) ++ { ++ element->archive_pass = -1; ++ return FALSE; ++ } ++ ++ orig_element = element; ++ if (bfd_is_thin_archive (abfd)) ++ { ++ element = _bfd_vms_lib_get_imagelib_file (element); ++ if (element == NULL || !bfd_check_format (element, bfd_object)) ++ { ++ orig_element->archive_pass = -1; ++ return FALSE; ++ } ++ } ++ ++ /* Unlike the generic linker, we know that this element provides ++ a definition for an undefined symbol and we know that we want ++ to include it. We don't need to check anything. */ ++ if (!(*info->callbacks ++ ->add_archive_element) (info, element, h->root.string, &element)) ++ continue; ++ if (!sw_64_vms_link_add_object_symbols (element, info)) ++ return FALSE; ++ ++ orig_element->archive_pass = pass; ++ } ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++sw_64_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ switch (bfd_get_format (abfd)) ++ { ++ case bfd_object: ++ vms_debug2 ((2, "vms_link_add_symbols for object %s\n", ++ abfd->filename)); ++ return sw_64_vms_link_add_object_symbols (abfd, info); ++ break; ++ case bfd_archive: ++ vms_debug2 ((2, "vms_link_add_symbols for archive %s\n", ++ abfd->filename)); ++ return sw_64_vms_link_add_archive_symbols (abfd, info); ++ break; ++ default: ++ bfd_set_error (bfd_error_wrong_format); ++ return FALSE; ++ } ++} ++ ++static bfd_boolean ++sw_64_vms_build_fixups (struct bfd_link_info *info) ++{ ++ struct sw_64_vms_link_hash_table *t = sw_64_vms_link_hash (info); ++ unsigned char *content; ++ unsigned int i; ++ unsigned int sz = 0; ++ unsigned int lp_sz = 0; ++ unsigned int ca_sz = 0; ++ unsigned int qr_sz = 0; ++ unsigned int shrimg_cnt = 0; ++ unsigned int chgprt_num = 0; ++ unsigned int chgprt_sz = 0; ++ struct vms_eiaf *eiaf; ++ unsigned int off; ++ asection *sec; ++ ++ /* Shared libraries. */ ++ for (i = 0; i < VEC_COUNT (t->shrlibs); i++) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ ++ shlib = &VEC_EL (t->shrlibs, struct sw_64_vms_shlib_el, i); ++ ++ if (!shlib->has_fixups) ++ continue; ++ ++ shrimg_cnt++; ++ ++ if (VEC_COUNT (shlib->ca) > 0) ++ { ++ /* Header + entries. */ ++ ca_sz += 8; ++ ca_sz += VEC_COUNT (shlib->ca) * 4; ++ } ++ if (VEC_COUNT (shlib->lp) > 0) ++ { ++ /* Header + entries. */ ++ lp_sz += 8; ++ lp_sz += VEC_COUNT (shlib->lp) * 4; ++ } ++ if (VEC_COUNT (shlib->qr) > 0) ++ { ++ /* Header + entries. */ ++ qr_sz += 8; ++ qr_sz += VEC_COUNT (shlib->qr) * 8; ++ } ++ } ++ /* Add markers. */ ++ if (ca_sz > 0) ++ ca_sz += 8; ++ if (lp_sz > 0) ++ lp_sz += 8; ++ if (qr_sz > 0) ++ qr_sz += 8; ++ ++ /* Finish now if there is no content. */ ++ if (ca_sz + lp_sz + qr_sz == 0) ++ return TRUE; ++ ++ /* Add an eicp entry for the fixup itself. */ ++ chgprt_num = 1; ++ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next) ++ { ++ /* This isect could be made RO or EXE after relocations are applied. */ ++ if ((sec->flags & SEC_RELOC) != 0 ++ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) ++ chgprt_num++; ++ } ++ chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp); ++ ++ /* Allocate section content (round-up size) */ ++ sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl) ++ + ca_sz + lp_sz + qr_sz + chgprt_sz; ++ sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1); ++ content = bfd_zalloc (info->output_bfd, sz); ++ if (content == NULL) ++ return FALSE; ++ ++ sec = sw_64_vms_link_hash (info)->fixup; ++ sec->contents = content; ++ sec->size = sz; ++ ++ eiaf = (struct vms_eiaf *)content; ++ off = sizeof (struct vms_eiaf); ++ bfd_putl32 (0, eiaf->majorid); ++ bfd_putl32 (0, eiaf->minorid); ++ bfd_putl32 (0, eiaf->iaflink); ++ bfd_putl32 (0, eiaf->fixuplnk); ++ bfd_putl32 (sizeof (struct vms_eiaf), eiaf->size); ++ bfd_putl32 (0, eiaf->flags); ++ bfd_putl32 (0, eiaf->qrelfixoff); ++ bfd_putl32 (0, eiaf->lrelfixoff); ++ bfd_putl32 (0, eiaf->qdotadroff); ++ bfd_putl32 (0, eiaf->ldotadroff); ++ bfd_putl32 (0, eiaf->codeadroff); ++ bfd_putl32 (0, eiaf->lpfixoff); ++ bfd_putl32 (0, eiaf->chgprtoff); ++ bfd_putl32 (shrimg_cnt ? off : 0, eiaf->shlstoff); ++ bfd_putl32 (shrimg_cnt, eiaf->shrimgcnt); ++ bfd_putl32 (0, eiaf->shlextra); ++ bfd_putl32 (0, eiaf->permctx); ++ bfd_putl32 (0, eiaf->base_va); ++ bfd_putl32 (0, eiaf->lppsbfixoff); ++ ++ if (shrimg_cnt) ++ { ++ shrimg_cnt = 0; ++ ++ /* Write shl. */ ++ for (i = 0; i < VEC_COUNT (t->shrlibs); i++) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ struct vms_shl *shl; ++ ++ shlib = &VEC_EL (t->shrlibs, struct sw_64_vms_shlib_el, i); ++ ++ if (!shlib->has_fixups) ++ continue; ++ ++ /* Renumber shared images. */ ++ PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++; ++ ++ shl = (struct vms_shl *)(content + off); ++ bfd_putl32 (0, shl->baseva); ++ bfd_putl32 (0, shl->shlptr); ++ bfd_putl32 (0, shl->ident); ++ bfd_putl32 (0, shl->permctx); ++ shl->size = sizeof (struct vms_shl); ++ bfd_putl16 (0, shl->fill_1); ++ shl->flags = 0; ++ bfd_putl32 (0, shl->icb); ++ shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name)); ++ memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name), ++ shl->imgnam[0]); ++ ++ off += sizeof (struct vms_shl); ++ } ++ ++ /* CA fixups. */ ++ if (ca_sz != 0) ++ { ++ bfd_putl32 (off, eiaf->codeadroff); ++ ++ for (i = 0; i < VEC_COUNT (t->shrlibs); i++) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ unsigned int j; ++ ++ shlib = &VEC_EL (t->shrlibs, struct sw_64_vms_shlib_el, i); ++ ++ if (VEC_COUNT (shlib->ca) == 0) ++ continue; ++ ++ bfd_putl32 (VEC_COUNT (shlib->ca), content + off); ++ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4); ++ off += 8; ++ ++ for (j = 0; j < VEC_COUNT (shlib->ca); j++) ++ { ++ bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr, ++ content + off); ++ off += 4; ++ } ++ } ++ ++ bfd_putl32 (0, content + off); ++ bfd_putl32 (0, content + off + 4); ++ off += 8; ++ } ++ ++ /* LP fixups. */ ++ if (lp_sz != 0) ++ { ++ bfd_putl32 (off, eiaf->lpfixoff); ++ ++ for (i = 0; i < VEC_COUNT (t->shrlibs); i++) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ unsigned int j; ++ ++ shlib = &VEC_EL (t->shrlibs, struct sw_64_vms_shlib_el, i); ++ ++ if (VEC_COUNT (shlib->lp) == 0) ++ continue; ++ ++ bfd_putl32 (VEC_COUNT (shlib->lp), content + off); ++ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4); ++ off += 8; ++ ++ for (j = 0; j < VEC_COUNT (shlib->lp); j++) ++ { ++ bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr, ++ content + off); ++ off += 4; ++ } ++ } ++ ++ bfd_putl32 (0, content + off); ++ bfd_putl32 (0, content + off + 4); ++ off += 8; ++ } ++ ++ /* QR fixups. */ ++ if (qr_sz != 0) ++ { ++ bfd_putl32 (off, eiaf->qdotadroff); ++ ++ for (i = 0; i < VEC_COUNT (t->shrlibs); i++) ++ { ++ struct sw_64_vms_shlib_el *shlib; ++ unsigned int j; ++ ++ shlib = &VEC_EL (t->shrlibs, struct sw_64_vms_shlib_el, i); ++ ++ if (VEC_COUNT (shlib->qr) == 0) ++ continue; ++ ++ bfd_putl32 (VEC_COUNT (shlib->qr), content + off); ++ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4); ++ off += 8; ++ ++ for (j = 0; j < VEC_COUNT (shlib->qr); j++) ++ { ++ struct sw_64_vms_vma_ref *r; ++ r = &VEC_EL (shlib->qr, struct sw_64_vms_vma_ref, j); ++ bfd_putl32 (r->vma - t->base_addr, content + off); ++ bfd_putl32 (r->ref, content + off + 4); ++ off += 8; ++ } ++ } ++ ++ bfd_putl32 (0, content + off); ++ bfd_putl32 (0, content + off + 4); ++ off += 8; ++ } ++ } ++ ++ /* Write the change protection table. */ ++ bfd_putl32 (off, eiaf->chgprtoff); ++ bfd_putl32 (chgprt_num, content + off); ++ off += 4; ++ ++ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next) ++ { ++ struct vms_eicp *eicp; ++ unsigned int prot; ++ ++ if ((sec->flags & SEC_LINKER_CREATED) != 0 && ++ strcmp (sec->name, "$FIXUP$") == 0) ++ prot = PRT__C_UREW; ++ else if ((sec->flags & SEC_RELOC) != 0 ++ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) ++ prot = PRT__C_UR; ++ else ++ continue; ++ ++ eicp = (struct vms_eicp *)(content + off); ++ bfd_putl64 (sec->vma - t->base_addr, eicp->baseva); ++ bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1), ++ eicp->size); ++ bfd_putl32 (prot, eicp->newprt); ++ off += sizeof (struct vms_eicp); ++ } ++ ++ return TRUE; ++} ++ ++/* Called by bfd_hash_traverse to fill the symbol table. ++ Return FALSE in case of failure. */ ++ ++static bfd_boolean ++sw_64_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) ++{ ++ struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh; ++ struct bfd_link_info *info = (struct bfd_link_info *)infov; ++ struct sw_64_vms_link_hash_entry *h; ++ struct vms_symbol_entry *sym; ++ ++ if (hc->type == bfd_link_hash_warning) ++ { ++ hc = hc->u.i.link; ++ if (hc->type == bfd_link_hash_new) ++ return TRUE; ++ } ++ h = (struct sw_64_vms_link_hash_entry *) hc; ++ ++ switch (h->root.type) ++ { ++ case bfd_link_hash_undefined: ++ return TRUE; ++ case bfd_link_hash_new: ++ case bfd_link_hash_warning: ++ abort (); ++ case bfd_link_hash_undefweak: ++ return TRUE; ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ { ++ asection *sec = h->root.u.def.section; ++ ++ /* FIXME: this is certainly a symbol from a dynamic library. */ ++ if (bfd_is_abs_section (sec)) ++ return TRUE; ++ ++ if (sec->owner->flags & DYNAMIC) ++ return TRUE; ++ } ++ break; ++ case bfd_link_hash_common: ++ break; ++ case bfd_link_hash_indirect: ++ return TRUE; ++ } ++ ++ /* Do not write not kept symbols. */ ++ if (info->strip == strip_some ++ && bfd_hash_lookup (info->keep_hash, h->root.root.string, ++ FALSE, FALSE) != NULL) ++ return TRUE; ++ ++ if (h->sym == NULL) ++ { ++ /* This symbol doesn't come from a VMS object. So we suppose it is ++ a data. */ ++ int len = strlen (h->root.root.string); ++ ++ sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd, ++ sizeof (*sym) + len); ++ if (sym == NULL) ++ abort (); ++ sym->namelen = len; ++ memcpy (sym->name, h->root.root.string, len); ++ sym->name[len] = 0; ++ sym->owner = info->output_bfd; ++ ++ sym->typ = EGSD__C_SYMG; ++ sym->data_type = 0; ++ sym->flags = EGSY__V_DEF | EGSY__V_REL; ++ sym->symbol_vector = h->root.u.def.value; ++ sym->section = h->root.u.def.section; ++ sym->value = h->root.u.def.value; ++ } ++ else ++ sym = h->sym; ++ ++ if (!add_symbol_entry (info->output_bfd, sym)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++sw_64_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) ++{ ++ asection *o; ++ struct bfd_link_order *p; ++ bfd *sub; ++ asection *fixupsec; ++ bfd_vma base_addr; ++ bfd_vma last_addr; ++ asection *dst; ++ asection *dmt; ++ ++ if (bfd_link_relocatable (info)) ++ { ++ /* FIXME: we do not yet support relocatable link. It is not obvious ++ how to do it for debug infos. */ ++ (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n")); ++ return FALSE; ++ } ++ ++ bfd_get_outsymbols (abfd) = NULL; ++ bfd_get_symcount (abfd) = 0; ++ ++ /* Mark all sections which will be included in the output file. */ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ if (p->type == bfd_indirect_link_order) ++ p->u.indirect.section->linker_mark = TRUE; ++ ++#if 0 ++ /* Handle all the link order information for the sections. */ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ printf ("For section %s (at 0x%08x, flags=0x%08x):\n", ++ o->name, (unsigned)o->vma, (unsigned)o->flags); ++ ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ { ++ printf (" at 0x%08x - 0x%08x: ", ++ (unsigned)p->offset, (unsigned)(p->offset + p->size - 1)); ++ switch (p->type) ++ { ++ case bfd_section_reloc_link_order: ++ case bfd_symbol_reloc_link_order: ++ printf (" section/symbol reloc\n"); ++ break; ++ case bfd_indirect_link_order: ++ printf (" section %s of %s\n", ++ p->u.indirect.section->name, ++ p->u.indirect.section->owner->filename); ++ break; ++ case bfd_data_link_order: ++ printf (" explicit data\n"); ++ break; ++ default: ++ printf (" *unknown* type %u\n", p->type); ++ break; ++ } ++ } ++ } ++#endif ++ ++ /* Generate the symbol table. */ ++ BFD_ASSERT (PRIV (syms) == NULL); ++ if (info->strip != strip_all) ++ bfd_hash_traverse (&info->hash->table, sw_64_vms_link_output_symbol, info); ++ ++ /* Find the entry point. */ ++ if (bfd_get_start_address (abfd) == 0) ++ { ++ bfd *startbfd = NULL; ++ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ { ++ /* Consider only VMS object files. */ ++ if (sub->xvec != abfd->xvec) ++ continue; ++ ++ if (!PRIV2 (sub, eom_data).eom_has_transfer) ++ continue; ++ if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd) ++ continue; ++ if (startbfd != NULL ++ && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR)) ++ { ++ (*info->callbacks->einfo) ++ /* xgettext:c-format */ ++ (_("%P: multiple entry points: in modules %pB and %pB\n"), ++ startbfd, sub); ++ continue; ++ } ++ startbfd = sub; ++ } ++ ++ if (startbfd) ++ { ++ unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx; ++ bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr; ++ asection *sec; ++ ++ sec = PRIV2 (startbfd, sections)[ps_idx]; ++ ++ bfd_set_start_address ++ (abfd, sec->output_section->vma + sec->output_offset + tfradr); ++ } ++ } ++ ++ /* Set transfer addresses. */ ++ { ++ int i; ++ struct bfd_link_hash_entry *h; ++ ++ i = 0; ++ PRIV (transfer_address[i++]) = 0xffffffff00000340ULL; /* SYS$IMGACT */ ++ h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", FALSE, FALSE, TRUE); ++ if (h != NULL && h->type == bfd_link_hash_defined) ++ PRIV (transfer_address[i++]) = ++ sw_64_vms_get_sym_value (h->u.def.section, h->u.def.value); ++ PRIV (transfer_address[i++]) = bfd_get_start_address (abfd); ++ while (i < 4) ++ PRIV (transfer_address[i++]) = 0; ++ } ++ ++ /* Allocate contents. ++ Also compute the virtual base address. */ ++ base_addr = (bfd_vma)-1; ++ last_addr = 0; ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ if (o->flags & SEC_HAS_CONTENTS) ++ { ++ o->contents = bfd_alloc (abfd, o->size); ++ if (o->contents == NULL) ++ return FALSE; ++ } ++ if (o->flags & SEC_LOAD) ++ { ++ if (o->vma < base_addr) ++ base_addr = o->vma; ++ if (o->vma + o->size > last_addr) ++ last_addr = o->vma + o->size; ++ } ++ /* Clear the RELOC flags. Currently we don't support incremental ++ linking. We use the RELOC flag for computing the eicp entries. */ ++ o->flags &= ~SEC_RELOC; ++ } ++ ++ /* Create the fixup section. */ ++ fixupsec = bfd_make_section_anyway_with_flags ++ (info->output_bfd, "$FIXUP$", ++ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); ++ if (fixupsec == NULL) ++ return FALSE; ++ last_addr = (last_addr + 0xffff) & ~0xffff; ++ fixupsec->vma = last_addr; ++ ++ sw_64_vms_link_hash (info)->fixup = fixupsec; ++ sw_64_vms_link_hash (info)->base_addr = base_addr; ++ ++ /* Create the DMT section, if necessary. */ ++ BFD_ASSERT (PRIV (dst_section) == NULL); ++ dst = bfd_get_section_by_name (abfd, "$DST$"); ++ if (dst != NULL && dst->size == 0) ++ dst = NULL; ++ if (dst != NULL) ++ { ++ PRIV (dst_section) = dst; ++ dmt = bfd_make_section_anyway_with_flags ++ (info->output_bfd, "$DMT$", ++ SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); ++ if (dmt == NULL) ++ return FALSE; ++ } ++ else ++ dmt = NULL; ++ ++ /* Read all sections from the inputs. */ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ { ++ if (sub->flags & DYNAMIC) ++ { ++ sw_64_vms_create_eisd_for_shared (abfd, sub); ++ continue; ++ } ++ ++ if (!sw_64_vms_read_sections_content (sub, info)) ++ return FALSE; ++ } ++ ++ /* Handle all the link order information for the sections. ++ Note: past this point, it is not possible to create new sections. */ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ { ++ switch (p->type) ++ { ++ case bfd_section_reloc_link_order: ++ case bfd_symbol_reloc_link_order: ++ abort (); ++ return FALSE; ++ case bfd_indirect_link_order: ++ /* Already done. */ ++ break; ++ default: ++ if (! _bfd_default_link_order (abfd, info, o, p)) ++ return FALSE; ++ break; ++ } ++ } ++ } ++ ++ /* Compute fixups. */ ++ if (!sw_64_vms_build_fixups (info)) ++ return FALSE; ++ ++ /* Compute the DMT. */ ++ if (dmt != NULL) ++ { ++ int pass; ++ unsigned char *contents = NULL; ++ ++ /* In pass 1, compute the size. In pass 2, write the DMT contents. */ ++ for (pass = 0; pass < 2; pass++) ++ { ++ unsigned int off = 0; ++ ++ /* For each object file (ie for each module). */ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ { ++ asection *sub_dst; ++ struct vms_dmt_header *dmth = NULL; ++ unsigned int psect_count; ++ ++ /* Skip this module if it has no DST. */ ++ sub_dst = PRIV2 (sub, dst_section); ++ if (sub_dst == NULL || sub_dst->size == 0) ++ continue; ++ ++ if (pass == 1) ++ { ++ /* Write the header. */ ++ dmth = (struct vms_dmt_header *)(contents + off); ++ bfd_putl32 (sub_dst->output_offset, dmth->modbeg); ++ bfd_putl32 (sub_dst->size, dmth->size); ++ } ++ ++ off += sizeof (struct vms_dmt_header); ++ psect_count = 0; ++ ++ /* For each section (ie for each psect). */ ++ for (o = sub->sections; o != NULL; o = o->next) ++ { ++ /* Only consider interesting sections. */ ++ if (!(o->flags & SEC_ALLOC)) ++ continue; ++ if (o->flags & SEC_LINKER_CREATED) ++ continue; ++ ++ if (pass == 1) ++ { ++ /* Write an entry. */ ++ struct vms_dmt_psect *dmtp; ++ ++ dmtp = (struct vms_dmt_psect *)(contents + off); ++ bfd_putl32 (o->output_offset + o->output_section->vma, ++ dmtp->start); ++ bfd_putl32 (o->size, dmtp->length); ++ psect_count++; ++ } ++ off += sizeof (struct vms_dmt_psect); ++ } ++ if (pass == 1) ++ bfd_putl32 (psect_count, dmth->psect_count); ++ } ++ ++ if (pass == 0) ++ { ++ contents = bfd_zalloc (info->output_bfd, off); ++ if (contents == NULL) ++ return FALSE; ++ dmt->contents = contents; ++ dmt->size = off; ++ } ++ else ++ { ++ BFD_ASSERT (off == dmt->size); ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Read the contents of a section. ++ buf points to a buffer of buf_size bytes to be filled with ++ section data (starting at offset into section) */ ++ ++static bfd_boolean ++sw_64_vms_get_section_contents (bfd *abfd, asection *section, ++ void *buf, file_ptr offset, ++ bfd_size_type count) ++{ ++ asection *sec; ++ ++ /* Image are easy. */ ++ if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) ++ return _bfd_generic_get_section_contents (abfd, section, ++ buf, offset, count); ++ ++ /* Safety check. */ ++ if (offset + count < count ++ || offset + count > section->size) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return FALSE; ++ } ++ ++ /* If the section is already in memory, just copy it. */ ++ if (section->flags & SEC_IN_MEMORY) ++ { ++ BFD_ASSERT (section->contents != NULL); ++ memcpy (buf, section->contents + offset, count); ++ return TRUE; ++ } ++ if (section->size == 0) ++ return TRUE; ++ ++ /* Alloc in memory and read ETIRs. */ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ BFD_ASSERT (sec->contents == NULL); ++ ++ if (sec->size != 0 && (sec->flags & SEC_HAS_CONTENTS)) ++ { ++ sec->contents = bfd_alloc (abfd, sec->size); ++ if (sec->contents == NULL) ++ return FALSE; ++ } ++ } ++ if (!sw_64_vms_read_sections_content (abfd, NULL)) ++ return FALSE; ++ for (sec = abfd->sections; sec; sec = sec->next) ++ if (sec->contents) ++ sec->flags |= SEC_IN_MEMORY; ++ memcpy (buf, section->contents + offset, count); ++ return TRUE; ++} ++ ++ ++/* Set the format of a file being written. */ ++ ++static bfd_boolean ++sw_64_vms_mkobject (bfd * abfd) ++{ ++ const bfd_arch_info_type *arch; ++ ++ vms_debug2 ((1, "sw_64_vms_mkobject (%p)\n", abfd)); ++ ++ if (!vms_initialize (abfd)) ++ return FALSE; ++ ++ PRIV (recwr.buf) = bfd_alloc (abfd, MAX_OUTREC_SIZE); ++ if (PRIV (recwr.buf) == NULL) ++ return FALSE; ++ ++ arch = bfd_scan_arch ("sw_64"); ++ ++ if (arch == 0) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return FALSE; ++ } ++ ++ abfd->arch_info = arch; ++ return TRUE; ++} ++ ++ ++/* 4.1, generic. */ ++ ++/* Called when the BFD is being closed to do any necessary cleanup. */ ++ ++static bfd_boolean ++vms_close_and_cleanup (bfd * abfd) ++{ ++ vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd)); ++ ++ if (abfd == NULL || abfd->tdata.any == NULL) ++ return TRUE; ++ ++ if (abfd->format == bfd_archive) ++ { ++ bfd_release (abfd, abfd->tdata.any); ++ abfd->tdata.any = NULL; ++ return TRUE; ++ } ++ ++ if (PRIV (recrd.buf) != NULL) ++ free (PRIV (recrd.buf)); ++ ++ if (PRIV (sections) != NULL) ++ free (PRIV (sections)); ++ ++ bfd_release (abfd, abfd->tdata.any); ++ abfd->tdata.any = NULL; ++ ++#ifdef VMS ++ if (abfd->direction == write_direction) ++ { ++ /* Last step on VMS is to convert the file to variable record length ++ format. */ ++ if (!bfd_cache_close (abfd)) ++ return FALSE; ++ if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename)) ++ return FALSE; ++ } ++#endif ++ ++ return TRUE; ++} ++ ++/* Called when a new section is created. */ ++ ++static bfd_boolean ++vms_new_section_hook (bfd * abfd, asection *section) ++{ ++ bfd_size_type amt; ++ ++ vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n", ++ abfd, section->index, section->name)); ++ ++ if (! bfd_set_section_alignment (abfd, section, 0)) ++ return FALSE; ++ ++ vms_debug2 ((7, "%u: %s\n", section->index, section->name)); ++ ++ amt = sizeof (struct vms_section_data_struct); ++ section->used_by_bfd = bfd_zalloc (abfd, amt); ++ if (section->used_by_bfd == NULL) ++ return FALSE; ++ ++ /* Create the section symbol. */ ++ return _bfd_generic_new_section_hook (abfd, section); ++} ++ ++/* Part 4.5, symbols. */ ++ ++/* Print symbol to file according to how. how is one of ++ bfd_print_symbol_name just print the name ++ bfd_print_symbol_more print more (???) ++ bfd_print_symbol_all print all we know, which is not much right now :-). */ ++ ++static void ++vms_print_symbol (bfd * abfd, ++ void * file, ++ asymbol *symbol, ++ bfd_print_symbol_type how) ++{ ++ vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n", ++ abfd, file, symbol, how)); ++ ++ switch (how) ++ { ++ case bfd_print_symbol_name: ++ case bfd_print_symbol_more: ++ fprintf ((FILE *)file," %s", symbol->name); ++ break; ++ ++ case bfd_print_symbol_all: ++ { ++ const char *section_name = symbol->section->name; ++ ++ bfd_print_symbol_vandf (abfd, file, symbol); ++ ++ fprintf ((FILE *) file," %-8s %s", section_name, symbol->name); ++ } ++ break; ++ } ++} ++ ++/* Return information about symbol in ret. ++ ++ fill type, value and name ++ type: ++ A absolute ++ B bss segment symbol ++ C common symbol ++ D data segment symbol ++ f filename ++ t a static function symbol ++ T text segment symbol ++ U undefined ++ - debug. */ ++ ++static void ++vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED, ++ asymbol *symbol, ++ symbol_info *ret) ++{ ++ asection *sec; ++ ++ vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret)); ++ ++ sec = symbol->section; ++ ++ if (ret == NULL) ++ return; ++ ++ if (sec == NULL) ++ ret->type = 'U'; ++ else if (bfd_is_com_section (sec)) ++ ret->type = 'C'; ++ else if (bfd_is_abs_section (sec)) ++ ret->type = 'A'; ++ else if (bfd_is_und_section (sec)) ++ ret->type = 'U'; ++ else if (bfd_is_ind_section (sec)) ++ ret->type = 'I'; ++ else if ((symbol->flags & BSF_FUNCTION) ++ || (bfd_get_section_flags (abfd, sec) & SEC_CODE)) ++ ret->type = 'T'; ++ else if (bfd_get_section_flags (abfd, sec) & SEC_DATA) ++ ret->type = 'D'; ++ else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) ++ ret->type = 'B'; ++ else ++ ret->type = '?'; ++ ++ if (ret->type != 'U') ++ ret->value = symbol->value + symbol->section->vma; ++ else ++ ret->value = 0; ++ ret->name = symbol->name; ++} ++ ++/* Return TRUE if the given symbol sym in the BFD abfd is ++ a compiler generated local label, else return FALSE. */ ++ ++static bfd_boolean ++vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, ++ const char *name) ++{ ++ return name[0] == '$'; ++} ++ ++/* Part 4.7, writing an object file. */ ++ ++/* Sets the contents of the section section in BFD abfd to the data starting ++ in memory at LOCATION. The data is written to the output section starting ++ at offset offset for count bytes. ++ ++ Normally TRUE is returned, else FALSE. Possible error returns are: ++ o bfd_error_no_contents - The output section does not have the ++ SEC_HAS_CONTENTS attribute, so nothing can be written to it. ++ o and some more too */ ++ ++static bfd_boolean ++_bfd_vms_set_section_contents (bfd * abfd, ++ asection *section, ++ const void * location, ++ file_ptr offset, ++ bfd_size_type count) ++{ ++ if (section->contents == NULL) ++ { ++ section->contents = bfd_alloc (abfd, section->size); ++ if (section->contents == NULL) ++ return FALSE; ++ ++ memcpy (section->contents + offset, location, (size_t) count); ++ } ++ ++ return TRUE; ++} ++ ++/* Set the architecture and machine type in BFD abfd to arch and mach. ++ Find the correct pointer to a structure and insert it into the arch_info ++ pointer. */ ++ ++static bfd_boolean ++sw_64_vms_set_arch_mach (bfd *abfd, ++ enum bfd_architecture arch, unsigned long mach) ++{ ++ if (arch != bfd_arch_sw_64 ++ && arch != bfd_arch_unknown) ++ return FALSE; ++ ++ return bfd_default_set_arch_mach (abfd, arch, mach); ++} ++ ++/* Set section VMS flags. Clear NO_FLAGS and set FLAGS. */ ++ ++void ++bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED, ++ asection *sec, flagword no_flags, flagword flags) ++{ ++ vms_section_data (sec)->no_flags = no_flags; ++ vms_section_data (sec)->flags = flags; ++} ++ ++struct vms_private_data_struct * ++bfd_vms_get_data (bfd *abfd) ++{ ++ return (struct vms_private_data_struct *)abfd->tdata.any; ++} ++ ++#define vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false ++#define vms_bfd_link_just_syms _bfd_generic_link_just_syms ++#define vms_bfd_copy_link_hash_symbol_type \ ++ _bfd_generic_copy_link_hash_symbol_type ++#define vms_bfd_is_group_section bfd_generic_is_group_section ++#define vms_bfd_discard_group bfd_generic_discard_group ++#define vms_section_already_linked _bfd_generic_section_already_linked ++#define vms_bfd_define_common_symbol bfd_generic_define_common_symbol ++#define vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol ++#define vms_bfd_define_start_stop bfd_generic_define_start_stop ++#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data ++ ++#define vms_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data ++#define vms_bfd_free_cached_info _bfd_generic_bfd_free_cached_info ++#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data ++#define vms_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data ++#define vms_bfd_set_private_flags _bfd_generic_bfd_set_private_flags ++#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data ++ ++/* Symbols table. */ ++#define sw_64_vms_make_empty_symbol _bfd_generic_make_empty_symbol ++#define sw_64_vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false ++#define sw_64_vms_print_symbol vms_print_symbol ++#define sw_64_vms_get_symbol_info vms_get_symbol_info ++#define sw_64_vms_get_symbol_version_string \ ++ _bfd_nosymbols_get_symbol_version_string ++ ++#define sw_64_vms_read_minisymbols _bfd_generic_read_minisymbols ++#define sw_64_vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol ++#define sw_64_vms_get_lineno _bfd_nosymbols_get_lineno ++#define sw_64_vms_find_inliner_info _bfd_nosymbols_find_inliner_info ++#define sw_64_vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol ++#define sw_64_vms_find_nearest_line _bfd_vms_find_nearest_line ++#define sw_64_vms_find_line _bfd_nosymbols_find_line ++#define sw_64_vms_bfd_is_local_label_name vms_bfd_is_local_label_name ++ ++/* Generic table. */ ++#define sw_64_vms_close_and_cleanup vms_close_and_cleanup ++#define sw_64_vms_bfd_free_cached_info vms_bfd_free_cached_info ++#define sw_64_vms_new_section_hook vms_new_section_hook ++#define sw_64_vms_set_section_contents _bfd_vms_set_section_contents ++#define sw_64_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window ++ ++#define sw_64_vms_bfd_get_relocated_section_contents \ ++ bfd_generic_get_relocated_section_contents ++ ++#define sw_64_vms_bfd_relax_section bfd_generic_relax_section ++#define sw_64_vms_bfd_gc_sections bfd_generic_gc_sections ++#define sw_64_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags ++#define sw_64_vms_bfd_merge_sections bfd_generic_merge_sections ++#define sw_64_vms_bfd_is_group_section bfd_generic_is_group_section ++#define sw_64_vms_bfd_discard_group bfd_generic_discard_group ++#define sw_64_vms_section_already_linked \ ++ _bfd_generic_section_already_linked ++ ++#define sw_64_vms_bfd_define_common_symbol bfd_generic_define_common_symbol ++#define sw_64_vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol ++#define sw_64_vms_bfd_define_start_stop bfd_generic_define_start_stop ++#define sw_64_vms_bfd_link_just_syms _bfd_generic_link_just_syms ++#define sw_64_vms_bfd_copy_link_hash_symbol_type \ ++ _bfd_generic_copy_link_hash_symbol_type ++ ++#define sw_64_vms_bfd_link_split_section _bfd_generic_link_split_section ++ ++#define sw_64_vms_get_dynamic_symtab_upper_bound \ ++ _bfd_nodynamic_get_dynamic_symtab_upper_bound ++#define sw_64_vms_canonicalize_dynamic_symtab \ ++ _bfd_nodynamic_canonicalize_dynamic_symtab ++#define sw_64_vms_get_dynamic_reloc_upper_bound \ ++ _bfd_nodynamic_get_dynamic_reloc_upper_bound ++#define sw_64_vms_canonicalize_dynamic_reloc \ ++ _bfd_nodynamic_canonicalize_dynamic_reloc ++#define sw_64_vms_bfd_link_check_relocs _bfd_generic_link_check_relocs ++ ++const bfd_target sw_64_vms_vec = ++{ ++ "vms-sw_64", /* Name. */ ++ bfd_target_evax_flavour, ++ BFD_ENDIAN_LITTLE, /* Data byte order is little. */ ++ BFD_ENDIAN_LITTLE, /* Header byte order is little. */ ++ ++ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS ++ | WP_TEXT | D_PAGED), /* Object flags. */ ++ (SEC_ALLOC | SEC_LOAD | SEC_RELOC ++ | SEC_READONLY | SEC_CODE | SEC_DATA ++ | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */ ++ 0, /* symbol_leading_char. */ ++ ' ', /* ar_pad_char. */ ++ 15, /* ar_max_namelen. */ ++ 0, /* match priority. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, ++ ++ { /* bfd_check_format. */ ++ _bfd_dummy_target, ++ sw_64_vms_object_p, ++ _bfd_vms_lib_sw_64_archive_p, ++ _bfd_dummy_target ++ }, ++ { /* bfd_set_format. */ ++ _bfd_bool_bfd_false_error, ++ sw_64_vms_mkobject, ++ _bfd_vms_lib_sw_64_mkarchive, ++ _bfd_bool_bfd_false_error ++ }, ++ { /* bfd_write_contents. */ ++ _bfd_bool_bfd_false_error, ++ sw_64_vms_write_object_contents, ++ _bfd_vms_lib_write_archive_contents, ++ _bfd_bool_bfd_false_error ++ }, ++ ++ BFD_JUMP_TABLE_GENERIC (sw_64_vms), ++ BFD_JUMP_TABLE_COPY (vms), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib), ++ BFD_JUMP_TABLE_SYMBOLS (sw_64_vms), ++ BFD_JUMP_TABLE_RELOCS (sw_64_vms), ++ BFD_JUMP_TABLE_WRITE (sw_64_vms), ++ BFD_JUMP_TABLE_LINK (sw_64_vms), ++ BFD_JUMP_TABLE_DYNAMIC (sw_64_vms), ++ ++ NULL, ++ ++ NULL ++}; +diff -Nuar gdb-10.2/build.sh gdb-10.2/build.sh +--- gdb-10.2/build.sh 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/build.sh 2025-04-16 17:06:51.932086800 +0800 +@@ -0,0 +1,51 @@ ++#!/bin/sh ++ ++cd ../ ++ ++# step 1: install dependency package ++install_package() ++{ ++ if [ `dpkg -l | grep $1 | wc -l` -ne 0 ] ++ then ++ echo "package $1 already exists." ++ else ++ sudo apt-get install $1 -y ++ echo "package $1 installed successfully." ++ fi ++} ++ ++install_package texinfo ++install_package expat ++install_package libexpat1-dev ++install_package python2.7-dev ++ ++# step 2: install gdb ++build_gdb_release() ++{ ++ rm -rf build ++ mkdir build ++ current_dir=$(pwd) ++ cd build ++ CFLAGS="-D_SW64_ -DSCORE" CXXFLAGS="-D_SW64_ -DCORE" \ ++ ../gdb-10.2/configure --host=sw_64-sunway-linux-gnu --build=sw_64-sunway-linux-gnu --prefix=$current_dir/install --with-guile=no --with-python --with-expat ++ make -j$(nproc) ++ make install ++ cd ../ ++} ++ ++build_gdb_debug() ++{ ++ rm -rf build-debug ++ mkdir build-debug ++ current_dir=$(pwd) ++ cd build-debug ++ CFLAGS="-g3 -O0 -D_SW64_ -DSCORE" CXXFLAGS="-g3 -O0 -D_SW64_ -DCORE" \ ++ ../gdb/configure --host=sw_64-sunway-linux-gnu --build=sw_64-sunway-linux-gnu --prefix=$current_dir/install-debug --with-guile=no --with-python --with-expat ++ make -j$(nproc) ++ make install ++ cd ../ ++} ++ ++ ++build_gdb_release ++#build_gdb_debug +diff -Nuar gdb-10.2/config.guess gdb-10.2/config.guess +--- gdb-10.2/config.guess 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/config.guess 2025-04-16 17:06:51.932086800 +0800 +@@ -925,6 +925,9 @@ + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; ++sw_64*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff -Nuar gdb-10.2/config.sub gdb-10.2/config.sub +--- gdb-10.2/config.sub 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/config.sub 2025-04-16 17:06:51.932086800 +0800 +@@ -1161,6 +1161,7 @@ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ ++ | sw_64 | sw_64sw6a | sw_64sw6b \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ +diff -Nuar gdb-10.2/gdb/ada-lang.c gdb-10.2/gdb/ada-lang.c +--- gdb-10.2/gdb/ada-lang.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/ada-lang.c 2025-04-16 17:06:41.952086800 +0800 +@@ -997,7 +997,7 @@ + int len = name.size (); + GROW_VECT (fold_buffer, fold_buffer_size, len + 1); + +- if (name[0] == '\'') ++ if (!name.empty () && name[0] == '\'') + { + strncpy (fold_buffer, name.data () + 1, len - 2); + fold_buffer[len - 2] = '\000'; +@@ -1006,8 +1006,9 @@ + { + int i; + +- for (i = 0; i <= len; i += 1) ++ for (i = 0; i < len; i += 1) + fold_buffer[i] = tolower (name[i]); ++ fold_buffer[i] = '\0'; + } + + return fold_buffer; +@@ -1157,7 +1158,7 @@ + i -= 1; + if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_') + len0 = i - 1; +- else if (encoded[i] == '$') ++ else if (i >= 0 && encoded[i] == '$') + len0 = i; + } + +@@ -13596,7 +13597,7 @@ + { + gdb::string_view user_name = lookup_name.name (); + +- if (user_name[0] == '<') ++ if (!user_name.empty () && user_name[0] == '<') + { + if (user_name.back () == '>') + m_encoded_name +diff -Nuar gdb-10.2/gdb/arch/sw_64.h gdb-10.2/gdb/arch/sw_64.h +--- gdb-10.2/gdb/arch/sw_64.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/arch/sw_64.h 2025-04-16 17:06:51.932086800 +0800 +@@ -0,0 +1,193 @@ ++/* Common target dependent code for GDB on SW systems. ++ Copyright (C) 1988-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef ARCH_SW_64_H ++#define ARCH_SW_64_H ++ ++#include "gdbsupport/tdesc.h" ++ ++/* Register numbers of various important registers. */ ++ ++enum gdb_regnum { ++ SW_A1_REGNUM = 0, /* first integer-like argument */ ++ SW_A4_REGNUM = 3, /* last integer-like argument */ ++ SW_AP_REGNUM = 11, ++ SW_IP_REGNUM = 12, ++ SW_SP_REGNUM = 13, /* Contains address of top of stack */ ++ SW_LR_REGNUM = 14, /* address to return to from a function call */ ++ SW_PC_REGNUM = 15, /* Contains program counter */ ++ /* F0..F7 are the fp registers for the (obsolete) FPA architecture. */ ++ SW_F0_REGNUM = 16, /* first floating point register */ ++ SW_F3_REGNUM = 19, /* last floating point argument register */ ++ SW_F7_REGNUM = 23, /* last floating point register */ ++ SW_FPS_REGNUM = 24, /* floating point status register */ ++ SW_PS_REGNUM = 25, /* Contains processor status */ ++ SW_WR0_REGNUM, /* WMMX data registers. */ ++ SW_WR15_REGNUM = SW_WR0_REGNUM + 15, ++ SW_WC0_REGNUM, /* WMMX control registers. */ ++ SW_WCSSF_REGNUM = SW_WC0_REGNUM + 2, ++ SW_WCASF_REGNUM = SW_WC0_REGNUM + 3, ++ SW_WC7_REGNUM = SW_WC0_REGNUM + 7, ++ SW_WCGR0_REGNUM, /* WMMX general purpose registers. */ ++ SW_WCGR3_REGNUM = SW_WCGR0_REGNUM + 3, ++ SW_WCGR7_REGNUM = SW_WCGR0_REGNUM + 7, ++ SW_D0_REGNUM, /* VFP double-precision registers. */ ++ SW_D31_REGNUM = SW_D0_REGNUM + 31, ++ SW_FPSCR_REGNUM, ++ ++ SW_NUM_REGS, ++ ++ /* Other useful registers. */ ++ SW_FP_REGNUM = 11, /* Frame register in SW code, if used. */ ++ THUMB_FP_REGNUM = 7, /* Frame register in Thumb code, if used. */ ++ SW_NUM_ARG_REGS = 4, ++ SW_LAST_ARG_REGNUM = SW_A4_REGNUM, ++ SW_NUM_FP_ARG_REGS = 4, ++ SW_LAST_FP_ARG_REGNUM = SW_F3_REGNUM ++}; ++ ++/* Enum describing the different kinds of breakpoints. */ ++enum sw_64_breakpoint_kinds ++{ ++ SW_BP_KIND_THUMB = 2, ++ SW_BP_KIND_THUMB2 = 3, ++ SW_BP_KIND_SW = 4, ++}; ++ ++/* Supported Arm FP hardware types. */ ++enum sw_64_fp_type { ++ SW_FP_TYPE_NONE = 0, ++ SW_FP_TYPE_VFPV2, ++ SW_FP_TYPE_VFPV3, ++ SW_FP_TYPE_IWMMXT, ++ SW_FP_TYPE_INVALID ++}; ++ ++/* Supported M-profile Arm types. */ ++enum sw_64_m_profile_type { ++ SW_M_TYPE_M_PROFILE, ++ SW_M_TYPE_VFP_D16, ++ SW_M_TYPE_WITH_FPA, ++ SW_M_TYPE_INVALID ++}; ++ ++/* Instruction condition field values. */ ++#define INST_EQ 0x0 ++#define INST_NE 0x1 ++#define INST_CS 0x2 ++#define INST_CC 0x3 ++#define INST_MI 0x4 ++#define INST_PL 0x5 ++#define INST_VS 0x6 ++#define INST_VC 0x7 ++#define INST_HI 0x8 ++#define INST_LS 0x9 ++#define INST_GE 0xa ++#define INST_LT 0xb ++#define INST_GT 0xc ++#define INST_LE 0xd ++#define INST_AL 0xe ++#define INST_NV 0xf ++ ++#define FLAG_N 0x80000000 ++#define FLAG_Z 0x40000000 ++#define FLAG_C 0x20000000 ++#define FLAG_V 0x10000000 ++ ++#define CPSR_T 0x20 ++ ++#define XPSR_T 0x01000000 ++ ++/* Size of registers. */ ++ ++#define SW_INT_REGISTER_SIZE 4 ++/* IEEE extended doubles are 80 bits. DWORD aligned they use 96 bits. */ ++#define SW_FP_REGISTER_SIZE 12 ++#define SW_VFP_REGISTER_SIZE 8 ++#define IWMMXT_VEC_REGISTER_SIZE 8 ++ ++/* Size of register sets. */ ++ ++/* r0-r12,sp,lr,pc,cpsr. */ ++#define SW_CORE_REGS_SIZE (17 * SW_INT_REGISTER_SIZE) ++/* f0-f8,fps. */ ++#define SW_FP_REGS_SIZE (8 * SW_FP_REGISTER_SIZE + SW_INT_REGISTER_SIZE) ++/* d0-d15,fpscr. */ ++#define SW_VFP2_REGS_SIZE (16 * SW_VFP_REGISTER_SIZE + SW_INT_REGISTER_SIZE) ++/* d0-d31,fpscr. */ ++#define SW_VFP3_REGS_SIZE (32 * SW_VFP_REGISTER_SIZE + SW_INT_REGISTER_SIZE) ++/* wR0-wR15,fpscr. */ ++#define IWMMXT_REGS_SIZE (16 * IWMMXT_VEC_REGISTER_SIZE \ ++ + 6 * SW_INT_REGISTER_SIZE) ++ ++/* Addresses for calling Thumb functions have the bit 0 set. ++ Here are some macros to test, set, or clear bit 0 of addresses. */ ++#define IS_THUMB_ADDR(addr) ((addr) & 1) ++#define MAKE_THUMB_ADDR(addr) ((addr) | 1) ++#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) ++ ++/* Support routines for instruction parsing. */ ++#define submask(x) ((1L << ((x) + 1)) - 1) ++#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) ++#define bit(obj,st) (((obj) >> (st)) & 1) ++#define sbits(obj,st,fn) \ ++ ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st)))) ++#define BranchDest(addr,instr) \ ++ ((CORE_ADDR) (((unsigned long) (addr)) + 8 + (sbits (instr, 0, 23) << 2))) ++ ++/* Forward declaration. */ ++struct regcache; ++ ++/* Return the size in bytes of the complete Thumb instruction whose ++ first halfword is INST1. */ ++int thumb_insn_size (unsigned short inst1); ++ ++/* Returns true if the condition evaluates to true. */ ++int condition_true (unsigned long cond, unsigned long status_reg); ++ ++/* Return 1 if THIS_INSTR might change control flow, 0 otherwise. */ ++int sw_64_instruction_changes_pc (uint32_t this_instr); ++ ++/* Return 1 if the 16-bit Thumb instruction INST might change ++ control flow, 0 otherwise. */ ++int thumb_instruction_changes_pc (unsigned short inst); ++ ++/* Return 1 if the 32-bit Thumb instruction in INST1 and INST2 ++ might change control flow, 0 otherwise. */ ++int thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2); ++ ++/* Advance the state of the IT block and return that state. */ ++int thumb_advance_itstate (unsigned int itstate); ++ ++/* Decode shifted register value. */ ++ ++unsigned long shifted_reg_val (struct regcache *regcache, ++ unsigned long inst, ++ int carry, ++ unsigned long pc_val, ++ unsigned long status_reg); ++ ++/* Create an Arm target description with the given FP hardware type. */ ++ ++target_desc *sw_64_create_target_description (sw_64_fp_type fp_type); ++ ++/* Create an Arm M-profile target description with the given hardware type. */ ++ ++target_desc *sw_64_create_mprofile_target_description (sw_64_m_profile_type m_type); ++ ++#endif /* ARCH_SW_H */ +diff -Nuar gdb-10.2/gdb/cli/cli-cmds.c gdb-10.2/gdb/cli/cli-cmds.c +--- gdb-10.2/gdb/cli/cli-cmds.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/cli/cli-cmds.c 2025-04-16 17:06:41.892086800 +0800 +@@ -435,6 +435,11 @@ + } + } + ++#ifdef CRASH_MERGE ++static int crash_from_tty = 0; ++extern "C" void untrusted_file(FILE *, char *); ++#endif ++ + int + is_complete_command (struct cmd_list_element *c) + { +@@ -654,8 +659,32 @@ + close (fd); + errno = save_errno; + } +- else +- opened.emplace (gdb_file_up (result), std::move (full_path)); ++#ifdef CRASH_MERGE ++ /* ++ * Only allow trusted versions of .gdbinit files to be ++ * sourced during session initialization. ++ */ ++ if (crash_from_tty == -1) ++ { ++ struct stat statbuf; ++ FILE *stream = result; ++ int _fd = fileno (stream); ++ if (fstat (_fd, &statbuf) < 0) ++ { ++ perror_with_name (full_path.get()); ++ fclose (stream); ++ return opened; ++ } ++ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH)) ++ { ++ untrusted_file(NULL, full_path.get()); ++ fclose (stream); ++ return opened; ++ } ++ } ++#endif ++ opened.emplace (gdb_file_up (result), std::move (full_path)); ++ + + return opened; + } +@@ -719,7 +748,11 @@ + If the source command was invoked interactively, throw an + error. Otherwise (e.g. if it was invoked by a script), + just emit a warning, rather than cause an error. */ ++#ifdef CRASH_MERGE ++ if (from_tty > 0) ++#else + if (from_tty) ++#endif + perror_with_name (file); + else + { +@@ -743,7 +776,14 @@ + void + source_script (const char *file, int from_tty) + { ++#ifdef CRASH_MERGE ++ crash_from_tty = from_tty; ++#endif + source_script_with_search (file, from_tty, 0); ++#ifdef CRASH_MERGE ++ crash_from_tty = 0; ++#endif ++ + } + + static void +diff -Nuar gdb-10.2/gdb/coffread.c gdb-10.2/gdb/coffread.c +--- gdb-10.2/gdb/coffread.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/coffread.c 2025-04-16 17:06:41.952086800 +0800 +@@ -159,6 +159,7 @@ + static unsigned long linetab_size; + + static char *stringtab = NULL; ++static long stringtab_length = 0; + + extern void stabsread_clear_cache (void); + +@@ -1297,6 +1298,7 @@ + /* This is in target format (probably not very useful, and not + currently used), not host format. */ + memcpy (stringtab, lengthbuf, sizeof lengthbuf); ++ stringtab_length = length; + if (length == sizeof length) /* Empty table -- just the count. */ + return 0; + +@@ -1316,8 +1318,9 @@ + + if (symbol_entry->_n._n_n._n_zeroes == 0) + { +- /* FIXME: Probably should be detecting corrupt symbol files by +- seeing whether offset points to within the stringtab. */ ++ if (symbol_entry->_n._n_n._n_offset > stringtab_length) ++ error (_("COFF Error: string table offset (%ld) outside string table (length %ld)"), ++ symbol_entry->_n._n_n._n_offset, stringtab_length); + result = stringtab + symbol_entry->_n._n_n._n_offset; + } + else +diff -Nuar gdb-10.2/gdb/completer.c gdb-10.2/gdb/completer.c +--- gdb-10.2/gdb/completer.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/completer.c 2025-04-16 17:06:41.922086800 +0800 +@@ -2949,6 +2949,8 @@ + + /* How many items of MAX length can we fit in the screen window? */ + cols = gdb_complete_get_screenwidth (displayer); ++ rl_reset_screen_size(); ++ rl_get_screen_size(NULL, &cols); + max += 2; + limit = cols / max; + if (limit != 1 && (limit * max == cols)) +diff -Nuar gdb-10.2/gdb/configure.host gdb-10.2/gdb/configure.host +--- gdb-10.2/gdb/configure.host 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/configure.host 2025-04-16 17:06:51.932086800 +0800 +@@ -60,6 +60,7 @@ + + aarch64*) gdb_host_cpu=aarch64 ;; + alpha*) gdb_host_cpu=alpha ;; ++sw_64*) gdb_host_cpu=sw_64 ;; + arm*) gdb_host_cpu=arm ;; + hppa*) gdb_host_cpu=pa ;; + i[34567]86*) gdb_host_cpu=i386 ;; +@@ -165,7 +166,7 @@ + sparc-*-solaris2* | sparcv9-*-solaris2* | sparc64-*-solaris2*) + gdb_host=sol2 + ;; +- ++sw_64*-*-linux*) gdb_host=sw_64-linux ;; + tilegx-*-linux*) gdb_host=linux ;; + + vax-*-netbsdelf* | vax-*-knetbsd*-gnu) +diff -Nuar gdb-10.2/gdb/configure.nat gdb-10.2/gdb/configure.nat +--- gdb-10.2/gdb/configure.nat 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/configure.nat 2025-04-16 17:06:51.932086800 +0800 +@@ -1,5 +1,5 @@ + # ; -*- mode: sh ; -*- +-# Copyright (C) 2013-2021 Free Software Foundation, Inc. ++# Copyright (C) 2013-2020 Free Software Foundation, Inc. + # + # This file is part of GDB. + # +@@ -123,6 +123,18 @@ + ;; + esac + ;; ++ sw_64-linux) ++ case ${gdb_host_cpu} in ++ sw_64) ++ # Host: Little-endian Sw_64 running Linux ++ NATDEPFILES="${NATDEPFILES} linux-nat-trad.o sw_64-linux-nat.o nat/sw_64-linux-watch.o" ++ # doublest.c currently assumes some properties of FP arithmetic ++ # on the host which require this. ++ #MH_CFLAGS='-mieee' ++ MH_CFLAGS='-mieee' ++ ;; ++ esac ++ ;; + cygwin) + case ${gdb_host_cpu} in + i386) +@@ -266,6 +278,11 @@ + NATDEPFILES="${NATDEPFILES} linux-nat-trad.o \ + mips-linux-nat.o nat/mips-linux-watch.o" + ;; ++ sw_64) ++ # Host: Linux/sw_64 ++ NATDEPFILES="${NATDEPFILES} linux-nat-trad.o \ ++ sw_64-linux-nat.o nat/sw_64-linux-watch.o" ++ ;; + pa) + # Host: Hewlett-Packard PA-RISC machine, running Linux + NATDEPFILES="${NATDEPFILES} hppa-linux-nat.o" +diff -Nuar gdb-10.2/gdb/configure.tgt gdb-10.2/gdb/configure.tgt +--- gdb-10.2/gdb/configure.tgt 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/configure.tgt 2025-04-16 17:06:51.932086800 +0800 +@@ -94,6 +94,10 @@ + # Target: Tensilica Xtensa processors + cpu_obs="xtensa-tdep.o xtensa-config.o solib-svr4.o" + ;; ++sw_64*-*-*) ++ # Target: sw_64 ++ cpu_obs="sw_64-tdep.o" ++ ;; + + esac + +@@ -146,6 +150,12 @@ + alpha-nbsd-tdep.o alpha-obsd-tdep.o nbsd-tdep.o" + ;; + ++sw_64*-*-linux*) ++ # Target: Little-endian sw_64 running Linux ++ gdb_target_obs="sw_64-mdebug-tdep.o sw_64-linux-tdep.o \ ++ linux-tdep.o solib-svr4.o linux-record.o" ++ ;; ++ + am33_2.0*-*-linux*) + # Target: Matsushita mn10300 (AM33) running Linux + gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \ +diff -Nuar gdb-10.2/gdb/c-typeprint.c gdb-10.2/gdb/c-typeprint.c +--- gdb-10.2/gdb/c-typeprint.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/c-typeprint.c 2025-04-16 17:06:41.922086800 +0800 +@@ -1202,6 +1202,9 @@ + = podata->end_bitpos + - TYPE_LENGTH (type->field (i).type ()) * TARGET_CHAR_BIT; + } ++ else if (strlen(TYPE_FIELD_NAME (type, i)) == 0) ++ /* crash: Print details for unnamed struct and union. */ ++ newshow = show; + + c_print_type_1 (type->field (i).type (), + TYPE_FIELD_NAME (type, i), +diff -Nuar gdb-10.2/gdb/data-directory/Makefile.in gdb-10.2/gdb/data-directory/Makefile.in +--- gdb-10.2/gdb/data-directory/Makefile.in 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdb/data-directory/Makefile.in 2025-04-16 17:06:51.932086800 +0800 +@@ -1,4 +1,4 @@ +-# Copyright (C) 2010-2021 Free Software Foundation, Inc. ++# Copyright (C) 2010-2020 Free Software Foundation, Inc. + + # Makefile for building a staged copy of the data-directory. + # This file is part of GDB. +@@ -61,7 +61,8 @@ + s390-linux.xml \ + s390x-linux.xml \ + sparc-linux.xml \ +- sparc64-linux.xml ++ sparc64-linux.xml \ ++ sw_64-linux.xml + + SYSCALLS_FILES = gdb-syscalls.dtd freebsd.xml netbsd.xml $(GEN_SYSCALLS_FILES) + +diff -Nuar gdb-10.2/gdb/defs.h gdb-10.2/gdb/defs.h +--- gdb-10.2/gdb/defs.h 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdb/defs.h 2025-04-16 17:06:41.892086800 +0800 +@@ -629,4 +629,7 @@ + + #include "utils.h" + ++#ifdef CRASH_MERGE ++extern "C" int gdb_main_entry(int, char **); ++#endif + #endif /* #ifndef DEFS_H */ +diff -Nuar gdb-10.2/gdb/dwarf2/read.c gdb-10.2/gdb/dwarf2/read.c +--- gdb-10.2/gdb/dwarf2/read.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/dwarf2/read.c 2025-04-16 17:06:41.952086800 +0800 +@@ -3015,7 +3015,11 @@ + indices. */ + if (version < 4) + { ++#ifdef CRASH_MERGE ++ static int warning_printed = 1; ++#else + static int warning_printed = 0; ++#endif + if (!warning_printed) + { + warning (_("Skipping obsolete .gdb_index section in %s."), +@@ -3034,7 +3038,11 @@ + "set use-deprecated-index-sections on". */ + if (version < 6 && !deprecated_ok) + { ++#ifdef CRASH_MERGE ++ static int warning_printed = 1; ++#else + static int warning_printed = 0; ++#endif + if (!warning_printed) + { + warning (_("\ +@@ -4917,7 +4925,10 @@ + result = recursively_find_pc_sect_compunit_symtab + (dw2_instantiate_symtab (data, per_objfile, false), pc); + +- gdb_assert (result != NULL); ++ if (warn_if_readin && result == nullptr) ++ warning (_("(Error: pc %s in address map, but not in symtab.)"), ++ paddress (objfile->arch (), pc)); ++ + return result; + } + +diff -Nuar gdb-10.2/gdb/findvar.c gdb-10.2/gdb/findvar.c +--- gdb-10.2/gdb/findvar.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/findvar.c 2025-04-16 17:06:51.932086800 +0800 +@@ -1,6 +1,6 @@ + /* Find a variable's value in memory, for GDB, the GNU debugger. + +- Copyright (C) 1986-2021 Free Software Foundation, Inc. ++ Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -790,7 +790,25 @@ + /* Determine address of TLS variable. */ + if (obj_section + && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) +- addr = target_translate_tls_address (obj_section->objfile, addr); ++#ifndef XWB20200308 ++ { ++ struct bfd_section *sect; ++ ++ /* here, addr same as output of swnm */ ++ sect = obj_section->the_bfd_section; ++ ++ /* all for slave */ ++ if ( !strcmp(sect->name, ".tdata")) ++ addr = target_translate_tls_address (obj_section->objfile, addr ); ++ ++ sect = bfd_get_section_by_name (obj_section->objfile->obfd, ".tdata_ local"); ++ if (sect) ++ addr += 1L<alignment_power; ++ //debug("%s address %#lx", SYMBOL_PRINT_NAME (var), addr); ++ } ++#else ++ addr = target_translate_tls_address (obj_section->objfile, addr); ++#endif + } + break; + +diff -Nuar gdb-10.2/gdb/fnchange.lst gdb-10.2/gdb/fnchange.lst +--- gdb-10.2/gdb/fnchange.lst 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/fnchange.lst 2025-04-16 17:06:51.932086800 +0800 +@@ -0,0 +1,730 @@ ++@V@/COPYING.LIBGLOSS @V@/COPYING.GLOSS ++@V@/bfd/ChangeLog-9193 @V@/bfd/ChangeLog.9193 ++@V@/bfd/ChangeLog-9495 @V@/bfd/ChangeLog.9495 ++@V@/bfd/ChangeLog-9697 @V@/bfd/ChangeLog.9697 ++@V@/bfd/ChangeLog-9899 @V@/bfd/ChangeLog.9899 ++@V@/bfd/ChangeLog-0001 @V@/bfd/ChangeLog.0001 ++@V@/bfd/ChangeLog-0203 @V@/bfd/ChangeLog.0203 ++@V@/bfd/ChangeLog-2004 @V@/bfd/ChangeLog.004 ++@V@/bfd/ChangeLog-2005 @V@/bfd/ChangeLog.005 ++@V@/bfd/ChangeLog-2006 @V@/bfd/ChangeLog.006 ++@V@/bfd/ChangeLog-2007 @V@/bfd/ChangeLog.007 ++@V@/bfd/ChangeLog-2008 @V@/bfd/ChangeLog.008 ++@V@/bfd/doc/ChangeLog-9103 @V@/bfd/ChangeLog.9103 ++@V@/bfd/coff-tic30.c @V@/bfd/cofftic30.c ++@V@/bfd/coff-tic4x.c @V@/bfd/cofftic40.c ++@V@/bfd/coff-tic54x.c @V@/bfd/cofftic54x.c ++@V@/bfd/coff-tic80.c @V@/bfd/cofftic80.c ++@V@/bfd/cpu-cr16.c @V@/bfd/cpucr16.c ++@V@/bfd/cpu-cr16c.c @V@/bfd/cpucr16c.c ++@V@/bfd/cpu-ia64-opc.c @V@/bfd/cpuia64-opc.c ++@V@/bfd/cpu-microblaze.c @V@/bfd/cpumb.c ++@V@/bfd/cpu-m68hc11.c @V@/bfd/cm68hc11.c ++@V@/bfd/cpu-m68hc12.c @V@/bfd/cm68hc12.c ++@V@/bfd/efi-app-ia32.c @V@/bfd/efiia32app.c ++@V@/bfd/efi-app-ia64.c @V@/bfd/efiia64app.c ++@V@/bfd/efi-bsdrv-ia32.c @V@/bfd/efiia32bsdrv.c ++@V@/bfd/efi-bsdrv-ia64.c @V@/bfd/efiia64bsdrv.c ++@V@/bfd/efi-rtdrv-ia32.c @V@/bfd/efiia32rtdrv.c ++@V@/bfd/efi-rtdrv-ia64.c @V@/bfd/efiia64rtdrv.c ++@V@/bfd/elf32-arc.c @V@/bfd/elf32arc.c ++@V@/bfd/elf32-crx.c @V@/bfd/elf32crx.c ++@V@/bfd/elf32-cris.c @V@/bfd/elf32cris.c ++@V@/bfd/elf32-cr16c.c @V@/bfd/elf32cr16c.c ++@V@/bfd/elf32-fr30.c @V@/bfd/elf32f30.c ++@V@/bfd/elf32-frv.c @V@/bfd/elf32fv.c ++@V@/bfd/elf32-i370.c @V@/bfd/e32i370.c ++@V@/bfd/elf32-i386.c @V@/bfd/e32i86.c ++@V@/bfd/elf32-microblaze.c @V@e32mb.c ++@V@/bfd/elf32-m32c.c @V@/bfd/em32c.c ++@V@/bfd/elf32-m32r.c @V@/bfd/em32r.c ++@V@/bfd/elf32-m68hc11.c @V@/bfd/em68hc11.c ++@V@/bfd/elf32-m68hc12.c @V@/bfd/em68hc12.c ++@V@/bfd/elf32-m68hc1x.c @V@/bfd/em68hc1x.c ++@V@/bfd/elf32-m68k.c @V@/bfd/em68k.c ++@V@/bfd/elf32-microblaze.c @V@/bfd/emicroblaze.c ++@V@/bfd/elf32-ppc.c @V@/bfd/e32ppc.c ++@V@/bfd/elf32-sh.c @V@/bfd/e32sh.c ++@V@/bfd/elf32-score.c @V@/bfd/e32score.c ++@V@/bfd/elf32-sh64.c @V@/bfd/e32sh64.c ++@V@/bfd/elf32-sh-relocs.c @V@/bfd/e32sh-relocs.c ++@V@/bfd/elf32-sh-relocs.h @V@/bfd/e32sh-relocs.h ++@V@/bfd/elf32-sh-symbian.c @V@/bfd/e32sh-symbian.c ++@V@/bfd/elf32-sh64-com.c @V@/bfd/e32sh64-com.c ++@V@/bfd/elf32-sparc.c @V@/bfd/e32sparc.c ++@V@/bfd/elf32-spu.c @V@/bfd/e32spu.c ++@V@/bfd/elf64-alpha.c @V@/bfd/e64alphf.c ++@V@/bfd/elf64-sw_64.c @V@/bfd/e64alphf.c ++@V@/bfd/elf64-sh64.c @V@/bfd/e64sh64.c ++@V@/config/bootstrap-O1.mk @V@/config/boot-O1.mk ++@V@/config/bootstrap-O3.mk @V@/config/boot-O3.mk ++@V@/config/bootstrap-debug-big.mk @V@/config/boot-dbig.mk ++@V@/config/bootstrap-debug-ckovw.mk @V@/config/boot-bckovw.mk ++@V@/config/bootstrap-debug-lean.mk @V@/config/boot-dlean.mk ++@V@/config/bootstrap-debug-lib.mk @V@/config/boot-dlib.mk ++@V@/config/bootstrap-debug.mk @V@/config/boot-debug.mk ++@V@/config/bootstrap-time.mk @V@/config/boot-time.mk ++@V@/config/inttypes-pri.m4 @V@/config/pri-inttypes.m4 ++@V@/config/inttypes_h.m4 @V@/config/uintmax-inttypes.m4 ++@V@/config/mt-mips-elfoabi @V@/config/mt-elfoabi-mips ++@V@/config/mt-mips-gnu @V@/config/mt-gnu-mips ++@V@/dejagnu/baseboards/mn10200-cygmon.exp @V@/dejagnu/baseboards/mn10200cygmon.exp ++@V@/dejagnu/baseboards/mn10200-sim.exp @V@/dejagnu/baseboards/mn10200sim.exp ++@V@/dejagnu/baseboards/mn10300-cygmon.exp @V@/dejagnu/baseboards/mn10300cygmon.exp ++@V@/dejagnu/baseboards/mn10300-sim.exp @V@/dejagnu/baseboards/mn10300sim.exp ++@V@/dejagnu/baseboards/powerpc-bug1.exp @V@/dejagnu/baseboards/powerpc1-bug.exp ++@V@/dejagnu/baseboards/powerpc-sim.exp @V@/dejagnu/baseboards/powerpcsim.exp ++@V@/dejagnu/baseboards/sparclite-coff.exp @V@/dejagnu/baseboards/sl-coff.exp ++@V@/dejagnu/baseboards/sparclite-cygmon.exp @V@/dejagnu/baseboards/sl-cygmon.exp ++@V@/dejagnu/baseboards/sparclite-sim-le.exp @V@/dejagnu/baseboards/sl-sim-le.exp ++@V@/dejagnu/baseboards/sparclite-sim.exp @V@/dejagnu/baseboards/sl-sim.exp ++@V@/dejagnu/contrib/test-g++ @V@/dejagnu/contrib/test-gxx ++@V@/dejagnu/example/calc/calc.h.in @V@/dejagnu/example/calc/calc.h-in ++@V@/expect/Dbg_cf.h.in @V@/expect/Dbg_cf.h-in ++@V@/expect/example/beer.exp.out @V@/expect/example/beer_exp.out ++@V@/expect/example/chesslib++.c @V@/expect/example/chesslibxx.c ++@V@/expect/example/chesslib.c @V@/expect/example/chesslb.c ++@V@/expect/example/chesslib2.c @V@/expect/example/chesslb2.c ++@V@/expect/example/chesslibxx.c @V@/expect/example/chesslbxx.c ++@V@/expect/exp_main_sub.c @V@/expect/exp_m_sub.c ++@V@/expect/exp_main_tk.c @V@/expect/exp_m_tk.c ++@V@/expect/expect_cf.h.in @V@/expect/expect_cf.h-in ++@V@/gdb/ChangeLog-1990 @V@/gdb/ChangeLog.90 ++@V@/gdb/ChangeLog-1991 @V@/gdb/ChangeLog.91 ++@V@/gdb/ChangeLog-1992 @V@/gdb/ChangeLog.92 ++@V@/gdb/ChangeLog-1993 @V@/gdb/ChangeLog.93 ++@V@/gdb/ChangeLog-1994 @V@/gdb/ChangeLog.94 ++@V@/gdb/ChangeLog-1995 @V@/gdb/ChangeLog.95 ++@V@/gdb/ChangeLog-1996 @V@/gdb/ChangeLog.96 ++@V@/gdb/ChangeLog-1997 @V@/gdb/ChangeLog.97 ++@V@/gdb/ChangeLog-1998 @V@/gdb/ChangeLog.98 ++@V@/gdb/ChangeLog-1999 @V@/gdb/ChangeLog.99 ++@V@/gdb/ChangeLog-2000 @V@/gdb/ChangeLog.000 ++@V@/gdb/ChangeLog-2001 @V@/gdb/ChangeLog.001 ++@V@/gdb/ChangeLog-2002 @V@/gdb/ChangeLog.002 ++@V@/gdb/ChangeLog-2003 @V@/gdb/ChangeLog.003 ++@V@/gdb/ChangeLog-2004 @V@/gdb/ChangeLog.004 ++@V@/gdb/ChangeLog-2005 @V@/gdb/ChangeLog.005 ++@V@/gdb/ChangeLog-2006 @V@/gdb/ChangeLog.006 ++@V@/gdb/ChangeLog-2007 @V@/gdb/ChangeLog.007 ++@V@/gdb/ChangeLog-2008 @V@/gdb/ChangeLog.008 ++@V@/gdb/ChangeLog-2009 @V@/gdb/ChangeLog.009 ++@V@/gdb/ChangeLog-2010 @V@/gdb/ChangeLog.010 ++@V@/gdb/ChangeLog-2011 @V@/gdb/ChangeLog.011 ++@V@/gdb/ChangeLog-2012 @V@/gdb/ChangeLog.012 ++@V@/gdb/ChangeLog-2013 @V@/gdb/ChangeLog.013 ++@V@/gdb/ChangeLog-2014 @V@/gdb/ChangeLog.014 ++@V@/gdb/ChangeLog-2015 @V@/gdb/ChangeLog.015 ++@V@/gdb/ChangeLog-2016 @V@/gdb/ChangeLog.016 ++@V@/gdb/ChangeLog-2017 @V@/gdb/ChangeLog.017 ++@V@/gdb/ChangeLog-2018 @V@/gdb/ChangeLog.018 ++@V@/gdb/ChangeLog-2019 @V@/gdb/ChangeLog.019 ++@V@/gdb/ChangeLog-3.x @V@/gdb/ChangeLog.3-x ++@V@/gdb/ada-exp.tab.c @V@/gdb/ada-exp_tab.c ++@V@/gdb/amd64-windows-nat.c @V@/gdb/a64w-nat.c ++@V@/gdb/amd64-windows-tdep.c @V@/gdb/a64w-tdep.c ++@V@/gdb/amd64-fbsd-nat.c @V@/gdb/a64fb-nat.c ++@V@/gdb/amd64-fbsd-tdep.c @V@/gdb/a64fb-tdep.c ++@V@/gdb/amd64-nbsd-nat.c @V@/gdb/a64nb-nat.c ++@V@/gdb/amd64-nbsd-tdep.c @V@/gdb/a64nb-tdep.c ++@V@/gdb/amd64-obsd-nat.c @V@/gdb/a64ob-nat.c ++@V@/gdb/amd64-obsd-tdep.c @V@/gdb/a64ob-tdep.c ++@V@/gdb/alpha-bsd-nat.c @V@/gdb/alphb-nat.c ++@V@/gdb/alpha-bsd-tdep.c @V@/gdb/alphb-tdep.c ++@V@/gdb/alpha-nbsd-tdep.c @V@/gdb/alphnb-tdep.c ++@V@/gdb/alpha-linux-nat.c @V@/gdb/alphl-nat.c ++@V@/gdb/alpha-linux-tdep.c @V@/gdb/alphl-tdep.c ++@V@/gdb/sw_64-bsd-nat.c @V@/gdb/sw_6b-nat.c ++@V@/gdb/sw_64-linux-nat.c @V@/gdb/sw_6l-nat.c ++@V@/gdb/sw_64-linux-tdep.c @V@/gdb/sw_6l-tdep.c ++@V@/gdb/arm-linux-nat.c @V@/gdb/armlin-nat.c ++@V@/gdb/arm-linux-tdep.c @V@/gdb/armlin-tdep.c ++@V@/gdb/arm-nbsd-nat.c @V@/gdb/armnbd-nat.c ++@V@/gdb/arm-nbsd-tdep.c @V@/gdb/armnbd-tdep.c ++@V@/gdb/c-exp.tab.c @V@/gdb/c-exp_tab.c ++@V@/gdb/config/alpha/tm-alphalinux.h @V@/gdb/config/alpha/tm-alplinux.h ++@V@/gdb/config/i386/nm-cygwin64.h @V@/gdb/config/i386/nm-cyg64.h ++@V@/gdb/config/i386/nm-linux64.h @V@/gdb/config/i386/nm-lx64.h ++@V@/gdb/config/i386/nm-i386sco4.h @V@/gdb/config/i386/nm-sco4.h ++@V@/gdb/config/i386/nm-i386sco5.h @V@/gdb/config/i386/nm-sco5.h ++@V@/gdb/config/i386/nm-i386v4.h @V@/gdb/config/i386/nm-v4.h ++@V@/gdb/config/i386/nm-i386v42mp.h @V@/gdb/config/i386/nm-v42mp.h ++@V@/gdb/config/i386/tm-i386sol2.h @V@/gdb/config/i386/tm-sol2.h ++@V@/gdb/config/i386/xm-i386v4.h @V@/gdb/config/i386/xm-v4.h ++@V@/gdb/config/m88k/xm-delta88v4.h @V@/gdb/config/m88k/xm-d88v4.h ++@V@/gdb/config/mips/tm-linux.h @V@/gdb/config/mips/tm-lx.h ++@V@/gdb/config/pa/nm-hppah11.h @V@/gdb/config/pa/nm-hppa11.h ++@V@/gdb/config/rs6000/tm-rs6000.h @V@/gdb/config/rs6000/tm-rs6k.h ++@V@/gdb/config/rs6000/tm-rs6000ly.h @V@/gdb/config/rs6000/tm-rs6kly.h ++@V@/gdb/config/sparc/tm-sparclynx.h @V@/gdb/config/sparc/tm-splynx.h ++@V@/gdb/cp-names.c @V@/gdb/cpnames.c ++@V@/gdb/darwin-nat.c @V@/gdb/drw-nat.c ++@V@/gdb/darwin-nat-info.c @V@/gdb/drw-nat-info.c ++@V@/gdb/features/mips64-cp0.xml @V@/gdb/features/mips64-0cp.xml ++@V@/gdb/features/arm-vfpv2.xml @V@/gdb/features/armvfpv2.xml ++@V@/gdb/features/arm-vfpv3.xml @V@/gdb/features/armvfpv3.xml ++@V@/gdb/features/arm-with-iwmmxt.xml @V@/gdb/features/arm-iwmmxt.xml ++@V@/gdb/features/arm-with-neon.xml @V@/gdb/features/arm-neon.xml ++@V@/gdb/features/arm-with-iwmmxt.c @V@/gdb/features/arm-iwmmxt.c ++@V@/gdb/features/arm-with-neon.c @V@/gdb/features/arm-neon.c ++@V@/gdb/features/arm-with-vfpv2.xml @V@/gdb/features/arm-wv2.xml ++@V@/gdb/features/arm-with-vfpv3.xml @V@/gdb/features/arm-wv3.xml ++@V@/gdb/features/arm-with-vfpv2.c @V@/gdb/features/arm-wv2.c ++@V@/gdb/features/arm-with-vfpv3.c @V@/gdb/features/arm-wv3.c ++@V@/gdb/features/rs6000/power-fpu-isa205.xml @V@/gdb/features/rs6000/power-isa205.xml ++@V@/gdb/features/rs6000/power64-core.xml @V@/gdb/features/rs6000/power64core.xml ++@V@/gdb/features/rs6000/power64-linux.xml @V@/gdb/features/rs6000/power64linux.xml ++@V@/gdb/features/rs6000/powerpc-32.c @V@/gdb/features/rs6000/ppc-32.c ++@V@/gdb/features/rs6000/powerpc-32l.c @V@/gdb/features/rs6000/ppc-32l.c ++@V@/gdb/features/rs6000/powerpc-403.c @V@/gdb/features/rs6000/ppc-403.c ++@V@/gdb/features/rs6000/powerpc-403gc.c @V@/gdb/features/rs6000/ppc-403gc.c ++@V@/gdb/features/rs6000/powerpc-505.c @V@/gdb/features/rs6000/ppc-505.c ++@V@/gdb/features/rs6000/powerpc-601.c @V@/gdb/features/rs6000/ppc-601.c ++@V@/gdb/features/rs6000/powerpc-602.c @V@/gdb/features/rs6000/ppc-602.c ++@V@/gdb/features/rs6000/powerpc-603.c @V@/gdb/features/rs6000/ppc-603.c ++@V@/gdb/features/rs6000/powerpc-604.c @V@/gdb/features/rs6000/ppc-604.c ++@V@/gdb/features/rs6000/powerpc-64.c @V@/gdb/features/rs6000/ppc-64.c ++@V@/gdb/features/rs6000/powerpc-64l.c @V@/gdb/features/rs6000/ppc-64l.c ++@V@/gdb/features/rs6000/powerpc-7400.c @V@/gdb/features/rs6000/ppc-7400.c ++@V@/gdb/features/rs6000/powerpc-750.c @V@/gdb/features/rs6000/ppc-7500.c ++@V@/gdb/features/rs6000/powerpc-860.c @V@/gdb/features/rs6000/ppc-860.c ++@V@/gdb/features/rs6000/powerpc-altivec32.c @V@/gdb/features/rs6000/ppc-a32.c ++@V@/gdb/features/rs6000/powerpc-altivec32l.c @V@/gdb/features/rs6000/ppc-a32l.c ++@V@/gdb/features/rs6000/powerpc-altivec64.c @V@/gdb/features/rs6000/ppc-a64.c ++@V@/gdb/features/rs6000/powerpc-altivec64l.c @V@/gdb/features/rs6000/ppc-a64l.c ++@V@/gdb/features/rs6000/powerpc-e500.c @V@/gdb/features/rs6000/ppc-e5h.c ++@V@/gdb/features/rs6000/powerpc-e500l.c @V@/gdb/features/rs6000/ppc-e5hl.c ++@V@/gdb/features/rs6000/powerpc-isa205-32l.c @V@/gdb/features/rs6000/ppc-is32.c ++@V@/gdb/features/rs6000/powerpc-isa205-64l.c @V@/gdb/features/rs6000/ppc-is64.c ++@V@/gdb/features/rs6000/powerpc-isa205-altivec32l.c @V@/gdb/features/rs6000/ppcia32l.c ++@V@/gdb/features/rs6000/powerpc-isa205-altivec64l.c @V@/gdb/features/rs6000/ppcia64l.c ++@V@/gdb/features/rs6000/powerpc-isa205-vsx32l.c @V@/gdb/features/rs6000/ppciv32l.c ++@V@/gdb/features/rs6000/powerpc-isa205-vsx64l.c @V@/gdb/features/rs6000/ppciv64l.c ++@V@/gdb/features/rs6000/powerpc-vsx32.c @V@/gdb/features/rs6000/ppc-v32.c ++@V@/gdb/features/rs6000/powerpc-vsx32l.c @V@/gdb/features/rs6000/ppc-v32l.c ++@V@/gdb/features/rs6000/powerpc-vsx64.c @V@/gdb/features/rs6000/ppc-v64.c ++@V@/gdb/features/rs6000/powerpc-vsx64l.c @V@/gdb/features/rs6000/ppc-v64l.c ++@V@/gdb/features/rs6000/powerpc-32.xml @V@/gdb/features/rs6000/ppc-32.xml ++@V@/gdb/features/rs6000/powerpc-32l.xml @V@/gdb/features/rs6000/ppc-32l.xml ++@V@/gdb/features/rs6000/powerpc-403.xml @V@/gdb/features/rs6000/ppc-403.xml ++@V@/gdb/features/rs6000/powerpc-403gc.xml @V@/gdb/features/rs6000/ppc-403gc.xml ++@V@/gdb/features/rs6000/powerpc-505.xml @V@/gdb/features/rs6000/ppc-505.xml ++@V@/gdb/features/rs6000/powerpc-601.xml @V@/gdb/features/rs6000/ppc-601.xml ++@V@/gdb/features/rs6000/powerpc-602.xml @V@/gdb/features/rs6000/ppc-602.xml ++@V@/gdb/features/rs6000/powerpc-603.xml @V@/gdb/features/rs6000/ppc-603.xml ++@V@/gdb/features/rs6000/powerpc-604.xml @V@/gdb/features/rs6000/ppc-604.xml ++@V@/gdb/features/rs6000/powerpc-64.xml @V@/gdb/features/rs6000/ppc-64.xml ++@V@/gdb/features/rs6000/powerpc-64l.xml @V@/gdb/features/rs6000/ppc-64l.xml ++@V@/gdb/features/rs6000/powerpc-7400.xml @V@/gdb/features/rs6000/ppc-7400.xml ++@V@/gdb/features/rs6000/powerpc-750.xml @V@/gdb/features/rs6000/ppc-7500.xml ++@V@/gdb/features/rs6000/powerpc-860.xml @V@/gdb/features/rs6000/ppc-860.xml ++@V@/gdb/features/rs6000/powerpc-altivec32.xml @V@/gdb/features/rs6000/ppc-a32.xml ++@V@/gdb/features/rs6000/powerpc-altivec32l.xml @V@/gdb/features/rs6000/ppc-a32l.xml ++@V@/gdb/features/rs6000/powerpc-altivec64.xml @V@/gdb/features/rs6000/ppc-a64.xml ++@V@/gdb/features/rs6000/powerpc-altivec64l.xml @V@/gdb/features/rs6000/ppc-a64l.xml ++@V@/gdb/features/rs6000/powerpc-e500.xml @V@/gdb/features/rs6000/ppc-e5h.xml ++@V@/gdb/features/rs6000/powerpc-e500l.xml @V@/gdb/features/rs6000/ppc-e5hl.xml ++@V@/gdb/features/rs6000/powerpc-isa205-32l.xml @V@/gdb/features/rs6000/ppc-is32.xml ++@V@/gdb/features/rs6000/powerpc-isa205-64l.xml @V@/gdb/features/rs6000/ppc-is64.xml ++@V@/gdb/features/rs6000/powerpc-isa205-altivec32l.xml @V@/gdb/features/rs6000/ppcia32l.xml ++@V@/gdb/features/rs6000/powerpc-isa205-altivec64l.xml @V@/gdb/features/rs6000/ppcia64l.xml ++@V@/gdb/features/rs6000/powerpc-isa205-vsx32l.xml @V@/gdb/features/rs6000/ppciv32l.xml ++@V@/gdb/features/rs6000/powerpc-isa205-vsx64l.xml @V@/gdb/features/rs6000/ppciv64l.xml ++@V@/gdb/features/rs6000/powerpc-vsx32.xml @V@/gdb/features/rs6000/ppc-v32.xml ++@V@/gdb/features/rs6000/powerpc-vsx32l.xml @V@/gdb/features/rs6000/ppc-v32l.xml ++@V@/gdb/features/rs6000/powerpc-vsx64.xml @V@/gdb/features/rs6000/ppc-v64.xml ++@V@/gdb/features/rs6000/powerpc-vsx64l.xml @V@/gdb/features/rs6000/ppc-v64l.xml ++@V@/gdb/features/i386/amd64-avx-linux.c @V@/gdb/features/i386/a64-al.c ++@V@/gdb/features/i386/amd64-avx.c @V@/gdb/features/i386/a64-a.c ++@V@/gdb/features/i386/amd64-avx-linux.xml @V@/gdb/features/i386/a64-al.xml ++@V@/gdb/features/i386/amd64-avx.xml @V@/gdb/features/i386/a64-a.xml ++@V@/gdb/features/i386/i386-avx-linux.c @V@/features/i386/i32-al.c ++@V@/gdb/features/i386/i386-avx.c @V@/gdb/features/i386/i32-a.c ++@V@/gdb/features/i386/i386-avx-linux.xml @V@/gdb/features/i386/i32-al.xml ++@V@/gdb/features/i386/i386-avx.xml @V@/gdb/features/i386/i32-a.xml ++@V@/gdb/features/i386/i386-mmx-linux.c @V@/features/i386/i32-ml.c ++@V@/gdb/features/i386/i386-mmx.c @V@/gdb/features/i386/i32-m.c ++@V@/gdb/features/i386/i386-mmx-linux.xml @V@/gdb/features/i386/i32-ml.xml ++@V@/gdb/features/i386/i386-mmx.xml @V@/gdb/features/i386/i32-m.xml ++@V@/gdb/features/tic6x-core.xml @V@/gdb/features/c6x-core.xml ++@V@/gdb/features/tic6x-gp.xml @V@/gdb/features/c6x-gp.xml ++@V@/gdb/features/tic6x-c6xp.xml @V@/gdb/features/c6x-c6xp.xml ++@V@/gdb/features/tic6x-c62x.xml @V@/gdb/features/c6x-62x.xml ++@V@/gdb/features/tic6x-c64x.xml @V@/gdb/features/c6x-64x.xml ++@V@/gdb/features/tic6x-c64xp.xml @V@/gdb/features/c6xc64xp.xml ++@V@/gdb/features/tic6x-c64xp.c @V@/gdb/features/c6xc64xp.c ++@V@/gdb/features/tic6x-c64x.c @V@/gdb/features/c6x-64x.c ++@V@/gdb/features/tic6x-c62x.c @V@/gdb/features/c6x-62x.c ++@V@/gdb/features/tic6x-c62x-linux.xml @V@/gdb/features/c6x-62xl.xml ++@V@/gdb/features/tic6x-c64x-linux.xml @V@/gdb/features/c6x-64xl.xml ++@V@/gdb/features/tic6x-c64xp-linux.xml @V@/gdb/features/c6x64xpl.xml ++@V@/gdb/features/tic6x-c64xp-linux.c @V@/gdb/features/c6x64xpl.c ++@V@/gdb/features/tic6x-c64x-linux.c @V@/gdb/features/c6x-64xl.c ++@V@/gdb/features/tic6x-c62x-linux.c @V@/gdb/features/c6x-62xl.c ++@V@/gdb/f-exp.tab.c @V@/gdb/f-exp_tab.c ++@V@/gdb/gdbserver/linux-cris-low.c @V@/gdb/gdbserver/lx-cris.c ++@V@/gdb/gdbserver/linux-crisv32-low.c @V@/gdb/gdbserver/lx-cris32.c ++@V@/gdb/gdbserver/linux-ppc-low.c @V@/gdb/gdbserver/lx-ppc-low.c ++@V@/gdb/gdbserver/linux-ppc64-low.c @V@/gdb/gdbserver/lx-ppc64-low.c ++@V@/gdb/gdbtk/ChangeLog-2001 @V@/gdb/gdbtk/ChangeLog.001 ++@V@/gdb/gdbtk/ChangeLog-2002 @V@/gdb/gdbtk/ChangeLog.002 ++@V@/gdb/gdbtk/ChangeLog-2003 @V@/gdb/gdbtk/ChangeLog.003 ++@V@/gdb/gdbtk/generic/ChangeLog-1997 @V@/gdb/gdbtk/generic/ChangeLog.97 ++@V@/gdb/gdbtk/generic/ChangeLog-1998 @V@/gdb/gdbtk/generic/ChangeLog.98 ++@V@/gdb/gdbtk/generic/ChangeLog-1999 @V@/gdb/gdbtk/generic/ChangeLog.99 ++@V@/gdb/gdbtk/generic/ChangeLog-2000 @V@/gdb/gdbtk/generic/ChangeLog.000 ++@V@/gdb/gdbtk/generic/gdbtk-varobj.c @V@/gdb/gdbtk/generic/gdbtk-vobj.c ++@V@/gdb/gdbtk/library/ChangeLog-1997 @V@/gdb/gdbtk/library/ChangeLog.97 ++@V@/gdb/gdbtk/library/ChangeLog-1998 @V@/gdb/gdbtk/library/ChangeLog.98 ++@V@/gdb/gdbtk/library/ChangeLog-1999 @V@/gdb/gdbtk/library/ChangeLog.99 ++@V@/gdb/gdbtk/library/ChangeLog-2000 @V@/gdb/gdbtk/library/ChangeLog.000 ++@V@/gdb/gdbtk/plugins/intel-pentium/intel-pentium.tcl.in @V@/gdb/gdbtk/plugins/intel-pentium/intel-pentium.t-in ++@V@/gdb/gdbtk/plugins/rhabout/rhabout.tcl.in @V@/gdb/gdbtk/plugins/rhabout/rhabout.t-in ++@V@/gdb/hppa-bsd-nat.c @V@/gdb/hppab-nat.c ++@V@/gdb/hppa-bsd-tdep.c @V@/gdb/hppab-tdep.c ++@V@/gdb/hpp-nbsd-nat.c @V@/gdb/hppnb-nat.c ++@V@/gdb/hpp-nbsd-tdep.c @V@/gdb/hppnb-tdep.c ++@V@/gdb/i386-darwin-nat.c @V@/gdb/i386dw-nat.c ++@V@/gdb/i386-darwin-tdep.c @V@/gdb/i386dw-tdep.c ++@V@/gdb/i386-linux-tdep.c @V@/gdb/i386lx-tdep.c ++@V@/gdb/i386-linux-nat.c @V@/gdb/i386lx-nat.c ++@V@/gdb/i386-bsd-nat.c @V@/gdb/i3bsd-nat.c ++@V@/gdb/i386-bsd-tdep.c @V@/gdb/i3bsd-tdep.c ++@V@/gdb/i386-fbsd-nat.c @V@/gdb/i3fbsd-nat.c ++@V@/gdb/i386-fbsd-tdep.c @V@/gdb/i3fbsd-tdep.c ++@V@/gdb/i386-gnu-nat.c @V@/gdb/i3gnu-nat.c ++@V@/gdb/i386-gnu-tdep.c @V@/gdb/i3gnu-tdep.c ++@V@/gdb/i386-nbsd-tdep.c @V@/gdb/i3nbsd-tdep.c ++@V@/gdb/i386-obsd-nat.c @V@/gdb/i3obsd-nat.c ++@V@/gdb/i386-obsd-tdep.c @V@/gdb/i3obsd-tdep.c ++@V@/gdb/i386-sol2-nat.c @V@/gdb/i3sol2-nat.c ++@V@/gdb/i386-sol2-tdep.c @V@/gdb/i3sol2-tdep.c ++@V@/gdb/ia64-aix-nat.c @V@/gdb/ia64ax-nat.c ++@V@/gdb/ia64-aix-tdep.c @V@/gdb/ia64ax-tdep.c ++@V@/gdb/ia64-linux-nat.c @V@/gdb/ia64lx-nat.c ++@V@/gdb/ia64-linux-tdep.c @V@/gdb/ia64lx-tdep.c ++@V@/gdb/jv-exp.tab.c @V@/gdb/jv-exp_tab.c ++@V@/gdb/m2-exp.tab.c @V@/gdb/m2-exp_tab.c ++@V@/gdb/m32r-linux-nat.c @V@/gdb/m32rlnxnat.c ++@V@/gdb/m32r-linux-tdep.c @V@/gdb/m32rlnxtdep.c ++@V@/gdb/m68k-linux-nat.c @V@/gdb/m68kl-nat.c ++@V@/gdb/m68k-linux-tdep.c @V@/gdb/m68kl-tdep.c ++@V@/gdb/m68k-bsd-nat.c @V@/gdb/m68bsd-nat.c ++@V@/gdb/m68k-bsd-tdep.c @V@/gdb/m68bsd-tdep.c ++@V@/gdb/m68k-nbsd-nat.c @V@/gdb/m6nbsd-nat.c ++@V@/gdb/m68k-nbsd-tdep.c @V@/gdb/m6nbsd-tdep.c ++@V@/gdb/microblaze-rom.c @V@/gdb/mb-rom.c ++@V@/gdb/microblaze-linux-tdep.c @V@/gdb/mbl-tdep.c ++@V@/gdb/microblaze-tdep.h @V@/gdb/mb-tdep.h ++@V@/gdb/microblaze-tdep.c @V@/gdb/mb-tdep.c ++@V@/gdb/mips-linux-nat.c @V@/gdb/mipslnxnat.c ++@V@/gdb/mips-linux-tdep.c @V@/gdb/mipslnxtdep.c ++@V@/gdb/mips-nbsd-nat.c @V@/gdb/mipsnbnat.c ++@V@/gdb/mips-nbsd-tdep.c @V@/gdb/mipsnbtdep.c ++@V@/gdb/mips64-obsd-nat.c @V@/gdb/mipsobnat.c ++@V@/gdb/mips64-obsd-tdep.c @V@/gdb/mipsobtdep.c ++@V@/gdb/mn10300-linux-tdep.c @V@/gdb/mn10300linux-tdep.c ++@V@/gdb/ns32k-nbsd-nat.c @V@/gdb/ns32nb-nat.c ++@V@/gdb/ns32k-nbsd-tdep.c @V@/gdb/ns32nb-tdep.c ++@V@/gdb/objc-exp.tab.c @V@/gdb/objc-exp_tab.c ++@V@/gdb/p-exp.tab.c @V@/gdb/p-exp_tab.c ++@V@/gdb/ppc-linux-tdep.c @V@/gdb/ppc-lx-tdep.c ++@V@/gdb/ppc-linux-nat.c @V@/gdb/ppc-lx-nat.c ++@V@/gdb/ppc-nbsd-nat.c @V@/gdb/ppcnb-nat.c ++@V@/gdb/ppc-nbsd-tdep.c @V@/gdb/ppcnb-tdep.c ++@V@/gdb/ppc-obsd-nat.c @V@/gdb/ppcob-nat.c ++@V@/gdb/ppc-obsd-tdep.c @V@/gdb/ppcob-tdep.c ++@V@/gdb/regformats/arm-with-vfpv2.dat @V@/gdb/regformats/arm-wv2.dat ++@V@/gdb/regformats/arm-with-vfpv3.dat @V@/gdb/regformats/arm-wv3.dat ++@V@/gdb/regformats/arm-with-iwmmxt.dat @V@/gdb/regformats/arm-iwmmxt.dat ++@V@/gdb/regformats/arm-with-neon.dat @V@/gdb/regformats/arm-neon.dat ++@V@/gdb/regformats/reg-i386-linux.dat @V@/gdb/regformats/r-i386-lnx.dat ++@V@/gdb/regformats/reg-x86-64-linux.dat @V@/gdb/regformats/r-x8664-linux.dat ++@V@/gdb/regformats/reg-x86-64.dat @V@/gdb/regformats/r-x8664.dat ++@V@/gdb/regformats/reg-s390x.dat @V@/gdb/regformats/r-s390x.dat ++@V@/gdb/regformats/reg-cris.dat @V@/gdb/regformats/r-cris.dat ++@V@/gdb/regformats/reg-crisv32.dat @V@/gdb/regformats/r-crisv32.dat ++@V@/gdb/regformats/rs6000/powerpc-32l.dat @V@/gdb/regformats/rs6000/ppc-32l.dat ++@V@/gdb/regformats/rs6000/powerpc-64l.dat @V@/gdb/regformats/rs6000/ppc-64l.dat ++@V@/gdb/regformats/rs6000/powerpc-altivec32l.dat @V@/gdb/regformats/rs6000/ppc-a32l.dat ++@V@/gdb/regformats/rs6000/powerpc-altivec64l.dat @V@/gdb/regformats/rs6000/ppc-a64l.dat ++@V@/gdb/regformats/rs6000/powerpc-e500l.dat @V@/gdb/regformats/rs6000/ppc-e5hl.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-32l.dat @V@/gdb/regformats/rs6000/ppc-i32l.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-64l.dat @V@/gdb/regformats/rs6000/ppc-i64l.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-altivec32l.dat @V@/gdb/regformats/rs6000/ppcia32l.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-altivec64l.dat @V@/gdb/regformats/rs6000/ppcia64l.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-vsx32l.dat @V@/gdb/regformats/rs6000/ppciv32l.dat ++@V@/gdb/regformats/rs6000/powerpc-isa205-vsx64l.dat @V@/gdb/regformats/rs6000/ppciv64l.dat ++@V@/gdb/regformats/rs6000/powerpc-vsx32l.dat @V@/gdb/regformats/rs6000/ppc-v32l.dat ++@V@/gdb/regformats/rs6000/powerpc-vsx64l.dat @V@/gdb/regformats/rs6000/ppc-v64l.dat ++@V@/gdb/regformats/tic6x-c62x.dat @V@/gdb/regformats/c6x-62x.dat ++@V@/gdb/regformats/tic6x-c64x.dat @V@/gdb/regformats/c6x-64x.dat ++@V@/gdb/regformats/tic6x-c64xp.dat @V@/gdb/regformats/c6xc64xp.dat ++@V@/gdb/regformats/tic6x-c62x-linux.dat @V@/gdb/regformats/c6x-62xl.dat ++@V@/gdb/regformats/tic6x-c64x-linux.dat @V@/gdb/regformats/c6x-64xl.dat ++@V@/gdb/regformats/tic6x-c64xp-linux.dat @V@/gdb/regformats/c6x64xpl.dat ++@V@/gdb/remote-e7000.c @V@/gdb/rmt-e7000.c ++@V@/gdb/remote-est.c @V@/gdb/rmt-est.c ++@V@/gdb/remote-mips.c @V@/gdb/rmt-mips.c ++@V@/gdb/remote-rdi.c @V@/gdb/rmt-rdi.c ++@V@/gdb/remote-rdp.c @V@/gdb/rmt-rdp.c ++@V@/gdb/remote-sds.c @V@/gdb/rmt-sds.c ++@V@/gdb/remote-sim.c @V@/gdb/rmt-sim.c ++@V@/gdb/remote-st.c @V@/gdb/rmt-st.c ++@V@/gdb/remote-vx.c @V@/gdb/rmt-vx.c ++@V@/gdb/remote-vx68.c @V@/gdb/rmt-vx68.c ++@V@/gdb/remote-vxmips.c @V@/gdb/rmt-vxmips.c ++@V@/gdb/remote-vxsparc.c @V@/gdb/rmt-vxsparc.c ++@V@/gdb/sparc64-fbsd-nat.c @V@/gdb/sp64fb-nat.c ++@V@/gdb/sparc64-fbsd-tdep.c @V@/gdb/sp64fb-tdep.c ++@V@/gdb/sparc64-nbsd-nat.c @V@/gdb/sp64nb-nat.c ++@V@/gdb/sparc64-nbsd-tdep.c @V@/gdb/sp64nb-tdep.c ++@V@/gdb/sparc64-linux-nat.c @V@/gdb/sp64lx-nat.c ++@V@/gdb/sparc64-linux-tdep.c @V@/gdb/sp64lx-tdep.c ++@V@/gdb/sparc64-nat.c @V@/gdb/sp64-nat.c ++@V@/gdb/sparc64-tdep.c @V@/gdb/sp64-tdep.c ++@V@/gdb/sparc64-sol2-tdep.c @V@/gdb/sp64s2-tdep.c ++@V@/gdb/sparc-nbsd-nat.c @V@/gdb/spnb-nat.c ++@V@/gdb/sparc-nbsd-tdep.c @V@/gdb/spnb-tdep.c ++@V@/gdb/sparc-linux-nat.c @V@/gdb/splx-nat.c ++@V@/gdb/sparc-linux-tdep.c @V@/gdb/splx-tdep.c ++@V@/gdb/sparc-sol2-nat.c @V@/gdb/spsol2-nat.c ++@V@/gdb/sparc-sol2-tdep.c @V@/gdb/spsol2-tdep.c ++@V@/gdb/tic6x-tdep.c @V@/gdb/c6x-tdep.c ++@V@/gdb/tic6x-tdep.h @V@/gdb/c6x-tdep.h ++@V@/gdb/tic6x-linux-tdep.c @V@/gdb/c6xl-tdep.c ++@V@/gdb/testsuite/.gdbinit @V@/gdb/testsuite/gdb.ini ++@V@/gdb/testsuite/gdb.arch/altivec-abi.c @V@/gdb/testsuite/gdb.arch/av-abi.c ++@V@/gdb/testsuite/gdb.arch/altivec-abi.exp @V@/gdb/testsuite/gdb.arch/av-abi.exp ++@V@/gdb/testsuite/gdb.arch/altivec-regs.c @V@/gdb/testsuite/gdb.arch/av-regs.c ++@V@/gdb/testsuite/gdb.arch/altivec-regs.exp @V@/gdb/testsuite/gdb.arch/av-regs.exp ++@V@/gdb/testsuite/gdb.arch/i386-size-overlap.c @V@/gdb/testsuite/gdb.arch/i386-overlap-size.c ++@V@/gdb/testsuite/gdb.arch/i386-size-overlap.exp @V@/gdb/testsuite/gdb.arch/i386-overlap-size.exp ++@V@/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp @V@/gdb/testsuite/gdb.arch/ppcaprol.exp ++@V@/gdb/testsuite/gdb.arch/powerpc-aix-prologue.c @V@/gdb/testsuite/gdb.arch/ppcaprol.c ++@V@/gdb/testsuite/gdb.arch/powerpc-d128-regs.c @V@/gdb/testsuite/gdb.arch/ppc-d128-regs.c ++@V@/gdb/testsuite/gdb.arch/powerpc-prologue.c @V@/gdb/testsuite/gdb.arch/ppc-prologue.c ++@V@/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp @V@/gdb/testsuite/gdb.arch/ppc-d128-regs.exp ++@V@/gdb/testsuite/gdb.arch/powerpc-prologue.exp @V@/gdb/testsuite/gdb.arch/ppc-prologue.exp ++@V@/gdb/testsuite/gdb.base/bitfields2.c @V@/gdb/testsuite/gdb.base/bitfiel2.c ++@V@/gdb/testsuite/gdb.base/bitfields2.exp @V@/gdb/testsuite/gdb.base/bitfiel2.exp ++@V@/gdb/testsuite/gdb.base/break-entry.exp @V@/gdb/testsuite/gdb.base/brkentry.exp ++@V@/gdb/testsuite/gdb.base/break-fun-addr1.c @V@/gdb/testsuite/gdb.base/b-f-a1.c ++@V@/gdb/testsuite/gdb.base/break-fun-addr2.c @V@/gdb/testsuite/gdb.base/b-f-a2.c ++@V@/gdb/testsuite/gdb.base/coremaker2.c @V@/gdb/testsuite/gdb.base/core2maker.c ++@V@/gdb/testsuite/gdb.base/hashline1.exp @V@/gdb/testsuite/gdb.base/hash1line.exp ++@V@/gdb/testsuite/gdb.base/hashline2.exp @V@/gdb/testsuite/gdb.base/hash2line.exp ++@V@/gdb/testsuite/gdb.base/hashline3.exp @V@/gdb/testsuite/gdb.base/hash3line.exp ++@V@/gdb/testsuite/gdb.base/hook-stop-continue.c @V@/gdb/testsuite/gdb.base/hstop-continue.c ++@V@/gdb/testsuite/gdb.base/hook-stop-frame.c @V@/gdb/testsuite/gdb.base/hstop-frame.c ++@V@/gdb/testsuite/gdb.base/hook-stop-continue.exp @V@/gdb/testsuite/gdb.base/hstop-continue.exp ++@V@/gdb/testsuite/gdb.base/hook-stop-frame.exp @V@/gdb/testsuite/gdb.base/hstop-frame.exp ++@V@/gdb/testsuite/gdb.base/print-file-var-lib1.c @V@/gdb/testsuite/gdb.base/pfv-lib1.c ++@V@/gdb/testsuite/gdb.base/print-file-var-lib2.c @V@/gdb/testsuite/gdb.base/pfv-lib2.c ++@V@/gdb/testsuite/gdb.base/print-file-var-main.c @V@/gdb/testsuite/gdb.base/pfv-main.c ++@V@/gdb/testsuite/gdb.base/print-file-var.exp @V@/gdb/testsuite/gdb.base/pfv.exp ++@V@/gdb/testsuite/gdb.base/return-nodebug1.c @V@/gdb/testsuite/gdb.base/return-1nodebug.c ++@V@/gdb/testsuite/gdb.base/siginfo-addr.c @V@/gdb/testsuite/gdb.base/si-addr.c ++@V@/gdb/testsuite/gdb.base/siginfo-obj.c @V@/gdb/testsuite/gdb.base/si-obj.c ++@V@/gdb/testsuite/gdb.base/siginfo-addr.exp @V@/gdb/testsuite/gdb.base/si-addr.exp ++@V@/gdb/testsuite/gdb.base/siginfo-obj.exp @V@/gdb/testsuite/gdb.base/si-obj.exp ++@V@/gdb/testsuite/gdb.base/solib-corrupted.exp @V@/gdb/testsuite/gdb.base/so-crptd.exp ++@V@/gdb/testsuite/gdb.base/solib-disc.c @V@/gdb/testsuite/gdb.base/so-disc.c ++@V@/gdb/testsuite/gdb.base/solib-display-lib.c @V@/gdb/testsuite/gdb.base/so-displib.c ++@V@/gdb/testsuite/gdb.base/solib-display-main.c @V@/gdb/testsuite/gdb.base/so-dispmain.c ++@V@/gdb/testsuite/gdb.base/solib-disc.exp @V@/gdb/testsuite/gdb.base/so-disc.exp ++@V@/gdb/testsuite/gdb.base/solib-display-lib.exp @V@/gdb/testsuite/gdb.base/so-displib.exp ++@V@/gdb/testsuite/gdb.base/solib-display-main.exp @V@/gdb/testsuite/gdb.base/so-dispmain.exp ++@V@/gdb/testsuite/gdb.base/solib-symbol-lib.c @V@/gdb/testsuite/gdb.base/so-symlib.c ++@V@/gdb/testsuite/gdb.base/solib-symbol-main.c @V@/gdb/testsuite/gdb.base/so-symmain.c ++@V@/gdb/testsuite/gdb.base/solib-overlap-lib.c @V@/gdb/testsuite/gdb.base/so-ovrlib.c ++@V@/gdb/testsuite/gdb.base/solib-overlap-main.c @V@/gdb/testsuite/gdb.base/so-ovrmain.c ++@V@/gdb/testsuite/gdb.base/symbol-without-target_section.exp @V@/gdb/testsuite/gdb.base/symnosec.exp ++@V@/gdb/testsuite/gdb.base/symbol-without-target_section.c @V@/gdb/testsuite/gdb.base/symnosec.c ++@V@/gdb/testsuite/gdb.base/type-opaque-lib.c @V@/gdb/testsuite/gdb.base/ty-opqlib.c ++@V@/gdb/testsuite/gdb.base/type-opaque-main.c @V@/gdb/testsuite/gdb.base/ty-opqmain.c ++@V@/gdb/testsuite/gdb.base/watchpoint-hw.c @V@/gdb/testsuite/gdb.base/wp-hw.c ++@V@/gdb/testsuite/gdb.base/watchpoint-solib-shr.c @V@/gdb/testsuite/gdb.base/wp-shr-solib.c ++@V@/gdb/testsuite/gdb.base/watchpoint-solib.c @V@/gdb/testsuite/gdb.base/wp-solib.c ++@V@/gdb/testsuite/gdb.base/watchpoint-hw.exp @V@/gdb/testsuite/gdb.base/wp-hw.exp ++@V@/gdb/testsuite/gdb.base/watchpoint-solib.exp @V@/gdb/testsuite/gdb.base/wp-solib.exp ++@V@/gdb/testsuite/gdb.base/watchpoint-cond-gone.exp @V@/gdb/testsuite/gdb.base/wpcondg.exp ++@V@/gdb/testsuite/gdb.base/watchpoint-cond-gone.c @V@/gdb/testsuite/gdb.base/wpcondg.c ++@V@/gdb/testsuite/gdb.base/watchpoint-cond-gone-stripped.c @V@/gdb/testsuite/gdb.base/wpcondgs.c ++@V@/gdb/testsuite/gdb.cp/m-static1.cc @V@/gdb/testsuite/gdb.cp/m-stat1.cc ++@V@/gdb/testsuite/gdb.cp/namespace1.cc @V@/gdb/testsuite/gdb.cp/namesp1.cc ++@V@/gdb/testsuite/gdb.cp/namespace-nested-import.cc @V@/gdb/testsuite/gdb.cp/nnested.cc ++@V@/gdb/testsuite/gdb.cp/namespace-using.cc @V@/gdb/testsuite/gdb.cp/nusing.cc ++@V@/gdb/testsuite/gdb.cp/namespace-nested-import.exp @V@/gdb/testsuite/gdb.cp/nnested.exp ++@V@/gdb/testsuite/gdb.cp/namespace-using.exp @V@/gdb/testsuite/gdb.cp/nusing.exp ++@V@/gdb/testsuite/gdb.cp/mb-inline1.cc @V@/gdb/testsuite/gdb.cp/mb-inln1.cc ++@V@/gdb/testsuite/gdb.cp/mb-inline2.cc @V@/gdb/testsuite/gdb.cp/mb-inln2.cc ++@V@/gdb/testsuite/gdb.dwarf2/dw2-intermix.exp @V@/gdb/testsuite/gdb.dwarf2/dw2-intmix.exp ++@V@/gdb/testsuite/gdb.dwarf2/dw2-intermix.S @V@/gdb/testsuite/gdb.dwarf2/dw2-intmix.S ++@V@/gdb/testsuite/gdb.dwarf2/dw2-ranges.S @V@/gdb/testsuite/gdb.dwarf2/dw2-rng.S ++@V@/gdb/testsuite/gdb.dwarf2/dw2-ranges2.S @V@/gdb/testsuite/gdb.dwarf2/dw2-rng2.S ++@V@/gdb/testsuite/gdb.dwarf2/dw2-ranges3.S @V@/gdb/testsuite/gdb.dwarf2/dw2-rng3.S ++@V@/gdb/testsuite/gdb.gdbtk/ChangeLog @V@/gdb/testsuite/gdb.tk/ChangeLog ++@V@/gdb/testsuite/gdb.gdbtk/Makefile.in @V@/gdb/testsuite/gdb.tk/Makefile.in ++@V@/gdb/testsuite/gdb.gdbtk/browser.exp @V@/gdb/testsuite/gdb.tk/browser.exp ++@V@/gdb/testsuite/gdb.gdbtk/browser.test @V@/gdb/testsuite/gdb.tk/browser.test ++@V@/gdb/testsuite/gdb.gdbtk/c_variable.c @V@/gdb/testsuite/gdb.tk/c_variable.c ++@V@/gdb/testsuite/gdb.gdbtk/c_variable.exp @V@/gdb/testsuite/gdb.tk/c_variable.exp ++@V@/gdb/testsuite/gdb.gdbtk/c_variable.test @V@/gdb/testsuite/gdb.tk/c_variable.test ++@V@/gdb/testsuite/gdb.gdbtk/configure @V@/gdb/testsuite/gdb.tk/configure ++@V@/gdb/testsuite/gdb.gdbtk/configure.in @V@/gdb/testsuite/gdb.tk/configure.in ++@V@/gdb/testsuite/gdb.gdbtk/console.exp @V@/gdb/testsuite/gdb.tk/console.exp ++@V@/gdb/testsuite/gdb.gdbtk/console.test @V@/gdb/testsuite/gdb.tk/console.test ++@V@/gdb/testsuite/gdb.gdbtk/cpp_variable.cc @V@/gdb/testsuite/gdb.tk/cpp_variable.cc ++@V@/gdb/testsuite/gdb.gdbtk/cpp_variable.exp @V@/gdb/testsuite/gdb.tk/cpp_variable.exp ++@V@/gdb/testsuite/gdb.gdbtk/cpp_variable.h @V@/gdb/testsuite/gdb.tk/cpp_variable.h ++@V@/gdb/testsuite/gdb.gdbtk/cpp_variable.test @V@/gdb/testsuite/gdb.tk/cpp_variable.test ++@V@/gdb/testsuite/gdb.gdbtk/defs @V@/gdb/testsuite/gdb.tk/defs ++@V@/gdb/testsuite/gdb.gdbtk/list0.c @V@/gdb/testsuite/gdb.tk/list0.c ++@V@/gdb/testsuite/gdb.gdbtk/list0.h @V@/gdb/testsuite/gdb.tk/list0.h ++@V@/gdb/testsuite/gdb.gdbtk/list1.c @V@/gdb/testsuite/gdb.tk/list1.c ++@V@/gdb/testsuite/gdb.gdbtk/README @V@/gdb/testsuite/gdb.tk/README ++@V@/gdb/testsuite/gdb.gdbtk/simple.c @V@/gdb/testsuite/gdb.tk/simple.c ++@V@/gdb/testsuite/gdb.gdbtk/srcwin.exp @V@/gdb/testsuite/gdb.tk/srcwin.exp ++@V@/gdb/testsuite/gdb.gdbtk/srcwin.test @V@/gdb/testsuite/gdb.tk/srcwin.test ++@V@/gdb/testsuite/gdb.gdbtk/srcwin2.test @V@/gdb/testsuite/gdb.tk/srcwin2.test ++@V@/gdb/testsuite/gdb.gdbtk/srcwin3.test @V@/gdb/testsuite/gdb.tk/srcwin3.test ++@V@/gdb/testsuite/gdb.gdbtk/stack1.c @V@/gdb/testsuite/gdb.tk/stack1.c ++@V@/gdb/testsuite/gdb.gdbtk/stack2.c @V@/gdb/testsuite/gdb.tk/stack2.c ++@V@/gdb/testsuite/gdb.gdbtk/windows.exp @V@/gdb/testsuite/gdb.tk/windows.exp ++@V@/gdb/testsuite/gdb.gdbtk/windows.test @V@/gdb/testsuite/gdb.tk/windows.test ++@V@/gdb/testsuite/gdb.mi/mi-var-cmd.exp @V@/gdb/testsuite/gdb.mi/mi-varcmd.exp ++@V@/gdb/testsuite/gdb.mi/mi-var-child.exp @V@/gdb/testsuite/gdb.mi/mi-varchild.exp ++@V@/gdb/testsuite/gdb.mi/mi-var-child-f.exp @V@/gdb/testsuite/gdb.mi/mi-fvarchild.exp ++@V@/gdb/testsuite/gdb.mi/mi1-var-block.exp @V@/gdb/testsuite/gdb.mi/mi1varblock.exp ++@V@/gdb/testsuite/gdb.mi/mi1-var-child.exp @V@/gdb/testsuite/gdb.mi/mi1varchild.exp ++@V@/gdb/testsuite/gdb.mi/mi1-var-cmd.exp @V@/gdb/testsuite/gdb.mi/mi1varcmd.exp ++@V@/gdb/testsuite/gdb.mi/mi1-var-display.exp @V@/gdb/testsuite/gdb.mi/mi1vardisplay.exp ++@V@/gdb/testsuite/gdb.mi/mi2-var-block.exp @V@/gdb/testsuite/gdb.mi/mi2varblock.exp ++@V@/gdb/testsuite/gdb.mi/mi2-var-child.exp @V@/gdb/testsuite/gdb.mi/mi2varchild.exp ++@V@/gdb/testsuite/gdb.mi/mi2-var-cmd.exp @V@/gdb/testsuite/gdb.mi/mi2varcmd.exp ++@V@/gdb/testsuite/gdb.mi/mi2-var-display.exp @V@/gdb/testsuite/gdb.mi/mi2vardisplay.exp ++@V@/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp @V@/gdb/testsuite/gdb.mi/minonstop-exit.exp ++@V@/gdb/testsuite/gdb.mi/non-stop-exit.c @V@/gdb/testsuite/gdb.mi/nonstop-exit.c ++@V@/gdb/testsuite/gdb.threads/watchthreads2.c @V@/gdb/testsuite/gdb.threads/watchth2.c ++@V@/gdb/testsuite/gdb.threads/watchthreads2.exp @V@/gdb/testsuite/gdb.threads/watchth2.exp ++@V@/gdb/amd64-linux-tdep.c @V@/gdb/amd64-ltdep.c ++@V@/gdb/amd64-linux-nat.c @V@/gdb/amd64-lnat.c ++@V@/gdb/hppa-linux-tdep.c @V@/gdb/palnxtdep.c ++@V@/gdb/hppa-linux-nat.c @V@/gdb/palnxnat.c ++@V@/gdb/hppa-nbsd-nat.c @V@/gdb/panbsd-nat.c ++@V@/gdb/hppa-nbsd-tdep.c @V@/gdb/panbsd-tdep.c ++@V@/gdb/amd64-windows-nat.c @V@/gdb/amd64-wnat.c ++@V@/gdb/amd64-windows-tdep.c @V@/gdb/amd64-wtdep.c ++@V@/gdb/i386-windows-nat.c @V@/gdb/i386-wnat.c ++@V@/gdb/windows-nat.c @V@/gdb/win-nat.c ++@V@/gdb/windows-nat.h @V@/gdb/win-nat.h ++@V@/gdb/windows-tdep.c @V@/gdb/win-tdep.c ++@V@/gdb/windows-tdep.h @V@/gdb/win-tdep.h ++@V@/gdb/windows-termcap.c @V@/gdb/win-tcap.c ++@V@/gdb/xtensa-linux-nat.c @V@/gdb/xtlinuxnat.c ++@V@/gdb/xtensa-linux-tdep.c @V@/gdb/xtlinuxtdep.c ++@V@/include/ChangeLog-9103 @V@/include/ChangeLog.9103 ++@V@/include/coff/ChangeLog-9103 @V@/include/coff/ChangeLog.9103 ++@V@/include/elf/ChangeLog-9103 @V@/include/elf/ChangeLog.9103 ++@V@/include/opcode/ChangeLog-9103 @V@/include/opcode/ChangeLog.9103 ++@V@/include/xtensa-isa-internal.h @V@/include/xt-internal.h ++@V@/include/xtensa-isa.h @V@/include/xt-isa.h ++@V@/intl/intlh.inst.in @V@/intl/intlh_inst.in ++@V@/intl/po2tbl.sed.in @V@/intl/po2tblsed.in ++@V@/intl/config.intl.in @V@/intl/config_intl.in ++@V@/intl/config.h.in @V@/intl/config.h-in ++@V@/itcl/itcl/itclConfig.sh.in @V@/itcl/itcl/itclConfig.sh-in ++@V@/itcl/itcl/unix/pkgIndex.tcl.in @V@/itcl/itcl/unix/pkgIndex.t-in ++@V@/itcl/itk/itkConfig.sh.in @V@/itcl/itk/itkConfig.sh-in ++@V@/itcl/itk/unix/pkgIndex.tcl.in @V@/itcl/itk/unix/pkgIndex.t-in ++@V@/itcl/iwidgets3.0.0 @V@/itcl/iwidgets3.0-0 ++@V@/libgui/config.h.in @V@/libgui/config.h-in ++@V@/libgui/src/tkTableCell.c @V@/libgui/src/tkTabCell.c ++@V@/libgui/src/tkTableCmd.c @V@/libgui/src/tkTabCmd.c ++@V@/libgui/src/tkWinPrintCanvas.c @V@/libgui/src/tkWPrtCanvas.c ++@V@/libgui/src/tkWinPrintText.c @V@/libgui/src/tkWPrtText.c ++@V@/opcodes/ChangeLog-9297 @V@/opcodes/ChangeLog.9297 ++@V@/opcodes/ChangeLog-9899 @V@/opcodes/ChangeLog.9899 ++@V@/opcodes/ChangeLog-0001 @V@/opcodes/ChangeLog.0001 ++@V@/opcodes/ChangeLog-0203 @V@/opcodes/ChangeLog.0203 ++@V@/opcodes/ChangeLog-2004 @V@/opcodes/ChangeLog.004 ++@V@/opcodes/ChangeLog-2005 @V@/opcodes/ChangeLog.005 ++@V@/opcodes/ChangeLog-2006 @V@/opcodes/ChangeLog.006 ++@V@/opcodes/ChangeLog-2007 @V@/opcodes/ChangeLog.007 ++@V@/opcodes/ChangeLog-2008 @V@/opcodes/ChangeLog.008 ++@V@/opcodes/ia64-opc-a.c @V@/opcodes/ia64opca.c ++@V@/opcodes/ia64-opc-b.c @V@/opcodes/ia64opcb.c ++@V@/opcodes/ia64-opc-d.c @V@/opcodes/ia64opcd.c ++@V@/opcodes/ia64-opc-f.c @V@/opcodes/ia64opcf.c ++@V@/opcodes/ia64-opc-i.c @V@/opcodes/ia64opci.c ++@V@/opcodes/ia64-opc-m.c @V@/opcodes/ia64opcm.c ++@V@/opcodes/ia64-opc-x.c @V@/opcodes/ia64opcx.c ++@V@/opcodes/ia64-opc.c @V@/opcodes/ia64-opc.c ++@V@/opcodes/iq2000-desc.c @V@/opcodes/iq2000desc.c ++@V@/opcodes/iq2000-dis.c @V@/opcodes/iq2000dis.c ++@V@/opcodes/microblaze-opc.h @V@/opcodes/mb-opc.h ++@V@/opcodes/microblaze-dis.c @V@/opcodes/mb-dis.c ++@V@/opcodes/microblaze-dis.h @V@/opcodes/mb-dis.h ++@V@/opcodes/microblaze-opcm.h @V@/opcodes/mb-opcm.h ++@V@/opcodes/m68hc11-dis.c @V@/opcodes/m68hc11dis.c ++@V@/opcodes/m68hc11-opc.c @V@/opcodes/m68hc11opc.c ++@V@/opcodes/microblaze-opc.h @V@/opcodes/mbl-opc.h ++@V@/opcodes/microblaze-opcm.h @V@/opcodes/mbl-opcm.h ++@V@/opcodes/openrisc-asm.c @V@/opcodes/orisc-asm.c ++@V@/opcodes/openrisc-desc.c @V@/opcodes/orisc-desc.c ++@V@/opcodes/openrisc-dis.c @V@/opcodes/orisc-dis.c ++@V@/opcodes/openrisc-ibld.c @V@/opcodes/orisc-ibld.c ++@V@/opcodes/openrisc-opc.c @V@/opcodes/orisc-opc.c ++@V@/opcodes/openrisc-opc.h @V@/opcodes/orisc-opc.h ++@V@/opcodes/openrisc-desc.h @V@/opcodes/orisc-desc.h ++@V@/opcodes/xstormy16-asm.c @V@/opcodes/xst16asm.c ++@V@/opcodes/xstormy16-desc.c @V@/opcodes/xst16dsc.c ++@V@/opcodes/xstormy16-desc.h @V@/opcodes/xst16dsc.h ++@V@/opcodes/xstormy16-dis.c @V@/opcodes/xst16dis.c ++@V@/opcodes/xstormy16-ibld.c @V@/opcodes/xst16ibd.c ++@V@/opcodes/xstormy16-opc.c @V@/opcodes/xst16opc.c ++@V@/opcodes/xstormy16-opc.h @V@/opcodes/xst16opc.h ++@V@/readline/config.h.bot @V@/readline/config.h-bot ++@V@/readline/config.h.in @V@/readline/config.h-in ++@V@/readline/examples/rlfe/config.h.in @V@/readline/examples/rlfe/config.h-in ++@V@/sim/frv/profile-fr400.c @V@/sim/frv/fr400-profile.c ++@V@/sim/cris/semcrisv10f-switch.c @V@/sim/cris/scrisv10f.c ++@V@/sim/cris/semcrisv32f-switch.c @V@/sim/cris/scrisv32f.c ++@V@/sim/frv/profile-fr400.h @V@/sim/frv/fr400-profile.h ++@V@/sim/frv/profile-fr500.c @V@/sim/frv/fr500-profile.c ++@V@/sim/frv/profile-fr500.h @V@/sim/frv/fr500-profile.h ++@V@/sim/frv/profile-fr550.c @V@/sim/frv/fr550-profile.c ++@V@/sim/frv/profile-fr550.h @V@/sim/frv/fr550-profile.h ++@V@/sim/microblaze @V@/sim/mb ++@V@/sim/microblaze/microblaze.h @V@/sim/mb/mb.h ++@V@/sim/microblaze/microblaze.isa @V@/sim/mb/mb.isa ++@V@/sim/m68hc11/dv-m68hc11eepr.c @V@/sim/m68hc11/dv-eepr.c ++@V@/sim/m68hc11/dv-m68hc11sio.c @V@/sim/m68hc11/dv-sio.c ++@V@/sim/m68hc11/dv-m68hc11spi.c @V@/sim/m68hc11/dv-spi.c ++@V@/sim/m68hc11/dv-m68hc11tim.c @V@/sim/m68hc11/dv-tim.c ++@V@/sim/mips/dv-tx3904irc.c @V@/sim/mips/dv-tx3irc.c ++@V@/sim/mips/dv-tx3904sio.c @V@/sim/mips/dv-tx3sio.c ++@V@/sim/mips/dv-tx3904tmr.c @V@/sim/mips/dv-tx3tmr.c ++@V@/sim/mn10300/dv-mn103int.c @V@/sim/mn10300/dv-mn1int.c ++@V@/sim/mn10300/dv-mn103iop.c @V@/sim/mn10300/dv-mn1iop.c ++@V@/sim/mn10300/dv-mn103ser.c @V@/sim/mn10300/dv-mn1ser.c ++@V@/sim/mn10300/dv-mn103tim.c @V@/sim/mn10300/dv-mn1tim.c ++@V@/sim/ppc/.gdbinit @V@/sim/ppc/gdb.ini ++@V@/sim/ppc/corefile-n.h @V@/sim/ppc/corefle-n.h ++@V@/sim/ppc/altivec_expression.h @V@/sim/ppc/av_expression.h ++@V@/sim/ppc/altivec_registers.h @V@/sim/ppc/av_registers.h ++@V@/sim/ppc/idecode_branch.h @V@/sim/ppc/idec_branch.h ++@V@/sim/ppc/idecode_expression.h @V@/sim/ppc/idec_expression.h ++@V@/sim/ppc/idecode_fields.h @V@/sim/ppc/idec_fields.h ++@V@/sim/ppc/sim-endian-n.h @V@/sim/ppc/sim-endn.h ++@V@/sim/sh64/sem-compact-switch.c @V@/sim/sh64/sem-cswitch.c ++@V@/sim/sh64/sem-media-switch.c @V@/sim/sh64/sem-mswitch.c ++@V@/sim/testsuite/d10v-elf/t-ae-ld-d.s @V@/sim/testsuite/d10v-elf/t-ld-d.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld-i.s @V@/sim/testsuite/d10v-elf/t-ld-i.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld-id.s @V@/sim/testsuite/d10v-elf/t-ld-id.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld-im.s @V@/sim/testsuite/d10v-elf/t-ld-im.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld-ip.s @V@/sim/testsuite/d10v-elf/t-ld-ip.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld2w-d.s @V@/sim/testsuite/d10v-elf/t-ld2-d.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld2w-i.s @V@/sim/testsuite/d10v-elf/t-ld2-i.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld2w-id.s @V@/sim/testsuite/d10v-elf/t-ld2-id.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld2w-im.s @V@/sim/testsuite/d10v-elf/t-ld2-im.s ++@V@/sim/testsuite/d10v-elf/t-ae-ld2w-ip.s @V@/sim/testsuite/d10v-elf/t-ld2-ip.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-d.s @V@/sim/testsuite/d10v-elf/t-st-d.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-i.s @V@/sim/testsuite/d10v-elf/t-st-i.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-id.s @V@/sim/testsuite/d10v-elf/t-st-id.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-im.s @V@/sim/testsuite/d10v-elf/t-st-im.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-ip.s @V@/sim/testsuite/d10v-elf/t-st-ip.s ++@V@/sim/testsuite/d10v-elf/t-ae-st-is.s @V@/sim/testsuite/d10v-elf/t-st-is.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-d.s @V@/sim/testsuite/d10v-elf/t-st2-d.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-i.s @V@/sim/testsuite/d10v-elf/t-st2-i.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-id.s @V@/sim/testsuite/d10v-elf/t-st2-id.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-im.s @V@/sim/testsuite/d10v-elf/t-st2-im.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-ip.s @V@/sim/testsuite/d10v-elf/t-st2-ip.s ++@V@/sim/testsuite/d10v-elf/t-ae-st2w-is.s @V@/sim/testsuite/d10v-elf/t-st2-is.s ++@V@/sim/testsuite/d30v-elf/ls-ld4bhu.S @V@/sim/testsuite/d30v-elf/ls-ld4bu.S ++@V@/sim/testsuite/sim/arm/misaligned1.ms @V@/sim/testsuite/sim/arm/mis1.ms ++@V@/sim/testsuite/sim/arm/misaligned2.ms @V@/sim/testsuite/sim/arm/mis2.ms ++@V@/sim/testsuite/sim/arm/misaligned3.ms @V@/sim/testsuite/sim/arm/mis3.ms ++@V@/sim/testsuite/sim/cris/asm/tjmpsrv32-2.ms @V@/sim/testsuite/sim/cris/tjmp32-2.ms ++@V@/sim/testsuite/sim/cris/asm/tjmpsrv32.ms @V@/sim/testsuite/sim/cris/tjmp32.ms ++@V@/sim/testsuite/sim/cris/c/ftruncate1.c @V@/sim/testsuite/sim/cris/ftrunc1.c ++@V@/sim/testsuite/sim/cris/c/ftruncate2.c @V@/sim/testsuite/sim/cris/ftrunc2.c ++@V@/sim/testsuite/sim/cris/c/hellodyn2.c @V@/sim/testsuite/sim/cris/c/hello2dyn.c ++@V@/sim/testsuite/sim/cris/c/hellodyn3.c @V@/sim/testsuite/sim/cris/c/hello3dyn.c ++@V@/sim/testsuite/sim/cris/c/mprotect1.c @V@/sim/testsuite/sim/cris/c/mprot1.c ++@V@/sim/testsuite/sim/cris/c/mprotect2.c @V@/sim/testsuite/sim/cris/c/mprot2.c ++@V@/sim/testsuite/sim/cris/c/readlink1.c @V@/sim/testsuite/sim/cris/rdlink1.c ++@V@/sim/testsuite/sim/cris/c/readlink2.c @V@/sim/testsuite/sim/cris/rdlink2.c ++@V@/sim/testsuite/sim/cris/c/readlink3.c @V@/sim/testsuite/sim/cris/rdlink3.c ++@V@/sim/testsuite/sim/cris/c/readlink4.c @V@/sim/testsuite/sim/cris/rdlink4.c ++@V@/sim/testsuite/sim/cris/c/readlink5.c @V@/sim/testsuite/sim/cris/rdlink5.c ++@V@/sim/testsuite/sim/cris/c/readlink6.c @V@/sim/testsuite/sim/cris/rdlink6.c ++@V@/sim/testsuite/sim/cris/c/readlink7.c @V@/sim/testsuite/sim/cris/rdlink7.c ++@V@/sim/testsuite/sim/cris/c/readlink8.c @V@/sim/testsuite/sim/cris/rdlink8.c ++@V@/sim/testsuite/sim/cris/c/readlink9.c @V@/sim/testsuite/sim/cris/rdlink9.c ++@V@/sim/testsuite/sim/cris/c/readlink10.c @V@/sim/testsuite/sim/cris/rdlink10.c ++@V@/sim/testsuite/sim/cris/c/rtsigprocmask1.c @V@/sim/testsuite/sim/cris/c/rtsig1procmask.c ++@V@/sim/testsuite/sim/cris/c/rtsigprocmask2.c @V@/sim/testsuite/sim/cris/c/rtsig2procmask.c ++@V@/sim/testsuite/sim/cris/c/rtsigsuspend1.c @V@/sim/testsuite/sim/cris/c/rtsig1suspend.c ++@V@/sim/testsuite/sim/cris/c/rtsigsuspend2.c @V@/sim/testsuite/sim/cris/c/rtsig2suspend.c ++@V@/sim/testsuite/sim/cris/c/sigreturn1.c @V@/sim/testsuite/sim/cris/sigret1.c ++@V@/sim/testsuite/sim/cris/c/sigreturn2.c @V@/sim/testsuite/sim/cris/sigret2.c ++@V@/sim/testsuite/sim/cris/c/sigreturn3.c @V@/sim/testsuite/sim/cris/sigret3.c ++@V@/sim/testsuite/sim/cris/c/sigreturn4.c @V@/sim/testsuite/sim/cris/sigret4.c ++@V@/sim/testsuite/sim/cris/c/truncate1.c @V@/sim/testsuite/sim/cris/trunc1.c ++@V@/sim/testsuite/sim/cris/c/truncate2.c @V@/sim/testsuite/sim/cris/trunc2.c ++@V@/sim/testsuite/sim/mips/fpu64-ps-sb1.s @V@/sim/testsuite/sim/mips/fpu64ps-sb1.s ++@V@/sim/testsuite/sim/mips/mips32-dsp2.s @V@/sim/testsuite/sim/mips/mips32-2dsp.s ++@V@/sim/testsuite/sim/frv/interrupts/Ipipe-fr400.cgs @V@/sim/testsuite/sim/frv/interrupts/Ip-fr400.cgs ++@V@/sim/testsuite/sim/frv/interrupts/Ipipe-fr500.cgs @V@/sim/testsuite/sim/frv/interrupts/Ip-fr500.cgs ++@V@/sim/testsuite/sim/frv/interrupts/badalign-fr550.cgs @V@/sim/testsuite/sim/frv/interrupts/fr550-badalign.cgs ++@V@/sim/testsuite/sim/frv/interrupts/compound-fr550.cgs @V@/sim/testsuite/sim/frv/interrupts/fr550-compound.cgs ++@V@/sim/testsuite/sim/frv/interrupts/data_store_error-fr550.cgs @V@/sim/testsuite/sim/frv/interrupts/fr550-data_store_error.cgs ++@V@/sim/testsuite/sim/frv/interrupts/fp_exception-fr550.cgs @V@/sim/testsuite/sim/frv/interrupts/fr550-fp_exception.cgs ++@V@/sim/testsuite/sim/frv/interrupts/insn_access_error-fr550.cgs @V@/sim/testsuite/sim/frv/interrupts/fr550-insn_access_error.cgs ++@V@/sim/testsuite/sim/mips/hilo-hazard-1.s @V@/sim/testsuite/sim/mips/hilo-hz1.s ++@V@/sim/testsuite/sim/mips/hilo-hazard-2.s @V@/sim/testsuite/sim/mips/hilo-hz2.s ++@V@/sim/testsuite/sim/mips/hilo-hazard-3.s @V@/sim/testsuite/sim/mips/hilo-hz3.s ++@V@/sim/testsuite/sim/sh64/compact/ldsl-mach.cgs @V@/sim/testsuite/sim/sh64/compact/mach-ldsl.cgs ++@V@/sim/testsuite/sim/sh64/compact/ldsl-macl.cgs @V@/sim/testsuite/sim/sh64/compact/macl-ldsl.cgs ++@V@/sim/testsuite/sim/sh64/compact/stsl-mach.cgs @V@/sim/testsuite/sim/sh64/compact/mach-stsl.cgs ++@V@/sim/testsuite/sim/sh64/compact/stsl-macl.cgs @V@/sim/testsuite/sim/sh64/compact/macl-stsl.cgs ++@V@/tcl/cygwin/tclConfig.sh.in @V@/tcl/cygwin/tclConfig.sh-in ++@V@/tcl/doc/ExprLongObj.3 @V@/tcl/doc/ExprLObj.3 ++@V@/tcl/mac/tclMacBOAAppInit.c @V@/tcl/mac/tclBOAAppInit.c ++@V@/tcl/mac/tclMacBOAMain.c @V@/tcl/mac/tclBOAMain.c ++@V@/tcl/mac/tclMacInit.c @V@/tcl/mac/tclInit.c ++@V@/tcl/mac/tclMacInterupt.c @V@/tcl/mac/tclInterupt.c ++@V@/tcl/mac/tclMacProjects.sea.hqx @V@/tcl/mac/tclMacProjects.shqx ++@V@/tcl/tests/namespace-old.test @V@/tcl/tests/namespace.otest ++@V@/tcl/unix/tclConfig.sh.in @V@/tcl/unix/tclConfig.sh-in ++@V@/tcl/unix/tclLoadAix.c @V@/tcl/unix/tclLdAix.c ++@V@/tcl/unix/tclLoadAout.c @V@/tcl/unix/tclLdAout.c ++@V@/tcl/unix/tclLoadDl.c @V@/tcl/unix/tclLdDl.c ++@V@/tcl/unix/tclLoadDld.c @V@/tcl/unix/tclLdDld.c ++@V@/tcl/unix/tclUnixFCmd.c @V@/tcl/unix/tclFCmd.c ++@V@/tcl/unix/tclUnixFile.c @V@/tcl/unix/tclFile.c ++@V@/tcl/unix/tclUnixTest.c @V@/tcl/unix/tclTest.c ++@V@/tcl/unix/tclUnixTime.c @V@/tcl/unix/tclTime.c ++@V@/tk/doc/ConfigWidg.3 @V@/tk/doc/CfgWidg.3 ++@V@/tk/doc/ConfigWind.3 @V@/tk/doc/CfgWind.3 ++@V@/tk/library/images/pwrdLogo100.gif @V@/tk/library/images/pwLogo100.gif ++@V@/tk/library/images/pwrdLogo150.gif @V@/tk/library/images/pwLogo150.gif ++@V@/tk/library/images/pwrdLogo175.gif @V@/tk/library/images/pwLogo175.gif ++@V@/tk/library/images/pwrdLogo200.gif @V@/tk/library/images/pwLogo200.gif ++@V@/tk/library/images/pwrdLogo75.gif @V@/tk/library/images/pwLogo75.gif ++@V@/tk/mac/tkMacMenu.c @V@/tk/mac/tkMenu.c ++@V@/tk/mac/tkMacMenubutton.c @V@/tk/mac/tkMenubutton.c ++@V@/tk/mac/tkMacMenus.c @V@/tk/mac/tkMenus.c ++@V@/tk/tests/option.file1 @V@/tk/tests/option1.file ++@V@/tk/tests/option.file2 @V@/tk/tests/option2.file ++@V@/tk/unix/tkConfig.sh.in @V@/tk/unix/tkConfig.sh-in ++@V@/tk/unix/tkUnixFocus.c @V@/tk/unix/tkFocus.c ++@V@/tk/unix/tkUnixFont.c @V@/tk/unix/tkFont.c ++@V@/tk/unix/tkUnixMenu.c @V@/tk/unix/tkMenu.c ++@V@/tk/unix/tkUnixMenubu.c @V@/tk/unix/tkMenubu.c ++@V@/tk/unix/tkUnixScale.c @V@/tk/unix/tkScale.c ++@V@/tk/unix/tkUnixScrlbr.c @V@/tk/unix/tkScrlbr.c ++@V@/tk/unix/tkUnixSelect.c @V@/tk/unix/tkSelect.c ++@V@/tk/unix/tkUnixSend.c @V@/tk/unix/tkSend.c +diff -Nuar gdb-10.2/gdb/gdb.info-6 gdb-10.2/gdb/gdb.info-6 +--- gdb-10.2/gdb/gdb.info-6 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/gdb.info-6 2025-04-16 17:06:51.942086800 +0800 +@@ -0,0 +1,7652 @@ ++This is gdb.info, produced by makeinfo version 6.7 from gdb.texinfo. ++ ++Copyright (C) 1988-2020 Free Software Foundation, Inc. ++ ++ Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 or ++any later version published by the Free Software Foundation; with the ++Invariant Sections being "Free Software" and "Free Software Needs Free ++Documentation", with the Front-Cover Texts being "A GNU Manual," and ++with the Back-Cover Texts as in (a) below. ++ ++ (a) The FSF's Back-Cover Text is: "You are free to copy and modify ++this GNU Manual. Buying copies from GNU Press supports the FSF in ++developing GNU and promoting software freedom." ++INFO-DIR-SECTION Software development ++START-INFO-DIR-ENTRY ++* Gdb: (gdb). The GNU debugger. ++* gdbserver: (gdb) Server. The GNU debugging server. ++END-INFO-DIR-ENTRY ++ ++ This file documents the GNU debugger GDB. ++ ++ This is the Tenth Edition, of 'Debugging with GDB: the GNU ++Source-Level Debugger' for GDB (GDB) Version 10.1. ++ ++ Copyright (C) 1988-2020 Free Software Foundation, Inc. ++ ++ Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 or ++any later version published by the Free Software Foundation; with the ++Invariant Sections being "Free Software" and "Free Software Needs Free ++Documentation", with the Front-Cover Texts being "A GNU Manual," and ++with the Back-Cover Texts as in (a) below. ++ ++ (a) The FSF's Back-Cover Text is: "You are free to copy and modify ++this GNU Manual. Buying copies from GNU Press supports the FSF in ++developing GNU and promoting software freedom." ++ ++ ++File: gdb.info, Node: GDB/MI Data Manipulation, Next: GDB/MI Tracepoint Commands, Prev: GDB/MI Variable Objects, Up: GDB/MI ++ ++27.16 GDB/MI Data Manipulation ++============================== ++ ++This section describes the GDB/MI commands that manipulate data: examine ++memory and registers, evaluate expressions, etc. ++ ++ For details about what an addressable memory unit is, *note ++addressable memory unit::. ++ ++The '-data-disassemble' Command ++------------------------------- ++ ++Synopsis ++........ ++ ++ -data-disassemble ++ [ -s START-ADDR -e END-ADDR ] ++ | [ -a ADDR ] ++ | [ -f FILENAME -l LINENUM [ -n LINES ] ] ++ -- MODE ++ ++Where: ++ ++'START-ADDR' ++ is the beginning address (or '$pc') ++'END-ADDR' ++ is the end address ++'ADDR' ++ is an address anywhere within (or the name of) the function to ++ disassemble. If an address is specified, the whole function ++ surrounding that address will be disassembled. If a name is ++ specified, the whole function with that name will be disassembled. ++'FILENAME' ++ is the name of the file to disassemble ++'LINENUM' ++ is the line number to disassemble around ++'LINES' ++ is the number of disassembly lines to be produced. If it is -1, ++ the whole function will be disassembled, in case no END-ADDR is ++ specified. If END-ADDR is specified as a non-zero value, and LINES ++ is lower than the number of disassembly lines between START-ADDR ++ and END-ADDR, only LINES lines are displayed; if LINES is higher ++ than the number of lines between START-ADDR and END-ADDR, only the ++ lines up to END-ADDR are displayed. ++'MODE' ++ is one of: ++ * 0 disassembly only ++ * 1 mixed source and disassembly (deprecated) ++ * 2 disassembly with raw opcodes ++ * 3 mixed source and disassembly with raw opcodes (deprecated) ++ * 4 mixed source and disassembly ++ * 5 mixed source and disassembly with raw opcodes ++ ++ Modes 1 and 3 are deprecated. The output is "source centric" which ++ hasn't proved useful in practice. *Note Machine Code::, for a ++ discussion of the difference between '/m' and '/s' output of the ++ 'disassemble' command. ++ ++Result ++...... ++ ++The result of the '-data-disassemble' command will be a list named ++'asm_insns', the contents of this list depend on the MODE used with the ++'-data-disassemble' command. ++ ++ For modes 0 and 2 the 'asm_insns' list contains tuples with the ++following fields: ++ ++'address' ++ The address at which this instruction was disassembled. ++ ++'func-name' ++ The name of the function this instruction is within. ++ ++'offset' ++ The decimal offset in bytes from the start of 'func-name'. ++ ++'inst' ++ The text disassembly for this 'address'. ++ ++'opcodes' ++ This field is only present for modes 2, 3 and 5. This contains the ++ raw opcode bytes for the 'inst' field. ++ ++ For modes 1, 3, 4 and 5 the 'asm_insns' list contains tuples named ++'src_and_asm_line', each of which has the following fields: ++ ++'line' ++ The line number within 'file'. ++ ++'file' ++ The file name from the compilation unit. This might be an absolute ++ file name or a relative file name depending on the compile command ++ used. ++ ++'fullname' ++ Absolute file name of 'file'. It is converted to a canonical form ++ using the source file search path (*note Specifying Source ++ Directories: Source Path.) and after resolving all the symbolic ++ links. ++ ++ If the source file is not found this field will contain the path as ++ present in the debug information. ++ ++'line_asm_insn' ++ This is a list of tuples containing the disassembly for 'line' in ++ 'file'. The fields of each tuple are the same as for ++ '-data-disassemble' in MODE 0 and 2, so 'address', 'func-name', ++ 'offset', 'inst', and optionally 'opcodes'. ++ ++ Note that whatever included in the 'inst' field, is not manipulated ++directly by GDB/MI, i.e., it is not possible to adjust its format. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'disassemble'. ++ ++Example ++....... ++ ++Disassemble from the current value of '$pc' to '$pc + 20': ++ ++ (gdb) ++ -data-disassemble -s $pc -e "$pc + 20" -- 0 ++ ^done, ++ asm_insns=[ ++ {address="0x000107c0",func-name="main",offset="4", ++ inst="mov 2, %o0"}, ++ {address="0x000107c4",func-name="main",offset="8", ++ inst="sethi %hi(0x11800), %o2"}, ++ {address="0x000107c8",func-name="main",offset="12", ++ inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"}, ++ {address="0x000107cc",func-name="main",offset="16", ++ inst="sethi %hi(0x11800), %o2"}, ++ {address="0x000107d0",func-name="main",offset="20", ++ inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}] ++ (gdb) ++ ++ Disassemble the whole 'main' function. Line 32 is part of 'main'. ++ ++ -data-disassemble -f basics.c -l 32 -- 0 ++ ^done,asm_insns=[ ++ {address="0x000107bc",func-name="main",offset="0", ++ inst="save %sp, -112, %sp"}, ++ {address="0x000107c0",func-name="main",offset="4", ++ inst="mov 2, %o0"}, ++ {address="0x000107c4",func-name="main",offset="8", ++ inst="sethi %hi(0x11800), %o2"}, ++ [...] ++ {address="0x0001081c",func-name="main",offset="96",inst="ret "}, ++ {address="0x00010820",func-name="main",offset="100",inst="restore "}] ++ (gdb) ++ ++ Disassemble 3 instructions from the start of 'main': ++ ++ (gdb) ++ -data-disassemble -f basics.c -l 32 -n 3 -- 0 ++ ^done,asm_insns=[ ++ {address="0x000107bc",func-name="main",offset="0", ++ inst="save %sp, -112, %sp"}, ++ {address="0x000107c0",func-name="main",offset="4", ++ inst="mov 2, %o0"}, ++ {address="0x000107c4",func-name="main",offset="8", ++ inst="sethi %hi(0x11800), %o2"}] ++ (gdb) ++ ++ Disassemble 3 instructions from the start of 'main' in mixed mode: ++ ++ (gdb) ++ -data-disassemble -f basics.c -l 32 -n 3 -- 1 ++ ^done,asm_insns=[ ++ src_and_asm_line={line="31", ++ file="../../../src/gdb/testsuite/gdb.mi/basics.c", ++ fullname="/absolute/path/to/src/gdb/testsuite/gdb.mi/basics.c", ++ line_asm_insn=[{address="0x000107bc", ++ func-name="main",offset="0",inst="save %sp, -112, %sp"}]}, ++ src_and_asm_line={line="32", ++ file="../../../src/gdb/testsuite/gdb.mi/basics.c", ++ fullname="/absolute/path/to/src/gdb/testsuite/gdb.mi/basics.c", ++ line_asm_insn=[{address="0x000107c0", ++ func-name="main",offset="4",inst="mov 2, %o0"}, ++ {address="0x000107c4",func-name="main",offset="8", ++ inst="sethi %hi(0x11800), %o2"}]}] ++ (gdb) ++ ++The '-data-evaluate-expression' Command ++--------------------------------------- ++ ++Synopsis ++........ ++ ++ -data-evaluate-expression EXPR ++ ++ Evaluate EXPR as an expression. The expression could contain an ++inferior function call. The function call will execute synchronously. ++If the expression contains spaces, it must be enclosed in double quotes. ++ ++GDB Command ++........... ++ ++The corresponding GDB commands are 'print', 'output', and 'call'. In ++'gdbtk' only, there's a corresponding 'gdb_eval' command. ++ ++Example ++....... ++ ++In the following example, the numbers that precede the commands are the ++"tokens" described in *note GDB/MI Command Syntax: GDB/MI Command ++Syntax. Notice how GDB/MI returns the same tokens in its output. ++ ++ 211-data-evaluate-expression A ++ 211^done,value="1" ++ (gdb) ++ 311-data-evaluate-expression &A ++ 311^done,value="0xefffeb7c" ++ (gdb) ++ 411-data-evaluate-expression A+3 ++ 411^done,value="4" ++ (gdb) ++ 511-data-evaluate-expression "A + 3" ++ 511^done,value="4" ++ (gdb) ++ ++The '-data-list-changed-registers' Command ++------------------------------------------ ++ ++Synopsis ++........ ++ ++ -data-list-changed-registers ++ ++ Display a list of the registers that have changed. ++ ++GDB Command ++........... ++ ++GDB doesn't have a direct analog for this command; 'gdbtk' has the ++corresponding command 'gdb_changed_register_list'. ++ ++Example ++....... ++ ++On a PPC MBX board: ++ ++ (gdb) ++ -exec-continue ++ ^running ++ ++ (gdb) ++ *stopped,reason="breakpoint-hit",disp="keep",bkptno="1",frame={ ++ func="main",args=[],file="try.c",fullname="/home/foo/bar/try.c", ++ line="5",arch="powerpc"} ++ (gdb) ++ -data-list-changed-registers ++ ^done,changed-registers=["0","1","2","4","5","6","7","8","9", ++ "10","11","13","14","15","16","17","18","19","20","21","22","23", ++ "24","25","26","27","28","30","31","64","65","66","67","69"] ++ (gdb) ++ ++The '-data-list-register-names' Command ++--------------------------------------- ++ ++Synopsis ++........ ++ ++ -data-list-register-names [ ( REGNO )+ ] ++ ++ Show a list of register names for the current target. If no ++arguments are given, it shows a list of the names of all the registers. ++If integer numbers are given as arguments, it will print a list of the ++names of the registers corresponding to the arguments. To ensure ++consistency between a register name and its number, the output list may ++include empty register names. ++ ++GDB Command ++........... ++ ++GDB does not have a command which corresponds to ++'-data-list-register-names'. In 'gdbtk' there is a corresponding ++command 'gdb_regnames'. ++ ++Example ++....... ++ ++For the PPC MBX board: ++ (gdb) ++ -data-list-register-names ++ ^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7", ++ "r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", ++ "r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", ++ "r30","r31","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","f31", ++ "", "pc","ps","cr","lr","ctr","xer"] ++ (gdb) ++ -data-list-register-names 1 2 3 ++ ^done,register-names=["r1","r2","r3"] ++ (gdb) ++ ++The '-data-list-register-values' Command ++---------------------------------------- ++ ++Synopsis ++........ ++ ++ -data-list-register-values ++ [ --skip-unavailable ] FMT [ ( REGNO )*] ++ ++ Display the registers' contents. The format according to which the ++registers' contents are to be returned is given by FMT, followed by an ++optional list of numbers specifying the registers to display. A missing ++list of numbers indicates that the contents of all the registers must be ++returned. The '--skip-unavailable' option indicates that only the ++available registers are to be returned. ++ ++ Allowed formats for FMT are: ++ ++'x' ++ Hexadecimal ++'o' ++ Octal ++'t' ++ Binary ++'d' ++ Decimal ++'r' ++ Raw ++'N' ++ Natural ++ ++GDB Command ++........... ++ ++The corresponding GDB commands are 'info reg', 'info all-reg', and (in ++'gdbtk') 'gdb_fetch_registers'. ++ ++Example ++....... ++ ++For a PPC MBX board (note: line breaks are for readability only, they ++don't appear in the actual output): ++ ++ (gdb) ++ -data-list-register-values r 64 65 ++ ^done,register-values=[{number="64",value="0xfe00a300"}, ++ {number="65",value="0x00029002"}] ++ (gdb) ++ -data-list-register-values x ++ ^done,register-values=[{number="0",value="0xfe0043c8"}, ++ {number="1",value="0x3fff88"},{number="2",value="0xfffffffe"}, ++ {number="3",value="0x0"},{number="4",value="0xa"}, ++ {number="5",value="0x3fff68"},{number="6",value="0x3fff58"}, ++ {number="7",value="0xfe011e98"},{number="8",value="0x2"}, ++ {number="9",value="0xfa202820"},{number="10",value="0xfa202808"}, ++ {number="11",value="0x1"},{number="12",value="0x0"}, ++ {number="13",value="0x4544"},{number="14",value="0xffdfffff"}, ++ {number="15",value="0xffffffff"},{number="16",value="0xfffffeff"}, ++ {number="17",value="0xefffffed"},{number="18",value="0xfffffffe"}, ++ {number="19",value="0xffffffff"},{number="20",value="0xffffffff"}, ++ {number="21",value="0xffffffff"},{number="22",value="0xfffffff7"}, ++ {number="23",value="0xffffffff"},{number="24",value="0xffffffff"}, ++ {number="25",value="0xffffffff"},{number="26",value="0xfffffffb"}, ++ {number="27",value="0xffffffff"},{number="28",value="0xf7bfffff"}, ++ {number="29",value="0x0"},{number="30",value="0xfe010000"}, ++ {number="31",value="0x0"},{number="32",value="0x0"}, ++ {number="33",value="0x0"},{number="34",value="0x0"}, ++ {number="35",value="0x0"},{number="36",value="0x0"}, ++ {number="37",value="0x0"},{number="38",value="0x0"}, ++ {number="39",value="0x0"},{number="40",value="0x0"}, ++ {number="41",value="0x0"},{number="42",value="0x0"}, ++ {number="43",value="0x0"},{number="44",value="0x0"}, ++ {number="45",value="0x0"},{number="46",value="0x0"}, ++ {number="47",value="0x0"},{number="48",value="0x0"}, ++ {number="49",value="0x0"},{number="50",value="0x0"}, ++ {number="51",value="0x0"},{number="52",value="0x0"}, ++ {number="53",value="0x0"},{number="54",value="0x0"}, ++ {number="55",value="0x0"},{number="56",value="0x0"}, ++ {number="57",value="0x0"},{number="58",value="0x0"}, ++ {number="59",value="0x0"},{number="60",value="0x0"}, ++ {number="61",value="0x0"},{number="62",value="0x0"}, ++ {number="63",value="0x0"},{number="64",value="0xfe00a300"}, ++ {number="65",value="0x29002"},{number="66",value="0x202f04b5"}, ++ {number="67",value="0xfe0043b0"},{number="68",value="0xfe00b3e4"}, ++ {number="69",value="0x20002b03"}] ++ (gdb) ++ ++The '-data-read-memory' Command ++------------------------------- ++ ++This command is deprecated, use '-data-read-memory-bytes' instead. ++ ++Synopsis ++........ ++ ++ -data-read-memory [ -o BYTE-OFFSET ] ++ ADDRESS WORD-FORMAT WORD-SIZE ++ NR-ROWS NR-COLS [ ASCHAR ] ++ ++where: ++ ++'ADDRESS' ++ An expression specifying the address of the first memory word to be ++ read. Complex expressions containing embedded white space should ++ be quoted using the C convention. ++ ++'WORD-FORMAT' ++ The format to be used to print the memory words. The notation is ++ the same as for GDB's 'print' command (*note Output Formats: Output ++ Formats.). ++ ++'WORD-SIZE' ++ The size of each memory word in bytes. ++ ++'NR-ROWS' ++ The number of rows in the output table. ++ ++'NR-COLS' ++ The number of columns in the output table. ++ ++'ASCHAR' ++ If present, indicates that each row should include an ASCII dump. ++ The value of ASCHAR is used as a padding character when a byte is ++ not a member of the printable ASCII character set (printable ASCII ++ characters are those whose code is between 32 and 126, ++ inclusively). ++ ++'BYTE-OFFSET' ++ An offset to add to the ADDRESS before fetching memory. ++ ++ This command displays memory contents as a table of NR-ROWS by ++NR-COLS words, each word being WORD-SIZE bytes. In total, 'NR-ROWS * ++NR-COLS * WORD-SIZE' bytes are read (returned as 'total-bytes'). Should ++less than the requested number of bytes be returned by the target, the ++missing words are identified using 'N/A'. The number of bytes read from ++the target is returned in 'nr-bytes' and the starting address used to ++read memory in 'addr'. ++ ++ The address of the next/previous row or page is available in ++'next-row' and 'prev-row', 'next-page' and 'prev-page'. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'x'. 'gdbtk' has 'gdb_get_mem' memory ++read command. ++ ++Example ++....... ++ ++Read six bytes of memory starting at 'bytes+6' but then offset by '-6' ++bytes. Format as three rows of two columns. One byte per word. ++Display each word in hex. ++ ++ (gdb) ++ 9-data-read-memory -o -6 -- bytes+6 x 1 3 2 ++ 9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", ++ next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", ++ prev-page="0x0000138a",memory=[ ++ {addr="0x00001390",data=["0x00","0x01"]}, ++ {addr="0x00001392",data=["0x02","0x03"]}, ++ {addr="0x00001394",data=["0x04","0x05"]}] ++ (gdb) ++ ++ Read two bytes of memory starting at address 'shorts + 64' and ++display as a single word formatted in decimal. ++ ++ (gdb) ++ 5-data-read-memory shorts+64 d 2 1 1 ++ 5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", ++ next-row="0x00001512",prev-row="0x0000150e", ++ next-page="0x00001512",prev-page="0x0000150e",memory=[ ++ {addr="0x00001510",data=["128"]}] ++ (gdb) ++ ++ Read thirty two bytes of memory starting at 'bytes+16' and format as ++eight rows of four columns. Include a string encoding with 'x' used as ++the non-printable character. ++ ++ (gdb) ++ 4-data-read-memory bytes+16 x 1 8 4 x ++ 4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", ++ next-row="0x000013c0",prev-row="0x0000139c", ++ next-page="0x000013c0",prev-page="0x00001380",memory=[ ++ {addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"}, ++ {addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"}, ++ {addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"}, ++ {addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"}, ++ {addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"}, ++ {addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"}, ++ {addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"}, ++ {addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"}] ++ (gdb) ++ ++The '-data-read-memory-bytes' Command ++------------------------------------- ++ ++Synopsis ++........ ++ ++ -data-read-memory-bytes [ -o OFFSET ] ++ ADDRESS COUNT ++ ++where: ++ ++'ADDRESS' ++ An expression specifying the address of the first addressable ++ memory unit to be read. Complex expressions containing embedded ++ white space should be quoted using the C convention. ++ ++'COUNT' ++ The number of addressable memory units to read. This should be an ++ integer literal. ++ ++'OFFSET' ++ The offset relative to ADDRESS at which to start reading. This ++ should be an integer literal. This option is provided so that a ++ frontend is not required to first evaluate address and then perform ++ address arithmetics itself. ++ ++ This command attempts to read all accessible memory regions in the ++specified range. First, all regions marked as unreadable in the memory ++map (if one is defined) will be skipped. *Note Memory Region ++Attributes::. Second, GDB will attempt to read the remaining regions. ++For each one, if reading full region results in an errors, GDB will try ++to read a subset of the region. ++ ++ In general, every single memory unit in the region may be readable or ++not, and the only way to read every readable unit is to try a read at ++every address, which is not practical. Therefore, GDB will attempt to ++read all accessible memory units at either beginning or the end of the ++region, using a binary division scheme. This heuristic works well for ++reading across a memory map boundary. Note that if a region has a ++readable range that is neither at the beginning or the end, GDB will not ++read it. ++ ++ The result record (*note GDB/MI Result Records::) that is output of ++the command includes a field named 'memory' whose content is a list of ++tuples. Each tuple represent a successfully read memory block and has ++the following fields: ++ ++'begin' ++ The start address of the memory block, as hexadecimal literal. ++ ++'end' ++ The end address of the memory block, as hexadecimal literal. ++ ++'offset' ++ The offset of the memory block, as hexadecimal literal, relative to ++ the start address passed to '-data-read-memory-bytes'. ++ ++'contents' ++ The contents of the memory block, in hex. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'x'. ++ ++Example ++....... ++ ++ (gdb) ++ -data-read-memory-bytes &a 10 ++ ^done,memory=[{begin="0xbffff154",offset="0x00000000", ++ end="0xbffff15e", ++ contents="01000000020000000300"}] ++ (gdb) ++ ++The '-data-write-memory-bytes' Command ++-------------------------------------- ++ ++Synopsis ++........ ++ ++ -data-write-memory-bytes ADDRESS CONTENTS ++ -data-write-memory-bytes ADDRESS CONTENTS [COUNT] ++ ++where: ++ ++'ADDRESS' ++ An expression specifying the address of the first addressable ++ memory unit to be written. Complex expressions containing embedded ++ white space should be quoted using the C convention. ++ ++'CONTENTS' ++ The hex-encoded data to write. It is an error if CONTENTS does not ++ represent an integral number of addressable memory units. ++ ++'COUNT' ++ Optional argument indicating the number of addressable memory units ++ to be written. If COUNT is greater than CONTENTS' length, GDB will ++ repeatedly write CONTENTS until it fills COUNT memory units. ++ ++GDB Command ++........... ++ ++There's no corresponding GDB command. ++ ++Example ++....... ++ ++ (gdb) ++ -data-write-memory-bytes &a "aabbccdd" ++ ^done ++ (gdb) ++ ++ (gdb) ++ -data-write-memory-bytes &a "aabbccdd" 16e ++ ^done ++ (gdb) ++ ++ ++File: gdb.info, Node: GDB/MI Tracepoint Commands, Next: GDB/MI Symbol Query, Prev: GDB/MI Data Manipulation, Up: GDB/MI ++ ++27.17 GDB/MI Tracepoint Commands ++================================ ++ ++The commands defined in this section implement MI support for ++tracepoints. For detailed introduction, see *note Tracepoints::. ++ ++The '-trace-find' Command ++------------------------- ++ ++Synopsis ++........ ++ ++ -trace-find MODE [PARAMETERS...] ++ ++ Find a trace frame using criteria defined by MODE and PARAMETERS. ++The following table lists permissible modes and their parameters. For ++details of operation, see *note tfind::. ++ ++'none' ++ No parameters are required. Stops examining trace frames. ++ ++'frame-number' ++ An integer is required as parameter. Selects tracepoint frame with ++ that index. ++ ++'tracepoint-number' ++ An integer is required as parameter. Finds next trace frame that ++ corresponds to tracepoint with the specified number. ++ ++'pc' ++ An address is required as parameter. Finds next trace frame that ++ corresponds to any tracepoint at the specified address. ++ ++'pc-inside-range' ++ Two addresses are required as parameters. Finds next trace frame ++ that corresponds to a tracepoint at an address inside the specified ++ range. Both bounds are considered to be inside the range. ++ ++'pc-outside-range' ++ Two addresses are required as parameters. Finds next trace frame ++ that corresponds to a tracepoint at an address outside the ++ specified range. Both bounds are considered to be inside the ++ range. ++ ++'line' ++ Line specification is required as parameter. *Note Specify ++ Location::. Finds next trace frame that corresponds to a ++ tracepoint at the specified location. ++ ++ If 'none' was passed as MODE, the response does not have fields. ++Otherwise, the response may have the following fields: ++ ++'found' ++ This field has either '0' or '1' as the value, depending on whether ++ a matching tracepoint was found. ++ ++'traceframe' ++ The index of the found traceframe. This field is present iff the ++ 'found' field has value of '1'. ++ ++'tracepoint' ++ The index of the found tracepoint. This field is present iff the ++ 'found' field has value of '1'. ++ ++'frame' ++ The information about the frame corresponding to the found trace ++ frame. This field is present only if a trace frame was found. ++ *Note GDB/MI Frame Information::, for description of this field. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tfind'. ++ ++-trace-define-variable ++---------------------- ++ ++Synopsis ++........ ++ ++ -trace-define-variable NAME [ VALUE ] ++ ++ Create trace variable NAME if it does not exist. If VALUE is ++specified, sets the initial value of the specified trace variable to ++that value. Note that the NAME should start with the '$' character. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tvariable'. ++ ++The '-trace-frame-collected' Command ++------------------------------------ ++ ++Synopsis ++........ ++ ++ -trace-frame-collected ++ [--var-print-values VAR_PVAL] ++ [--comp-print-values COMP_PVAL] ++ [--registers-format REGFORMAT] ++ [--memory-contents] ++ ++ This command returns the set of collected objects, register names, ++trace state variable names, memory ranges and computed expressions that ++have been collected at a particular trace frame. The optional ++parameters to the command affect the output format in different ways. ++See the output description table below for more details. ++ ++ The reported names can be used in the normal manner to create varobjs ++and inspect the objects themselves. The items returned by this command ++are categorized so that it is clear which is a variable, which is a ++register, which is a trace state variable, which is a memory range and ++which is a computed expression. ++ ++ For instance, if the actions were ++ collect myVar, myArray[myIndex], myObj.field, myPtr->field, myCount + 2 ++ collect *(int*)0xaf02bef0@40 ++ ++the object collected in its entirety would be 'myVar'. The object ++'myArray' would be partially collected, because only the element at ++index 'myIndex' would be collected. The remaining objects would be ++computed expressions. ++ ++ An example output would be: ++ ++ (gdb) ++ -trace-frame-collected ++ ^done, ++ explicit-variables=[{name="myVar",value="1"}], ++ computed-expressions=[{name="myArray[myIndex]",value="0"}, ++ {name="myObj.field",value="0"}, ++ {name="myPtr->field",value="1"}, ++ {name="myCount + 2",value="3"}, ++ {name="$tvar1 + 1",value="43970027"}], ++ registers=[{number="0",value="0x7fe2c6e79ec8"}, ++ {number="1",value="0x0"}, ++ {number="2",value="0x4"}, ++ ... ++ {number="125",value="0x0"}], ++ tvars=[{name="$tvar1",current="43970026"}], ++ memory=[{address="0x0000000000602264",length="4"}, ++ {address="0x0000000000615bc0",length="4"}] ++ (gdb) ++ ++ Where: ++ ++'explicit-variables' ++ The set of objects that have been collected in their entirety (as ++ opposed to collecting just a few elements of an array or a few ++ struct members). For each object, its name and value are printed. ++ The '--var-print-values' option affects how or whether the value ++ field is output. If VAR_PVAL is 0, then print only the names; if ++ it is 1, print also their values; and if it is 2, print the name, ++ type and value for simple data types, and the name and type for ++ arrays, structures and unions. ++ ++'computed-expressions' ++ The set of computed expressions that have been collected at the ++ current trace frame. The '--comp-print-values' option affects this ++ set like the '--var-print-values' option affects the ++ 'explicit-variables' set. See above. ++ ++'registers' ++ The registers that have been collected at the current trace frame. ++ For each register collected, the name and current value are ++ returned. The value is formatted according to the ++ '--registers-format' option. See the '-data-list-register-values' ++ command for a list of the allowed formats. The default is 'x'. ++ ++'tvars' ++ The trace state variables that have been collected at the current ++ trace frame. For each trace state variable collected, the name and ++ current value are returned. ++ ++'memory' ++ The set of memory ranges that have been collected at the current ++ trace frame. Its content is a list of tuples. Each tuple ++ represents a collected memory range and has the following fields: ++ ++ 'address' ++ The start address of the memory range, as hexadecimal literal. ++ ++ 'length' ++ The length of the memory range, as decimal literal. ++ ++ 'contents' ++ The contents of the memory block, in hex. This field is only ++ present if the '--memory-contents' option is specified. ++ ++GDB Command ++........... ++ ++There is no corresponding GDB command. ++ ++Example ++....... ++ ++-trace-list-variables ++--------------------- ++ ++Synopsis ++........ ++ ++ -trace-list-variables ++ ++ Return a table of all defined trace variables. Each element of the ++table has the following fields: ++ ++'name' ++ The name of the trace variable. This field is always present. ++ ++'initial' ++ The initial value. This is a 64-bit signed integer. This field is ++ always present. ++ ++'current' ++ The value the trace variable has at the moment. This is a 64-bit ++ signed integer. This field is absent iff current value is not ++ defined, for example if the trace was never run, or is presently ++ running. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tvariables'. ++ ++Example ++....... ++ ++ (gdb) ++ -trace-list-variables ++ ^done,trace-variables={nr_rows="1",nr_cols="3", ++ hdr=[{width="15",alignment="-1",col_name="name",colhdr="Name"}, ++ {width="11",alignment="-1",col_name="initial",colhdr="Initial"}, ++ {width="11",alignment="-1",col_name="current",colhdr="Current"}], ++ body=[variable={name="$trace_timestamp",initial="0"} ++ variable={name="$foo",initial="10",current="15"}]} ++ (gdb) ++ ++-trace-save ++----------- ++ ++Synopsis ++........ ++ ++ -trace-save [ -r ] [ -ctf ] FILENAME ++ ++ Saves the collected trace data to FILENAME. Without the '-r' option, ++the data is downloaded from the target and saved in a local file. With ++the '-r' option the target is asked to perform the save. ++ ++ By default, this command will save the trace in the tfile format. ++You can supply the optional '-ctf' argument to save it the CTF format. ++See *note Trace Files:: for more information about CTF. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tsave'. ++ ++-trace-start ++------------ ++ ++Synopsis ++........ ++ ++ -trace-start ++ ++ Starts a tracing experiment. The result of this command does not ++have any fields. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tstart'. ++ ++-trace-status ++------------- ++ ++Synopsis ++........ ++ ++ -trace-status ++ ++ Obtains the status of a tracing experiment. The result may include ++the following fields: ++ ++'supported' ++ May have a value of either '0', when no tracing operations are ++ supported, '1', when all tracing operations are supported, or ++ 'file' when examining trace file. In the latter case, examining of ++ trace frame is possible but new tracing experiement cannot be ++ started. This field is always present. ++ ++'running' ++ May have a value of either '0' or '1' depending on whether tracing ++ experiement is in progress on target. This field is present if ++ 'supported' field is not '0'. ++ ++'stop-reason' ++ Report the reason why the tracing was stopped last time. This ++ field may be absent iff tracing was never stopped on target yet. ++ The value of 'request' means the tracing was stopped as result of ++ the '-trace-stop' command. The value of 'overflow' means the ++ tracing buffer is full. The value of 'disconnection' means tracing ++ was automatically stopped when GDB has disconnected. The value of ++ 'passcount' means tracing was stopped when a tracepoint was passed ++ a maximal number of times for that tracepoint. This field is ++ present if 'supported' field is not '0'. ++ ++'stopping-tracepoint' ++ The number of tracepoint whose passcount as exceeded. This field ++ is present iff the 'stop-reason' field has the value of ++ 'passcount'. ++ ++'frames' ++'frames-created' ++ The 'frames' field is a count of the total number of trace frames ++ in the trace buffer, while 'frames-created' is the total created ++ during the run, including ones that were discarded, such as when a ++ circular trace buffer filled up. Both fields are optional. ++ ++'buffer-size' ++'buffer-free' ++ These fields tell the current size of the tracing buffer and the ++ remaining space. These fields are optional. ++ ++'circular' ++ The value of the circular trace buffer flag. '1' means that the ++ trace buffer is circular and old trace frames will be discarded if ++ necessary to make room, '0' means that the trace buffer is linear ++ and may fill up. ++ ++'disconnected' ++ The value of the disconnected tracing flag. '1' means that tracing ++ will continue after GDB disconnects, '0' means that the trace run ++ will stop. ++ ++'trace-file' ++ The filename of the trace file being examined. This field is ++ optional, and only present when examining a trace file. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tstatus'. ++ ++-trace-stop ++----------- ++ ++Synopsis ++........ ++ ++ -trace-stop ++ ++ Stops a tracing experiment. The result of this command has the same ++fields as '-trace-status', except that the 'supported' and 'running' ++fields are not output. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'tstop'. ++ ++ ++File: gdb.info, Node: GDB/MI Symbol Query, Next: GDB/MI File Commands, Prev: GDB/MI Tracepoint Commands, Up: GDB/MI ++ ++27.18 GDB/MI Symbol Query Commands ++================================== ++ ++The '-symbol-info-functions' Command ++------------------------------------ ++ ++Synopsis ++........ ++ ++ -symbol-info-functions [--include-nondebug] ++ [--type TYPE_REGEXP] ++ [--name NAME_REGEXP] ++ [--max-results LIMIT] ++ ++Return a list containing the names and types for all global functions ++taken from the debug information. The functions are grouped by source ++file, and shown with the line number on which each function is defined. ++ ++ The '--include-nondebug' option causes the output to include code ++symbols from the symbol table. ++ ++ The options '--type' and '--name' allow the symbols returned to be ++filtered based on either the name of the function, or the type signature ++of the function. ++ ++ The option '--max-results' restricts the command to return no more ++than LIMIT results. If exactly LIMIT results are returned then there ++might be additional results available if a higher limit is used. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info functions'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-functions ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"}, ++ {line="42", name="main", type="int ()", ++ description="int main();"}, ++ {line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="33", name="f2", type="float (another_float_t)", ++ description="float f2(another_float_t);"}, ++ {line="39", name="f3", type="int (another_int_t)", ++ description="int f3(another_int_t);"}, ++ {line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"}]}]} ++ (gdb) ++ -symbol-info-functions --name f1 ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"}]}]} ++ (gdb) ++ -symbol-info-functions --type void ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"}]}]} ++ (gdb) ++ -symbol-info-functions --include-nondebug ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"}, ++ {line="42", name="main", type="int ()", ++ description="int main();"}, ++ {line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="33", name="f2", type="float (another_float_t)", ++ description="float f2(another_float_t);"}, ++ {line="39", name="f3", type="int (another_int_t)", ++ description="int f3(another_int_t);"}, ++ {line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"}]}], ++ nondebug= ++ [{address="0x0000000000400398",name="_init"}, ++ {address="0x00000000004003b0",name="_start"}, ++ ... ++ ]} ++ ++The '-symbol-info-module-functions' Command ++------------------------------------------- ++ ++Synopsis ++........ ++ ++ -symbol-info-module-functions [--module MODULE_REGEXP] ++ [--name NAME_REGEXP] ++ [--type TYPE_REGEXP] ++ ++Return a list containing the names of all known functions within all ++know Fortran modules. The functions are grouped by source file and ++containing module, and shown with the line number on which each function ++is defined. ++ ++ The option '--module' only returns results for modules matching ++MODULE_REGEXP. The option '--name' only returns functions whose name ++matches NAME_REGEXP, and '--type' only returns functions whose type ++matches TYPE_REGEXP. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info module functions'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-module-functions ++ ^done,symbols= ++ [{module="mod1", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="21",name="mod1::check_all",type="void (void)", ++ description="void mod1::check_all(void);"}]}]}, ++ {module="mod2", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="30",name="mod2::check_var_i",type="void (void)", ++ description="void mod2::check_var_i(void);"}]}]}, ++ {module="mod3", ++ files=[{filename="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="21",name="mod3::check_all",type="void (void)", ++ description="void mod3::check_all(void);"}, ++ {line="27",name="mod3::check_mod2",type="void (void)", ++ description="void mod3::check_mod2(void);"}]}]}, ++ {module="modmany", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="35",name="modmany::check_some",type="void (void)", ++ description="void modmany::check_some(void);"}]}]}, ++ {module="moduse", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="44",name="moduse::check_all",type="void (void)", ++ description="void moduse::check_all(void);"}, ++ {line="49",name="moduse::check_var_x",type="void (void)", ++ description="void moduse::check_var_x(void);"}]}]}] ++ ++The '-symbol-info-module-variables' Command ++------------------------------------------- ++ ++Synopsis ++........ ++ ++ -symbol-info-module-variables [--module MODULE_REGEXP] ++ [--name NAME_REGEXP] ++ [--type TYPE_REGEXP] ++ ++Return a list containing the names of all known variables within all ++know Fortran modules. The variables are grouped by source file and ++containing module, and shown with the line number on which each variable ++is defined. ++ ++ The option '--module' only returns results for modules matching ++MODULE_REGEXP. The option '--name' only returns variables whose name ++matches NAME_REGEXP, and '--type' only returns variables whose type ++matches TYPE_REGEXP. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info module variables'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-module-variables ++ ^done,symbols= ++ [{module="mod1", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="18",name="mod1::var_const",type="integer(kind=4)", ++ description="integer(kind=4) mod1::var_const;"}, ++ {line="17",name="mod1::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod1::var_i;"}]}]}, ++ {module="mod2", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="28",name="mod2::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod2::var_i;"}]}]}, ++ {module="mod3", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="18",name="mod3::mod1",type="integer(kind=4)", ++ description="integer(kind=4) mod3::mod1;"}, ++ {line="17",name="mod3::mod2",type="integer(kind=4)", ++ description="integer(kind=4) mod3::mod2;"}, ++ {line="19",name="mod3::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod3::var_i;"}]}]}, ++ {module="modmany", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="33",name="modmany::var_a",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_a;"}, ++ {line="33",name="modmany::var_b",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_b;"}, ++ {line="33",name="modmany::var_c",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_c;"}, ++ {line="33",name="modmany::var_i",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_i;"}]}]}, ++ {module="moduse", ++ files=[{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="42",name="moduse::var_x",type="integer(kind=4)", ++ description="integer(kind=4) moduse::var_x;"}, ++ {line="42",name="moduse::var_y",type="integer(kind=4)", ++ description="integer(kind=4) moduse::var_y;"}]}]}] ++ ++The '-symbol-info-modules' Command ++---------------------------------- ++ ++Synopsis ++........ ++ ++ -symbol-info-modules [--name NAME_REGEXP] ++ [--max-results LIMIT] ++ ++ ++Return a list containing the names of all known Fortran modules. The ++modules are grouped by source file, and shown with the line number on ++which each modules is defined. ++ ++ The option '--name' allows the modules returned to be filtered based ++the name of the module. ++ ++ The option '--max-results' restricts the command to return no more ++than LIMIT results. If exactly LIMIT results are returned then there ++might be additional results available if a higher limit is used. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info modules'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-modules ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="16",name="mod1"}, ++ {line="22",name="mod2"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="16",name="mod3"}, ++ {line="22",name="modmany"}, ++ {line="26",name="moduse"}]}]} ++ (gdb) ++ -symbol-info-modules --name mod[123] ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[{line="16",name="mod1"}, ++ {line="22",name="mod2"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[{line="16",name="mod3"}]}]} ++ ++The '-symbol-info-types' Command ++-------------------------------- ++ ++Synopsis ++........ ++ ++ -symbol-info-types [--name NAME_REGEXP] ++ [--max-results LIMIT] ++ ++ ++Return a list of all defined types. The types are grouped by source ++file, and shown with the line number on which each user defined type is ++defined. Some base types are not defined in the source code but are ++added to the debug information by the compiler, for example 'int', ++'float', etc.; these types do not have an associated line number. ++ ++ The option '--name' allows the list of types returned to be filtered ++by name. ++ ++ The option '--max-results' restricts the command to return no more ++than LIMIT results. If exactly LIMIT results are returned then there ++might be additional results available if a higher limit is used. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info types'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-types ++ ^done,symbols= ++ {debug= ++ [{filename="gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{name="float"}, ++ {name="int"}, ++ {line="27",name="typedef int my_int_t;"}]}, ++ {filename="gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="24",name="typedef float another_float_t;"}, ++ {line="23",name="typedef int another_int_t;"}, ++ {name="float"}, ++ {name="int"}]}]} ++ (gdb) ++ -symbol-info-types --name _int_ ++ ^done,symbols= ++ {debug= ++ [{filename="gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="27",name="typedef int my_int_t;"}]}, ++ {filename="gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="23",name="typedef int another_int_t;"}]}]} ++ ++The '-symbol-info-variables' Command ++------------------------------------ ++ ++Synopsis ++........ ++ ++ -symbol-info-variables [--include-nondebug] ++ [--type TYPE_REGEXP] ++ [--name NAME_REGEXP] ++ [--max-results LIMIT] ++ ++ ++Return a list containing the names and types for all global variables ++taken from the debug information. The variables are grouped by source ++file, and shown with the line number on which each variable is defined. ++ ++ The '--include-nondebug' option causes the output to include data ++symbols from the symbol table. ++ ++ The options '--type' and '--name' allow the symbols returned to be ++filtered based on either the name of the variable, or the type of the ++variable. ++ ++ The option '--max-results' restricts the command to return no more ++than LIMIT results. If exactly LIMIT results are returned then there ++might be additional results available if a higher limit is used. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info variables'. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-info-variables ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="25",name="global_f1",type="float", ++ description="static float global_f1;"}, ++ {line="24",name="global_i1",type="int", ++ description="static int global_i1;"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="21",name="global_f2",type="int", ++ description="int global_f2;"}, ++ {line="20",name="global_i2",type="int", ++ description="int global_i2;"}, ++ {line="19",name="global_f1",type="float", ++ description="static float global_f1;"}, ++ {line="18",name="global_i1",type="int", ++ description="static int global_i1;"}]}]} ++ (gdb) ++ -symbol-info-variables --name f1 ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="25",name="global_f1",type="float", ++ description="static float global_f1;"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="19",name="global_f1",type="float", ++ description="static float global_f1;"}]}]} ++ (gdb) ++ -symbol-info-variables --type float ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="25",name="global_f1",type="float", ++ description="static float global_f1;"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="19",name="global_f1",type="float", ++ description="static float global_f1;"}]}]} ++ (gdb) ++ -symbol-info-variables --include-nondebug ++ ^done,symbols= ++ {debug= ++ [{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[{line="25",name="global_f1",type="float", ++ description="static float global_f1;"}, ++ {line="24",name="global_i1",type="int", ++ description="static int global_i1;"}]}, ++ {filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[{line="21",name="global_f2",type="int", ++ description="int global_f2;"}, ++ {line="20",name="global_i2",type="int", ++ description="int global_i2;"}, ++ {line="19",name="global_f1",type="float", ++ description="static float global_f1;"}, ++ {line="18",name="global_i1",type="int", ++ description="static int global_i1;"}]}], ++ nondebug= ++ [{address="0x00000000004005d0",name="_IO_stdin_used"}, ++ {address="0x00000000004005d8",name="__dso_handle"} ++ ... ++ ]} ++ ++The '-symbol-list-lines' Command ++-------------------------------- ++ ++Synopsis ++........ ++ ++ -symbol-list-lines FILENAME ++ ++ Print the list of lines that contain code and their associated ++program addresses for the given source filename. The entries are sorted ++in ascending PC order. ++ ++GDB Command ++........... ++ ++There is no corresponding GDB command. ++ ++Example ++....... ++ ++ (gdb) ++ -symbol-list-lines basics.c ++ ^done,lines=[{pc="0x08048554",line="7"},{pc="0x0804855a",line="8"}] ++ (gdb) ++ ++ ++File: gdb.info, Node: GDB/MI File Commands, Next: GDB/MI Target Manipulation, Prev: GDB/MI Symbol Query, Up: GDB/MI ++ ++27.19 GDB/MI File Commands ++========================== ++ ++This section describes the GDB/MI commands to specify executable file ++names and to read in and obtain symbol table information. ++ ++The '-file-exec-and-symbols' Command ++------------------------------------ ++ ++Synopsis ++........ ++ ++ -file-exec-and-symbols FILE ++ ++ Specify the executable file to be debugged. This file is the one ++from which the symbol table is also read. If no file is specified, the ++command clears the executable and symbol information. If breakpoints ++are set when using this command with no arguments, GDB will produce ++error messages. Otherwise, no output is produced, except a completion ++notification. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'file'. ++ ++Example ++....... ++ ++ (gdb) ++ -file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++ ^done ++ (gdb) ++ ++The '-file-exec-file' Command ++----------------------------- ++ ++Synopsis ++........ ++ ++ -file-exec-file FILE ++ ++ Specify the executable file to be debugged. Unlike ++'-file-exec-and-symbols', the symbol table is _not_ read from this file. ++If used without argument, GDB clears the information about the ++executable file. No output is produced, except a completion ++notification. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'exec-file'. ++ ++Example ++....... ++ ++ (gdb) ++ -file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++ ^done ++ (gdb) ++ ++The '-file-list-exec-source-file' Command ++----------------------------------------- ++ ++Synopsis ++........ ++ ++ -file-list-exec-source-file ++ ++ List the line number, the current source file, and the absolute path ++to the current source file for the current executable. The macro ++information field has a value of '1' or '0' depending on whether or not ++the file includes preprocessor macro information. ++ ++GDB Command ++........... ++ ++The GDB equivalent is 'info source' ++ ++Example ++....... ++ ++ (gdb) ++ 123-file-list-exec-source-file ++ 123^done,line="1",file="foo.c",fullname="/home/bar/foo.c,macro-info="1" ++ (gdb) ++ ++The '-file-list-exec-source-files' Command ++------------------------------------------ ++ ++Synopsis ++........ ++ ++ -file-list-exec-source-files ++ ++ List the source files for the current executable. ++ ++ It will always output both the filename and fullname (absolute file ++name) of a source file. ++ ++GDB Command ++........... ++ ++The GDB equivalent is 'info sources'. 'gdbtk' has an analogous command ++'gdb_listfiles'. ++ ++Example ++....... ++ ++ (gdb) ++ -file-list-exec-source-files ++ ^done,files=[ ++ {file=foo.c,fullname=/home/foo.c}, ++ {file=/home/bar.c,fullname=/home/bar.c}, ++ {file=gdb_could_not_find_fullpath.c}] ++ (gdb) ++ ++The '-file-list-shared-libraries' Command ++----------------------------------------- ++ ++Synopsis ++........ ++ ++ -file-list-shared-libraries [ REGEXP ] ++ ++ List the shared libraries in the program. With a regular expression ++REGEXP, only those libraries whose names match REGEXP are listed. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info shared'. The fields have a ++similar meaning to the '=library-loaded' notification. The 'ranges' ++field specifies the multiple segments belonging to this library. Each ++range has the following fields: ++ ++'from' ++ The address defining the inclusive lower bound of the segment. ++'to' ++ The address defining the exclusive upper bound of the segment. ++ ++Example ++....... ++ ++ (gdb) ++ -file-list-exec-source-files ++ ^done,shared-libraries=[ ++ {id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[{from="0x72815989",to="0x728162c0"}]}, ++ {id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[{from="0x76ee48c0",to="0x76ee9160"}]}] ++ (gdb) ++ ++The '-file-symbol-file' Command ++------------------------------- ++ ++Synopsis ++........ ++ ++ -file-symbol-file FILE ++ ++ Read symbol table info from the specified FILE argument. When used ++without arguments, clears GDB's symbol table info. No output is ++produced, except for a completion notification. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'symbol-file'. ++ ++Example ++....... ++ ++ (gdb) ++ -file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++ ^done ++ (gdb) ++ ++ ++File: gdb.info, Node: GDB/MI Target Manipulation, Next: GDB/MI File Transfer Commands, Prev: GDB/MI File Commands, Up: GDB/MI ++ ++27.20 GDB/MI Target Manipulation Commands ++========================================= ++ ++The '-target-attach' Command ++---------------------------- ++ ++Synopsis ++........ ++ ++ -target-attach PID | GID | FILE ++ ++ Attach to a process PID or a file FILE outside of GDB, or a thread ++group GID. If attaching to a thread group, the id previously returned ++by '-list-thread-groups --available' must be used. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'attach'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-attach 34 ++ =thread-created,id="1" ++ *stopped,thread-id="1",frame={addr="0xb7f7e410",func="bar",args=[]} ++ ^done ++ (gdb) ++ ++The '-target-detach' Command ++---------------------------- ++ ++Synopsis ++........ ++ ++ -target-detach [ PID | GID ] ++ ++ Detach from the remote target which normally resumes its execution. ++If either PID or GID is specified, detaches from either the specified ++process, or specified thread group. There's no output. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'detach'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-detach ++ ^done ++ (gdb) ++ ++The '-target-disconnect' Command ++-------------------------------- ++ ++Synopsis ++........ ++ ++ -target-disconnect ++ ++ Disconnect from the remote target. There's no output and the target ++is generally not resumed. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'disconnect'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-disconnect ++ ^done ++ (gdb) ++ ++The '-target-download' Command ++------------------------------ ++ ++Synopsis ++........ ++ ++ -target-download ++ ++ Loads the executable onto the remote target. It prints out an update ++message every half second, which includes the fields: ++ ++'section' ++ The name of the section. ++'section-sent' ++ The size of what has been sent so far for that section. ++'section-size' ++ The size of the section. ++'total-sent' ++ The total size of what was sent so far (the current and the ++ previous sections). ++'total-size' ++ The size of the overall executable to download. ++ ++Each message is sent as status record (*note GDB/MI Output Syntax: ++GDB/MI Output Syntax.). ++ ++ In addition, it prints the name and size of the sections, as they are ++downloaded. These messages include the following fields: ++ ++'section' ++ The name of the section. ++'section-size' ++ The size of the section. ++'total-size' ++ The size of the overall executable to download. ++ ++At the end, a summary is printed. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'load'. ++ ++Example ++....... ++ ++Note: each status message appears on a single line. Here the messages ++have been broken down so that they can fit onto a page. ++ ++ (gdb) ++ -target-download ++ +download,{section=".text",section-size="6668",total-size="9880"} ++ +download,{section=".text",section-sent="512",section-size="6668", ++ total-sent="512",total-size="9880"} ++ +download,{section=".text",section-sent="1024",section-size="6668", ++ total-sent="1024",total-size="9880"} ++ +download,{section=".text",section-sent="1536",section-size="6668", ++ total-sent="1536",total-size="9880"} ++ +download,{section=".text",section-sent="2048",section-size="6668", ++ total-sent="2048",total-size="9880"} ++ +download,{section=".text",section-sent="2560",section-size="6668", ++ total-sent="2560",total-size="9880"} ++ +download,{section=".text",section-sent="3072",section-size="6668", ++ total-sent="3072",total-size="9880"} ++ +download,{section=".text",section-sent="3584",section-size="6668", ++ total-sent="3584",total-size="9880"} ++ +download,{section=".text",section-sent="4096",section-size="6668", ++ total-sent="4096",total-size="9880"} ++ +download,{section=".text",section-sent="4608",section-size="6668", ++ total-sent="4608",total-size="9880"} ++ +download,{section=".text",section-sent="5120",section-size="6668", ++ total-sent="5120",total-size="9880"} ++ +download,{section=".text",section-sent="5632",section-size="6668", ++ total-sent="5632",total-size="9880"} ++ +download,{section=".text",section-sent="6144",section-size="6668", ++ total-sent="6144",total-size="9880"} ++ +download,{section=".text",section-sent="6656",section-size="6668", ++ total-sent="6656",total-size="9880"} ++ +download,{section=".init",section-size="28",total-size="9880"} ++ +download,{section=".fini",section-size="28",total-size="9880"} ++ +download,{section=".data",section-size="3156",total-size="9880"} ++ +download,{section=".data",section-sent="512",section-size="3156", ++ total-sent="7236",total-size="9880"} ++ +download,{section=".data",section-sent="1024",section-size="3156", ++ total-sent="7748",total-size="9880"} ++ +download,{section=".data",section-sent="1536",section-size="3156", ++ total-sent="8260",total-size="9880"} ++ +download,{section=".data",section-sent="2048",section-size="3156", ++ total-sent="8772",total-size="9880"} ++ +download,{section=".data",section-sent="2560",section-size="3156", ++ total-sent="9284",total-size="9880"} ++ +download,{section=".data",section-sent="3072",section-size="3156", ++ total-sent="9796",total-size="9880"} ++ ^done,address="0x10004",load-size="9880",transfer-rate="6586", ++ write-rate="429" ++ (gdb) ++ ++GDB Command ++........... ++ ++No equivalent. ++ ++Example ++....... ++ ++N.A. ++ ++The '-target-flash-erase' Command ++--------------------------------- ++ ++Synopsis ++........ ++ ++ -target-flash-erase ++ ++ Erases all known flash memory regions on the target. ++ ++ The corresponding GDB command is 'flash-erase'. ++ ++ The output is a list of flash regions that have been erased, with ++starting addresses and memory region sizes. ++ ++ (gdb) ++ -target-flash-erase ++ ^done,erased-regions={address="0x0",size="0x40000"} ++ (gdb) ++ ++The '-target-select' Command ++---------------------------- ++ ++Synopsis ++........ ++ ++ -target-select TYPE PARAMETERS ... ++ ++ Connect GDB to the remote target. This command takes two args: ++ ++'TYPE' ++ The type of target, for instance 'remote', etc. ++'PARAMETERS' ++ Device names, host names and the like. *Note Commands for Managing ++ Targets: Target Commands, for more details. ++ ++ The output is a connection notification, followed by the address at ++which the target program is, in the following form: ++ ++ ^connected,addr="ADDRESS",func="FUNCTION NAME", ++ args=[ARG LIST] ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'target'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-select remote /dev/ttya ++ ^connected,addr="0xfe00a300",func="??",args=[] ++ (gdb) ++ ++ ++File: gdb.info, Node: GDB/MI File Transfer Commands, Next: GDB/MI Ada Exceptions Commands, Prev: GDB/MI Target Manipulation, Up: GDB/MI ++ ++27.21 GDB/MI File Transfer Commands ++=================================== ++ ++The '-target-file-put' Command ++------------------------------ ++ ++Synopsis ++........ ++ ++ -target-file-put HOSTFILE TARGETFILE ++ ++ Copy file HOSTFILE from the host system (the machine running GDB) to ++TARGETFILE on the target system. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'remote put'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-file-put localfile remotefile ++ ^done ++ (gdb) ++ ++The '-target-file-get' Command ++------------------------------ ++ ++Synopsis ++........ ++ ++ -target-file-get TARGETFILE HOSTFILE ++ ++ Copy file TARGETFILE from the target system to HOSTFILE on the host ++system. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'remote get'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-file-get remotefile localfile ++ ^done ++ (gdb) ++ ++The '-target-file-delete' Command ++--------------------------------- ++ ++Synopsis ++........ ++ ++ -target-file-delete TARGETFILE ++ ++ Delete TARGETFILE from the target system. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'remote delete'. ++ ++Example ++....... ++ ++ (gdb) ++ -target-file-delete remotefile ++ ^done ++ (gdb) ++ ++ ++File: gdb.info, Node: GDB/MI Ada Exceptions Commands, Next: GDB/MI Support Commands, Prev: GDB/MI File Transfer Commands, Up: GDB/MI ++ ++27.22 Ada Exceptions GDB/MI Commands ++==================================== ++ ++The '-info-ada-exceptions' Command ++---------------------------------- ++ ++Synopsis ++........ ++ ++ -info-ada-exceptions [ REGEXP] ++ ++ List all Ada exceptions defined within the program being debugged. ++With a regular expression REGEXP, only those exceptions whose names ++match REGEXP are listed. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info exceptions'. ++ ++Result ++...... ++ ++The result is a table of Ada exceptions. The following columns are ++defined for each exception: ++ ++'name' ++ The name of the exception. ++ ++'address' ++ The address of the exception. ++ ++Example ++....... ++ ++ -info-ada-exceptions aint ++ ^done,ada-exceptions={nr_rows="2",nr_cols="2", ++ hdr=[{width="1",alignment="-1",col_name="name",colhdr="Name"}, ++ {width="1",alignment="-1",col_name="address",colhdr="Address"}], ++ body=[{name="constraint_error",address="0x0000000000613da0"}, ++ {name="const.aint_global_e",address="0x0000000000613b00"}]} ++ ++Catching Ada Exceptions ++----------------------- ++ ++The commands describing how to ask GDB to stop when a program raises an ++exception are described at *note Ada Exception GDB/MI Catchpoint ++Commands::. ++ ++ ++File: gdb.info, Node: GDB/MI Support Commands, Next: GDB/MI Miscellaneous Commands, Prev: GDB/MI Ada Exceptions Commands, Up: GDB/MI ++ ++27.23 GDB/MI Support Commands ++============================= ++ ++Since new commands and features get regularly added to GDB/MI, some ++commands are available to help front-ends query the debugger about ++support for these capabilities. Similarly, it is also possible to query ++GDB about target support of certain features. ++ ++The '-info-gdb-mi-command' Command ++---------------------------------- ++ ++Synopsis ++........ ++ ++ -info-gdb-mi-command CMD_NAME ++ ++ Query support for the GDB/MI command named CMD_NAME. ++ ++ Note that the dash ('-') starting all GDB/MI commands is technically ++not part of the command name (*note GDB/MI Input Syntax::), and thus ++should be omitted in CMD_NAME. However, for ease of use, this command ++also accepts the form with the leading dash. ++ ++GDB Command ++........... ++ ++There is no corresponding GDB command. ++ ++Result ++...... ++ ++The result is a tuple. There is currently only one field: ++ ++'exists' ++ This field is equal to '"true"' if the GDB/MI command exists, ++ '"false"' otherwise. ++ ++Example ++....... ++ ++Here is an example where the GDB/MI command does not exist: ++ ++ -info-gdb-mi-command unsupported-command ++ ^done,command={exists="false"} ++ ++And here is an example where the GDB/MI command is known to the ++debugger: ++ ++ -info-gdb-mi-command symbol-list-lines ++ ^done,command={exists="true"} ++ ++The '-list-features' Command ++---------------------------- ++ ++Returns a list of particular features of the MI protocol that this ++version of gdb implements. A feature can be a command, or a new field ++in an output of some command, or even an important bugfix. While a ++frontend can sometimes detect presence of a feature at runtime, it is ++easier to perform detection at debugger startup. ++ ++ The command returns a list of strings, with each string naming an ++available feature. Each returned string is just a name, it does not ++have any internal structure. The list of possible feature names is ++given below. ++ ++ Example output: ++ ++ (gdb) -list-features ++ ^done,result=["feature1","feature2"] ++ ++ The current list of features is: ++ ++'frozen-varobjs' ++ Indicates support for the '-var-set-frozen' command, as well as ++ possible presence of the 'frozen' field in the output of ++ '-varobj-create'. ++'pending-breakpoints' ++ Indicates support for the '-f' option to the '-break-insert' ++ command. ++'python' ++ Indicates Python scripting support, Python-based pretty-printing ++ commands, and possible presence of the 'display_hint' field in the ++ output of '-var-list-children' ++'thread-info' ++ Indicates support for the '-thread-info' command. ++'data-read-memory-bytes' ++ Indicates support for the '-data-read-memory-bytes' and the ++ '-data-write-memory-bytes' commands. ++'breakpoint-notifications' ++ Indicates that changes to breakpoints and breakpoints created via ++ the CLI will be announced via async records. ++'ada-task-info' ++ Indicates support for the '-ada-task-info' command. ++'language-option' ++ Indicates that all GDB/MI commands accept the '--language' option ++ (*note Context management::). ++'info-gdb-mi-command' ++ Indicates support for the '-info-gdb-mi-command' command. ++'undefined-command-error-code' ++ Indicates support for the "undefined-command" error code in error ++ result records, produced when trying to execute an undefined GDB/MI ++ command (*note GDB/MI Result Records::). ++'exec-run-start-option' ++ Indicates that the '-exec-run' command supports the '--start' ++ option (*note GDB/MI Program Execution::). ++'data-disassemble-a-option' ++ Indicates that the '-data-disassemble' command supports the '-a' ++ option (*note GDB/MI Data Manipulation::). ++ ++The '-list-target-features' Command ++----------------------------------- ++ ++Returns a list of particular features that are supported by the target. ++Those features affect the permitted MI commands, but unlike the features ++reported by the '-list-features' command, the features depend on which ++target GDB is using at the moment. Whenever a target can change, due to ++commands such as '-target-select', '-target-attach' or '-exec-run', the ++list of target features may change, and the frontend should obtain it ++again. Example output: ++ ++ (gdb) -list-target-features ++ ^done,result=["async"] ++ ++ The current list of features is: ++ ++'async' ++ Indicates that the target is capable of asynchronous command ++ execution, which means that GDB will accept further commands while ++ the target is running. ++ ++'reverse' ++ Indicates that the target is capable of reverse execution. *Note ++ Reverse Execution::, for more information. ++ ++ ++File: gdb.info, Node: GDB/MI Miscellaneous Commands, Prev: GDB/MI Support Commands, Up: GDB/MI ++ ++27.24 Miscellaneous GDB/MI Commands ++=================================== ++ ++The '-gdb-exit' Command ++----------------------- ++ ++Synopsis ++........ ++ ++ -gdb-exit ++ ++ Exit GDB immediately. ++ ++GDB Command ++........... ++ ++Approximately corresponds to 'quit'. ++ ++Example ++....... ++ ++ (gdb) ++ -gdb-exit ++ ^exit ++ ++The '-gdb-set' Command ++---------------------- ++ ++Synopsis ++........ ++ ++ -gdb-set ++ ++ Set an internal GDB variable. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'set'. ++ ++Example ++....... ++ ++ (gdb) ++ -gdb-set $foo=3 ++ ^done ++ (gdb) ++ ++The '-gdb-show' Command ++----------------------- ++ ++Synopsis ++........ ++ ++ -gdb-show ++ ++ Show the current value of a GDB variable. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'show'. ++ ++Example ++....... ++ ++ (gdb) ++ -gdb-show annotate ++ ^done,value="0" ++ (gdb) ++ ++The '-gdb-version' Command ++-------------------------- ++ ++Synopsis ++........ ++ ++ -gdb-version ++ ++ Show version information for GDB. Used mostly in testing. ++ ++GDB Command ++........... ++ ++The GDB equivalent is 'show version'. GDB by default shows this ++information when you start an interactive session. ++ ++Example ++....... ++ ++ (gdb) ++ -gdb-version ++ ~GNU gdb 5.2.1 ++ ~Copyright 2000 Free Software Foundation, Inc. ++ ~GDB is free software, covered by the GNU General Public License, and ++ ~you are welcome to change it and/or distribute copies of it under ++ ~ certain conditions. ++ ~Type "show copying" to see the conditions. ++ ~There is absolutely no warranty for GDB. Type "show warranty" for ++ ~ details. ++ ~This GDB was configured as ++ "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". ++ ^done ++ (gdb) ++ ++The '-list-thread-groups' Command ++--------------------------------- ++ ++Synopsis ++-------- ++ ++ -list-thread-groups [ --available ] [ --recurse 1 ] [ GROUP ... ] ++ ++ Lists thread groups (*note Thread groups::). When a single thread ++group is passed as the argument, lists the children of that group. When ++several thread group are passed, lists information about those thread ++groups. Without any parameters, lists information about all top-level ++thread groups. ++ ++ Normally, thread groups that are being debugged are reported. With ++the '--available' option, GDB reports thread groups available on the ++target. ++ ++ The output of this command may have either a 'threads' result or a ++'groups' result. The 'thread' result has a list of tuples as value, ++with each tuple describing a thread (*note GDB/MI Thread Information::). ++The 'groups' result has a list of tuples as value, each tuple describing ++a thread group. If top-level groups are requested (that is, no ++parameter is passed), or when several groups are passed, the output ++always has a 'groups' result. The format of the 'group' result is ++described below. ++ ++ To reduce the number of roundtrips it's possible to list thread ++groups together with their children, by passing the '--recurse' option ++and the recursion depth. Presently, only recursion depth of 1 is ++permitted. If this option is present, then every reported thread group ++will also include its children, either as 'group' or 'threads' field. ++ ++ In general, any combination of option and parameters is permitted, ++with the following caveats: ++ ++ * When a single thread group is passed, the output will typically be ++ the 'threads' result. Because threads may not contain anything, ++ the 'recurse' option will be ignored. ++ ++ * When the '--available' option is passed, limited information may be ++ available. In particular, the list of threads of a process might ++ be inaccessible. Further, specifying specific thread groups might ++ not give any performance advantage over listing all thread groups. ++ The frontend should assume that '-list-thread-groups --available' ++ is always an expensive operation and cache the results. ++ ++ The 'groups' result is a list of tuples, where each tuple may have ++the following fields: ++ ++'id' ++ Identifier of the thread group. This field is always present. The ++ identifier is an opaque string; frontends should not try to convert ++ it to an integer, even though it might look like one. ++ ++'type' ++ The type of the thread group. At present, only 'process' is a ++ valid type. ++ ++'pid' ++ The target-specific process identifier. This field is only present ++ for thread groups of type 'process' and only if the process exists. ++ ++'exit-code' ++ The exit code of this group's last exited thread, formatted in ++ octal. This field is only present for thread groups of type ++ 'process' and only if the process is not running. ++ ++'num_children' ++ The number of children this thread group has. This field may be ++ absent for an available thread group. ++ ++'threads' ++ This field has a list of tuples as value, each tuple describing a ++ thread. It may be present if the '--recurse' option is specified, ++ and it's actually possible to obtain the threads. ++ ++'cores' ++ This field is a list of integers, each identifying a core that one ++ thread of the group is running on. This field may be absent if ++ such information is not available. ++ ++'executable' ++ The name of the executable file that corresponds to this thread ++ group. The field is only present for thread groups of type ++ 'process', and only if there is a corresponding executable file. ++ ++Example ++------- ++ ++ gdb ++ -list-thread-groups ++ ^done,groups=[{id="17",type="process",pid="yyy",num_children="2"}] ++ -list-thread-groups 17 ++ ^done,threads=[{id="2",target-id="Thread 0xb7e14b90 (LWP 21257)", ++ frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]},state="running"}, ++ {id="1",target-id="Thread 0xb7e156b0 (LWP 21254)", ++ frame={level="0",addr="0x0804891f",func="foo",args=[{name="i",value="10"}], ++ file="/tmp/a.c",fullname="/tmp/a.c",line="158",arch="i386:x86_64"},state="running"}]] ++ -list-thread-groups --available ++ ^done,groups=[{id="17",type="process",pid="yyy",num_children="2",cores=[1,2]}] ++ -list-thread-groups --available --recurse 1 ++ ^done,groups=[{id="17", types="process",pid="yyy",num_children="2",cores=[1,2], ++ threads=[{id="1",target-id="Thread 0xb7e14b90",cores=[1]}, ++ {id="2",target-id="Thread 0xb7e14b90",cores=[2]}]},..] ++ -list-thread-groups --available --recurse 1 17 18 ++ ^done,groups=[{id="17", types="process",pid="yyy",num_children="2",cores=[1,2], ++ threads=[{id="1",target-id="Thread 0xb7e14b90",cores=[1]}, ++ {id="2",target-id="Thread 0xb7e14b90",cores=[2]}]},...] ++ ++The '-info-os' Command ++---------------------- ++ ++Synopsis ++........ ++ ++ -info-os [ TYPE ] ++ ++ If no argument is supplied, the command returns a table of available ++operating-system-specific information types. If one of these types is ++supplied as an argument TYPE, then the command returns a table of data ++of that type. ++ ++ The types of information available depend on the target operating ++system. ++ ++GDB Command ++........... ++ ++The corresponding GDB command is 'info os'. ++ ++Example ++....... ++ ++When run on a GNU/Linux system, the output will look something like ++this: ++ ++ gdb ++ -info-os ++ ^done,OSDataTable={nr_rows="10",nr_cols="3", ++ hdr=[{width="10",alignment="-1",col_name="col0",colhdr="Type"}, ++ {width="10",alignment="-1",col_name="col1",colhdr="Description"}, ++ {width="10",alignment="-1",col_name="col2",colhdr="Title"}], ++ body=[item={col0="cpus",col1="Listing of all cpus/cores on the system", ++ col2="CPUs"}, ++ item={col0="files",col1="Listing of all file descriptors", ++ col2="File descriptors"}, ++ item={col0="modules",col1="Listing of all loaded kernel modules", ++ col2="Kernel modules"}, ++ item={col0="msg",col1="Listing of all message queues", ++ col2="Message queues"}, ++ item={col0="processes",col1="Listing of all processes", ++ col2="Processes"}, ++ item={col0="procgroups",col1="Listing of all process groups", ++ col2="Process groups"}, ++ item={col0="semaphores",col1="Listing of all semaphores", ++ col2="Semaphores"}, ++ item={col0="shm",col1="Listing of all shared-memory regions", ++ col2="Shared-memory regions"}, ++ item={col0="sockets",col1="Listing of all internet-domain sockets", ++ col2="Sockets"}, ++ item={col0="threads",col1="Listing of all threads", ++ col2="Threads"}] ++ gdb ++ -info-os processes ++ ^done,OSDataTable={nr_rows="190",nr_cols="4", ++ hdr=[{width="10",alignment="-1",col_name="col0",colhdr="pid"}, ++ {width="10",alignment="-1",col_name="col1",colhdr="user"}, ++ {width="10",alignment="-1",col_name="col2",colhdr="command"}, ++ {width="10",alignment="-1",col_name="col3",colhdr="cores"}], ++ body=[item={col0="1",col1="root",col2="/sbin/init",col3="0"}, ++ item={col0="2",col1="root",col2="[kthreadd]",col3="1"}, ++ item={col0="3",col1="root",col2="[ksoftirqd/0]",col3="0"}, ++ ... ++ item={col0="26446",col1="stan",col2="bash",col3="0"}, ++ item={col0="28152",col1="stan",col2="bash",col3="1"}]} ++ (gdb) ++ ++ (Note that the MI output here includes a '"Title"' column that does ++not appear in command-line 'info os'; this column is useful for MI ++clients that want to enumerate the types of data, such as in a popup ++menu, but is needless clutter on the command line, and 'info os' omits ++it.) ++ ++The '-add-inferior' Command ++--------------------------- ++ ++Synopsis ++-------- ++ ++ -add-inferior ++ ++ Creates a new inferior (*note Inferiors Connections and Programs::). ++The created inferior is not associated with any executable. Such ++association may be established with the '-file-exec-and-symbols' command ++(*note GDB/MI File Commands::). The command response has a single ++field, 'inferior', whose value is the identifier of the thread group ++corresponding to the new inferior. ++ ++Example ++------- ++ ++ gdb ++ -add-inferior ++ ^done,inferior="i3" ++ ++The '-interpreter-exec' Command ++------------------------------- ++ ++Synopsis ++-------- ++ ++ -interpreter-exec INTERPRETER COMMAND ++ ++ Execute the specified COMMAND in the given INTERPRETER. ++ ++GDB Command ++----------- ++ ++The corresponding GDB command is 'interpreter-exec'. ++ ++Example ++------- ++ ++ (gdb) ++ -interpreter-exec console "break main" ++ &"During symbol reading, couldn't parse type; debugger out of date?.\n" ++ &"During symbol reading, bad structure-type format.\n" ++ ~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" ++ ^done ++ (gdb) ++ ++The '-inferior-tty-set' Command ++------------------------------- ++ ++Synopsis ++-------- ++ ++ -inferior-tty-set /dev/pts/1 ++ ++ Set terminal for future runs of the program being debugged. ++ ++GDB Command ++----------- ++ ++The corresponding GDB command is 'set inferior-tty' /dev/pts/1. ++ ++Example ++------- ++ ++ (gdb) ++ -inferior-tty-set /dev/pts/1 ++ ^done ++ (gdb) ++ ++The '-inferior-tty-show' Command ++-------------------------------- ++ ++Synopsis ++-------- ++ ++ -inferior-tty-show ++ ++ Show terminal for future runs of program being debugged. ++ ++GDB Command ++----------- ++ ++The corresponding GDB command is 'show inferior-tty'. ++ ++Example ++------- ++ ++ (gdb) ++ -inferior-tty-set /dev/pts/1 ++ ^done ++ (gdb) ++ -inferior-tty-show ++ ^done,inferior_tty_terminal="/dev/pts/1" ++ (gdb) ++ ++The '-enable-timings' Command ++----------------------------- ++ ++Synopsis ++-------- ++ ++ -enable-timings [yes | no] ++ ++ Toggle the printing of the wallclock, user and system times for an MI ++command as a field in its output. This command is to help frontend ++developers optimize the performance of their code. No argument is ++equivalent to 'yes'. ++ ++GDB Command ++----------- ++ ++No equivalent. ++ ++Example ++------- ++ ++ (gdb) ++ -enable-timings ++ ^done ++ (gdb) ++ -break-insert main ++ ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y", ++ addr="0x080484ed",func="main",file="myprog.c", ++ fullname="/home/nickrob/myprog.c",line="73",thread-groups=["i1"], ++ times="0"}, ++ time={wallclock="0.05185",user="0.00800",system="0.00000"} ++ (gdb) ++ -enable-timings no ++ ^done ++ (gdb) ++ -exec-run ++ ^running ++ (gdb) ++ *stopped,reason="breakpoint-hit",disp="keep",bkptno="1",thread-id="0", ++ frame={addr="0x080484ed",func="main",args=[{name="argc",value="1"}, ++ {name="argv",value="0xbfb60364"}],file="myprog.c", ++ fullname="/home/nickrob/myprog.c",line="73",arch="i386:x86_64"} ++ (gdb) ++ ++The '-complete' Command ++----------------------- ++ ++Synopsis ++-------- ++ ++ -complete COMMAND ++ ++ Show a list of completions for partially typed CLI COMMAND. ++ ++ This command is intended for GDB/MI frontends that cannot use two ++separate CLI and MI channels -- for example: because of lack of PTYs ++like on Windows or because GDB is used remotely via a SSH connection. ++ ++Result ++------ ++ ++The result consists of two or three fields: ++ ++'completion' ++ This field contains the completed COMMAND. If COMMAND has no known ++ completions, this field is omitted. ++ ++'matches' ++ This field contains a (possibly empty) array of matches. It is ++ always present. ++ ++'max_completions_reached' ++ This field contains '1' if number of known completions is above ++ 'max-completions' limit (*note Completion::), otherwise it contains ++ '0'. It is always present. ++ ++GDB Command ++----------- ++ ++The corresponding GDB command is 'complete'. ++ ++Example ++------- ++ ++ (gdb) ++ -complete br ++ ^done,completion="break", ++ matches=["break","break-range"], ++ max_completions_reached="0" ++ (gdb) ++ -complete "b ma" ++ ^done,completion="b ma", ++ matches=["b madvise","b main"],max_completions_reached="0" ++ (gdb) ++ -complete "b push_b" ++ ^done,completion="b push_back(", ++ matches=[ ++ "b A::push_back(void*)", ++ "b std::string::push_back(char)", ++ "b std::vector >::push_back(int&&)"], ++ max_completions_reached="0" ++ (gdb) ++ -complete "nonexist" ++ ^done,matches=[],max_completions_reached="0" ++ (gdb) ++ ++ ++ ++File: gdb.info, Node: Annotations, Next: JIT Interface, Prev: GDB/MI, Up: Top ++ ++28 GDB Annotations ++****************** ++ ++This chapter describes annotations in GDB. Annotations were designed to ++interface GDB to graphical user interfaces or other similar programs ++which want to interact with GDB at a relatively high level. ++ ++ The annotation mechanism has largely been superseded by GDB/MI (*note ++GDB/MI::). ++ ++* Menu: ++ ++* Annotations Overview:: What annotations are; the general syntax. ++* Server Prefix:: Issuing a command without affecting user state. ++* Prompting:: Annotations marking GDB's need for input. ++* Errors:: Annotations for error messages. ++* Invalidation:: Some annotations describe things now invalid. ++* Annotations for Running:: ++ Whether the program is running, how it stopped, etc. ++* Source Annotations:: Annotations describing source code. ++ ++ ++File: gdb.info, Node: Annotations Overview, Next: Server Prefix, Up: Annotations ++ ++28.1 What is an Annotation? ++=========================== ++ ++Annotations start with a newline character, two 'control-z' characters, ++and the name of the annotation. If there is no additional information ++associated with this annotation, the name of the annotation is followed ++immediately by a newline. If there is additional information, the name ++of the annotation is followed by a space, the additional information, ++and a newline. The additional information cannot contain newline ++characters. ++ ++ Any output not beginning with a newline and two 'control-z' ++characters denotes literal output from GDB. Currently there is no need ++for GDB to output a newline followed by two 'control-z' characters, but ++if there was such a need, the annotations could be extended with an ++'escape' annotation which means those three characters as output. ++ ++ The annotation LEVEL, which is specified using the '--annotate' ++command line option (*note Mode Options::), controls how much ++information GDB prints together with its prompt, values of expressions, ++source lines, and other types of output. Level 0 is for no annotations, ++level 1 is for use when GDB is run as a subprocess of GNU Emacs, level 3 ++is the maximum annotation suitable for programs that control GDB, and ++level 2 annotations have been made obsolete (*note Limitations of the ++Annotation Interface: (annotate)Limitations.). ++ ++'set annotate LEVEL' ++ The GDB command 'set annotate' sets the level of annotations to the ++ specified LEVEL. ++ ++'show annotate' ++ Show the current annotation level. ++ ++ This chapter describes level 3 annotations. ++ ++ A simple example of starting up GDB with annotations is: ++ ++ $ gdb --annotate=3 ++ GNU gdb 6.0 ++ Copyright 2003 Free Software Foundation, Inc. ++ GDB is free software, covered by the GNU General Public License, ++ and you are welcome to change it and/or distribute copies of it ++ under certain conditions. ++ Type "show copying" to see the conditions. ++ There is absolutely no warranty for GDB. Type "show warranty" ++ for details. ++ This GDB was configured as "i386-pc-linux-gnu" ++ ++ ^Z^Zpre-prompt ++ (gdb) ++ ^Z^Zprompt ++ quit ++ ++ ^Z^Zpost-prompt ++ $ ++ ++ Here 'quit' is input to GDB; the rest is output from GDB. The three ++lines beginning '^Z^Z' (where '^Z' denotes a 'control-z' character) are ++annotations; the rest is output from GDB. ++ ++ ++File: gdb.info, Node: Server Prefix, Next: Prompting, Prev: Annotations Overview, Up: Annotations ++ ++28.2 The Server Prefix ++====================== ++ ++If you prefix a command with 'server ' then it will not affect the ++command history, nor will it affect GDB's notion of which command to ++repeat if is pressed on a line by itself. This means that ++commands can be run behind a user's back by a front-end in a transparent ++manner. ++ ++ The 'server ' prefix does not affect the recording of values into the ++value history; to print a value without recording it into the value ++history, use the 'output' command instead of the 'print' command. ++ ++ Using this prefix also disables confirmation requests (*note ++confirmation requests::). ++ ++ ++File: gdb.info, Node: Prompting, Next: Errors, Prev: Server Prefix, Up: Annotations ++ ++28.3 Annotation for GDB Input ++============================= ++ ++When GDB prompts for input, it annotates this fact so it is possible to ++know when to send output, when the output from a given command is over, ++etc. ++ ++ Different kinds of input each have a different "input type". Each ++input type has three annotations: a 'pre-' annotation, which denotes the ++beginning of any prompt which is being output, a plain annotation, which ++denotes the end of the prompt, and then a 'post-' annotation which ++denotes the end of any echo which may (or may not) be associated with ++the input. For example, the 'prompt' input type features the following ++annotations: ++ ++ ^Z^Zpre-prompt ++ ^Z^Zprompt ++ ^Z^Zpost-prompt ++ ++ The input types are ++ ++'prompt' ++ When GDB is prompting for a command (the main GDB prompt). ++ ++'commands' ++ When GDB prompts for a set of commands, like in the 'commands' ++ command. The annotations are repeated for each command which is ++ input. ++ ++'overload-choice' ++ When GDB wants the user to select between various overloaded ++ functions. ++ ++'query' ++ When GDB wants the user to confirm a potentially dangerous ++ operation. ++ ++'prompt-for-continue' ++ When GDB is asking the user to press return to continue. Note: ++ Don't expect this to work well; instead use 'set height 0' to ++ disable prompting. This is because the counting of lines is buggy ++ in the presence of annotations. ++ ++ ++File: gdb.info, Node: Errors, Next: Invalidation, Prev: Prompting, Up: Annotations ++ ++28.4 Errors ++=========== ++ ++ ^Z^Zquit ++ ++ This annotation occurs right before GDB responds to an interrupt. ++ ++ ^Z^Zerror ++ ++ This annotation occurs right before GDB responds to an error. ++ ++ Quit and error annotations indicate that any annotations which GDB ++was in the middle of may end abruptly. For example, if a ++'value-history-begin' annotation is followed by a 'error', one cannot ++expect to receive the matching 'value-history-end'. One cannot expect ++not to receive it either, however; an error annotation does not ++necessarily mean that GDB is immediately returning all the way to the ++top level. ++ ++ A quit or error annotation may be preceded by ++ ++ ^Z^Zerror-begin ++ ++ Any output between that and the quit or error annotation is the error ++message. ++ ++ Warning messages are not yet annotated. ++ ++ ++File: gdb.info, Node: Invalidation, Next: Annotations for Running, Prev: Errors, Up: Annotations ++ ++28.5 Invalidation Notices ++========================= ++ ++The following annotations say that certain pieces of state may have ++changed. ++ ++'^Z^Zframes-invalid' ++ ++ The frames (for example, output from the 'backtrace' command) may ++ have changed. ++ ++'^Z^Zbreakpoints-invalid' ++ ++ The breakpoints may have changed. For example, the user just added ++ or deleted a breakpoint. ++ ++ ++File: gdb.info, Node: Annotations for Running, Next: Source Annotations, Prev: Invalidation, Up: Annotations ++ ++28.6 Running the Program ++======================== ++ ++When the program starts executing due to a GDB command such as 'step' or ++'continue', ++ ++ ^Z^Zstarting ++ ++ is output. When the program stops, ++ ++ ^Z^Zstopped ++ ++ is output. Before the 'stopped' annotation, a variety of annotations ++describe how the program stopped. ++ ++'^Z^Zexited EXIT-STATUS' ++ The program exited, and EXIT-STATUS is the exit status (zero for ++ successful exit, otherwise nonzero). ++ ++'^Z^Zsignalled' ++ The program exited with a signal. After the '^Z^Zsignalled', the ++ annotation continues: ++ ++ INTRO-TEXT ++ ^Z^Zsignal-name ++ NAME ++ ^Z^Zsignal-name-end ++ MIDDLE-TEXT ++ ^Z^Zsignal-string ++ STRING ++ ^Z^Zsignal-string-end ++ END-TEXT ++ ++ where NAME is the name of the signal, such as 'SIGILL' or ++ 'SIGSEGV', and STRING is the explanation of the signal, such as ++ 'Illegal Instruction' or 'Segmentation fault'. The arguments ++ INTRO-TEXT, MIDDLE-TEXT, and END-TEXT are for the user's benefit ++ and have no particular format. ++ ++'^Z^Zsignal' ++ The syntax of this annotation is just like 'signalled', but GDB is ++ just saying that the program received the signal, not that it was ++ terminated with it. ++ ++'^Z^Zbreakpoint NUMBER' ++ The program hit breakpoint number NUMBER. ++ ++'^Z^Zwatchpoint NUMBER' ++ The program hit watchpoint number NUMBER. ++ ++ ++File: gdb.info, Node: Source Annotations, Prev: Annotations for Running, Up: Annotations ++ ++28.7 Displaying Source ++====================== ++ ++The following annotation is used instead of displaying source code: ++ ++ ^Z^Zsource FILENAME:LINE:CHARACTER:MIDDLE:ADDR ++ ++ where FILENAME is an absolute file name indicating which source file, ++LINE is the line number within that file (where 1 is the first line in ++the file), CHARACTER is the character position within the file (where 0 ++is the first character in the file) (for most debug formats this will ++necessarily point to the beginning of a line), MIDDLE is 'middle' if ++ADDR is in the middle of the line, or 'beg' if ADDR is at the beginning ++of the line, and ADDR is the address in the target program associated ++with the source which is being displayed. The ADDR is in the form '0x' ++followed by one or more lowercase hex digits (note that this does not ++depend on the language). ++ ++ ++File: gdb.info, Node: JIT Interface, Next: In-Process Agent, Prev: Annotations, Up: Top ++ ++29 JIT Compilation Interface ++**************************** ++ ++This chapter documents GDB's "just-in-time" (JIT) compilation interface. ++A JIT compiler is a program or library that generates native executable ++code at runtime and executes it, usually in order to achieve good ++performance while maintaining platform independence. ++ ++ Programs that use JIT compilation are normally difficult to debug ++because portions of their code are generated at runtime, instead of ++being loaded from object files, which is where GDB normally finds the ++program's symbols and debug information. In order to debug programs ++that use JIT compilation, GDB has an interface that allows the program ++to register in-memory symbol files with GDB at runtime. ++ ++ If you are using GDB to debug a program that uses this interface, ++then it should work transparently so long as you have not stripped the ++binary. If you are developing a JIT compiler, then the interface is ++documented in the rest of this chapter. At this time, the only known ++client of this interface is the LLVM JIT. ++ ++ Broadly speaking, the JIT interface mirrors the dynamic loader ++interface. The JIT compiler communicates with GDB by writing data into ++a global variable and calling a function at a well-known symbol. When ++GDB attaches, it reads a linked list of symbol files from the global ++variable to find existing code, and puts a breakpoint in the function so ++that it can find out about additional code. ++ ++* Menu: ++ ++* Declarations:: Relevant C struct declarations ++* Registering Code:: Steps to register code ++* Unregistering Code:: Steps to unregister code ++* Custom Debug Info:: Emit debug information in a custom format ++ ++ ++File: gdb.info, Node: Declarations, Next: Registering Code, Up: JIT Interface ++ ++29.1 JIT Declarations ++===================== ++ ++These are the relevant struct declarations that a C program should ++include to implement the interface: ++ ++ typedef enum ++ { ++ JIT_NOACTION = 0, ++ JIT_REGISTER_FN, ++ JIT_UNREGISTER_FN ++ } jit_actions_t; ++ ++ struct jit_code_entry ++ { ++ struct jit_code_entry *next_entry; ++ struct jit_code_entry *prev_entry; ++ const char *symfile_addr; ++ uint64_t symfile_size; ++ }; ++ ++ struct jit_descriptor ++ { ++ uint32_t version; ++ /* This type should be jit_actions_t, but we use uint32_t ++ to be explicit about the bitwidth. */ ++ uint32_t action_flag; ++ struct jit_code_entry *relevant_entry; ++ struct jit_code_entry *first_entry; ++ }; ++ ++ /* GDB puts a breakpoint in this function. */ ++ void __attribute__((noinline)) __jit_debug_register_code() { }; ++ ++ /* Make sure to specify the version statically, because the ++ debugger may check the version before we can set it. */ ++ struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; ++ ++ If the JIT is multi-threaded, then it is important that the JIT ++synchronize any modifications to this global data properly, which can ++easily be done by putting a global mutex around modifications to these ++structures. ++ ++ ++File: gdb.info, Node: Registering Code, Next: Unregistering Code, Prev: Declarations, Up: JIT Interface ++ ++29.2 Registering Code ++===================== ++ ++To register code with GDB, the JIT should follow this protocol: ++ ++ * Generate an object file in memory with symbols and other desired ++ debug information. The file must include the virtual addresses of ++ the sections. ++ ++ * Create a code entry for the file, which gives the start and size of ++ the symbol file. ++ ++ * Add it to the linked list in the JIT descriptor. ++ ++ * Point the relevant_entry field of the descriptor at the entry. ++ ++ * Set 'action_flag' to 'JIT_REGISTER' and call ++ '__jit_debug_register_code'. ++ ++ When GDB is attached and the breakpoint fires, GDB uses the ++'relevant_entry' pointer so it doesn't have to walk the list looking for ++new code. However, the linked list must still be maintained in order to ++allow GDB to attach to a running process and still find the symbol ++files. ++ ++ ++File: gdb.info, Node: Unregistering Code, Next: Custom Debug Info, Prev: Registering Code, Up: JIT Interface ++ ++29.3 Unregistering Code ++======================= ++ ++If code is freed, then the JIT should use the following protocol: ++ ++ * Remove the code entry corresponding to the code from the linked ++ list. ++ ++ * Point the 'relevant_entry' field of the descriptor at the code ++ entry. ++ ++ * Set 'action_flag' to 'JIT_UNREGISTER' and call ++ '__jit_debug_register_code'. ++ ++ If the JIT frees or recompiles code without unregistering it, then ++GDB and the JIT will leak the memory used for the associated symbol ++files. ++ ++ ++File: gdb.info, Node: Custom Debug Info, Prev: Unregistering Code, Up: JIT Interface ++ ++29.4 Custom Debug Info ++====================== ++ ++Generating debug information in platform-native file formats (like ELF ++or COFF) may be an overkill for JIT compilers; especially if all the ++debug info is used for is displaying a meaningful backtrace. The issue ++can be resolved by having the JIT writers decide on a debug info format ++and also provide a reader that parses the debug info generated by the ++JIT compiler. This section gives a brief overview on writing such a ++parser. More specific details can be found in the source file ++'gdb/jit-reader.in', which is also installed as a header at ++'INCLUDEDIR/gdb/jit-reader.h' for easy inclusion. ++ ++ The reader is implemented as a shared object (so this functionality ++is not available on platforms which don't allow loading shared objects ++at runtime). Two GDB commands, 'jit-reader-load' and ++'jit-reader-unload' are provided, to be used to load and unload the ++readers from a preconfigured directory. Once loaded, the shared object ++is used the parse the debug information emitted by the JIT compiler. ++ ++* Menu: ++ ++* Using JIT Debug Info Readers:: How to use supplied readers correctly ++* Writing JIT Debug Info Readers:: Creating a debug-info reader ++ ++ ++File: gdb.info, Node: Using JIT Debug Info Readers, Next: Writing JIT Debug Info Readers, Up: Custom Debug Info ++ ++29.4.1 Using JIT Debug Info Readers ++----------------------------------- ++ ++Readers can be loaded and unloaded using the 'jit-reader-load' and ++'jit-reader-unload' commands. ++ ++'jit-reader-load READER' ++ Load the JIT reader named READER, which is a shared object ++ specified as either an absolute or a relative file name. In the ++ latter case, GDB will try to load the reader from a pre-configured ++ directory, usually 'LIBDIR/gdb/' on a UNIX system (here LIBDIR is ++ the system library directory, often '/usr/local/lib'). ++ ++ Only one reader can be active at a time; trying to load a second ++ reader when one is already loaded will result in GDB reporting an ++ error. A new JIT reader can be loaded by first unloading the ++ current one using 'jit-reader-unload' and then invoking ++ 'jit-reader-load'. ++ ++'jit-reader-unload' ++ Unload the currently loaded JIT reader. ++ ++ ++File: gdb.info, Node: Writing JIT Debug Info Readers, Prev: Using JIT Debug Info Readers, Up: Custom Debug Info ++ ++29.4.2 Writing JIT Debug Info Readers ++------------------------------------- ++ ++As mentioned, a reader is essentially a shared object conforming to a ++certain ABI. This ABI is described in 'jit-reader.h'. ++ ++ 'jit-reader.h' defines the structures, macros and functions required ++to write a reader. It is installed (along with GDB), in ++'INCLUDEDIR/gdb' where INCLUDEDIR is the system include directory. ++ ++ Readers need to be released under a GPL compatible license. A reader ++can be declared as released under such a license by placing the macro ++'GDB_DECLARE_GPL_COMPATIBLE_READER' in a source file. ++ ++ The entry point for readers is the symbol 'gdb_init_reader', which is ++expected to be a function with the prototype ++ ++ extern struct gdb_reader_funcs *gdb_init_reader (void); ++ ++ 'struct gdb_reader_funcs' contains a set of pointers to callback ++functions. These functions are executed to read the debug info ++generated by the JIT compiler ('read'), to unwind stack frames ++('unwind') and to create canonical frame IDs ('get_frame_id'). It also ++has a callback that is called when the reader is being unloaded ++('destroy'). The struct looks like this ++ ++ struct gdb_reader_funcs ++ { ++ /* Must be set to GDB_READER_INTERFACE_VERSION. */ ++ int reader_version; ++ ++ /* For use by the reader. */ ++ void *priv_data; ++ ++ gdb_read_debug_info *read; ++ gdb_unwind_frame *unwind; ++ gdb_get_frame_id *get_frame_id; ++ gdb_destroy_reader *destroy; ++ }; ++ ++ The callbacks are provided with another set of callbacks by GDB to do ++their job. For 'read', these callbacks are passed in a 'struct ++gdb_symbol_callbacks' and for 'unwind' and 'get_frame_id', in a 'struct ++gdb_unwind_callbacks'. 'struct gdb_symbol_callbacks' has callbacks to ++create new object files and new symbol tables inside those object files. ++'struct gdb_unwind_callbacks' has callbacks to read registers off the ++current frame and to write out the values of the registers in the ++previous frame. Both have a callback ('target_read') to read bytes off ++the target's address space. ++ ++ ++File: gdb.info, Node: In-Process Agent, Next: GDB Bugs, Prev: JIT Interface, Up: Top ++ ++30 In-Process Agent ++******************* ++ ++The traditional debugging model is conceptually low-speed, but works ++fine, because most bugs can be reproduced in debugging-mode execution. ++However, as multi-core or many-core processors are becoming mainstream, ++and multi-threaded programs become more and more popular, there should ++be more and more bugs that only manifest themselves at normal-mode ++execution, for example, thread races, because debugger's interference ++with the program's timing may conceal the bugs. On the other hand, in ++some applications, it is not feasible for the debugger to interrupt the ++program's execution long enough for the developer to learn anything ++helpful about its behavior. If the program's correctness depends on its ++real-time behavior, delays introduced by a debugger might cause the ++program to fail, even when the code itself is correct. It is useful to ++be able to observe the program's behavior without interrupting it. ++ ++ Therefore, traditional debugging model is too intrusive to reproduce ++some bugs. In order to reduce the interference with the program, we can ++reduce the number of operations performed by debugger. The "In-Process ++Agent", a shared library, is running within the same process with ++inferior, and is able to perform some debugging operations itself. As a ++result, debugger is only involved when necessary, and performance of ++debugging can be improved accordingly. Note that interference with ++program can be reduced but can't be removed completely, because the ++in-process agent will still stop or slow down the program. ++ ++ The in-process agent can interpret and execute Agent Expressions ++(*note Agent Expressions::) during performing debugging operations. The ++agent expressions can be used for different purposes, such as collecting ++data in tracepoints, and condition evaluation in breakpoints. ++ ++ You can control whether the in-process agent is used as an aid for ++debugging with the following commands: ++ ++'set agent on' ++ Causes the in-process agent to perform some operations on behalf of ++ the debugger. Just which operations requested by the user will be ++ done by the in-process agent depends on the its capabilities. For ++ example, if you request to evaluate breakpoint conditions in the ++ in-process agent, and the in-process agent has such capability as ++ well, then breakpoint conditions will be evaluated in the ++ in-process agent. ++ ++'set agent off' ++ Disables execution of debugging operations by the in-process agent. ++ All of the operations will be performed by GDB. ++ ++'show agent' ++ Display the current setting of execution of debugging operations by ++ the in-process agent. ++ ++* Menu: ++ ++* In-Process Agent Protocol:: ++ ++ ++File: gdb.info, Node: In-Process Agent Protocol, Up: In-Process Agent ++ ++30.1 In-Process Agent Protocol ++============================== ++ ++The in-process agent is able to communicate with both GDB and GDBserver ++(*note In-Process Agent::). This section documents the protocol used ++for communications between GDB or GDBserver and the IPA. In general, GDB ++or GDBserver sends commands (*note IPA Protocol Commands::) and data to ++in-process agent, and then in-process agent replies back with the return ++result of the command, or some other information. The data sent to ++in-process agent is composed of primitive data types, such as 4-byte or ++8-byte type, and composite types, which are called objects (*note IPA ++Protocol Objects::). ++ ++* Menu: ++ ++* IPA Protocol Objects:: ++* IPA Protocol Commands:: ++ ++ ++File: gdb.info, Node: IPA Protocol Objects, Next: IPA Protocol Commands, Up: In-Process Agent Protocol ++ ++30.1.1 IPA Protocol Objects ++--------------------------- ++ ++The commands sent to and results received from agent may contain some ++complex data types called "objects". ++ ++ The in-process agent is running on the same machine with GDB or ++GDBserver, so it doesn't have to handle as much differences between two ++ends as remote protocol (*note Remote Protocol::) tries to handle. ++However, there are still some differences of two ends in two processes: ++ ++ 1. word size. On some 64-bit machines, GDB or GDBserver can be ++ compiled as a 64-bit executable, while in-process agent is a 32-bit ++ one. ++ 2. ABI. Some machines may have multiple types of ABI, GDB or GDBserver ++ is compiled with one, and in-process agent is compiled with the ++ other one. ++ ++ Here are the IPA Protocol Objects: ++ ++ 1. agent expression object. It represents an agent expression (*note ++ Agent Expressions::). ++ 2. tracepoint action object. It represents a tracepoint action (*note ++ Tracepoint Action Lists: Tracepoint Actions.) to collect registers, ++ memory, static trace data and to evaluate expression. ++ 3. tracepoint object. It represents a tracepoint (*note ++ Tracepoints::). ++ ++ The following table describes important attributes of each IPA ++protocol object: ++ ++Name Size Description ++--------------------------------------------------------------------------- ++_agent expression ++object_ ++length 4 length of bytes code ++byte code LENGTH contents of byte code ++_tracepoint action ++for collecting ++memory_ ++'M' 1 type of tracepoint action ++addr 8 if BASEREG is '-1', ADDR is the ++ address of the lowest byte to ++ collect, otherwise ADDR is the ++ offset of BASEREG for memory ++ collecting. ++len 8 length of memory for collecting ++basereg 4 the register number containing the ++ starting memory address for ++ collecting. ++_tracepoint action ++for collecting ++registers_ ++'R' 1 type of tracepoint action ++_tracepoint action ++for collecting ++static trace data_ ++'L' 1 type of tracepoint action ++_tracepoint action ++for expression ++evaluation_ ++'X' 1 type of tracepoint action ++agent expression length of *note agent expression object:: ++_tracepoint object_ ++number 4 number of tracepoint ++address 8 address of tracepoint inserted on ++type 4 type of tracepoint ++enabled 1 enable or disable of tracepoint ++step_count 8 step ++pass_count 8 pass ++numactions 4 number of tracepoint actions ++hit count 8 hit count ++trace frame usage 8 trace frame usage ++compiled_cond 8 compiled condition ++orig_size 8 orig size ++condition 4 if zero if condition is NULL, ++ condition is otherwise is ++ NULL *note agent expression object:: ++ otherwise ++ length of ++ *note agent expression object:: ++actions variable numactions number of ++ *note tracepoint action object:: ++ ++ ++File: gdb.info, Node: IPA Protocol Commands, Prev: IPA Protocol Objects, Up: In-Process Agent Protocol ++ ++30.1.2 IPA Protocol Commands ++---------------------------- ++ ++The spaces in each command are delimiters to ease reading this commands ++specification. They don't exist in real commands. ++ ++'FastTrace:TRACEPOINT_OBJECT GDB_JUMP_PAD_HEAD' ++ Installs a new fast tracepoint described by TRACEPOINT_OBJECT ++ (*note tracepoint object::). The GDB_JUMP_PAD_HEAD, 8-byte long, ++ is the head of "jumppad", which is used to jump to data collection ++ routine in IPA finally. ++ ++ Replies: ++ 'OK TARGET_ADDRESS GDB_JUMP_PAD_HEAD FJUMP_SIZE FJUMP' ++ TARGET_ADDRESS is address of tracepoint in the inferior. The ++ GDB_JUMP_PAD_HEAD is updated head of jumppad. Both of ++ TARGET_ADDRESS and GDB_JUMP_PAD_HEAD are 8-byte long. The ++ FJUMP contains a sequence of instructions jump to jumppad ++ entry. The FJUMP_SIZE, 4-byte long, is the size of FJUMP. ++ 'E NN' ++ for an error ++ ++'close' ++ Closes the in-process agent. This command is sent when GDB or ++ GDBserver is about to kill inferiors. ++ ++'qTfSTM' ++ *Note qTfSTM::. ++'qTsSTM' ++ *Note qTsSTM::. ++'qTSTMat' ++ *Note qTSTMat::. ++'probe_marker_at:ADDRESS' ++ Asks in-process agent to probe the marker at ADDRESS. ++ ++ Replies: ++ 'E NN' ++ for an error ++'unprobe_marker_at:ADDRESS' ++ Asks in-process agent to unprobe the marker at ADDRESS. ++ ++ ++File: gdb.info, Node: GDB Bugs, Next: Command Line Editing, Prev: In-Process Agent, Up: Top ++ ++31 Reporting Bugs in GDB ++************************ ++ ++Your bug reports play an essential role in making GDB reliable. ++ ++ Reporting a bug may help you by bringing a solution to your problem, ++or it may not. But in any case the principal function of a bug report ++is to help the entire community by making the next version of GDB work ++better. Bug reports are your contribution to the maintenance of GDB. ++ ++ In order for a bug report to serve its purpose, you must include the ++information that enables us to fix the bug. ++ ++* Menu: ++ ++* Bug Criteria:: Have you found a bug? ++* Bug Reporting:: How to report bugs ++ ++ ++File: gdb.info, Node: Bug Criteria, Next: Bug Reporting, Up: GDB Bugs ++ ++31.1 Have You Found a Bug? ++========================== ++ ++If you are not sure whether you have found a bug, here are some ++guidelines: ++ ++ * If the debugger gets a fatal signal, for any input whatever, that ++ is a GDB bug. Reliable debuggers never crash. ++ ++ * If GDB produces an error message for valid input, that is a bug. ++ (Note that if you're cross debugging, the problem may also be ++ somewhere in the connection to the target.) ++ ++ * If GDB does not produce an error message for invalid input, that is ++ a bug. However, you should note that your idea of "invalid input" ++ might be our idea of "an extension" or "support for traditional ++ practice". ++ ++ * If you are an experienced user of debugging tools, your suggestions ++ for improvement of GDB are welcome in any case. ++ ++ ++File: gdb.info, Node: Bug Reporting, Prev: Bug Criteria, Up: GDB Bugs ++ ++31.2 How to Report Bugs ++======================= ++ ++A number of companies and individuals offer support for GNU products. ++If you obtained GDB from a support organization, we recommend you ++contact that organization first. ++ ++ You can find contact information for many support companies and ++individuals in the file 'etc/SERVICE' in the GNU Emacs distribution. ++ ++ In any event, we also recommend that you submit bug reports for GDB ++to . ++ ++ The fundamental principle of reporting bugs usefully is this: *report ++all the facts*. If you are not sure whether to state a fact or leave it ++out, state it! ++ ++ Often people omit facts because they think they know what causes the ++problem and assume that some details do not matter. Thus, you might ++assume that the name of the variable you use in an example does not ++matter. Well, probably it does not, but one cannot be sure. Perhaps ++the bug is a stray memory reference which happens to fetch from the ++location where that name is stored in memory; perhaps, if the name were ++different, the contents of that location would fool the debugger into ++doing the right thing despite the bug. Play it safe and give a ++specific, complete example. That is the easiest thing for you to do, ++and the most helpful. ++ ++ Keep in mind that the purpose of a bug report is to enable us to fix ++the bug. It may be that the bug has been reported previously, but ++neither you nor we can know that unless your bug report is complete and ++self-contained. ++ ++ Sometimes people give a few sketchy facts and ask, "Does this ring a ++bell?" Those bug reports are useless, and we urge everyone to _refuse ++to respond to them_ except to chide the sender to report bugs properly. ++ ++ To enable us to fix the bug, you should include all these things: ++ ++ * The version of GDB. GDB announces it if you start with no ++ arguments; you can also print it at any time using 'show version'. ++ ++ Without this, we will not know whether there is any point in ++ looking for the bug in the current version of GDB. ++ ++ * The type of machine you are using, and the operating system name ++ and version number. ++ ++ * The details of the GDB build-time configuration. GDB shows these ++ details if you invoke it with the '--configuration' command-line ++ option, or if you type 'show configuration' at GDB's prompt. ++ ++ * What compiler (and its version) was used to compile GDB--e.g. ++ "gcc-2.8.1". ++ ++ * What compiler (and its version) was used to compile the program you ++ are debugging--e.g. "gcc-2.8.1", or "HP92453-01 A.10.32.03 HP C ++ Compiler". For GCC, you can say 'gcc --version' to get this ++ information; for other compilers, see the documentation for those ++ compilers. ++ ++ * The command arguments you gave the compiler to compile your example ++ and observe the bug. For example, did you use '-O'? To guarantee ++ you will not omit something important, list them all. A copy of ++ the Makefile (or the output from make) is sufficient. ++ ++ If we were to try to guess the arguments, we would probably guess ++ wrong and then we might not encounter the bug. ++ ++ * A complete input script, and all necessary source files, that will ++ reproduce the bug. ++ ++ * A description of what behavior you observe that you believe is ++ incorrect. For example, "It gets a fatal signal." ++ ++ Of course, if the bug is that GDB gets a fatal signal, then we will ++ certainly notice it. But if the bug is incorrect output, we might ++ not notice unless it is glaringly wrong. You might as well not ++ give us a chance to make a mistake. ++ ++ Even if the problem you experience is a fatal signal, you should ++ still say so explicitly. Suppose something strange is going on, ++ such as, your copy of GDB is out of synch, or you have encountered ++ a bug in the C library on your system. (This has happened!) Your ++ copy might crash and ours would not. If you told us to expect a ++ crash, then when ours fails to crash, we would know that the bug ++ was not happening for us. If you had not told us to expect a ++ crash, then we would not be able to draw any conclusion from our ++ observations. ++ ++ To collect all this information, you can use a session recording ++ program such as 'script', which is available on many Unix systems. ++ Just run your GDB session inside 'script' and then include the ++ 'typescript' file with your bug report. ++ ++ Another way to record a GDB session is to run GDB inside Emacs and ++ then save the entire buffer to a file. ++ ++ * If you wish to suggest changes to the GDB source, send us context ++ diffs. If you even discuss something in the GDB source, refer to ++ it by context, not by line number. ++ ++ The line numbers in our development sources will not match those in ++ your sources. Your line numbers would convey no useful information ++ to us. ++ ++ Here are some things that are not necessary: ++ ++ * A description of the envelope of the bug. ++ ++ Often people who encounter a bug spend a lot of time investigating ++ which changes to the input file will make the bug go away and which ++ changes will not affect it. ++ ++ This is often time consuming and not very useful, because the way ++ we will find the bug is by running a single example under the ++ debugger with breakpoints, not by pure deduction from a series of ++ examples. We recommend that you save your time for something else. ++ ++ Of course, if you can find a simpler example to report _instead_ of ++ the original one, that is a convenience for us. Errors in the ++ output will be easier to spot, running under the debugger will take ++ less time, and so on. ++ ++ However, simplification is not vital; if you do not want to do ++ this, report the bug anyway and send us the entire test case you ++ used. ++ ++ * A patch for the bug. ++ ++ A patch for the bug does help us if it is a good one. But do not ++ omit the necessary information, such as the test case, on the ++ assumption that a patch is all we need. We might see problems with ++ your patch and decide to fix the problem another way, or we might ++ not understand it at all. ++ ++ Sometimes with a program as complicated as GDB it is very hard to ++ construct an example that will make the program follow a certain ++ path through the code. If you do not send us the example, we will ++ not be able to construct one, so we will not be able to verify that ++ the bug is fixed. ++ ++ And if we cannot understand what bug you are trying to fix, or why ++ your patch should be an improvement, we will not install it. A ++ test case will help us to understand. ++ ++ * A guess about what the bug is or what it depends on. ++ ++ Such guesses are usually wrong. Even we cannot guess right about ++ such things without first using the debugger to find the facts. ++ ++ ++File: gdb.info, Node: Command Line Editing, Next: Using History Interactively, Prev: GDB Bugs, Up: Top ++ ++32 Command Line Editing ++*********************** ++ ++This chapter describes the basic features of the GNU command line ++editing interface. ++ ++* Menu: ++ ++* Introduction and Notation:: Notation used in this text. ++* Readline Interaction:: The minimum set of commands for editing a line. ++* Readline Init File:: Customizing Readline from a user's view. ++* Bindable Readline Commands:: A description of most of the Readline commands ++ available for binding ++* Readline vi Mode:: A short description of how to make Readline ++ behave like the vi editor. ++ ++ ++File: gdb.info, Node: Introduction and Notation, Next: Readline Interaction, Up: Command Line Editing ++ ++32.1 Introduction to Line Editing ++================================= ++ ++The following paragraphs describe the notation used to represent ++keystrokes. ++ ++ The text 'C-k' is read as 'Control-K' and describes the character ++produced when the key is pressed while the Control key is depressed. ++ ++ The text 'M-k' is read as 'Meta-K' and describes the character ++produced when the Meta key (if you have one) is depressed, and the ++key is pressed. The Meta key is labeled on many keyboards. On ++keyboards with two keys labeled (usually to either side of the ++space bar), the on the left side is generally set to work as a ++Meta key. The key on the right may also be configured to work as ++a Meta key or may be configured as some other modifier, such as a ++Compose key for typing accented characters. ++ ++ If you do not have a Meta or key, or another key working as a ++Meta key, the identical keystroke can be generated by typing ++_first_, and then typing . Either process is known as "metafying" ++the key. ++ ++ The text 'M-C-k' is read as 'Meta-Control-k' and describes the ++character produced by "metafying" 'C-k'. ++ ++ In addition, several keys have their own names. Specifically, , ++, , , , and all stand for themselves when seen ++in this text, or in an init file (*note Readline Init File::). If your ++keyboard lacks a key, typing will produce the desired ++character. The key may be labeled or on some ++keyboards. ++ ++ ++File: gdb.info, Node: Readline Interaction, Next: Readline Init File, Prev: Introduction and Notation, Up: Command Line Editing ++ ++32.2 Readline Interaction ++========================= ++ ++Often during an interactive session you type in a long line of text, ++only to notice that the first word on the line is misspelled. The ++Readline library gives you a set of commands for manipulating the text ++as you type it in, allowing you to just fix your typo, and not forcing ++you to retype the majority of the line. Using these editing commands, ++you move the cursor to the place that needs correction, and delete or ++insert the text of the corrections. Then, when you are satisfied with ++the line, you simply press . You do not have to be at the end of ++the line to press ; the entire line is accepted regardless of the ++location of the cursor within the line. ++ ++* Menu: ++ ++* Readline Bare Essentials:: The least you need to know about Readline. ++* Readline Movement Commands:: Moving about the input line. ++* Readline Killing Commands:: How to delete text, and how to get it back! ++* Readline Arguments:: Giving numeric arguments to commands. ++* Searching:: Searching through previous lines. ++ ++ ++File: gdb.info, Node: Readline Bare Essentials, Next: Readline Movement Commands, Up: Readline Interaction ++ ++32.2.1 Readline Bare Essentials ++------------------------------- ++ ++In order to enter characters into the line, simply type them. The typed ++character appears where the cursor was, and then the cursor moves one ++space to the right. If you mistype a character, you can use your erase ++character to back up and delete the mistyped character. ++ ++ Sometimes you may mistype a character, and not notice the error until ++you have typed several other characters. In that case, you can type ++'C-b' to move the cursor to the left, and then correct your mistake. ++Afterwards, you can move the cursor to the right with 'C-f'. ++ ++ When you add text in the middle of a line, you will notice that ++characters to the right of the cursor are 'pushed over' to make room for ++the text that you have inserted. Likewise, when you delete text behind ++the cursor, characters to the right of the cursor are 'pulled back' to ++fill in the blank space created by the removal of the text. A list of ++the bare essentials for editing the text of an input line follows. ++ ++'C-b' ++ Move back one character. ++'C-f' ++ Move forward one character. ++ or ++ Delete the character to the left of the cursor. ++'C-d' ++ Delete the character underneath the cursor. ++Printing characters ++ Insert the character into the line at the cursor. ++'C-_' or 'C-x C-u' ++ Undo the last editing command. You can undo all the way back to an ++ empty line. ++ ++(Depending on your configuration, the key be set to delete ++the character to the left of the cursor and the key set to delete ++the character underneath the cursor, like 'C-d', rather than the ++character to the left of the cursor.) ++ ++ ++File: gdb.info, Node: Readline Movement Commands, Next: Readline Killing Commands, Prev: Readline Bare Essentials, Up: Readline Interaction ++ ++32.2.2 Readline Movement Commands ++--------------------------------- ++ ++The above table describes the most basic keystrokes that you need in ++order to do editing of the input line. For your convenience, many other ++commands have been added in addition to 'C-b', 'C-f', 'C-d', and . ++Here are some commands for moving more rapidly about the line. ++ ++'C-a' ++ Move to the start of the line. ++'C-e' ++ Move to the end of the line. ++'M-f' ++ Move forward a word, where a word is composed of letters and ++ digits. ++'M-b' ++ Move backward a word. ++'C-l' ++ Clear the screen, reprinting the current line at the top. ++ ++ Notice how 'C-f' moves forward a character, while 'M-f' moves forward ++a word. It is a loose convention that control keystrokes operate on ++characters while meta keystrokes operate on words. ++ ++ ++File: gdb.info, Node: Readline Killing Commands, Next: Readline Arguments, Prev: Readline Movement Commands, Up: Readline Interaction ++ ++32.2.3 Readline Killing Commands ++-------------------------------- ++ ++"Killing" text means to delete the text from the line, but to save it ++away for later use, usually by "yanking" (re-inserting) it back into the ++line. ('Cut' and 'paste' are more recent jargon for 'kill' and 'yank'.) ++ ++ If the description for a command says that it 'kills' text, then you ++can be sure that you can get the text back in a different (or the same) ++place later. ++ ++ When you use a kill command, the text is saved in a "kill-ring". Any ++number of consecutive kills save all of the killed text together, so ++that when you yank it back, you get it all. The kill ring is not line ++specific; the text that you killed on a previously typed line is ++available to be yanked back later, when you are typing another line. ++ ++ Here is the list of commands for killing text. ++ ++'C-k' ++ Kill the text from the current cursor position to the end of the ++ line. ++ ++'M-d' ++ Kill from the cursor to the end of the current word, or, if between ++ words, to the end of the next word. Word boundaries are the same ++ as those used by 'M-f'. ++ ++'M-' ++ Kill from the cursor the start of the current word, or, if between ++ words, to the start of the previous word. Word boundaries are the ++ same as those used by 'M-b'. ++ ++'C-w' ++ Kill from the cursor to the previous whitespace. This is different ++ than 'M-' because the word boundaries differ. ++ ++ Here is how to "yank" the text back into the line. Yanking means to ++copy the most-recently-killed text from the kill buffer. ++ ++'C-y' ++ Yank the most recently killed text back into the buffer at the ++ cursor. ++ ++'M-y' ++ Rotate the kill-ring, and yank the new top. You can only do this ++ if the prior command is 'C-y' or 'M-y'. ++ ++ ++File: gdb.info, Node: Readline Arguments, Next: Searching, Prev: Readline Killing Commands, Up: Readline Interaction ++ ++32.2.4 Readline Arguments ++------------------------- ++ ++You can pass numeric arguments to Readline commands. Sometimes the ++argument acts as a repeat count, other times it is the sign of the ++argument that is significant. If you pass a negative argument to a ++command which normally acts in a forward direction, that command will ++act in a backward direction. For example, to kill text back to the ++start of the line, you might type 'M-- C-k'. ++ ++ The general way to pass numeric arguments to a command is to type ++meta digits before the command. If the first 'digit' typed is a minus ++sign ('-'), then the sign of the argument will be negative. Once you ++have typed one meta digit to get the argument started, you can type the ++remainder of the digits, and then the command. For example, to give the ++'C-d' command an argument of 10, you could type 'M-1 0 C-d', which will ++delete the next ten characters on the input line. ++ ++ ++File: gdb.info, Node: Searching, Prev: Readline Arguments, Up: Readline Interaction ++ ++32.2.5 Searching for Commands in the History ++-------------------------------------------- ++ ++Readline provides commands for searching through the command history for ++lines containing a specified string. There are two search modes: ++"incremental" and "non-incremental". ++ ++ Incremental searches begin before the user has finished typing the ++search string. As each character of the search string is typed, ++Readline displays the next entry from the history matching the string ++typed so far. An incremental search requires only as many characters as ++needed to find the desired history entry. To search backward in the ++history for a particular string, type 'C-r'. Typing 'C-s' searches ++forward through the history. The characters present in the value of the ++'isearch-terminators' variable are used to terminate an incremental ++search. If that variable has not been assigned a value, the and ++'C-J' characters will terminate an incremental search. 'C-g' will abort ++an incremental search and restore the original line. When the search is ++terminated, the history entry containing the search string becomes the ++current line. ++ ++ To find other matching entries in the history list, type 'C-r' or ++'C-s' as appropriate. This will search backward or forward in the ++history for the next entry matching the search string typed so far. Any ++other key sequence bound to a Readline command will terminate the search ++and execute that command. For instance, a will terminate the ++search and accept the line, thereby executing the command from the ++history list. A movement command will terminate the search, make the ++last line found the current line, and begin editing. ++ ++ Readline remembers the last incremental search string. If two 'C-r's ++are typed without any intervening characters defining a new search ++string, any remembered search string is used. ++ ++ Non-incremental searches read the entire search string before ++starting to search for matching history lines. The search string may be ++typed by the user or be part of the contents of the current line. ++ ++ ++File: gdb.info, Node: Readline Init File, Next: Bindable Readline Commands, Prev: Readline Interaction, Up: Command Line Editing ++ ++32.3 Readline Init File ++======================= ++ ++Although the Readline library comes with a set of Emacs-like keybindings ++installed by default, it is possible to use a different set of ++keybindings. Any user can customize programs that use Readline by ++putting commands in an "inputrc" file, conventionally in his home ++directory. The name of this file is taken from the value of the ++environment variable 'INPUTRC'. If that variable is unset, the default ++is '~/.inputrc'. If that file does not exist or cannot be read, the ++ultimate default is '/etc/inputrc'. ++ ++ When a program which uses the Readline library starts up, the init ++file is read, and the key bindings are set. ++ ++ In addition, the 'C-x C-r' command re-reads this init file, thus ++incorporating any changes that you might have made to it. ++ ++* Menu: ++ ++* Readline Init File Syntax:: Syntax for the commands in the inputrc file. ++ ++* Conditional Init Constructs:: Conditional key bindings in the inputrc file. ++ ++* Sample Init File:: An example inputrc file. ++ ++ ++File: gdb.info, Node: Readline Init File Syntax, Next: Conditional Init Constructs, Up: Readline Init File ++ ++32.3.1 Readline Init File Syntax ++-------------------------------- ++ ++There are only a few basic constructs allowed in the Readline init file. ++Blank lines are ignored. Lines beginning with a '#' are comments. ++Lines beginning with a '$' indicate conditional constructs (*note ++Conditional Init Constructs::). Other lines denote variable settings ++and key bindings. ++ ++Variable Settings ++ You can modify the run-time behavior of Readline by altering the ++ values of variables in Readline using the 'set' command within the ++ init file. The syntax is simple: ++ ++ set VARIABLE VALUE ++ ++ Here, for example, is how to change from the default Emacs-like key ++ binding to use 'vi' line editing commands: ++ ++ set editing-mode vi ++ ++ Variable names and values, where appropriate, are recognized ++ without regard to case. Unrecognized variable names are ignored. ++ ++ Boolean variables (those that can be set to on or off) are set to ++ on if the value is null or empty, ON (case-insensitive), or 1. Any ++ other value results in the variable being set to off. ++ ++ A great deal of run-time behavior is changeable with the following ++ variables. ++ ++ 'bell-style' ++ Controls what happens when Readline wants to ring the terminal ++ bell. If set to 'none', Readline never rings the bell. If ++ set to 'visible', Readline uses a visible bell if one is ++ available. If set to 'audible' (the default), Readline ++ attempts to ring the terminal's bell. ++ ++ 'bind-tty-special-chars' ++ If set to 'on' (the default), Readline attempts to bind the ++ control characters treated specially by the kernel's terminal ++ driver to their Readline equivalents. ++ ++ 'blink-matching-paren' ++ If set to 'on', Readline attempts to briefly move the cursor ++ to an opening parenthesis when a closing parenthesis is ++ inserted. The default is 'off'. ++ ++ 'colored-completion-prefix' ++ If set to 'on', when listing completions, Readline displays ++ the common prefix of the set of possible completions using a ++ different color. The color definitions are taken from the ++ value of the 'LS_COLORS' environment variable. The default is ++ 'off'. ++ ++ 'colored-stats' ++ If set to 'on', Readline displays possible completions using ++ different colors to indicate their file type. The color ++ definitions are taken from the value of the 'LS_COLORS' ++ environment variable. The default is 'off'. ++ ++ 'comment-begin' ++ The string to insert at the beginning of the line when the ++ 'insert-comment' command is executed. The default value is ++ '"#"'. ++ ++ 'completion-display-width' ++ The number of screen columns used to display possible matches ++ when performing completion. The value is ignored if it is ++ less than 0 or greater than the terminal screen width. A ++ value of 0 will cause matches to be displayed one per line. ++ The default value is -1. ++ ++ 'completion-ignore-case' ++ If set to 'on', Readline performs filename matching and ++ completion in a case-insensitive fashion. The default value ++ is 'off'. ++ ++ 'completion-map-case' ++ If set to 'on', and COMPLETION-IGNORE-CASE is enabled, ++ Readline treats hyphens ('-') and underscores ('_') as ++ equivalent when performing case-insensitive filename matching ++ and completion. The default value is 'off'. ++ ++ 'completion-prefix-display-length' ++ The length in characters of the common prefix of a list of ++ possible completions that is displayed without modification. ++ When set to a value greater than zero, common prefixes longer ++ than this value are replaced with an ellipsis when displaying ++ possible completions. ++ ++ 'completion-query-items' ++ The number of possible completions that determines when the ++ user is asked whether the list of possibilities should be ++ displayed. If the number of possible completions is greater ++ than this value, Readline will ask the user whether or not he ++ wishes to view them; otherwise, they are simply listed. This ++ variable must be set to an integer value greater than or equal ++ to 0. A negative value means Readline should never ask. The ++ default limit is '100'. ++ ++ 'convert-meta' ++ If set to 'on', Readline will convert characters with the ++ eighth bit set to an ASCII key sequence by stripping the ++ eighth bit and prefixing an character, converting them ++ to a meta-prefixed key sequence. The default value is 'on', ++ but will be set to 'off' if the locale is one that contains ++ eight-bit characters. ++ ++ 'disable-completion' ++ If set to 'On', Readline will inhibit word completion. ++ Completion characters will be inserted into the line as if ++ they had been mapped to 'self-insert'. The default is 'off'. ++ ++ 'echo-control-characters' ++ When set to 'on', on operating systems that indicate they ++ support it, readline echoes a character corresponding to a ++ signal generated from the keyboard. The default is 'on'. ++ ++ 'editing-mode' ++ The 'editing-mode' variable controls which default set of key ++ bindings is used. By default, Readline starts up in Emacs ++ editing mode, where the keystrokes are most similar to Emacs. ++ This variable can be set to either 'emacs' or 'vi'. ++ ++ 'emacs-mode-string' ++ If the SHOW-MODE-IN-PROMPT variable is enabled, this string is ++ displayed immediately before the last line of the primary ++ prompt when emacs editing mode is active. The value is ++ expanded like a key binding, so the standard set of meta- and ++ control prefixes and backslash escape sequences is available. ++ Use the '\1' and '\2' escapes to begin and end sequences of ++ non-printing characters, which can be used to embed a terminal ++ control sequence into the mode string. The default is '@'. ++ ++ 'enable-bracketed-paste' ++ When set to 'On', Readline will configure the terminal in a ++ way that will enable it to insert each paste into the editing ++ buffer as a single string of characters, instead of treating ++ each character as if it had been read from the keyboard. This ++ can prevent pasted characters from being interpreted as ++ editing commands. The default is 'off'. ++ ++ 'enable-keypad' ++ When set to 'on', Readline will try to enable the application ++ keypad when it is called. Some systems need this to enable ++ the arrow keys. The default is 'off'. ++ ++ 'enable-meta-key' ++ When set to 'on', Readline will try to enable any meta ++ modifier key the terminal claims to support when it is called. ++ On many terminals, the meta key is used to send eight-bit ++ characters. The default is 'on'. ++ ++ 'expand-tilde' ++ If set to 'on', tilde expansion is performed when Readline ++ attempts word completion. The default is 'off'. ++ ++ 'history-preserve-point' ++ If set to 'on', the history code attempts to place the point ++ (the current cursor position) at the same location on each ++ history line retrieved with 'previous-history' or ++ 'next-history'. The default is 'off'. ++ ++ 'history-size' ++ Set the maximum number of history entries saved in the history ++ list. If set to zero, any existing history entries are ++ deleted and no new entries are saved. If set to a value less ++ than zero, the number of history entries is not limited. By ++ default, the number of history entries is not limited. If an ++ attempt is made to set HISTORY-SIZE to a non-numeric value, ++ the maximum number of history entries will be set to 500. ++ ++ 'horizontal-scroll-mode' ++ This variable can be set to either 'on' or 'off'. Setting it ++ to 'on' means that the text of the lines being edited will ++ scroll horizontally on a single screen line when they are ++ longer than the width of the screen, instead of wrapping onto ++ a new screen line. By default, this variable is set to 'off'. ++ ++ 'input-meta' ++ If set to 'on', Readline will enable eight-bit input (it will ++ not clear the eighth bit in the characters it reads), ++ regardless of what the terminal claims it can support. The ++ default value is 'off', but Readline will set it to 'on' if ++ the locale contains eight-bit characters. The name ++ 'meta-flag' is a synonym for this variable. ++ ++ 'isearch-terminators' ++ The string of characters that should terminate an incremental ++ search without subsequently executing the character as a ++ command (*note Searching::). If this variable has not been ++ given a value, the characters and 'C-J' will terminate ++ an incremental search. ++ ++ 'keymap' ++ Sets Readline's idea of the current keymap for key binding ++ commands. Built-in 'keymap' names are 'emacs', ++ 'emacs-standard', 'emacs-meta', 'emacs-ctlx', 'vi', 'vi-move', ++ 'vi-command', and 'vi-insert'. 'vi' is equivalent to ++ 'vi-command' ('vi-move' is also a synonym); 'emacs' is ++ equivalent to 'emacs-standard'. Applications may add ++ additional names. The default value is 'emacs'. The value of ++ the 'editing-mode' variable also affects the default keymap. ++ ++ 'keyseq-timeout' ++ Specifies the duration Readline will wait for a character when ++ reading an ambiguous key sequence (one that can form a ++ complete key sequence using the input read so far, or can take ++ additional input to complete a longer key sequence). If no ++ input is received within the timeout, Readline will use the ++ shorter but complete key sequence. Readline uses this value ++ to determine whether or not input is available on the current ++ input source ('rl_instream' by default). The value is ++ specified in milliseconds, so a value of 1000 means that ++ Readline will wait one second for additional input. If this ++ variable is set to a value less than or equal to zero, or to a ++ non-numeric value, Readline will wait until another key is ++ pressed to decide which key sequence to complete. The default ++ value is '500'. ++ ++ 'mark-directories' ++ If set to 'on', completed directory names have a slash ++ appended. The default is 'on'. ++ ++ 'mark-modified-lines' ++ This variable, when set to 'on', causes Readline to display an ++ asterisk ('*') at the start of history lines which have been ++ modified. This variable is 'off' by default. ++ ++ 'mark-symlinked-directories' ++ If set to 'on', completed names which are symbolic links to ++ directories have a slash appended (subject to the value of ++ 'mark-directories'). The default is 'off'. ++ ++ 'match-hidden-files' ++ This variable, when set to 'on', causes Readline to match ++ files whose names begin with a '.' (hidden files) when ++ performing filename completion. If set to 'off', the leading ++ '.' must be supplied by the user in the filename to be ++ completed. This variable is 'on' by default. ++ ++ 'menu-complete-display-prefix' ++ If set to 'on', menu completion displays the common prefix of ++ the list of possible completions (which may be empty) before ++ cycling through the list. The default is 'off'. ++ ++ 'output-meta' ++ If set to 'on', Readline will display characters with the ++ eighth bit set directly rather than as a meta-prefixed escape ++ sequence. The default is 'off', but Readline will set it to ++ 'on' if the locale contains eight-bit characters. ++ ++ 'page-completions' ++ If set to 'on', Readline uses an internal 'more'-like pager to ++ display a screenful of possible completions at a time. This ++ variable is 'on' by default. ++ ++ 'print-completions-horizontally' ++ If set to 'on', Readline will display completions with matches ++ sorted horizontally in alphabetical order, rather than down ++ the screen. The default is 'off'. ++ ++ 'revert-all-at-newline' ++ If set to 'on', Readline will undo all changes to history ++ lines before returning when 'accept-line' is executed. By ++ default, history lines may be modified and retain individual ++ undo lists across calls to 'readline'. The default is 'off'. ++ ++ 'show-all-if-ambiguous' ++ This alters the default behavior of the completion functions. ++ If set to 'on', words which have more than one possible ++ completion cause the matches to be listed immediately instead ++ of ringing the bell. The default value is 'off'. ++ ++ 'show-all-if-unmodified' ++ This alters the default behavior of the completion functions ++ in a fashion similar to SHOW-ALL-IF-AMBIGUOUS. If set to ++ 'on', words which have more than one possible completion ++ without any possible partial completion (the possible ++ completions don't share a common prefix) cause the matches to ++ be listed immediately instead of ringing the bell. The ++ default value is 'off'. ++ ++ 'show-mode-in-prompt' ++ If set to 'on', add a string to the beginning of the prompt ++ indicating the editing mode: emacs, vi command, or vi ++ insertion. The mode strings are user-settable (e.g., ++ EMACS-MODE-STRING). The default value is 'off'. ++ ++ 'skip-completed-text' ++ If set to 'on', this alters the default completion behavior ++ when inserting a single match into the line. It's only active ++ when performing completion in the middle of a word. If ++ enabled, readline does not insert characters from the ++ completion that match characters after point in the word being ++ completed, so portions of the word following the cursor are ++ not duplicated. For instance, if this is enabled, attempting ++ completion when the cursor is after the 'e' in 'Makefile' will ++ result in 'Makefile' rather than 'Makefilefile', assuming ++ there is a single possible completion. The default value is ++ 'off'. ++ ++ 'vi-cmd-mode-string' ++ If the SHOW-MODE-IN-PROMPT variable is enabled, this string is ++ displayed immediately before the last line of the primary ++ prompt when vi editing mode is active and in command mode. ++ The value is expanded like a key binding, so the standard set ++ of meta- and control prefixes and backslash escape sequences ++ is available. Use the '\1' and '\2' escapes to begin and end ++ sequences of non-printing characters, which can be used to ++ embed a terminal control sequence into the mode string. The ++ default is '(cmd)'. ++ ++ 'vi-ins-mode-string' ++ If the SHOW-MODE-IN-PROMPT variable is enabled, this string is ++ displayed immediately before the last line of the primary ++ prompt when vi editing mode is active and in insertion mode. ++ The value is expanded like a key binding, so the standard set ++ of meta- and control prefixes and backslash escape sequences ++ is available. Use the '\1' and '\2' escapes to begin and end ++ sequences of non-printing characters, which can be used to ++ embed a terminal control sequence into the mode string. The ++ default is '(ins)'. ++ ++ 'visible-stats' ++ If set to 'on', a character denoting a file's type is appended ++ to the filename when listing possible completions. The ++ default is 'off'. ++ ++Key Bindings ++ The syntax for controlling key bindings in the init file is simple. ++ First you need to find the name of the command that you want to ++ change. The following sections contain tables of the command name, ++ the default keybinding, if any, and a short description of what the ++ command does. ++ ++ Once you know the name of the command, simply place on a line in ++ the init file the name of the key you wish to bind the command to, ++ a colon, and then the name of the command. There can be no space ++ between the key name and the colon - that will be interpreted as ++ part of the key name. The name of the key can be expressed in ++ different ways, depending on what you find most comfortable. ++ ++ In addition to command names, readline allows keys to be bound to a ++ string that is inserted when the key is pressed (a MACRO). ++ ++ KEYNAME: FUNCTION-NAME or MACRO ++ KEYNAME is the name of a key spelled out in English. For ++ example: ++ Control-u: universal-argument ++ Meta-Rubout: backward-kill-word ++ Control-o: "> output" ++ ++ In the example above, 'C-u' is bound to the function ++ 'universal-argument', 'M-DEL' is bound to the function ++ 'backward-kill-word', and 'C-o' is bound to run the macro ++ expressed on the right hand side (that is, to insert the text ++ '> output' into the line). ++ ++ A number of symbolic character names are recognized while ++ processing this key binding syntax: DEL, ESC, ESCAPE, LFD, ++ NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB. ++ ++ "KEYSEQ": FUNCTION-NAME or MACRO ++ KEYSEQ differs from KEYNAME above in that strings denoting an ++ entire key sequence can be specified, by placing the key ++ sequence in double quotes. Some GNU Emacs style key escapes ++ can be used, as in the following example, but the special ++ character names are not recognized. ++ ++ "\C-u": universal-argument ++ "\C-x\C-r": re-read-init-file ++ "\e[11~": "Function Key 1" ++ ++ In the above example, 'C-u' is again bound to the function ++ 'universal-argument' (just as it was in the first example), ++ ''C-x' 'C-r'' is bound to the function 're-read-init-file', ++ and ' <[> <1> <1> <~>' is bound to insert the text ++ 'Function Key 1'. ++ ++ The following GNU Emacs style escape sequences are available when ++ specifying key sequences: ++ ++ '\C-' ++ control prefix ++ '\M-' ++ meta prefix ++ '\e' ++ an escape character ++ '\\' ++ backslash ++ '\"' ++ <">, a double quotation mark ++ '\'' ++ <'>, a single quote or apostrophe ++ ++ In addition to the GNU Emacs style escape sequences, a second set ++ of backslash escapes is available: ++ ++ '\a' ++ alert (bell) ++ '\b' ++ backspace ++ '\d' ++ delete ++ '\f' ++ form feed ++ '\n' ++ newline ++ '\r' ++ carriage return ++ '\t' ++ horizontal tab ++ '\v' ++ vertical tab ++ '\NNN' ++ the eight-bit character whose value is the octal value NNN ++ (one to three digits) ++ '\xHH' ++ the eight-bit character whose value is the hexadecimal value ++ HH (one or two hex digits) ++ ++ When entering the text of a macro, single or double quotes must be ++ used to indicate a macro definition. Unquoted text is assumed to ++ be a function name. In the macro body, the backslash escapes ++ described above are expanded. Backslash will quote any other ++ character in the macro text, including '"' and '''. For example, ++ the following binding will make ''C-x' \' insert a single '\' into ++ the line: ++ "\C-x\\": "\\" ++ ++ ++File: gdb.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File ++ ++32.3.2 Conditional Init Constructs ++---------------------------------- ++ ++Readline implements a facility similar in spirit to the conditional ++compilation features of the C preprocessor which allows key bindings and ++variable settings to be performed as the result of tests. There are ++four parser directives used. ++ ++'$if' ++ The '$if' construct allows bindings to be made based on the editing ++ mode, the terminal being used, or the application using Readline. ++ The text of the test, after any comparison operator, extends to the ++ end of the line; unless otherwise noted, no characters are required ++ to isolate it. ++ ++ 'mode' ++ The 'mode=' form of the '$if' directive is used to test ++ whether Readline is in 'emacs' or 'vi' mode. This may be used ++ in conjunction with the 'set keymap' command, for instance, to ++ set bindings in the 'emacs-standard' and 'emacs-ctlx' keymaps ++ only if Readline is starting out in 'emacs' mode. ++ ++ 'term' ++ The 'term=' form may be used to include terminal-specific key ++ bindings, perhaps to bind the key sequences output by the ++ terminal's function keys. The word on the right side of the ++ '=' is tested against both the full name of the terminal and ++ the portion of the terminal name before the first '-'. This ++ allows 'sun' to match both 'sun' and 'sun-cmd', for instance. ++ ++ 'version' ++ The 'version' test may be used to perform comparisons against ++ specific Readline versions. The 'version' expands to the ++ current Readline version. The set of comparison operators ++ includes '=' (and '=='), '!=', '<=', '>=', '<', and '>'. The ++ version number supplied on the right side of the operator ++ consists of a major version number, an optional decimal point, ++ and an optional minor version (e.g., '7.1'). If the minor ++ version is omitted, it is assumed to be '0'. The operator may ++ be separated from the string 'version' and from the version ++ number argument by whitespace. The following example sets a ++ variable if the Readline version being used is 7.0 or newer: ++ $if version >= 7.0 ++ set show-mode-in-prompt on ++ $endif ++ ++ 'application' ++ The APPLICATION construct is used to include ++ application-specific settings. Each program using the ++ Readline library sets the APPLICATION NAME, and you can test ++ for a particular value. This could be used to bind key ++ sequences to functions useful for a specific program. For ++ instance, the following command adds a key sequence that ++ quotes the current or previous word in Bash: ++ $if Bash ++ # Quote the current or previous word ++ "\C-xq": "\eb\"\ef\"" ++ $endif ++ ++ 'variable' ++ The VARIABLE construct provides simple equality tests for ++ Readline variables and values. The permitted comparison ++ operators are '=', '==', and '!='. The variable name must be ++ separated from the comparison operator by whitespace; the ++ operator may be separated from the value on the right hand ++ side by whitespace. Both string and boolean variables may be ++ tested. Boolean variables must be tested against the values ++ ON and OFF. The following example is equivalent to the ++ 'mode=emacs' test described above: ++ $if editing-mode == emacs ++ set show-mode-in-prompt on ++ $endif ++ ++'$endif' ++ This command, as seen in the previous example, terminates an '$if' ++ command. ++ ++'$else' ++ Commands in this branch of the '$if' directive are executed if the ++ test fails. ++ ++'$include' ++ This directive takes a single filename as an argument and reads ++ commands and bindings from that file. For example, the following ++ directive reads from '/etc/inputrc': ++ $include /etc/inputrc ++ ++ ++File: gdb.info, Node: Sample Init File, Prev: Conditional Init Constructs, Up: Readline Init File ++ ++32.3.3 Sample Init File ++----------------------- ++ ++Here is an example of an INPUTRC file. This illustrates key binding, ++variable assignment, and conditional syntax. ++ ++ # This file controls the behaviour of line input editing for ++ # programs that use the GNU Readline library. Existing ++ # programs include FTP, Bash, and GDB. ++ # ++ # You can re-read the inputrc file with C-x C-r. ++ # Lines beginning with '#' are comments. ++ # ++ # First, include any system-wide bindings and variable ++ # assignments from /etc/Inputrc ++ $include /etc/Inputrc ++ ++ # ++ # Set various bindings for emacs mode. ++ ++ set editing-mode emacs ++ ++ $if mode=emacs ++ ++ Meta-Control-h: backward-kill-word Text after the function name is ignored ++ ++ # ++ # Arrow keys in keypad mode ++ # ++ #"\M-OD": backward-char ++ #"\M-OC": forward-char ++ #"\M-OA": previous-history ++ #"\M-OB": next-history ++ # ++ # Arrow keys in ANSI mode ++ # ++ "\M-[D": backward-char ++ "\M-[C": forward-char ++ "\M-[A": previous-history ++ "\M-[B": next-history ++ # ++ # Arrow keys in 8 bit keypad mode ++ # ++ #"\M-\C-OD": backward-char ++ #"\M-\C-OC": forward-char ++ #"\M-\C-OA": previous-history ++ #"\M-\C-OB": next-history ++ # ++ # Arrow keys in 8 bit ANSI mode ++ # ++ #"\M-\C-[D": backward-char ++ #"\M-\C-[C": forward-char ++ #"\M-\C-[A": previous-history ++ #"\M-\C-[B": next-history ++ ++ C-q: quoted-insert ++ ++ $endif ++ ++ # An old-style binding. This happens to be the default. ++ TAB: complete ++ ++ # Macros that are convenient for shell interaction ++ $if Bash ++ # edit the path ++ "\C-xp": "PATH=${PATH}\e\C-e\C-a\ef\C-f" ++ # prepare to type a quoted word -- ++ # insert open and close double quotes ++ # and move to just after the open quote ++ "\C-x\"": "\"\"\C-b" ++ # insert a backslash (testing backslash escapes ++ # in sequences and macros) ++ "\C-x\\": "\\" ++ # Quote the current or previous word ++ "\C-xq": "\eb\"\ef\"" ++ # Add a binding to refresh the line, which is unbound ++ "\C-xr": redraw-current-line ++ # Edit variable on current line. ++ "\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" ++ $endif ++ ++ # use a visible bell if one is available ++ set bell-style visible ++ ++ # don't strip characters to 7 bits when reading ++ set input-meta on ++ ++ # allow iso-latin1 characters to be inserted rather ++ # than converted to prefix-meta sequences ++ set convert-meta off ++ ++ # display characters with the eighth bit set directly ++ # rather than as meta-prefixed characters ++ set output-meta on ++ ++ # if there are more than 150 possible completions for ++ # a word, ask the user if he wants to see all of them ++ set completion-query-items 150 ++ ++ # For FTP ++ $if Ftp ++ "\C-xg": "get \M-?" ++ "\C-xt": "put \M-?" ++ "\M-.": yank-last-arg ++ $endif ++ ++ ++File: gdb.info, Node: Bindable Readline Commands, Next: Readline vi Mode, Prev: Readline Init File, Up: Command Line Editing ++ ++32.4 Bindable Readline Commands ++=============================== ++ ++* Menu: ++ ++* Commands For Moving:: Moving about the line. ++* Commands For History:: Getting at previous lines. ++* Commands For Text:: Commands for changing text. ++* Commands For Killing:: Commands for killing and yanking. ++* Numeric Arguments:: Specifying numeric arguments, repeat counts. ++* Commands For Completion:: Getting Readline to do the typing for you. ++* Keyboard Macros:: Saving and re-executing typed characters ++* Miscellaneous Commands:: Other miscellaneous commands. ++ ++This section describes Readline commands that may be bound to key ++sequences. Command names without an accompanying key sequence are ++unbound by default. ++ ++ In the following descriptions, "point" refers to the current cursor ++position, and "mark" refers to a cursor position saved by the 'set-mark' ++command. The text between the point and mark is referred to as the ++"region". ++ ++ ++File: gdb.info, Node: Commands For Moving, Next: Commands For History, Up: Bindable Readline Commands ++ ++32.4.1 Commands For Moving ++-------------------------- ++ ++'beginning-of-line (C-a)' ++ Move to the start of the current line. ++ ++'end-of-line (C-e)' ++ Move to the end of the line. ++ ++'forward-char (C-f)' ++ Move forward a character. ++ ++'backward-char (C-b)' ++ Move back a character. ++ ++'forward-word (M-f)' ++ Move forward to the end of the next word. Words are composed of ++ letters and digits. ++ ++'backward-word (M-b)' ++ Move back to the start of the current or previous word. Words are ++ composed of letters and digits. ++ ++'previous-screen-line ()' ++ Attempt to move point to the same physical screen column on the ++ previous physical screen line. This will not have the desired ++ effect if the current Readline line does not take up more than one ++ physical line or if point is not greater than the length of the ++ prompt plus the screen width. ++ ++'next-screen-line ()' ++ Attempt to move point to the same physical screen column on the ++ next physical screen line. This will not have the desired effect ++ if the current Readline line does not take up more than one ++ physical line or if the length of the current Readline line is not ++ greater than the length of the prompt plus the screen width. ++ ++'clear-screen (C-l)' ++ Clear the screen and redraw the current line, leaving the current ++ line at the top of the screen. ++ ++'redraw-current-line ()' ++ Refresh the current line. By default, this is unbound. ++ ++ ++File: gdb.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands ++ ++32.4.2 Commands For Manipulating The History ++-------------------------------------------- ++ ++'accept-line (Newline or Return)' ++ Accept the line regardless of where the cursor is. If this line is ++ non-empty, it may be added to the history list for future recall ++ with 'add_history()'. If this line is a modified history line, the ++ history line is restored to its original state. ++ ++'previous-history (C-p)' ++ Move 'back' through the history list, fetching the previous ++ command. ++ ++'next-history (C-n)' ++ Move 'forward' through the history list, fetching the next command. ++ ++'beginning-of-history (M-<)' ++ Move to the first line in the history. ++ ++'end-of-history (M->)' ++ Move to the end of the input history, i.e., the line currently ++ being entered. ++ ++'reverse-search-history (C-r)' ++ Search backward starting at the current line and moving 'up' ++ through the history as necessary. This is an incremental search. ++ ++'forward-search-history (C-s)' ++ Search forward starting at the current line and moving 'down' ++ through the history as necessary. This is an incremental search. ++ ++'non-incremental-reverse-search-history (M-p)' ++ Search backward starting at the current line and moving 'up' ++ through the history as necessary using a non-incremental search for ++ a string supplied by the user. The search string may match ++ anywhere in a history line. ++ ++'non-incremental-forward-search-history (M-n)' ++ Search forward starting at the current line and moving 'down' ++ through the history as necessary using a non-incremental search for ++ a string supplied by the user. The search string may match ++ anywhere in a history line. ++ ++'history-search-forward ()' ++ Search forward through the history for the string of characters ++ between the start of the current line and the point. The search ++ string must match at the beginning of a history line. This is a ++ non-incremental search. By default, this command is unbound. ++ ++'history-search-backward ()' ++ Search backward through the history for the string of characters ++ between the start of the current line and the point. The search ++ string must match at the beginning of a history line. This is a ++ non-incremental search. By default, this command is unbound. ++ ++'history-substring-search-forward ()' ++ Search forward through the history for the string of characters ++ between the start of the current line and the point. The search ++ string may match anywhere in a history line. This is a ++ non-incremental search. By default, this command is unbound. ++ ++'history-substring-search-backward ()' ++ Search backward through the history for the string of characters ++ between the start of the current line and the point. The search ++ string may match anywhere in a history line. This is a ++ non-incremental search. By default, this command is unbound. ++ ++'yank-nth-arg (M-C-y)' ++ Insert the first argument to the previous command (usually the ++ second word on the previous line) at point. With an argument N, ++ insert the Nth word from the previous command (the words in the ++ previous command begin with word 0). A negative argument inserts ++ the Nth word from the end of the previous command. Once the ++ argument N is computed, the argument is extracted as if the '!N' ++ history expansion had been specified. ++ ++'yank-last-arg (M-. or M-_)' ++ Insert last argument to the previous command (the last word of the ++ previous history entry). With a numeric argument, behave exactly ++ like 'yank-nth-arg'. Successive calls to 'yank-last-arg' move back ++ through the history list, inserting the last word (or the word ++ specified by the argument to the first call) of each line in turn. ++ Any numeric argument supplied to these successive calls determines ++ the direction to move through the history. A negative argument ++ switches the direction through the history (back or forward). The ++ history expansion facilities are used to extract the last argument, ++ as if the '!$' history expansion had been specified. ++ ++ ++File: gdb.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands ++ ++32.4.3 Commands For Changing Text ++--------------------------------- ++ ++'end-of-file (usually C-d)' ++ The character indicating end-of-file as set, for example, by ++ 'stty'. If this character is read when there are no characters on ++ the line, and point is at the beginning of the line, Readline ++ interprets it as the end of input and returns EOF. ++ ++'delete-char (C-d)' ++ Delete the character at point. If this function is bound to the ++ same character as the tty EOF character, as 'C-d' commonly is, see ++ above for the effects. ++ ++'backward-delete-char (Rubout)' ++ Delete the character behind the cursor. A numeric argument means ++ to kill the characters instead of deleting them. ++ ++'forward-backward-delete-char ()' ++ Delete the character under the cursor, unless the cursor is at the ++ end of the line, in which case the character behind the cursor is ++ deleted. By default, this is not bound to a key. ++ ++'quoted-insert (C-q or C-v)' ++ Add the next character typed to the line verbatim. This is how to ++ insert key sequences like 'C-q', for example. ++ ++'tab-insert (M-)' ++ Insert a tab character. ++ ++'self-insert (a, b, A, 1, !, ...)' ++ Insert yourself. ++ ++'bracketed-paste-begin ()' ++ This function is intended to be bound to the "bracketed paste" ++ escape sequence sent by some terminals, and such a binding is ++ assigned by default. It allows Readline to insert the pasted text ++ as a single unit without treating each character as if it had been ++ read from the keyboard. The characters are inserted as if each one ++ was bound to 'self-insert' instead of executing any editing ++ commands. ++ ++'transpose-chars (C-t)' ++ Drag the character before the cursor forward over the character at ++ the cursor, moving the cursor forward as well. If the insertion ++ point is at the end of the line, then this transposes the last two ++ characters of the line. Negative arguments have no effect. ++ ++'transpose-words (M-t)' ++ Drag the word before point past the word after point, moving point ++ past that word as well. If the insertion point is at the end of ++ the line, this transposes the last two words on the line. ++ ++'upcase-word (M-u)' ++ Uppercase the current (or following) word. With a negative ++ argument, uppercase the previous word, but do not move the cursor. ++ ++'downcase-word (M-l)' ++ Lowercase the current (or following) word. With a negative ++ argument, lowercase the previous word, but do not move the cursor. ++ ++'capitalize-word (M-c)' ++ Capitalize the current (or following) word. With a negative ++ argument, capitalize the previous word, but do not move the cursor. ++ ++'overwrite-mode ()' ++ Toggle overwrite mode. With an explicit positive numeric argument, ++ switches to overwrite mode. With an explicit non-positive numeric ++ argument, switches to insert mode. This command affects only ++ 'emacs' mode; 'vi' mode does overwrite differently. Each call to ++ 'readline()' starts in insert mode. ++ ++ In overwrite mode, characters bound to 'self-insert' replace the ++ text at point rather than pushing the text to the right. ++ Characters bound to 'backward-delete-char' replace the character ++ before point with a space. ++ ++ By default, this command is unbound. ++ ++ ++File: gdb.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands ++ ++32.4.4 Killing And Yanking ++-------------------------- ++ ++'kill-line (C-k)' ++ Kill the text from point to the end of the line. ++ ++'backward-kill-line (C-x Rubout)' ++ Kill backward from the cursor to the beginning of the current line. ++ ++'unix-line-discard (C-u)' ++ Kill backward from the cursor to the beginning of the current line. ++ ++'kill-whole-line ()' ++ Kill all characters on the current line, no matter where point is. ++ By default, this is unbound. ++ ++'kill-word (M-d)' ++ Kill from point to the end of the current word, or if between ++ words, to the end of the next word. Word boundaries are the same ++ as 'forward-word'. ++ ++'backward-kill-word (M-)' ++ Kill the word behind point. Word boundaries are the same as ++ 'backward-word'. ++ ++'unix-word-rubout (C-w)' ++ Kill the word behind point, using white space as a word boundary. ++ The killed text is saved on the kill-ring. ++ ++'unix-filename-rubout ()' ++ Kill the word behind point, using white space and the slash ++ character as the word boundaries. The killed text is saved on the ++ kill-ring. ++ ++'delete-horizontal-space ()' ++ Delete all spaces and tabs around point. By default, this is ++ unbound. ++ ++'kill-region ()' ++ Kill the text in the current region. By default, this command is ++ unbound. ++ ++'copy-region-as-kill ()' ++ Copy the text in the region to the kill buffer, so it can be yanked ++ right away. By default, this command is unbound. ++ ++'copy-backward-word ()' ++ Copy the word before point to the kill buffer. The word boundaries ++ are the same as 'backward-word'. By default, this command is ++ unbound. ++ ++'copy-forward-word ()' ++ Copy the word following point to the kill buffer. The word ++ boundaries are the same as 'forward-word'. By default, this ++ command is unbound. ++ ++'yank (C-y)' ++ Yank the top of the kill ring into the buffer at point. ++ ++'yank-pop (M-y)' ++ Rotate the kill-ring, and yank the new top. You can only do this ++ if the prior command is 'yank' or 'yank-pop'. ++ ++ ++File: gdb.info, Node: Numeric Arguments, Next: Commands For Completion, Prev: Commands For Killing, Up: Bindable Readline Commands ++ ++32.4.5 Specifying Numeric Arguments ++----------------------------------- ++ ++'digit-argument (M-0, M-1, ... M--)' ++ Add this digit to the argument already accumulating, or start a new ++ argument. 'M--' starts a negative argument. ++ ++'universal-argument ()' ++ This is another way to specify an argument. If this command is ++ followed by one or more digits, optionally with a leading minus ++ sign, those digits define the argument. If the command is followed ++ by digits, executing 'universal-argument' again ends the numeric ++ argument, but is otherwise ignored. As a special case, if this ++ command is immediately followed by a character that is neither a ++ digit nor minus sign, the argument count for the next command is ++ multiplied by four. The argument count is initially one, so ++ executing this function the first time makes the argument count ++ four, a second time makes the argument count sixteen, and so on. ++ By default, this is not bound to a key. ++ ++ ++File: gdb.info, Node: Commands For Completion, Next: Keyboard Macros, Prev: Numeric Arguments, Up: Bindable Readline Commands ++ ++32.4.6 Letting Readline Type For You ++------------------------------------ ++ ++'complete ()' ++ Attempt to perform completion on the text before point. The actual ++ completion performed is application-specific. The default is ++ filename completion. ++ ++'possible-completions (M-?)' ++ List the possible completions of the text before point. When ++ displaying completions, Readline sets the number of columns used ++ for display to the value of 'completion-display-width', the value ++ of the environment variable 'COLUMNS', or the screen width, in that ++ order. ++ ++'insert-completions (M-*)' ++ Insert all completions of the text before point that would have ++ been generated by 'possible-completions'. ++ ++'menu-complete ()' ++ Similar to 'complete', but replaces the word to be completed with a ++ single match from the list of possible completions. Repeated ++ execution of 'menu-complete' steps through the list of possible ++ completions, inserting each match in turn. At the end of the list ++ of completions, the bell is rung (subject to the setting of ++ 'bell-style') and the original text is restored. An argument of N ++ moves N positions forward in the list of matches; a negative ++ argument may be used to move backward through the list. This ++ command is intended to be bound to , but is unbound by ++ default. ++ ++'menu-complete-backward ()' ++ Identical to 'menu-complete', but moves backward through the list ++ of possible completions, as if 'menu-complete' had been given a ++ negative argument. ++ ++'delete-char-or-list ()' ++ Deletes the character under the cursor if not at the beginning or ++ end of the line (like 'delete-char'). If at the end of the line, ++ behaves identically to 'possible-completions'. This command is ++ unbound by default. ++ ++ ++File: gdb.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands ++ ++32.4.7 Keyboard Macros ++---------------------- ++ ++'start-kbd-macro (C-x ()' ++ Begin saving the characters typed into the current keyboard macro. ++ ++'end-kbd-macro (C-x ))' ++ Stop saving the characters typed into the current keyboard macro ++ and save the definition. ++ ++'call-last-kbd-macro (C-x e)' ++ Re-execute the last keyboard macro defined, by making the ++ characters in the macro appear as if typed at the keyboard. ++ ++'print-last-kbd-macro ()' ++ Print the last keboard macro defined in a format suitable for the ++ INPUTRC file. ++ ++ ++File: gdb.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands ++ ++32.4.8 Some Miscellaneous Commands ++---------------------------------- ++ ++'re-read-init-file (C-x C-r)' ++ Read in the contents of the INPUTRC file, and incorporate any ++ bindings or variable assignments found there. ++ ++'abort (C-g)' ++ Abort the current editing command and ring the terminal's bell ++ (subject to the setting of 'bell-style'). ++ ++'do-lowercase-version (M-A, M-B, M-X, ...)' ++ If the metafied character X is upper case, run the command that is ++ bound to the corresponding metafied lower case character. The ++ behavior is undefined if X is already lower case. ++ ++'prefix-meta ()' ++ Metafy the next character typed. This is for keyboards without a ++ meta key. Typing ' f' is equivalent to typing 'M-f'. ++ ++'undo (C-_ or C-x C-u)' ++ Incremental undo, separately remembered for each line. ++ ++'revert-line (M-r)' ++ Undo all changes made to this line. This is like executing the ++ 'undo' command enough times to get back to the beginning. ++ ++'tilde-expand (M-~)' ++ Perform tilde expansion on the current word. ++ ++'set-mark (C-@)' ++ Set the mark to the point. If a numeric argument is supplied, the ++ mark is set to that position. ++ ++'exchange-point-and-mark (C-x C-x)' ++ Swap the point with the mark. The current cursor position is set ++ to the saved position, and the old cursor position is saved as the ++ mark. ++ ++'character-search (C-])' ++ A character is read and point is moved to the next occurrence of ++ that character. A negative count searches for previous ++ occurrences. ++ ++'character-search-backward (M-C-])' ++ A character is read and point is moved to the previous occurrence ++ of that character. A negative count searches for subsequent ++ occurrences. ++ ++'skip-csi-sequence ()' ++ Read enough characters to consume a multi-key sequence such as ++ those defined for keys like Home and End. Such sequences begin ++ with a Control Sequence Indicator (CSI), usually ESC-[. If this ++ sequence is bound to "\e[", keys producing such sequences will have ++ no effect unless explicitly bound to a readline command, instead of ++ inserting stray characters into the editing buffer. This is ++ unbound by default, but usually bound to ESC-[. ++ ++'insert-comment (M-#)' ++ Without a numeric argument, the value of the 'comment-begin' ++ variable is inserted at the beginning of the current line. If a ++ numeric argument is supplied, this command acts as a toggle: if the ++ characters at the beginning of the line do not match the value of ++ 'comment-begin', the value is inserted, otherwise the characters in ++ 'comment-begin' are deleted from the beginning of the line. In ++ either case, the line is accepted as if a newline had been typed. ++ ++'dump-functions ()' ++ Print all of the functions and their key bindings to the Readline ++ output stream. If a numeric argument is supplied, the output is ++ formatted in such a way that it can be made part of an INPUTRC ++ file. This command is unbound by default. ++ ++'dump-variables ()' ++ Print all of the settable variables and their values to the ++ Readline output stream. If a numeric argument is supplied, the ++ output is formatted in such a way that it can be made part of an ++ INPUTRC file. This command is unbound by default. ++ ++'dump-macros ()' ++ Print all of the Readline key sequences bound to macros and the ++ strings they output. If a numeric argument is supplied, the output ++ is formatted in such a way that it can be made part of an INPUTRC ++ file. This command is unbound by default. ++ ++'emacs-editing-mode (C-e)' ++ When in 'vi' command mode, this causes a switch to 'emacs' editing ++ mode. ++ ++'vi-editing-mode (M-C-j)' ++ When in 'emacs' editing mode, this causes a switch to 'vi' editing ++ mode. ++ ++ ++File: gdb.info, Node: Readline vi Mode, Prev: Bindable Readline Commands, Up: Command Line Editing ++ ++32.5 Readline vi Mode ++===================== ++ ++While the Readline library does not have a full set of 'vi' editing ++functions, it does contain enough to allow simple editing of the line. ++The Readline 'vi' mode behaves as specified in the POSIX standard. ++ ++ In order to switch interactively between 'emacs' and 'vi' editing ++modes, use the command 'M-C-j' (bound to emacs-editing-mode when in 'vi' ++mode and to vi-editing-mode in 'emacs' mode). The Readline default is ++'emacs' mode. ++ ++ When you enter a line in 'vi' mode, you are already placed in ++'insertion' mode, as if you had typed an 'i'. Pressing switches ++you into 'command' mode, where you can edit the text of the line with ++the standard 'vi' movement keys, move to previous history lines with 'k' ++and subsequent lines with 'j', and so forth. ++ ++ ++File: gdb.info, Node: Using History Interactively, Next: In Memoriam, Prev: Command Line Editing, Up: Top ++ ++33 Using History Interactively ++****************************** ++ ++This chapter describes how to use the GNU History Library interactively, ++from a user's standpoint. It should be considered a user's guide. For ++information on using the GNU History Library in your own programs, *note ++(history)Programming with GNU History::. ++ ++* Menu: ++ ++* History Interaction:: What it feels like using History as a user. ++ ++ ++File: gdb.info, Node: History Interaction, Up: Using History Interactively ++ ++33.1 History Expansion ++====================== ++ ++The History library provides a history expansion feature that is similar ++to the history expansion provided by 'csh'. This section describes the ++syntax used to manipulate the history information. ++ ++ History expansions introduce words from the history list into the ++input stream, making it easy to repeat commands, insert the arguments to ++a previous command into the current input line, or fix errors in ++previous commands quickly. ++ ++ History expansion takes place in two parts. The first is to ++determine which line from the history list should be used during ++substitution. The second is to select portions of that line for ++inclusion into the current one. The line selected from the history is ++called the "event", and the portions of that line that are acted upon ++are called "words". Various "modifiers" are available to manipulate the ++selected words. The line is broken into words in the same fashion that ++Bash does, so that several words surrounded by quotes are considered one ++word. History expansions are introduced by the appearance of the ++history expansion character, which is '!' by default. ++ ++ History expansion implements shell-like quoting conventions: a ++backslash can be used to remove the special handling for the next ++character; single quotes enclose verbatim sequences of characters, and ++can be used to inhibit history expansion; and characters enclosed within ++double quotes may be subject to history expansion, since backslash can ++escape the history expansion character, but single quotes may not, since ++they are not treated specially within double quotes. ++ ++* Menu: ++ ++* Event Designators:: How to specify which history line to use. ++* Word Designators:: Specifying which words are of interest. ++* Modifiers:: Modifying the results of substitution. ++ ++ ++File: gdb.info, Node: Event Designators, Next: Word Designators, Up: History Interaction ++ ++33.1.1 Event Designators ++------------------------ ++ ++An event designator is a reference to a command line entry in the ++history list. Unless the reference is absolute, events are relative to ++the current position in the history list. ++ ++'!' ++ Start a history substitution, except when followed by a space, tab, ++ the end of the line, or '='. ++ ++'!N' ++ Refer to command line N. ++ ++'!-N' ++ Refer to the command N lines back. ++ ++'!!' ++ Refer to the previous command. This is a synonym for '!-1'. ++ ++'!STRING' ++ Refer to the most recent command preceding the current position in ++ the history list starting with STRING. ++ ++'!?STRING[?]' ++ Refer to the most recent command preceding the current position in ++ the history list containing STRING. The trailing '?' may be ++ omitted if the STRING is followed immediately by a newline. ++ ++'^STRING1^STRING2^' ++ Quick Substitution. Repeat the last command, replacing STRING1 ++ with STRING2. Equivalent to '!!:s/STRING1/STRING2/'. ++ ++'!#' ++ The entire command line typed so far. ++ ++ ++File: gdb.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction ++ ++33.1.2 Word Designators ++----------------------- ++ ++Word designators are used to select desired words from the event. A ':' ++separates the event specification from the word designator. It may be ++omitted if the word designator begins with a '^', '$', '*', '-', or '%'. ++Words are numbered from the beginning of the line, with the first word ++being denoted by 0 (zero). Words are inserted into the current line ++separated by single spaces. ++ ++ For example, ++ ++'!!' ++ designates the preceding command. When you type this, the ++ preceding command is repeated in toto. ++ ++'!!:$' ++ designates the last argument of the preceding command. This may be ++ shortened to '!$'. ++ ++'!fi:2' ++ designates the second argument of the most recent command starting ++ with the letters 'fi'. ++ ++ Here are the word designators: ++ ++'0 (zero)' ++ The '0'th word. For many applications, this is the command word. ++ ++'N' ++ The Nth word. ++ ++'^' ++ The first argument; that is, word 1. ++ ++'$' ++ The last argument. ++ ++'%' ++ The word matched by the most recent '?STRING?' search. ++ ++'X-Y' ++ A range of words; '-Y' abbreviates '0-Y'. ++ ++'*' ++ All of the words, except the '0'th. This is a synonym for '1-$'. ++ It is not an error to use '*' if there is just one word in the ++ event; the empty string is returned in that case. ++ ++'X*' ++ Abbreviates 'X-$' ++ ++'X-' ++ Abbreviates 'X-$' like 'X*', but omits the last word. ++ ++ If a word designator is supplied without an event specification, the ++previous command is used as the event. ++ ++ ++File: gdb.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction ++ ++33.1.3 Modifiers ++---------------- ++ ++After the optional word designator, you can add a sequence of one or ++more of the following modifiers, each preceded by a ':'. ++ ++'h' ++ Remove a trailing pathname component, leaving only the head. ++ ++'t' ++ Remove all leading pathname components, leaving the tail. ++ ++'r' ++ Remove a trailing suffix of the form '.SUFFIX', leaving the ++ basename. ++ ++'e' ++ Remove all but the trailing suffix. ++ ++'p' ++ Print the new command but do not execute it. ++ ++'s/OLD/NEW/' ++ Substitute NEW for the first occurrence of OLD in the event line. ++ Any delimiter may be used in place of '/'. The delimiter may be ++ quoted in OLD and NEW with a single backslash. If '&' appears in ++ NEW, it is replaced by OLD. A single backslash will quote the '&'. ++ The final delimiter is optional if it is the last character on the ++ input line. ++ ++'&' ++ Repeat the previous substitution. ++ ++'g' ++'a' ++ Cause changes to be applied over the entire event line. Used in ++ conjunction with 's', as in 'gs/OLD/NEW/', or with '&'. ++ ++'G' ++ Apply the following 's' modifier once to each word in the event. ++ ++ ++File: gdb.info, Node: In Memoriam, Next: Formatting Documentation, Prev: Using History Interactively, Up: Top ++ ++Appendix A In Memoriam ++********************** ++ ++The GDB project mourns the loss of the following long-time contributors: ++ ++'Fred Fish' ++ Fred was a long-standing contributor to GDB (1991-2006), and to ++ Free Software in general. Outside of GDB, he was known in the ++ Amiga world for his series of Fish Disks, and the GeekGadget ++ project. ++ ++'Michael Snyder' ++ Michael was one of the Global Maintainers of the GDB project, with ++ contributions recorded as early as 1996, until 2011. In addition ++ to his day to day participation, he was a large driving force ++ behind adding Reverse Debugging to GDB. ++ ++ Beyond their technical contributions to the project, they were also ++enjoyable members of the Free Software Community. We will miss them. ++ ++ ++File: gdb.info, Node: Formatting Documentation, Next: Installing GDB, Prev: In Memoriam, Up: Top ++ ++Appendix B Formatting Documentation ++*********************************** ++ ++The GDB 4 release includes an already-formatted reference card, ready ++for printing with PostScript or Ghostscript, in the 'gdb' subdirectory ++of the main source directory(1). If you can use PostScript or ++Ghostscript with your printer, you can print the reference card ++immediately with 'refcard.ps'. ++ ++ The release also includes the source for the reference card. You can ++format it, using TeX, by typing: ++ ++ make refcard.dvi ++ ++ The GDB reference card is designed to print in "landscape" mode on US ++"letter" size paper; that is, on a sheet 11 inches wide by 8.5 inches ++high. You will need to specify this form of printing as an option to ++your DVI output program. ++ ++ All the documentation for GDB comes as part of the machine-readable ++distribution. The documentation is written in Texinfo format, which is ++a documentation system that uses a single source file to produce both ++on-line information and a printed manual. You can use one of the Info ++formatting commands to create the on-line version of the documentation ++and TeX (or 'texi2roff') to typeset the printed version. ++ ++ GDB includes an already formatted copy of the on-line Info version of ++this manual in the 'gdb' subdirectory. The main Info file is ++'gdb-10.1/gdb/gdb.info', and it refers to subordinate files matching ++'gdb.info*' in the same directory. If necessary, you can print out ++these files, or read them with any editor; but they are easier to read ++using the 'info' subsystem in GNU Emacs or the standalone 'info' ++program, available as part of the GNU Texinfo distribution. ++ ++ If you want to format these Info files yourself, you need one of the ++Info formatting programs, such as 'texinfo-format-buffer' or 'makeinfo'. ++ ++ If you have 'makeinfo' installed, and are in the top level GDB source ++directory ('gdb-10.1', in the case of version 10.1), you can make the ++Info file by typing: ++ ++ cd gdb ++ make gdb.info ++ ++ If you want to typeset and print copies of this manual, you need TeX, ++a program to print its DVI output files, and 'texinfo.tex', the Texinfo ++definitions file. ++ ++ TeX is a typesetting program; it does not print files directly, but ++produces output files called DVI files. To print a typeset document, ++you need a program to print DVI files. If your system has TeX ++installed, chances are it has such a program. The precise command to ++use depends on your system; 'lpr -d' is common; another (for PostScript ++devices) is 'dvips'. The DVI print command may require a file name ++without any extension or a '.dvi' extension. ++ ++ TeX also requires a macro definitions file called 'texinfo.tex'. ++This file tells TeX how to typeset a document written in Texinfo format. ++On its own, TeX cannot either read or typeset a Texinfo file. ++'texinfo.tex' is distributed with GDB and is located in the ++'gdb-VERSION-NUMBER/texinfo' directory. ++ ++ If you have TeX and a DVI printer program installed, you can typeset ++and print this manual. First switch to the 'gdb' subdirectory of the ++main source directory (for example, to 'gdb-10.1/gdb') and type: ++ ++ make gdb.dvi ++ ++ Then give 'gdb.dvi' to your DVI printing program. ++ ++ ---------- Footnotes ---------- ++ ++ (1) In 'gdb-10.1/gdb/refcard.ps' of the version 10.1 release. ++ ++ ++File: gdb.info, Node: Installing GDB, Next: Maintenance Commands, Prev: Formatting Documentation, Up: Top ++ ++Appendix C Installing GDB ++************************* ++ ++* Menu: ++ ++* Requirements:: Requirements for building GDB ++* Running Configure:: Invoking the GDB 'configure' script ++* Separate Objdir:: Compiling GDB in another directory ++* Config Names:: Specifying names for hosts and targets ++* Configure Options:: Summary of options for configure ++* System-wide configuration:: Having a system-wide init file ++ ++ ++File: gdb.info, Node: Requirements, Next: Running Configure, Up: Installing GDB ++ ++C.1 Requirements for Building GDB ++================================= ++ ++Building GDB requires various tools and packages to be available. Other ++packages will be used only if they are found. ++ ++Tools/Packages Necessary for Building GDB ++========================================= ++ ++C++11 compiler ++ GDB is written in C++11. It should be buildable with any recent ++ C++11 compiler, e.g. GCC. ++ ++GNU make ++ GDB's build system relies on features only found in the GNU make ++ program. Other variants of 'make' will not work. ++ ++Tools/Packages Optional for Building GDB ++======================================== ++ ++Expat ++ GDB can use the Expat XML parsing library. This library may be ++ included with your operating system distribution; if it is not, you ++ can get the latest version from . ++ The 'configure' script will search for this library in several ++ standard locations; if it is installed in an unusual path, you can ++ use the '--with-libexpat-prefix' option to specify its location. ++ ++ Expat is used for: ++ ++ * Remote protocol memory maps (*note Memory Map Format::) ++ * Target descriptions (*note Target Descriptions::) ++ * Remote shared library lists (*Note Library List Format::, or ++ alternatively *note Library List Format for SVR4 Targets::) ++ * MS-Windows shared libraries (*note Shared Libraries::) ++ * Traceframe info (*note Traceframe Info Format::) ++ * Branch trace (*note Branch Trace Format::, *note Branch Trace ++ Configuration Format::) ++ ++Guile ++ GDB can be scripted using GNU Guile. *Note Guile::. By default, ++ GDB will be compiled if the Guile libraries are installed and are ++ found by 'configure'. You can use the '--with-guile' option to ++ request Guile, and pass either the Guile version number or the file ++ name of the relevant 'pkg-config' program to choose a particular ++ version of Guile. ++ ++iconv ++ GDB's features related to character sets (*note Character Sets::) ++ require a functioning 'iconv' implementation. If you are on a GNU ++ system, then this is provided by the GNU C Library. Some other ++ systems also provide a working 'iconv'. ++ ++ If GDB is using the 'iconv' program which is installed in a ++ non-standard place, you will need to tell GDB where to find it. ++ This is done with '--with-iconv-bin' which specifies the directory ++ that contains the 'iconv' program. This program is run in order to ++ make a list of the available character sets. ++ ++ On systems without 'iconv', you can install GNU Libiconv. If ++ Libiconv is installed in a standard place, GDB will automatically ++ use it if it is needed. If you have previously installed Libiconv ++ in a non-standard place, you can use the '--with-libiconv-prefix' ++ option to 'configure'. ++ ++ GDB's top-level 'configure' and 'Makefile' will arrange to build ++ Libiconv if a directory named 'libiconv' appears in the top-most ++ source directory. If Libiconv is built this way, and if the ++ operating system does not provide a suitable 'iconv' ++ implementation, then the just-built library will automatically be ++ used by GDB. One easy way to set this up is to download GNU ++ Libiconv, unpack it inside the top-level directory of the GDB ++ source tree, and then rename the directory holding the Libiconv ++ source code to 'libiconv'. ++ ++lzma ++ GDB can support debugging sections that are compressed with the ++ LZMA library. *Note MiniDebugInfo::. If this library is not ++ included with your operating system, you can find it in the xz ++ package at . If the LZMA library is ++ available in the usual place, then the 'configure' script will use ++ it automatically. If it is installed in an unusual path, you can ++ use the '--with-lzma-prefix' option to specify its location. ++ ++MPFR ++ GDB can use the GNU MPFR multiple-precision floating-point library. ++ This library may be included with your operating system ++ distribution; if it is not, you can get the latest version from ++ . The 'configure' script will search for this ++ library in several standard locations; if it is installed in an ++ unusual path, you can use the '--with-libmpfr-prefix' option to ++ specify its location. ++ ++ GNU MPFR is used to emulate target floating-point arithmetic during ++ expression evaluation when the target uses different floating-point ++ formats than the host. If GNU MPFR it is not available, GDB will ++ fall back to using host floating-point arithmetic. ++ ++Python ++ GDB can be scripted using Python language. *Note Python::. By ++ default, GDB will be compiled if the Python libraries are installed ++ and are found by 'configure'. You can use the '--with-python' ++ option to request Python, and pass either the file name of the ++ relevant 'python' executable, or the name of the directory in which ++ Python is installed, to choose a particular installation of Python. ++ ++zlib ++ GDB will use the 'zlib' library, if available, to read compressed ++ debug sections. Some linkers, such as GNU gold, are capable of ++ producing binaries with compressed debug sections. If GDB is ++ compiled with 'zlib', it will be able to read the debug information ++ in such binaries. ++ ++ The 'zlib' library is likely included with your operating system ++ distribution; if it is not, you can get the latest version from ++ . ++ ++ ++File: gdb.info, Node: Running Configure, Next: Separate Objdir, Prev: Requirements, Up: Installing GDB ++ ++C.2 Invoking the GDB 'configure' Script ++======================================= ++ ++GDB comes with a 'configure' script that automates the process of ++preparing GDB for installation; you can then use 'make' to build the ++'gdb' program. ++ ++ The GDB distribution includes all the source code you need for GDB in ++a single directory, whose name is usually composed by appending the ++version number to 'gdb'. ++ ++ For example, the GDB version 10.1 distribution is in the 'gdb-10.1' ++directory. That directory contains: ++ ++'gdb-10.1/configure (and supporting files)' ++ script for configuring GDB and all its supporting libraries ++ ++'gdb-10.1/gdb' ++ the source specific to GDB itself ++ ++'gdb-10.1/bfd' ++ source for the Binary File Descriptor library ++ ++'gdb-10.1/include' ++ GNU include files ++ ++'gdb-10.1/libiberty' ++ source for the '-liberty' free software library ++ ++'gdb-10.1/opcodes' ++ source for the library of opcode tables and disassemblers ++ ++'gdb-10.1/readline' ++ source for the GNU command-line interface ++ ++ There may be other subdirectories as well. ++ ++ The simplest way to configure and build GDB is to run 'configure' ++from the 'gdb-VERSION-NUMBER' source directory, which in this example is ++the 'gdb-10.1' directory. ++ ++ First switch to the 'gdb-VERSION-NUMBER' source directory if you are ++not already in it; then run 'configure'. Pass the identifier for the ++platform on which GDB will run as an argument. ++ ++ For example: ++ ++ cd gdb-10.1 ++ ./configure ++ make ++ ++ Running 'configure' and then running 'make' builds the included ++supporting libraries, then 'gdb' itself. The configured source files, ++and the binaries, are left in the corresponding source directories. ++ ++ 'configure' is a Bourne-shell ('/bin/sh') script; if your system does ++not recognize this automatically when you run a different shell, you may ++need to run 'sh' on it explicitly: ++ ++ sh configure ++ ++ You should run the 'configure' script from the top directory in the ++source tree, the 'gdb-VERSION-NUMBER' directory. If you run 'configure' ++from one of the subdirectories, you will configure only that ++subdirectory. That is usually not what you want. In particular, if you ++run the first 'configure' from the 'gdb' subdirectory of the ++'gdb-VERSION-NUMBER' directory, you will omit the configuration of ++'bfd', 'readline', and other sibling directories of the 'gdb' ++subdirectory. This leads to build errors about missing include files ++such as 'bfd/bfd.h'. ++ ++ You can install 'GDB' anywhere. The best way to do this is to pass ++the '--prefix' option to 'configure', and then install it with 'make ++install'. ++ ++ ++File: gdb.info, Node: Separate Objdir, Next: Config Names, Prev: Running Configure, Up: Installing GDB ++ ++C.3 Compiling GDB in Another Directory ++====================================== ++ ++If you want to run GDB versions for several host or target machines, you ++need a different 'gdb' compiled for each combination of host and target. ++'configure' is designed to make this easy by allowing you to generate ++each configuration in a separate subdirectory, rather than in the source ++directory. If your 'make' program handles the 'VPATH' feature (GNU ++'make' does), running 'make' in each of these directories builds the ++'gdb' program specified there. ++ ++ To build 'gdb' in a separate directory, run 'configure' with the ++'--srcdir' option to specify where to find the source. (You also need ++to specify a path to find 'configure' itself from your working ++directory. If the path to 'configure' would be the same as the argument ++to '--srcdir', you can leave out the '--srcdir' option; it is assumed.) ++ ++ For example, with version 10.1, you can build GDB in a separate ++directory for a Sun 4 like this: ++ ++ cd gdb-10.1 ++ mkdir ../gdb-sun4 ++ cd ../gdb-sun4 ++ ../gdb-10.1/configure ++ make ++ ++ When 'configure' builds a configuration using a remote source ++directory, it creates a tree for the binaries with the same structure ++(and using the same names) as the tree under the source directory. In ++the example, you'd find the Sun 4 library 'libiberty.a' in the directory ++'gdb-sun4/libiberty', and GDB itself in 'gdb-sun4/gdb'. ++ ++ Make sure that your path to the 'configure' script has just one ++instance of 'gdb' in it. If your path to 'configure' looks like ++'../gdb-10.1/gdb/configure', you are configuring only one subdirectory ++of GDB, not the whole package. This leads to build errors about missing ++include files such as 'bfd/bfd.h'. ++ ++ One popular reason to build several GDB configurations in separate ++directories is to configure GDB for cross-compiling (where GDB runs on ++one machine--the "host"--while debugging programs that run on another ++machine--the "target"). You specify a cross-debugging target by giving ++the '--target=TARGET' option to 'configure'. ++ ++ When you run 'make' to build a program or library, you must run it in ++a configured directory--whatever directory you were in when you called ++'configure' (or one of its subdirectories). ++ ++ The 'Makefile' that 'configure' generates in each source directory ++also runs recursively. If you type 'make' in a source directory such as ++'gdb-10.1' (or in a separate configured directory configured with ++'--srcdir=DIRNAME/gdb-10.1'), you will build all the required libraries, ++and then build GDB. ++ ++ When you have multiple hosts or targets configured in separate ++directories, you can run 'make' on them in parallel (for example, if ++they are NFS-mounted on each of the hosts); they will not interfere with ++each other. ++ ++ ++File: gdb.info, Node: Config Names, Next: Configure Options, Prev: Separate Objdir, Up: Installing GDB ++ ++C.4 Specifying Names for Hosts and Targets ++========================================== ++ ++The specifications used for hosts and targets in the 'configure' script ++are based on a three-part naming scheme, but some short predefined ++aliases are also supported. The full naming scheme encodes three pieces ++of information in the following pattern: ++ ++ ARCHITECTURE-VENDOR-OS ++ ++ For example, you can use the alias 'sun4' as a HOST argument, or as ++the value for TARGET in a '--target=TARGET' option. The equivalent full ++name is 'sparc-sun-sunos4'. ++ ++ The 'configure' script accompanying GDB does not provide any query ++facility to list all supported host and target names or aliases. ++'configure' calls the Bourne shell script 'config.sub' to map ++abbreviations to full names; you can read the script, if you wish, or ++you can use it to test your guesses on abbreviations--for example: ++ ++ % sh config.sub i386-linux ++ i386-pc-linux-gnu ++ % sh config.sub alpha-linux ++ alpha-unknown-linux-gnu ++ % sh config.sub sw_64-linux ++ sw_64-unknown-linux-gnu ++ % sh config.sub hp9k700 ++ hppa1.1-hp-hpux ++ % sh config.sub sun4 ++ sparc-sun-sunos4.1.1 ++ % sh config.sub sun3 ++ m68k-sun-sunos4.1.1 ++ % sh config.sub i986v ++ Invalid configuration `i986v': machine `i986v' not recognized ++ ++'config.sub' is also distributed in the GDB source directory ++('gdb-10.1', for version 10.1). ++ ++ ++File: gdb.info, Node: Configure Options, Next: System-wide configuration, Prev: Config Names, Up: Installing GDB ++ ++C.5 'configure' Options ++======================= ++ ++Here is a summary of the 'configure' options and arguments that are most ++often useful for building GDB. 'configure' also has several other ++options not listed here. *note (autoconf.info)Running configure ++scripts::, for a full explanation of 'configure'. ++ ++ configure [--help] ++ [--prefix=DIR] ++ [--exec-prefix=DIR] ++ [--srcdir=DIRNAME] ++ [--target=TARGET] ++ ++You may introduce options with a single '-' rather than '--' if you ++prefer; but you may abbreviate option names if you use '--'. ++ ++'--help' ++ Display a quick summary of how to invoke 'configure'. ++ ++'--prefix=DIR' ++ Configure the source to install programs and files under directory ++ 'DIR'. ++ ++'--exec-prefix=DIR' ++ Configure the source to install programs under directory 'DIR'. ++ ++'--srcdir=DIRNAME' ++ Use this option to make configurations in directories separate from ++ the GDB source directories. Among other things, you can use this ++ to build (or maintain) several configurations simultaneously, in ++ separate directories. 'configure' writes configuration-specific ++ files in the current directory, but arranges for them to use the ++ source in the directory DIRNAME. 'configure' creates directories ++ under the working directory in parallel to the source directories ++ below DIRNAME. ++ ++'--target=TARGET' ++ Configure GDB for cross-debugging programs running on the specified ++ TARGET. Without this option, GDB is configured to debug programs ++ that run on the same machine (HOST) as GDB itself. ++ ++ There is no convenient way to generate a list of all available ++ targets. Also see the '--enable-targets' option, below. ++ ++ There are many other options that are specific to GDB. This lists ++just the most common ones; there are some very specialized options not ++described here. ++ ++'--enable-targets=[TARGET]...' ++'--enable-targets=all' ++ Configure GDB for cross-debugging programs running on the specified ++ list of targets. The special value 'all' configures GDB for ++ debugging programs running on any target it supports. ++ ++'--with-gdb-datadir=PATH' ++ Set the GDB-specific data directory. GDB will look here for ++ certain supporting files or scripts. This defaults to the 'gdb' ++ subdirectory of 'datadir' (which can be set using '--datadir'). ++ ++'--with-relocated-sources=DIR' ++ Sets up the default source path substitution rule so that directory ++ names recorded in debug information will be automatically adjusted ++ for any directory under DIR. DIR should be a subdirectory of GDB's ++ configured prefix, the one mentioned in the '--prefix' or ++ '--exec-prefix' options to configure. This option is useful if GDB ++ is supposed to be moved to a different place after it is built. ++ ++'--enable-64-bit-bfd' ++ Enable 64-bit support in BFD on 32-bit hosts. ++ ++'--disable-gdbmi' ++ Build GDB without the GDB/MI machine interface (*note GDB/MI::). ++ ++'--enable-tui' ++ Build GDB with the text-mode full-screen user interface (TUI). ++ Requires a curses library (ncurses and cursesX are also supported). ++ ++'--with-curses' ++ Use the curses library instead of the termcap library, for ++ text-mode terminal operations. ++ ++'--with-debuginfod' ++ Build GDB with libdebuginfod, the debuginfod client library. Used ++ to automatically fetch source files and separate debug files from ++ debuginfod servers using the associated executable's build ID. ++ Enabled by default if libdebuginfod is installed and found at ++ configure time. debuginfod is packaged with elfutils, starting ++ with version 0.178. You can get the latest version from ++ 'https://sourceware.org/elfutils/'. ++ ++'--with-libunwind-ia64' ++ Use the libunwind library for unwinding function call stack on ia64 ++ target platforms. See http://www.nongnu.org/libunwind/index.html ++ for details. ++ ++'--with-system-readline' ++ Use the readline library installed on the host, rather than the ++ library supplied as part of GDB. Readline 7 or newer is required; ++ this is enforced by the build system. ++ ++'--with-system-zlib' ++ Use the zlib library installed on the host, rather than the library ++ supplied as part of GDB. ++ ++'--with-expat' ++ Build GDB with Expat, a library for XML parsing. (Done by default ++ if libexpat is installed and found at configure time.) This ++ library is used to read XML files supplied with GDB. If it is ++ unavailable, some features, such as remote protocol memory maps, ++ target descriptions, and shared library lists, that are based on ++ XML files, will not be available in GDB. If your host does not ++ have libexpat installed, you can get the latest version from ++ 'http://expat.sourceforge.net'. ++ ++'--with-libiconv-prefix[=DIR]' ++ ++ Build GDB with GNU libiconv, a character set encoding conversion ++ library. This is not done by default, as on GNU systems the ++ 'iconv' that is built in to the C library is sufficient. If your ++ host does not have a working 'iconv', you can get the latest ++ version of GNU iconv from 'https://www.gnu.org/software/libiconv/'. ++ ++ GDB's build system also supports building GNU libiconv as part of ++ the overall build. *Note Requirements::. ++ ++'--with-lzma' ++ Build GDB with LZMA, a compression library. (Done by default if ++ liblzma is installed and found at configure time.) LZMA is used by ++ GDB's "mini debuginfo" feature, which is only useful on platforms ++ using the ELF object file format. If your host does not have ++ liblzma installed, you can get the latest version from ++ 'https://tukaani.org/xz/'. ++ ++'--with-mpfr' ++ Build GDB with GNU MPFR, a library for multiple-precision ++ floating-point computation with correct rounding. (Done by default ++ if GNU MPFR is installed and found at configure time.) This ++ library is used to emulate target floating-point arithmetic during ++ expression evaluation when the target uses different floating-point ++ formats than the host. If GNU MPFR is not available, GDB will fall ++ back to using host floating-point arithmetic. If your host does ++ not have GNU MPFR installed, you can get the latest version from ++ 'http://www.mpfr.org'. ++ ++'--with-python[=PYTHON]' ++ Build GDB with Python scripting support. (Done by default if ++ libpython is present and found at configure time.) Python makes ++ GDB scripting much more powerful than the restricted CLI scripting ++ language. If your host does not have Python installed, you can ++ find it on 'http://www.python.org/download/'. The oldest version ++ of Python supported by GDB is 2.6. The optional argument PYTHON is ++ used to find the Python headers and libraries. It can be either ++ the name of a Python executable, or the name of the directory in ++ which Python is installed. ++ ++'--with-guile[=GUILE]'' ++ Build GDB with GNU Guile scripting support. (Done by default if ++ libguile is present and found at configure time.) If your host ++ does not have Guile installed, you can find it at ++ 'https://www.gnu.org/software/guile/'. The optional argument GUILE ++ can be a version number, which will cause 'configure' to try to use ++ that version of Guile; or the file name of a 'pkg-config' ++ executable, which will be queried to find the information needed to ++ compile and link against Guile. ++ ++'--without-included-regex' ++ Don't use the regex library included with GDB (as part of the ++ libiberty library). This is the default on hosts with version 2 of ++ the GNU C library. ++ ++'--with-sysroot=DIR' ++ Use DIR as the default system root directory for libraries whose ++ file names begin with '/lib'' or '/usr/lib''. (The value of DIR ++ can be modified at run time by using the 'set sysroot' command.) ++ If DIR is under the GDB configured prefix (set with '--prefix' or ++ '--exec-prefix options', the default system root will be ++ automatically adjusted if and when GDB is moved to a different ++ location. ++ ++'--with-system-gdbinit=FILE' ++ Configure GDB to automatically load a system-wide init file. FILE ++ should be an absolute file name. If FILE is in a directory under ++ the configured prefix, and GDB is moved to another location after ++ being built, the location of the system-wide init file will be ++ adjusted accordingly. ++ ++'--with-system-gdbinit-dir=DIRECTORY' ++ Configure GDB to automatically load init files from a system-wide ++ directory. DIRECTORY should be an absolute directory name. If ++ DIRECTORY is in a directory under the configured prefix, and GDB is ++ moved to another location after being built, the location of the ++ system-wide init directory will be adjusted accordingly. ++ ++'--enable-build-warnings' ++ When building the GDB sources, ask the compiler to warn about any ++ code which looks even vaguely suspicious. It passes many different ++ warning flags, depending on the exact version of the compiler you ++ are using. ++ ++'--enable-werror' ++ Treat compiler warnings as werrors. It adds the '-Werror' flag to ++ the compiler, which will fail the compilation if the compiler ++ outputs any warning messages. ++ ++'--enable-ubsan' ++ Enable the GCC undefined behavior sanitizer. This is disabled by ++ default, but passing '--enable-ubsan=yes' or '--enable-ubsan=auto' ++ to 'configure' will enable it. The undefined behavior sanitizer ++ checks for C++ undefined behavior. It has a performance cost, so ++ if you are looking at GDB's performance, you should disable it. ++ The undefined behavior sanitizer was first introduced in GCC 4.9. ++ ++ ++File: gdb.info, Node: System-wide configuration, Prev: Configure Options, Up: Installing GDB ++ ++C.6 System-wide configuration and settings ++========================================== ++ ++GDB can be configured to have a system-wide init file and a system-wide ++init file directory; this file and files in that directory (if they have ++a recognized file extension) will be read and executed at startup (*note ++What GDB does during startup: Startup.). ++ ++ Here are the corresponding configure options: ++ ++'--with-system-gdbinit=FILE' ++ Specify that the default location of the system-wide init file is ++ FILE. ++'--with-system-gdbinit-dir=DIRECTORY' ++ Specify that the default location of the system-wide init file ++ directory is DIRECTORY. ++ ++ If GDB has been configured with the option '--prefix=$prefix', they ++may be subject to relocation. Two possible cases: ++ ++ * If the default location of this init file/directory contains ++ '$prefix', it will be subject to relocation. Suppose that the ++ configure options are '--prefix=$prefix ++ --with-system-gdbinit=$prefix/etc/gdbinit'; if GDB is moved from ++ '$prefix' to '$install', the system init file is looked for as ++ '$install/etc/gdbinit' instead of '$prefix/etc/gdbinit'. ++ ++ * By contrast, if the default location does not contain the prefix, ++ it will not be relocated. E.g. if GDB has been configured with ++ '--prefix=/usr/local --with-system-gdbinit=/usr/share/gdb/gdbinit', ++ then GDB will always look for '/usr/share/gdb/gdbinit', wherever ++ GDB is installed. ++ ++ If the configured location of the system-wide init file (as given by ++the '--with-system-gdbinit' option at configure time) is in the ++data-directory (as specified by '--with-gdb-datadir' at configure time) ++or in one of its subdirectories, then GDB will look for the system-wide ++init file in the directory specified by the '--data-directory' ++command-line option. Note that the system-wide init file is only read ++once, during GDB initialization. If the data-directory is changed after ++GDB has started with the 'set data-directory' command, the file will not ++be reread. ++ ++ This applies similarly to the system-wide directory specified in ++'--with-system-gdbinit-dir'. ++ ++ Any supported scripting language can be used for these init files, as ++long as the file extension matches the scripting language. To be ++interpreted as regular GDB commands, the files needs to have a '.gdb' ++extension. ++ ++* Menu: ++ ++* System-wide Configuration Scripts:: Installed System-wide Configuration Scripts ++ ++ ++File: gdb.info, Node: System-wide Configuration Scripts, Up: System-wide configuration ++ ++C.6.1 Installed System-wide Configuration Scripts ++------------------------------------------------- ++ ++The 'system-gdbinit' directory, located inside the data-directory (as ++specified by '--with-gdb-datadir' at configure time) contains a number ++of scripts which can be used as system-wide init files. To ++automatically source those scripts at startup, GDB should be configured ++with '--with-system-gdbinit'. Otherwise, any user should be able to ++source them by hand as needed. ++ ++ The following scripts are currently available: ++ ++ * 'elinos.py' This script is useful when debugging a program on an ++ ELinOS target. It takes advantage of the environment variables ++ defined in a standard ELinOS environment in order to determine the ++ location of the system shared libraries, and then sets the ++ 'solib-absolute-prefix' and 'solib-search-path' variables ++ appropriately. ++ ++ * 'wrs-linux.py' This script is useful when debugging a program on a ++ target running Wind River Linux. It expects the 'ENV_PREFIX' to be ++ set to the host-side sysroot used by the target system. ++ ++ ++File: gdb.info, Node: Maintenance Commands, Next: Remote Protocol, Prev: Installing GDB, Up: Top ++ ++Appendix D Maintenance Commands ++******************************* ++ ++In addition to commands intended for GDB users, GDB includes a number of ++commands intended for GDB developers, that are not documented elsewhere ++in this manual. These commands are provided here for reference. (For ++commands that turn on debugging messages, see *note Debugging Output::.) ++ ++'maint agent [-at LOCATION,] EXPRESSION' ++'maint agent-eval [-at LOCATION,] EXPRESSION' ++ Translate the given EXPRESSION into remote agent bytecodes. This ++ command is useful for debugging the Agent Expression mechanism ++ (*note Agent Expressions::). The 'agent' version produces an ++ expression useful for data collection, such as by tracepoints, ++ while 'maint agent-eval' produces an expression that evaluates ++ directly to a result. For instance, a collection expression for ++ 'globa + globb' will include bytecodes to record four bytes of ++ memory at each of the addresses of 'globa' and 'globb', while ++ discarding the result of the addition, while an evaluation ++ expression will do the addition and return the sum. If '-at' is ++ given, generate remote agent bytecode for LOCATION. If not, ++ generate remote agent bytecode for current frame PC address. ++ ++'maint agent-printf FORMAT,EXPR,...' ++ Translate the given format string and list of argument expressions ++ into remote agent bytecodes and display them as a disassembled ++ list. This command is useful for debugging the agent version of ++ dynamic printf (*note Dynamic Printf::). ++ ++'maint info breakpoints' ++ Using the same format as 'info breakpoints', display both the ++ breakpoints you've set explicitly, and those GDB is using for ++ internal purposes. Internal breakpoints are shown with negative ++ breakpoint numbers. The type column identifies what kind of ++ breakpoint is shown: ++ ++ 'breakpoint' ++ Normal, explicitly set breakpoint. ++ ++ 'watchpoint' ++ Normal, explicitly set watchpoint. ++ ++ 'longjmp' ++ Internal breakpoint, used to handle correctly stepping through ++ 'longjmp' calls. ++ ++ 'longjmp resume' ++ Internal breakpoint at the target of a 'longjmp'. ++ ++ 'until' ++ Temporary internal breakpoint used by the GDB 'until' command. ++ ++ 'finish' ++ Temporary internal breakpoint used by the GDB 'finish' ++ command. ++ ++ 'shlib events' ++ Shared library events. ++ ++'maint info btrace' ++ Pint information about raw branch tracing data. ++ ++'maint btrace packet-history' ++ Print the raw branch trace packets that are used to compute the ++ execution history for the 'record btrace' command. Both the ++ information and the format in which it is printed depend on the ++ btrace recording format. ++ ++ 'bts' ++ For the BTS recording format, print a list of blocks of ++ sequential code. For each block, the following information is ++ printed: ++ ++ Block number ++ Newer blocks have higher numbers. The oldest block has ++ number zero. ++ Lowest 'PC' ++ Highest 'PC' ++ ++ 'pt' ++ For the Intel Processor Trace recording format, print a list ++ of Intel Processor Trace packets. For each packet, the ++ following information is printed: ++ ++ Packet number ++ Newer packets have higher numbers. The oldest packet has ++ number zero. ++ Trace offset ++ The packet's offset in the trace stream. ++ Packet opcode and payload ++ ++'maint btrace clear-packet-history' ++ Discards the cached packet history printed by the 'maint btrace ++ packet-history' command. The history will be computed again when ++ needed. ++ ++'maint btrace clear' ++ Discard the branch trace data. The data will be fetched anew and ++ the branch trace will be recomputed when needed. ++ ++ This implicitly truncates the branch trace to a single branch trace ++ buffer. When updating branch trace incrementally, the branch trace ++ available to GDB may be bigger than a single branch trace buffer. ++ ++'maint set btrace pt skip-pad' ++'maint show btrace pt skip-pad' ++ Control whether GDB will skip PAD packets when computing the packet ++ history. ++ ++'set displaced-stepping' ++'show displaced-stepping' ++ Control whether or not GDB will do "displaced stepping" if the ++ target supports it. Displaced stepping is a way to single-step ++ over breakpoints without removing them from the inferior, by ++ executing an out-of-line copy of the instruction that was ++ originally at the breakpoint location. It is also known as ++ out-of-line single-stepping. ++ ++ 'set displaced-stepping on' ++ If the target architecture supports it, GDB will use displaced ++ stepping to step over breakpoints. ++ ++ 'set displaced-stepping off' ++ GDB will not use displaced stepping to step over breakpoints, ++ even if such is supported by the target architecture. ++ ++ 'set displaced-stepping auto' ++ This is the default mode. GDB will use displaced stepping ++ only if non-stop mode is active (*note Non-Stop Mode::) and ++ the target architecture supports displaced stepping. ++ ++'maint check-psymtabs' ++ Check the consistency of currently expanded psymtabs versus ++ symtabs. Use this to check, for example, whether a symbol is in ++ one but not the other. ++ ++'maint check-symtabs' ++ Check the consistency of currently expanded symtabs. ++ ++'maint expand-symtabs [REGEXP]' ++ Expand symbol tables. If REGEXP is specified, only expand symbol ++ tables for file names matching REGEXP. ++ ++'maint set catch-demangler-crashes [on|off]' ++'maint show catch-demangler-crashes' ++ Control whether GDB should attempt to catch crashes in the symbol ++ name demangler. The default is to attempt to catch crashes. If ++ enabled, the first time a crash is caught, a core file is created, ++ the offending symbol is displayed and the user is presented with ++ the option to terminate the current session. ++ ++'maint cplus first_component NAME' ++ Print the first C++ class/namespace component of NAME. ++ ++'maint cplus namespace' ++ Print the list of possible C++ namespaces. ++ ++'maint deprecate COMMAND [REPLACEMENT]' ++'maint undeprecate COMMAND' ++ Deprecate or undeprecate the named COMMAND. Deprecated commands ++ cause GDB to issue a warning when you use them. The optional ++ argument REPLACEMENT says which newer command should be used in ++ favor of the deprecated one; if it is given, GDB will mention the ++ replacement as part of the warning. ++ ++'maint dump-me' ++ Cause a fatal signal in the debugger and force it to dump its core. ++ This is supported only on systems which support aborting a program ++ with the 'SIGQUIT' signal. ++ ++'maint internal-error [MESSAGE-TEXT]' ++'maint internal-warning [MESSAGE-TEXT]' ++'maint demangler-warning [MESSAGE-TEXT]' ++ ++ Cause GDB to call the internal function 'internal_error', ++ 'internal_warning' or 'demangler_warning' and hence behave as ++ though an internal problem has been detected. In addition to ++ reporting the internal problem, these functions give the user the ++ opportunity to either quit GDB or (for 'internal_error' and ++ 'internal_warning') create a core file of the current GDB session. ++ ++ These commands take an optional parameter MESSAGE-TEXT that is used ++ as the text of the error or warning message. ++ ++ Here's an example of using 'internal-error': ++ ++ (gdb) maint internal-error testing, 1, 2 ++ .../maint.c:121: internal-error: testing, 1, 2 ++ A problem internal to GDB has been detected. Further ++ debugging may prove unreliable. ++ Quit this debugging session? (y or n) n ++ Create a core file? (y or n) n ++ (gdb) ++ ++'maint set internal-error ACTION [ask|yes|no]' ++'maint show internal-error ACTION' ++'maint set internal-warning ACTION [ask|yes|no]' ++'maint show internal-warning ACTION' ++'maint set demangler-warning ACTION [ask|yes|no]' ++'maint show demangler-warning ACTION' ++ When GDB reports an internal problem (error or warning) it gives ++ the user the opportunity to both quit GDB and create a core file of ++ the current GDB session. These commands let you override the ++ default behaviour for each particular ACTION, described in the ++ table below. ++ ++ 'quit' ++ You can specify that GDB should always (yes) or never (no) ++ quit. The default is to ask the user what to do. ++ ++ 'corefile' ++ You can specify that GDB should always (yes) or never (no) ++ create a core file. The default is to ask the user what to ++ do. Note that there is no 'corefile' option for ++ 'demangler-warning': demangler warnings always create a core ++ file and this cannot be disabled. ++ ++'maint packet TEXT' ++ If GDB is talking to an inferior via the serial protocol, then this ++ command sends the string TEXT to the inferior, and displays the ++ response packet. GDB supplies the initial '$' character, the ++ terminating '#' character, and the checksum. ++ ++'maint print architecture [FILE]' ++ Print the entire architecture configuration. The optional argument ++ FILE names the file where the output goes. ++ ++'maint print c-tdesc' ++ Print the target description (*note Target Descriptions::) as a C ++ source file. By default, the target description is for the current ++ target, but if the optional argument FILE is provided, that file is ++ used to produce the description. The FILE should be an XML ++ document, of the form described in *note Target Description ++ Format::. The created source file is built into GDB when GDB is ++ built again. This command is used by developers after they add or ++ modify XML target descriptions. ++ ++'maint print xml-tdesc [FILE]' ++ Print the target description (*note Target Descriptions::) as an ++ XML file. By default print the target description for the current ++ target, but if the optional argument FILE is provided, then that ++ file is read in by GDB and then used to produce the description. ++ The FILE should be an XML document, of the form described in *note ++ Target Description Format::. ++ ++'maint check xml-descriptions DIR' ++ Check that the target descriptions dynamically created by GDB equal ++ the descriptions created from XML files found in DIR. ++ ++'maint check libthread-db' ++ Run integrity checks on the current inferior's thread debugging ++ library. This exercises all 'libthread_db' functionality used by ++ GDB on GNU/Linux systems, and by extension also exercises the ++ 'proc_service' functions provided by GDB that 'libthread_db' uses. ++ Note that parts of the test may be skipped on some platforms when ++ debugging core files. ++ ++'maint print core-file-backed-mappings' ++ Print the file-backed mappings which were loaded from a core file ++ note. This output represents state internal to GDB and should be ++ similar to the mappings displayed by the 'info proc mappings' ++ command. ++ ++'maint print dummy-frames' ++ Prints the contents of GDB's internal dummy-frame stack. ++ ++ (gdb) b add ++ ... ++ (gdb) print add(2,3) ++ Breakpoint 2, add (a=2, b=3) at ... ++ 58 return (a + b); ++ The program being debugged stopped while in a function called from GDB. ++ ... ++ (gdb) maint print dummy-frames ++ 0xa8206d8: id={stack=0xbfffe734,code=0xbfffe73f,!special}, ptid=process 9353 ++ (gdb) ++ ++ Takes an optional file parameter. ++ ++'maint print registers [FILE]' ++'maint print raw-registers [FILE]' ++'maint print cooked-registers [FILE]' ++'maint print register-groups [FILE]' ++'maint print remote-registers [FILE]' ++ Print GDB's internal register data structures. ++ ++ The command 'maint print raw-registers' includes the contents of ++ the raw register cache; the command 'maint print cooked-registers' ++ includes the (cooked) value of all registers, including registers ++ which aren't available on the target nor visible to user; the ++ command 'maint print register-groups' includes the groups that each ++ register is a member of; and the command 'maint print ++ remote-registers' includes the remote target's register numbers and ++ offsets in the 'G' packets. ++ ++ These commands take an optional parameter, a file name to which to ++ write the information. ++ ++'maint print reggroups [FILE]' ++ Print GDB's internal register group data structures. The optional ++ argument FILE tells to what file to write the information. ++ ++ The register groups info looks like this: ++ ++ (gdb) maint print reggroups ++ Group Type ++ general user ++ float user ++ all user ++ vector user ++ system user ++ save internal ++ restore internal ++ ++'flushregs' ++ This command forces GDB to flush its internal register cache. ++ ++'maint print objfiles [REGEXP]' ++ Print a dump of all known object files. If REGEXP is specified, ++ only print object files whose names match REGEXP. For each object ++ file, this command prints its name, address in memory, and all of ++ its psymtabs and symtabs. ++ ++'maint print user-registers' ++ List all currently available "user registers". User registers ++ typically provide alternate names for actual hardware registers. ++ They include the four "standard" registers '$fp', '$pc', '$sp', and ++ '$ps'. *Note standard registers::. User registers can be used in ++ expressions in the same way as the canonical register names, but ++ only the latter are listed by the 'info registers' and 'maint print ++ registers' commands. ++ ++'maint print section-scripts [REGEXP]' ++ Print a dump of scripts specified in the '.debug_gdb_section' ++ section. If REGEXP is specified, only print scripts loaded by ++ object files matching REGEXP. For each script, this command prints ++ its name as specified in the objfile, and the full path if known. ++ *Note dotdebug_gdb_scripts section::. ++ ++'maint print statistics' ++ This command prints, for each object file in the program, various ++ data about that object file followed by the byte cache ("bcache") ++ statistics for the object file. The objfile data includes the ++ number of minimal, partial, full, and stabs symbols, the number of ++ types defined by the objfile, the number of as yet unexpanded psym ++ tables, the number of line tables and string tables, and the amount ++ of memory used by the various tables. The bcache statistics ++ include the counts, sizes, and counts of duplicates of all and ++ unique objects, max, average, and median entry size, total memory ++ used and its overhead and savings, and various measures of the hash ++ table size and chain lengths. ++ ++'maint print target-stack' ++ A "target" is an interface between the debugger and a particular ++ kind of file or process. Targets can be stacked in "strata", so ++ that more than one target can potentially respond to a request. In ++ particular, memory accesses will walk down the stack of targets ++ until they find a target that is interested in handling that ++ particular address. ++ ++ This command prints a short description of each layer that was ++ pushed on the "target stack", starting from the top layer down to ++ the bottom one. ++ ++'maint print type EXPR' ++ Print the type chain for a type specified by EXPR. The argument ++ can be either a type name or a symbol. If it is a symbol, the type ++ of that symbol is described. The type chain produced by this ++ command is a recursive definition of the data type as stored in ++ GDB's data structures, including its flags and contained types. ++ ++'maint selftest [FILTER]' ++ Run any self tests that were compiled in to GDB. This will print a ++ message showing how many tests were run, and how many failed. If a ++ FILTER is passed, only the tests with FILTER in their name will by ++ ran. ++ ++'maint info selftests' ++ List the selftests compiled in to GDB. ++ ++'maint set dwarf always-disassemble' ++'maint show dwarf always-disassemble' ++ Control the behavior of 'info address' when using DWARF debugging ++ information. ++ ++ The default is 'off', which means that GDB should try to describe a ++ variable's location in an easily readable format. When 'on', GDB ++ will instead display the DWARF location expression in an ++ assembly-like format. Note that some locations are too complex for ++ GDB to describe simply; in this case you will always see the ++ disassembly form. ++ ++ Here is an example of the resulting disassembly: ++ ++ (gdb) info addr argc ++ Symbol "argc" is a complex DWARF expression: ++ 1: DW_OP_fbreg 0 ++ ++ For more information on these expressions, see the DWARF standard ++ (http://www.dwarfstd.org/). ++ ++'maint set dwarf max-cache-age' ++'maint show dwarf max-cache-age' ++ Control the DWARF compilation unit cache. ++ ++ In object files with inter-compilation-unit references, such as ++ those produced by the GCC option '-feliminate-dwarf2-dups', the ++ DWARF reader needs to frequently refer to previously read ++ compilation units. This setting controls how long a compilation ++ unit will remain in the cache if it is not referenced. A higher ++ limit means that cached compilation units will be stored in memory ++ longer, and more total memory will be used. Setting it to zero ++ disables caching, which will slow down GDB startup, but reduce ++ memory consumption. ++ ++'maint set dwarf unwinders' ++'maint show dwarf unwinders' ++ Control use of the DWARF frame unwinders. ++ ++ Many targets that support DWARF debugging use GDB's DWARF frame ++ unwinders to build the backtrace. Many of these targets will also ++ have a second mechanism for building the backtrace for use in cases ++ where DWARF information is not available, this second mechanism is ++ often an analysis of a function's prologue. ++ ++ In order to extend testing coverage of the second level stack ++ unwinding mechanisms it is helpful to be able to disable the DWARF ++ stack unwinders, this can be done with this switch. ++ ++ In normal use of GDB disabling the DWARF unwinders is not ++ advisable, there are cases that are better handled through DWARF ++ than prologue analysis, and the debug experience is likely to be ++ better with the DWARF frame unwinders enabled. ++ ++ If DWARF frame unwinders are not supported for a particular target ++ architecture, then enabling this flag does not cause them to be ++ used. ++ ++'maint set worker-threads' ++'maint show worker-threads' ++ Control the number of worker threads that may be used by GDB. On ++ capable hosts, GDB may use multiple threads to speed up certain ++ CPU-intensive operations, such as demangling symbol names. While ++ the number of threads used by GDB may vary, this command can be ++ used to set an upper bound on this number. The default is ++ 'unlimited', which lets GDB choose a reasonable number. Note that ++ this only controls worker threads started by GDB itself; libraries ++ used by GDB may start threads of their own. ++ ++'maint set profile' ++'maint show profile' ++ Control profiling of GDB. ++ ++ Profiling will be disabled until you use the 'maint set profile' ++ command to enable it. When you enable profiling, the system will ++ begin collecting timing and execution count data; when you disable ++ profiling or exit GDB, the results will be written to a log file. ++ Remember that if you use profiling, GDB will overwrite the ++ profiling log file (often called 'gmon.out'). If you have a record ++ of important profiling data in a 'gmon.out' file, be sure to move ++ it to a safe location. ++ ++ Configuring with '--enable-profiling' arranges for GDB to be ++ compiled with the '-pg' compiler option. ++ ++'maint set show-debug-regs' ++'maint show show-debug-regs' ++ Control whether to show variables that mirror the hardware debug ++ registers. Use 'on' to enable, 'off' to disable. If enabled, the ++ debug registers values are shown when GDB inserts or removes a ++ hardware breakpoint or watchpoint, and when the inferior triggers a ++ hardware-assisted breakpoint or watchpoint. ++ ++'maint set show-all-tib' ++'maint show show-all-tib' ++ Control whether to show all non zero areas within a 1k block ++ starting at thread local base, when using the 'info w32 ++ thread-information-block' command. ++ ++'maint set target-async' ++'maint show target-async' ++ This controls whether GDB targets operate in synchronous or ++ asynchronous mode (*note Background Execution::). Normally the ++ default is asynchronous, if it is available; but this can be ++ changed to more easily debug problems occurring only in synchronous ++ mode. ++ ++'maint set target-non-stop' ++'maint show target-non-stop' ++ ++ This controls whether GDB targets always operate in non-stop mode ++ even if 'set non-stop' is 'off' (*note Non-Stop Mode::). The ++ default is 'auto', meaning non-stop mode is enabled if supported by ++ the target. ++ ++ 'maint set target-non-stop auto' ++ This is the default mode. GDB controls the target in non-stop ++ mode if the target supports it. ++ ++ 'maint set target-non-stop on' ++ GDB controls the target in non-stop mode even if the target ++ does not indicate support. ++ ++ 'maint set target-non-stop off' ++ GDB does not control the target in non-stop mode even if the ++ target supports it. ++ ++'maint set tui-resize-message' ++'maint show tui-resize-message' ++ Control whether GDB displays a message each time the terminal is ++ resized when in TUI mode. The default is 'off', which means that ++ GDB is silent during resizes. When 'on', GDB will display a ++ message after a resize is completed; the message will include a ++ number indicating how many times the terminal has been resized. ++ This setting is intended for use by the test suite, where it would ++ otherwise be difficult to determine when a resize and refresh has ++ been completed. ++ ++'maint set per-command' ++'maint show per-command' ++ ++ GDB can display the resources used by each command. This is useful ++ in debugging performance problems. ++ ++ 'maint set per-command space [on|off]' ++ 'maint show per-command space' ++ Enable or disable the printing of the memory used by GDB for ++ each command. If enabled, GDB will display how much memory ++ each command took, following the command's own output. This ++ can also be requested by invoking GDB with the '--statistics' ++ command-line switch (*note Mode Options::). ++ ++ 'maint set per-command time [on|off]' ++ 'maint show per-command time' ++ Enable or disable the printing of the execution time of GDB ++ for each command. If enabled, GDB will display how much time ++ it took to execute each command, following the command's own ++ output. Both CPU time and wallclock time are printed. ++ Printing both is useful when trying to determine whether the ++ cost is CPU or, e.g., disk/network latency. Note that the CPU ++ time printed is for GDB only, it does not include the ++ execution time of the inferior because there's no mechanism ++ currently to compute how much time was spent by GDB and how ++ much time was spent by the program been debugged. This can ++ also be requested by invoking GDB with the '--statistics' ++ command-line switch (*note Mode Options::). ++ ++ 'maint set per-command symtab [on|off]' ++ 'maint show per-command symtab' ++ Enable or disable the printing of basic symbol table ++ statistics for each command. If enabled, GDB will display the ++ following information: ++ ++ a. number of symbol tables ++ b. number of primary symbol tables ++ c. number of blocks in the blockvector ++ ++'maint set check-libthread-db [on|off]' ++'maint show check-libthread-db' ++ Control whether GDB should run integrity checks on inferior ++ specific thread debugging libraries as they are loaded. The ++ default is not to perform such checks. If any check fails GDB will ++ unload the library and continue searching for a suitable candidate ++ as described in *note set libthread-db-search-path::. For more ++ information about the tests, see *note maint check libthread-db::. ++ ++'maint space VALUE' ++ An alias for 'maint set per-command space'. A non-zero value ++ enables it, zero disables it. ++ ++'maint time VALUE' ++ An alias for 'maint set per-command time'. A non-zero value ++ enables it, zero disables it. ++ ++'maint translate-address [SECTION] ADDR' ++ Find the symbol stored at the location specified by the address ++ ADDR and an optional section name SECTION. If found, GDB prints ++ the name of the closest symbol and an offset from the symbol's ++ location to the specified address. This is similar to the 'info ++ address' command (*note Symbols::), except that this command also ++ allows to find symbols in other sections. ++ ++ If section was not specified, the section in which the symbol was ++ found is also printed. For dynamically linked executables, the ++ name of executable or shared library containing the symbol is ++ printed as well. ++ ++'maint test-options require-delimiter' ++'maint test-options unknown-is-error' ++'maint test-options unknown-is-operand' ++ These commands are used by the testsuite to validate the command ++ options framework. The 'require-delimiter' variant requires a ++ double-dash delimiter to indicate end of options. The ++ 'unknown-is-error' and 'unknown-is-operand' do not. The ++ 'unknown-is-error' variant throws an error on unknown option, while ++ 'unknown-is-operand' treats unknown options as the start of the ++ command's operands. When run, the commands output the result of ++ the processed options. When completed, the commands store the ++ internal result of completion in a variable exposed by the 'maint ++ show test-options-completion-result' command. ++ ++'maint show test-options-completion-result' ++ Shows the result of completing the 'maint test-options' ++ subcommands. This is used by the testsuite to validate completion ++ support in the command options framework. ++ ++'maint set test-settings KIND' ++'maint show test-settings KIND' ++ These are representative commands for each KIND of setting type GDB ++ supports. They are used by the testsuite for exercising the ++ settings infrastructure. ++ ++'maint with SETTING [VALUE] [-- COMMAND]' ++ Like the 'with' command, but works with 'maintenance set' ++ variables. This is used by the testsuite to exercise the 'with' ++ command's infrastructure. ++ ++ The following command is useful for non-interactive invocations of ++GDB, such as in the test suite. ++ ++'set watchdog NSEC' ++ Set the maximum number of seconds GDB will wait for the target ++ operation to finish. If this time expires, GDB reports and error ++ and the command is aborted. ++ ++'show watchdog' ++ Show the current setting of the target wait timeout. ++ ++ ++File: gdb.info, Node: Remote Protocol, Next: Agent Expressions, Prev: Maintenance Commands, Up: Top ++ ++Appendix E GDB Remote Serial Protocol ++************************************* ++ ++* Menu: ++ ++* Overview:: ++* Packets:: ++* Stop Reply Packets:: ++* General Query Packets:: ++* Architecture-Specific Protocol Details:: ++* Tracepoint Packets:: ++* Host I/O Packets:: ++* Interrupts:: ++* Notification Packets:: ++* Remote Non-Stop:: ++* Packet Acknowledgment:: ++* Examples:: ++* File-I/O Remote Protocol Extension:: ++* Library List Format:: ++* Library List Format for SVR4 Targets:: ++* Memory Map Format:: ++* Thread List Format:: ++* Traceframe Info Format:: ++* Branch Trace Format:: ++* Branch Trace Configuration Format:: ++ ++ ++File: gdb.info, Node: Overview, Next: Packets, Up: Remote Protocol ++ ++E.1 Overview ++============ ++ ++There may be occasions when you need to know something about the ++protocol--for example, if there is only one serial port to your target ++machine, you might want your program to do something special if it ++recognizes a packet meant for GDB. ++ ++ In the examples below, '->' and '<-' are used to indicate transmitted ++and received data, respectively. ++ ++ All GDB commands and responses (other than acknowledgments and ++notifications, see *note Notification Packets::) are sent as a PACKET. ++A PACKET is introduced with the character '$', the actual PACKET-DATA, ++and the terminating character '#' followed by a two-digit CHECKSUM: ++ ++ $PACKET-DATA#CHECKSUM ++ ++The two-digit CHECKSUM is computed as the modulo 256 sum of all ++characters between the leading '$' and the trailing '#' (an eight bit ++unsigned checksum). ++ ++ Implementors should note that prior to GDB 5.0 the protocol ++specification also included an optional two-digit SEQUENCE-ID: ++ ++ $SEQUENCE-ID:PACKET-DATA#CHECKSUM ++ ++That SEQUENCE-ID was appended to the acknowledgment. GDB has never ++output SEQUENCE-IDs. Stubs that handle packets added since GDB 5.0 must ++not accept SEQUENCE-ID. ++ ++ When either the host or the target machine receives a packet, the ++first response expected is an acknowledgment: either '+' (to indicate ++the package was received correctly) or '-' (to request retransmission): ++ ++ -> $PACKET-DATA#CHECKSUM ++ <- + ++ ++ The '+'/'-' acknowledgments can be disabled once a connection is ++established. *Note Packet Acknowledgment::, for details. ++ ++ The host (GDB) sends COMMANDs, and the target (the debugging stub ++incorporated in your program) sends a RESPONSE. In the case of step and ++continue COMMANDs, the response is only sent when the operation has ++completed, and the target has again stopped all threads in all attached ++processes. This is the default all-stop mode behavior, but the remote ++protocol also supports GDB's non-stop execution mode; see *note Remote ++Non-Stop::, for details. ++ ++ PACKET-DATA consists of a sequence of characters with the exception ++of '#' and '$' (see 'X' packet for additional exceptions). ++ ++ Fields within the packet should be separated using ',' ';' or ':'. ++Except where otherwise noted all numbers are represented in HEX with ++leading zeros suppressed. ++ ++ Implementors should note that prior to GDB 5.0, the character ':' ++could not appear as the third character in a packet (as it would ++potentially conflict with the SEQUENCE-ID). ++ ++ Binary data in most packets is encoded either as two hexadecimal ++digits per byte of binary data. This allowed the traditional remote ++protocol to work over connections which were only seven-bit clean. Some ++packets designed more recently assume an eight-bit clean connection, and ++use a more efficient encoding to send and receive binary data. ++ ++ The binary data representation uses '7d' (ASCII '}') as an escape ++character. Any escaped byte is transmitted as the escape character ++followed by the original character XORed with '0x20'. For example, the ++byte '0x7d' would be transmitted as the two bytes '0x7d 0x5d'. The ++bytes '0x23' (ASCII '#'), '0x24' (ASCII '$'), and '0x7d' (ASCII '}') ++must always be escaped. Responses sent by the stub must also escape ++'0x2a' (ASCII '*'), so that it is not interpreted as the start of a ++run-length encoded sequence (described next). ++ ++ Response DATA can be run-length encoded to save space. Run-length ++encoding replaces runs of identical characters with one instance of the ++repeated character, followed by a '*' and a repeat count. The repeat ++count is itself sent encoded, to avoid binary characters in DATA: a ++value of N is sent as 'N+29'. For a repeat count greater or equal to 3, ++this produces a printable ASCII character, e.g. a space (ASCII code 32) ++for a repeat count of 3. (This is because run-length encoding starts to ++win for counts 3 or more.) Thus, for example, '0* ' is a run-length ++encoding of "0000": the space character after '*' means repeat the ++leading '0' '32 - 29 = 3' more times. ++ ++ The printable characters '#' and '$' or with a numeric value greater ++than 126 must not be used. Runs of six repeats ('#') or seven repeats ++('$') can be expanded using a repeat count of only five ('"'). For ++example, '00000000' can be encoded as '0*"00'. ++ ++ The error response returned for some packets includes a two character ++error number. That number is not well defined. ++ ++ For any COMMAND not supported by the stub, an empty response ('$#00') ++should be returned. That way it is possible to extend the protocol. A ++newer GDB can tell if a packet is supported based on that response. ++ ++ At a minimum, a stub is required to support the '?' command to tell ++GDB the reason for halting, 'g' and 'G' commands for register access, ++and the 'm' and 'M' commands for memory access. Stubs that only control ++single-threaded targets can implement run control with the 'c' ++(continue) command, and if the target architecture supports ++hardware-assisted single-stepping, the 's' (step) command. Stubs that ++support multi-threading targets should support the 'vCont' command. All ++other commands are optional. ++ ++ ++File: gdb.info, Node: Packets, Next: Stop Reply Packets, Prev: Overview, Up: Remote Protocol ++ ++E.2 Packets ++=========== ++ ++The following table provides a complete list of all currently defined ++COMMANDs and their corresponding response DATA. *Note File-I/O Remote ++Protocol Extension::, for details about the File I/O extension of the ++remote protocol. ++ ++ Each packet's description has a template showing the packet's overall ++syntax, followed by an explanation of the packet's meaning. We include ++spaces in some of the templates for clarity; these are not part of the ++packet's syntax. No GDB packet uses spaces to separate its components. ++For example, a template like 'foo BAR BAZ' describes a packet beginning ++with the three ASCII bytes 'foo', followed by a BAR, followed directly ++by a BAZ. GDB does not transmit a space character between the 'foo' and ++the BAR, or between the BAR and the BAZ. ++ ++ Several packets and replies include a THREAD-ID field to identify a ++thread. Normally these are positive numbers with a target-specific ++interpretation, formatted as big-endian hex strings. A THREAD-ID can ++also be a literal '-1' to indicate all threads, or '0' to pick any ++thread. ++ ++ In addition, the remote protocol supports a multiprocess feature in ++which the THREAD-ID syntax is extended to optionally include both ++process and thread ID fields, as 'pPID.TID'. The PID (process) and TID ++(thread) components each have the format described above: a positive ++number with target-specific interpretation formatted as a big-endian hex ++string, literal '-1' to indicate all processes or threads ++(respectively), or '0' to indicate an arbitrary process or thread. ++Specifying just a process, as 'pPID', is equivalent to 'pPID.-1'. It is ++an error to specify all processes but a specific thread, such as ++'p-1.TID'. Note that the 'p' prefix is _not_ used for those packets and ++replies explicitly documented to include a process ID, rather than a ++THREAD-ID. ++ ++ The multiprocess THREAD-ID syntax extensions are only used if both ++GDB and the stub report support for the 'multiprocess' feature using ++'qSupported'. *Note multiprocess extensions::, for more information. ++ ++ Note that all packet forms beginning with an upper- or lower-case ++letter, other than those described here, are reserved for future use. ++ ++ Here are the packet descriptions. ++ ++'!' ++ Enable extended mode. In extended mode, the remote server is made ++ persistent. The 'R' packet is used to restart the program being ++ debugged. ++ ++ Reply: ++ 'OK' ++ The remote target both supports and has enabled extended mode. ++ ++'?' ++ Indicate the reason the target halted. The reply is the same as ++ for step and continue. This packet has a special interpretation ++ when the target is in non-stop mode; see *note Remote Non-Stop::. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'A ARGLEN,ARGNUM,ARG,...' ++ Initialized 'argv[]' array passed into program. ARGLEN specifies ++ the number of bytes in the hex encoded byte stream ARG. See ++ 'gdbserver' for more details. ++ ++ Reply: ++ 'OK' ++ The arguments were set. ++ 'E NN' ++ An error occurred. ++ ++'b BAUD' ++ (Don't use this packet; its behavior is not well-defined.) Change ++ the serial line speed to BAUD. ++ ++ JTC: _When does the transport layer state change? When it's ++ received, or after the ACK is transmitted. In either case, there ++ are problems if the command or the acknowledgment packet is ++ dropped._ ++ ++ Stan: _If people really wanted to add something like this, and get ++ it working for the first time, they ought to modify ser-unix.c to ++ send some kind of out-of-band message to a specially-setup stub and ++ have the switch happen "in between" packets, so that from remote ++ protocol's point of view, nothing actually happened._ ++ ++'B ADDR,MODE' ++ Set (MODE is 'S') or clear (MODE is 'C') a breakpoint at ADDR. ++ ++ Don't use this packet. Use the 'Z' and 'z' packets instead (*note ++ insert breakpoint or watchpoint packet::). ++ ++'bc' ++ Backward continue. Execute the target system in reverse. No ++ parameter. *Note Reverse Execution::, for more information. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'bs' ++ Backward single step. Execute one instruction in reverse. No ++ parameter. *Note Reverse Execution::, for more information. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'c [ADDR]' ++ Continue at ADDR, which is the address to resume. If ADDR is ++ omitted, resume at current address. ++ ++ This packet is deprecated for multi-threading support. *Note vCont ++ packet::. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'C SIG[;ADDR]' ++ Continue with signal SIG (hex signal number). If ';ADDR' is ++ omitted, resume at same address. ++ ++ This packet is deprecated for multi-threading support. *Note vCont ++ packet::. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'d' ++ Toggle debug flag. ++ ++ Don't use this packet; instead, define a general set packet (*note ++ General Query Packets::). ++ ++'D' ++'D;PID' ++ The first form of the packet is used to detach GDB from the remote ++ system. It is sent to the remote target before GDB disconnects via ++ the 'detach' command. ++ ++ The second form, including a process ID, is used when multiprocess ++ protocol extensions are enabled (*note multiprocess extensions::), ++ to detach only a specific process. The PID is specified as a ++ big-endian hex string. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'F RC,EE,CF;XX' ++ A reply from GDB to an 'F' packet sent by the target. This is part ++ of the File-I/O protocol extension. *Note File-I/O Remote Protocol ++ Extension::, for the specification. ++ ++'g' ++ Read general registers. ++ ++ Reply: ++ 'XX...' ++ Each byte of register data is described by two hex digits. ++ The bytes with the register are transmitted in target byte ++ order. The size of each register and their position within ++ the 'g' packet are determined by the GDB internal gdbarch ++ functions 'DEPRECATED_REGISTER_RAW_SIZE' and ++ 'gdbarch_register_name'. ++ ++ When reading registers from a trace frame (*note Using the ++ Collected Data: Analyze Collected Data.), the stub may also ++ return a string of literal 'x''s in place of the register data ++ digits, to indicate that the corresponding register has not ++ been collected, thus its value is unavailable. For example, ++ for an architecture with 4 registers of 4 bytes each, the ++ following reply indicates to GDB that registers 0 and 2 have ++ not been collected, while registers 1 and 3 have been ++ collected, and both have zero value: ++ ++ -> g ++ <- xxxxxxxx00000000xxxxxxxx00000000 ++ ++ 'E NN' ++ for an error. ++ ++'G XX...' ++ Write general registers. *Note read registers packet::, for a ++ description of the XX... data. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'H OP THREAD-ID' ++ Set thread for subsequent operations ('m', 'M', 'g', 'G', et.al.). ++ Depending on the operation to be performed, OP should be 'c' for ++ step and continue operations (note that this is deprecated, ++ supporting the 'vCont' command is a better option), and 'g' for ++ other operations. The thread designator THREAD-ID has the format ++ and interpretation described in *note thread-id syntax::. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'i [ADDR[,NNN]]' ++ Step the remote target by a single clock cycle. If ',NNN' is ++ present, cycle step NNN cycles. If ADDR is present, cycle step ++ starting at that address. ++ ++'I' ++ Signal, then cycle step. *Note step with signal packet::. *Note ++ cycle step packet::. ++ ++'k' ++ Kill request. ++ ++ The exact effect of this packet is not specified. ++ ++ For a bare-metal target, it may power cycle or reset the target ++ system. For that reason, the 'k' packet has no reply. ++ ++ For a single-process target, it may kill that process if possible. ++ ++ A multiple-process target may choose to kill just one process, or ++ all that are under GDB's control. For more precise control, use ++ the vKill packet (*note vKill packet::). ++ ++ If the target system immediately closes the connection in response ++ to 'k', GDB does not consider the lack of packet acknowledgment to ++ be an error, and assumes the kill was successful. ++ ++ If connected using 'target extended-remote', and the target does ++ not close the connection in response to a kill request, GDB probes ++ the target state as if a new connection was opened (*note ? ++ packet::). ++ ++'m ADDR,LENGTH' ++ Read LENGTH addressable memory units starting at address ADDR ++ (*note addressable memory unit::). Note that ADDR may not be ++ aligned to any particular boundary. ++ ++ The stub need not use any particular size or alignment when ++ gathering data from memory for the response; even if ADDR is ++ word-aligned and LENGTH is a multiple of the word size, the stub is ++ free to use byte accesses, or not. For this reason, this packet ++ may not be suitable for accessing memory-mapped I/O devices. ++ ++ Reply: ++ 'XX...' ++ Memory contents; each byte is transmitted as a two-digit ++ hexadecimal number. The reply may contain fewer addressable ++ memory units than requested if the server was able to read ++ only part of the region of memory. ++ 'E NN' ++ NN is errno ++ ++'M ADDR,LENGTH:XX...' ++ Write LENGTH addressable memory units starting at address ADDR ++ (*note addressable memory unit::). The data is given by XX...; ++ each byte is transmitted as a two-digit hexadecimal number. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error (this includes the case where only part of the ++ data was written). ++ ++'p N' ++ Read the value of register N; N is in hex. *Note read registers ++ packet::, for a description of how the returned register value is ++ encoded. ++ ++ Reply: ++ 'XX...' ++ the register's value ++ 'E NN' ++ for an error ++ '' ++ Indicating an unrecognized QUERY. ++ ++'P N...=R...' ++ Write register N... with value R.... The register number N is in ++ hexadecimal, and R... contains two hex digits for each byte in the ++ register (target byte order). ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'q NAME PARAMS...' ++'Q NAME PARAMS...' ++ General query ('q') and set ('Q'). These packets are described ++ fully in *note General Query Packets::. ++ ++'r' ++ Reset the entire system. ++ ++ Don't use this packet; use the 'R' packet instead. ++ ++'R XX' ++ Restart the program being debugged. The XX, while needed, is ++ ignored. This packet is only available in extended mode (*note ++ extended mode::). ++ ++ The 'R' packet has no reply. ++ ++'s [ADDR]' ++ Single step, resuming at ADDR. If ADDR is omitted, resume at same ++ address. ++ ++ This packet is deprecated for multi-threading support. *Note vCont ++ packet::. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'S SIG[;ADDR]' ++ Step with signal. This is analogous to the 'C' packet, but ++ requests a single-step, rather than a normal resumption of ++ execution. ++ ++ This packet is deprecated for multi-threading support. *Note vCont ++ packet::. ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'t ADDR:PP,MM' ++ Search backwards starting at address ADDR for a match with pattern ++ PP and mask MM, both of which are are 4 byte long. There must be ++ at least 3 digits in ADDR. ++ ++'T THREAD-ID' ++ Find out if the thread THREAD-ID is alive. *Note thread-id ++ syntax::. ++ ++ Reply: ++ 'OK' ++ thread is still alive ++ 'E NN' ++ thread is dead ++ ++'v' ++ Packets starting with 'v' are identified by a multi-letter name, up ++ to the first ';' or '?' (or the end of the packet). ++ ++'vAttach;PID' ++ Attach to a new process with the specified process ID PID. The ++ process ID is a hexadecimal integer identifying the process. In ++ all-stop mode, all threads in the attached process are stopped; in ++ non-stop mode, it may be attached without being stopped if that is ++ supported by the target. ++ ++ This packet is only available in extended mode (*note extended ++ mode::). ++ ++ Reply: ++ 'E NN' ++ for an error ++ 'Any stop packet' ++ for success in all-stop mode (*note Stop Reply Packets::) ++ 'OK' ++ for success in non-stop mode (*note Remote Non-Stop::) ++ ++'vCont[;ACTION[:THREAD-ID]]...' ++ Resume the inferior, specifying different actions for each thread. ++ ++ For each inferior thread, the leftmost action with a matching ++ THREAD-ID is applied. Threads that don't match any action remain ++ in their current state. Thread IDs are specified using the syntax ++ described in *note thread-id syntax::. If multiprocess extensions ++ (*note multiprocess extensions::) are supported, actions can be ++ specified to match all threads in a process by using the 'pPID.-1' ++ form of the THREAD-ID. An action with no THREAD-ID matches all ++ threads. Specifying no actions is an error. ++ ++ Currently supported actions are: ++ ++ 'c' ++ Continue. ++ 'C SIG' ++ Continue with signal SIG. The signal SIG should be two hex ++ digits. ++ 's' ++ Step. ++ 'S SIG' ++ Step with signal SIG. The signal SIG should be two hex ++ digits. ++ 't' ++ Stop. ++ 'r START,END' ++ Step once, and then keep stepping as long as the thread stops ++ at addresses between START (inclusive) and END (exclusive). ++ The remote stub reports a stop reply when either the thread ++ goes out of the range or is stopped due to an unrelated ++ reason, such as hitting a breakpoint. *Note range stepping::. ++ ++ If the range is empty (START == END), then the action becomes ++ equivalent to the 's' action. In other words, single-step ++ once, and report the stop (even if the stepped instruction ++ jumps to START). ++ ++ (A stop reply may be sent at any point even if the PC is still ++ within the stepping range; for example, it is valid to ++ implement this packet in a degenerate way as a single ++ instruction step operation.) ++ ++ The optional argument ADDR normally associated with the 'c', 'C', ++ 's', and 'S' packets is not supported in 'vCont'. ++ ++ The 't' action is only relevant in non-stop mode (*note Remote ++ Non-Stop::) and may be ignored by the stub otherwise. A stop reply ++ should be generated for any affected thread not already stopped. ++ When a thread is stopped by means of a 't' action, the ++ corresponding stop reply should indicate that the thread has ++ stopped with signal '0', regardless of whether the target uses some ++ other signal as an implementation detail. ++ ++ The server must ignore 'c', 'C', 's', 'S', and 'r' actions for ++ threads that are already running. Conversely, the server must ++ ignore 't' actions for threads that are already stopped. ++ ++ _Note:_ In non-stop mode, a thread is considered running until GDB ++ acknowledges an asynchronous stop notification for it with the ++ 'vStopped' packet (*note Remote Non-Stop::). ++ ++ The stub must support 'vCont' if it reports support for ++ multiprocess extensions (*note multiprocess extensions::). ++ ++ Reply: *Note Stop Reply Packets::, for the reply specifications. ++ ++'vCont?' ++ Request a list of actions supported by the 'vCont' packet. ++ ++ Reply: ++ 'vCont[;ACTION...]' ++ The 'vCont' packet is supported. Each ACTION is a supported ++ command in the 'vCont' packet. ++ '' ++ The 'vCont' packet is not supported. ++ ++'vCtrlC' ++ Interrupt remote target as if a control-C was pressed on the remote ++ terminal. This is the equivalent to reacting to the '^C' ('\003', ++ the control-C character) character in all-stop mode while the ++ target is running, except this works in non-stop mode. *Note ++ interrupting remote targets::, for more info on the all-stop ++ variant. ++ ++ Reply: ++ 'E NN' ++ for an error ++ 'OK' ++ for success ++ ++'vFile:OPERATION:PARAMETER...' ++ Perform a file operation on the target system. For details, see ++ *note Host I/O Packets::. ++ ++'vFlashErase:ADDR,LENGTH' ++ Direct the stub to erase LENGTH bytes of flash starting at ADDR. ++ The region may enclose any number of flash blocks, but its start ++ and end must fall on block boundaries, as indicated by the flash ++ block size appearing in the memory map (*note Memory Map Format::). ++ GDB groups flash memory programming operations together, and sends ++ a 'vFlashDone' request after each group; the stub is allowed to ++ delay erase operation until the 'vFlashDone' packet is received. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'vFlashWrite:ADDR:XX...' ++ Direct the stub to write data to flash address ADDR. The data is ++ passed in binary form using the same encoding as for the 'X' packet ++ (*note Binary Data::). The memory ranges specified by ++ 'vFlashWrite' packets preceding a 'vFlashDone' packet must not ++ overlap, and must appear in order of increasing addresses (although ++ 'vFlashErase' packets for higher addresses may already have been ++ received; the ordering is guaranteed only between 'vFlashWrite' ++ packets). If a packet writes to an address that was neither erased ++ by a preceding 'vFlashErase' packet nor by some other ++ target-specific method, the results are unpredictable. ++ ++ Reply: ++ 'OK' ++ for success ++ 'E.memtype' ++ for vFlashWrite addressing non-flash memory ++ 'E NN' ++ for an error ++ ++'vFlashDone' ++ Indicate to the stub that flash programming operation is finished. ++ The stub is permitted to delay or batch the effects of a group of ++ 'vFlashErase' and 'vFlashWrite' packets until a 'vFlashDone' packet ++ is received. The contents of the affected regions of flash memory ++ are unpredictable until the 'vFlashDone' request is completed. ++ ++'vKill;PID' ++ Kill the process with the specified process ID PID, which is a ++ hexadecimal integer identifying the process. This packet is used ++ in preference to 'k' when multiprocess protocol extensions are ++ supported; see *note multiprocess extensions::. ++ ++ Reply: ++ 'E NN' ++ for an error ++ 'OK' ++ for success ++ ++'vMustReplyEmpty' ++ The correct reply to an unknown 'v' packet is to return the empty ++ string, however, some older versions of 'gdbserver' would ++ incorrectly return 'OK' for unknown 'v' packets. ++ ++ The 'vMustReplyEmpty' is used as a feature test to check how ++ 'gdbserver' handles unknown packets, it is important that this ++ packet be handled in the same way as other unknown 'v' packets. If ++ this packet is handled differently to other unknown 'v' packets ++ then it is possible that GDB may run into problems in other areas, ++ specifically around use of 'vFile:setfs:'. ++ ++'vRun;FILENAME[;ARGUMENT]...' ++ Run the program FILENAME, passing it each ARGUMENT on its command ++ line. The file and arguments are hex-encoded strings. If FILENAME ++ is an empty string, the stub may use a default program (e.g. the ++ last program run). The program is created in the stopped state. ++ ++ This packet is only available in extended mode (*note extended ++ mode::). ++ ++ Reply: ++ 'E NN' ++ for an error ++ 'Any stop packet' ++ for success (*note Stop Reply Packets::) ++ ++'vStopped' ++ *Note Notification Packets::. ++ ++'X ADDR,LENGTH:XX...' ++ Write data to memory, where the data is transmitted in binary. ++ Memory is specified by its address ADDR and number of addressable ++ memory units LENGTH (*note addressable memory unit::); 'XX...' is ++ binary data (*note Binary Data::). ++ ++ Reply: ++ 'OK' ++ for success ++ 'E NN' ++ for an error ++ ++'z TYPE,ADDR,KIND' ++'Z TYPE,ADDR,KIND' ++ Insert ('Z') or remove ('z') a TYPE breakpoint or watchpoint ++ starting at address ADDRESS of kind KIND. ++ ++ Each breakpoint and watchpoint packet TYPE is documented ++ separately. ++ ++ _Implementation notes: A remote target shall return an empty string ++ for an unrecognized breakpoint or watchpoint packet TYPE. A remote ++ target shall support either both or neither of a given 'ZTYPE...' ++ and 'zTYPE...' packet pair. To avoid potential problems with ++ duplicate packets, the operations should be implemented in an ++ idempotent way._ ++ ++'z0,ADDR,KIND' ++'Z0,ADDR,KIND[;COND_LIST...][;cmds:PERSIST,CMD_LIST...]' ++ Insert ('Z0') or remove ('z0') a software breakpoint at address ++ ADDR of type KIND. ++ ++ A software breakpoint is implemented by replacing the instruction ++ at ADDR with a software breakpoint or trap instruction. The KIND ++ is target-specific and typically indicates the size of the ++ breakpoint in bytes that should be inserted. E.g., the ARM and ++ MIPS can insert either a 2 or 4 byte breakpoint. Some ++ architectures have additional meanings for KIND (*note ++ Architecture-Specific Protocol Details::); if no ++ architecture-specific value is being used, it should be '0'. KIND ++ is hex-encoded. COND_LIST is an optional list of conditional ++ expressions in bytecode form that should be evaluated on the ++ target's side. These are the conditions that should be taken into ++ consideration when deciding if the breakpoint trigger should be ++ reported back to GDB. ++ ++ See also the 'swbreak' stop reason (*note swbreak stop reason::) ++ for how to best report a software breakpoint event to GDB. ++ ++ The COND_LIST parameter is comprised of a series of expressions, ++ concatenated without separators. Each expression has the following ++ form: ++ ++ 'X LEN,EXPR' ++ LEN is the length of the bytecode expression and EXPR is the ++ actual conditional expression in bytecode form. ++ ++ The optional CMD_LIST parameter introduces commands that may be run ++ on the target, rather than being reported back to GDB. The ++ parameter starts with a numeric flag PERSIST; if the flag is ++ nonzero, then the breakpoint may remain active and the commands ++ continue to be run even when GDB disconnects from the target. ++ Following this flag is a series of expressions concatenated with no ++ separators. Each expression has the following form: ++ ++ 'X LEN,EXPR' ++ LEN is the length of the bytecode expression and EXPR is the ++ actual commands expression in bytecode form. ++ ++ _Implementation note: It is possible for a target to copy or move ++ code that contains software breakpoints (e.g., when implementing ++ overlays). The behavior of this packet, in the presence of such a ++ target, is not defined._ ++ ++ Reply: ++ 'OK' ++ success ++ '' ++ not supported ++ 'E NN' ++ for an error ++ ++'z1,ADDR,KIND' ++'Z1,ADDR,KIND[;COND_LIST...][;cmds:PERSIST,CMD_LIST...]' ++ Insert ('Z1') or remove ('z1') a hardware breakpoint at address ++ ADDR. ++ ++ A hardware breakpoint is implemented using a mechanism that is not ++ dependent on being able to modify the target's memory. The KIND, ++ COND_LIST, and CMD_LIST arguments have the same meaning as in 'Z0' ++ packets. ++ ++ _Implementation note: A hardware breakpoint is not affected by code ++ movement._ ++ ++ Reply: ++ 'OK' ++ success ++ '' ++ not supported ++ 'E NN' ++ for an error ++ ++'z2,ADDR,KIND' ++'Z2,ADDR,KIND' ++ Insert ('Z2') or remove ('z2') a write watchpoint at ADDR. The ++ number of bytes to watch is specified by KIND. ++ ++ Reply: ++ 'OK' ++ success ++ '' ++ not supported ++ 'E NN' ++ for an error ++ ++'z3,ADDR,KIND' ++'Z3,ADDR,KIND' ++ Insert ('Z3') or remove ('z3') a read watchpoint at ADDR. The ++ number of bytes to watch is specified by KIND. ++ ++ Reply: ++ 'OK' ++ success ++ '' ++ not supported ++ 'E NN' ++ for an error ++ ++'z4,ADDR,KIND' ++'Z4,ADDR,KIND' ++ Insert ('Z4') or remove ('z4') an access watchpoint at ADDR. The ++ number of bytes to watch is specified by KIND. ++ ++ Reply: ++ 'OK' ++ success ++ '' ++ not supported ++ 'E NN' ++ for an error ++ ++ ++File: gdb.info, Node: Stop Reply Packets, Next: General Query Packets, Prev: Packets, Up: Remote Protocol ++ ++E.3 Stop Reply Packets ++====================== ++ ++The 'C', 'c', 'S', 's', 'vCont', 'vAttach', 'vRun', 'vStopped', and '?' ++packets can receive any of the below as a reply. Except for '?' and ++'vStopped', that reply is only returned when the target halts. In the ++below the exact meaning of "signal number" is defined by the header ++'include/gdb/signals.h' in the GDB source code. ++ ++ In non-stop mode, the server will simply reply 'OK' to commands such ++as 'vCont'; any stop will be the subject of a future notification. ++*Note Remote Non-Stop::. ++ ++ As in the description of request packets, we include spaces in the ++reply templates for clarity; these are not part of the reply packet's ++syntax. No GDB stop reply packet uses spaces to separate its ++components. ++ ++'S AA' ++ The program received signal number AA (a two-digit hexadecimal ++ number). This is equivalent to a 'T' response with no N:R pairs. ++ ++'T AA N1:R1;N2:R2;...' ++ The program received signal number AA (a two-digit hexadecimal ++ number). This is equivalent to an 'S' response, except that the ++ 'N:R' pairs can carry values of important registers and other ++ information directly in the stop reply packet, reducing round-trip ++ latency. Single-step and breakpoint traps are reported this way. ++ Each 'N:R' pair is interpreted as follows: ++ ++ * If N is a hexadecimal number, it is a register number, and the ++ corresponding R gives that register's value. The data R is a ++ series of bytes in target byte order, with each byte given by ++ a two-digit hex number. ++ ++ * If N is 'thread', then R is the THREAD-ID of the stopped ++ thread, as specified in *note thread-id syntax::. ++ ++ * If N is 'core', then R is the hexadecimal number of the core ++ on which the stop event was detected. ++ ++ * If N is a recognized "stop reason", it describes a more ++ specific event that stopped the target. The currently defined ++ stop reasons are listed below. The AA should be '05', the ++ trap signal. At most one stop reason should be present. ++ ++ * Otherwise, GDB should ignore this 'N:R' pair and go on to the ++ next; this allows us to extend the protocol in the future. ++ ++ The currently defined stop reasons are: ++ ++ 'watch' ++ 'rwatch' ++ 'awatch' ++ The packet indicates a watchpoint hit, and R is the data ++ address, in hex. ++ ++ 'syscall_entry' ++ 'syscall_return' ++ The packet indicates a syscall entry or return, and R is the ++ syscall number, in hex. ++ ++ 'library' ++ The packet indicates that the loaded libraries have changed. ++ GDB should use 'qXfer:libraries:read' to fetch a new list of ++ loaded libraries. The R part is ignored. ++ ++ 'replaylog' ++ The packet indicates that the target cannot continue replaying ++ logged execution events, because it has reached the end (or ++ the beginning when executing backward) of the log. The value ++ of R will be either 'begin' or 'end'. *Note Reverse ++ Execution::, for more information. ++ ++ 'swbreak' ++ The packet indicates a software breakpoint instruction was ++ executed, irrespective of whether it was GDB that planted the ++ breakpoint or the breakpoint is hardcoded in the program. The ++ R part must be left empty. ++ ++ On some architectures, such as x86, at the architecture level, ++ when a breakpoint instruction executes the program counter ++ points at the breakpoint address plus an offset. On such ++ targets, the stub is responsible for adjusting the PC to point ++ back at the breakpoint address. ++ ++ This packet should not be sent by default; older GDB versions ++ did not support it. GDB requests it, by supplying an ++ appropriate 'qSupported' feature (*note qSupported::). The ++ remote stub must also supply the appropriate 'qSupported' ++ feature indicating support. ++ ++ This packet is required for correct non-stop mode operation. ++ ++ 'hwbreak' ++ The packet indicates the target stopped for a hardware ++ breakpoint. The R part must be left empty. ++ ++ The same remarks about 'qSupported' and non-stop mode above ++ apply. ++ ++ 'fork' ++ The packet indicates that 'fork' was called, and R is the ++ thread ID of the new child process. Refer to *note thread-id ++ syntax:: for the format of the THREAD-ID field. This packet ++ is only applicable to targets that support fork events. ++ ++ This packet should not be sent by default; older GDB versions ++ did not support it. GDB requests it, by supplying an ++ appropriate 'qSupported' feature (*note qSupported::). The ++ remote stub must also supply the appropriate 'qSupported' ++ feature indicating support. ++ ++ 'vfork' ++ The packet indicates that 'vfork' was called, and R is the ++ thread ID of the new child process. Refer to *note thread-id ++ syntax:: for the format of the THREAD-ID field. This packet ++ is only applicable to targets that support vfork events. ++ ++ This packet should not be sent by default; older GDB versions ++ did not support it. GDB requests it, by supplying an ++ appropriate 'qSupported' feature (*note qSupported::). The ++ remote stub must also supply the appropriate 'qSupported' ++ feature indicating support. ++ ++ 'vforkdone' ++ The packet indicates that a child process created by a vfork ++ has either called 'exec' or terminated, so that the address ++ spaces of the parent and child process are no longer shared. ++ The R part is ignored. This packet is only applicable to ++ targets that support vforkdone events. ++ ++ This packet should not be sent by default; older GDB versions ++ did not support it. GDB requests it, by supplying an ++ appropriate 'qSupported' feature (*note qSupported::). The ++ remote stub must also supply the appropriate 'qSupported' ++ feature indicating support. ++ ++ 'exec' ++ The packet indicates that 'execve' was called, and R is the ++ absolute pathname of the file that was executed, in hex. This ++ packet is only applicable to targets that support exec events. ++ ++ This packet should not be sent by default; older GDB versions ++ did not support it. GDB requests it, by supplying an ++ appropriate 'qSupported' feature (*note qSupported::). The ++ remote stub must also supply the appropriate 'qSupported' ++ feature indicating support. ++ ++ 'create' ++ The packet indicates that the thread was just created. The ++ new thread is stopped until GDB sets it running with a ++ resumption packet (*note vCont packet::). This packet should ++ not be sent by default; GDB requests it with the *note ++ QThreadEvents:: packet. See also the 'w' (*note thread exit ++ event::) remote reply below. The R part is ignored. ++ ++'W AA' ++'W AA ; process:PID' ++ The process exited, and AA is the exit status. This is only ++ applicable to certain targets. ++ ++ The second form of the response, including the process ID of the ++ exited process, can be used only when GDB has reported support for ++ multiprocess protocol extensions; see *note multiprocess ++ extensions::. Both AA and PID are formatted as big-endian hex ++ strings. ++ ++'X AA' ++'X AA ; process:PID' ++ The process terminated with signal AA. ++ ++ The second form of the response, including the process ID of the ++ terminated process, can be used only when GDB has reported support ++ for multiprocess protocol extensions; see *note multiprocess ++ extensions::. Both AA and PID are formatted as big-endian hex ++ strings. ++ ++'w AA ; TID' ++ ++ The thread exited, and AA is the exit status. This response should ++ not be sent by default; GDB requests it with the *note ++ QThreadEvents:: packet. See also *note thread create event:: ++ above. AA is formatted as a big-endian hex string. ++ ++'N' ++ There are no resumed threads left in the target. In other words, ++ even though the process is alive, the last resumed thread has ++ exited. For example, say the target process has two threads: ++ thread 1 and thread 2. The client leaves thread 1 stopped, and ++ resumes thread 2, which subsequently exits. At this point, even ++ though the process is still alive, and thus no 'W' stop reply is ++ sent, no thread is actually executing either. The 'N' stop reply ++ thus informs the client that it can stop waiting for stop replies. ++ This packet should not be sent by default; older GDB versions did ++ not support it. GDB requests it, by supplying an appropriate ++ 'qSupported' feature (*note qSupported::). The remote stub must ++ also supply the appropriate 'qSupported' feature indicating ++ support. ++ ++'O XX...' ++ 'XX...' is hex encoding of ASCII data, to be written as the ++ program's console output. This can happen at any time while the ++ program is running and the debugger should continue to wait for ++ 'W', 'T', etc. This reply is not permitted in non-stop mode. ++ ++'F CALL-ID,PARAMETER...' ++ CALL-ID is the identifier which says which host system call should ++ be called. This is just the name of the function. Translation ++ into the correct system call is only applicable as it's defined in ++ GDB. *Note File-I/O Remote Protocol Extension::, for a list of ++ implemented system calls. ++ ++ 'PARAMETER...' is a list of parameters as defined for this very ++ system call. ++ ++ The target replies with this packet when it expects GDB to call a ++ host system call on behalf of the target. GDB replies with an ++ appropriate 'F' packet and keeps up waiting for the next reply ++ packet from the target. The latest 'C', 'c', 'S' or 's' action is ++ expected to be continued. *Note File-I/O Remote Protocol ++ Extension::, for more details. ++ +diff -Nuar gdb-10.2/gdb/gdb.texinfo gdb-10.2/gdb/gdb.texinfo +--- gdb-10.2/gdb/gdb.texinfo 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/gdb.texinfo 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,46966 @@ ++\input texinfo @c -*-texinfo-*- ++@c Copyright (C) 1988--2020 Free Software Foundation, Inc. ++@c ++@c %**start of header ++@c makeinfo ignores cmds prev to setfilename, so its arg cannot make use ++@c of @set vars. However, you can override filename with makeinfo -o. ++@setfilename gdb.info ++@c ++@c man begin INCLUDE ++@include gdb-cfg.texi ++@c man end ++@c ++@settitle Debugging with @value{GDBN} ++@setchapternewpage odd ++@c %**end of header ++ ++@iftex ++@c @smallbook ++@c @cropmarks ++@end iftex ++ ++@finalout ++@c To avoid file-name clashes between index.html and Index.html, when ++@c the manual is produced on a Posix host and then moved to a ++@c case-insensitive filesystem (e.g., MS-Windows), we separate the ++@c indices into two: Concept Index and all the rest. ++@syncodeindex ky fn ++@syncodeindex tp fn ++ ++@c readline appendices use @vindex, @findex and @ftable, ++@c annotate.texi and gdbmi use @findex. ++@syncodeindex vr fn ++ ++@c !!set GDB manual's edition---not the same as GDB version! ++@c This is updated by GNU Press. ++@set EDITION Tenth ++ ++@c !!set GDB edit command default editor ++@set EDITOR /bin/ex ++ ++@c THIS MANUAL REQUIRES TEXINFO 4.0 OR LATER. ++ ++@c This is a dir.info fragment to support semi-automated addition of ++@c manuals to an info tree. ++@dircategory Software development ++@direntry ++* Gdb: (gdb). The GNU debugger. ++* gdbserver: (gdb) Server. The GNU debugging server. ++@end direntry ++ ++@copying ++@c man begin COPYRIGHT ++Copyright @copyright{} 1988-2020 Free Software Foundation, Inc. ++ ++Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 or ++any later version published by the Free Software Foundation; with the ++Invariant Sections being ``Free Software'' and ``Free Software Needs ++Free Documentation'', with the Front-Cover Texts being ``A GNU Manual,'' ++and with the Back-Cover Texts as in (a) below. ++ ++(a) The FSF's Back-Cover Text is: ``You are free to copy and modify ++this GNU Manual. Buying copies from GNU Press supports the FSF in ++developing GNU and promoting software freedom.'' ++@c man end ++@end copying ++ ++@ifnottex ++This file documents the @sc{gnu} debugger @value{GDBN}. ++ ++This is the @value{EDITION} Edition, of @cite{Debugging with ++@value{GDBN}: the @sc{gnu} Source-Level Debugger} for @value{GDBN} ++@ifset VERSION_PACKAGE ++@value{VERSION_PACKAGE} ++@end ifset ++Version @value{GDBVN}. ++ ++@insertcopying ++@end ifnottex ++ ++@titlepage ++@title Debugging with @value{GDBN} ++@subtitle The @sc{gnu} Source-Level Debugger ++@sp 1 ++@subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN} ++@ifset VERSION_PACKAGE ++@sp 1 ++@subtitle @value{VERSION_PACKAGE} ++@end ifset ++@author Richard Stallman, Roland Pesch, Stan Shebs, et al. ++@page ++@tex ++{\parskip=0pt ++\hfill (Send bugs and comments on @value{GDBN} to @value{BUGURL}.)\par ++\hfill {\it Debugging with @value{GDBN}}\par ++\hfill \TeX{}info \texinfoversion\par ++} ++@end tex ++ ++@vskip 0pt plus 1filll ++Published by the Free Software Foundation @* ++51 Franklin Street, Fifth Floor, ++Boston, MA 02110-1301, USA@* ++ISBN 978-0-9831592-3-0 @* ++ ++@insertcopying ++@end titlepage ++@page ++ ++@ifnottex ++@node Top, Summary ++ ++@top Debugging with @value{GDBN} ++ ++This file describes @value{GDBN}, the @sc{gnu} symbolic debugger. ++ ++This is the @value{EDITION} Edition, for @value{GDBN} ++@ifset VERSION_PACKAGE ++@value{VERSION_PACKAGE} ++@end ifset ++Version @value{GDBVN}. ++ ++Copyright (C) 1988-2020 Free Software Foundation, Inc. ++ ++This edition of the GDB manual is dedicated to the memory of Fred ++Fish. Fred was a long-standing contributor to GDB and to Free ++software in general. We will miss him. ++ ++@menu ++* Summary:: Summary of @value{GDBN} ++* Sample Session:: A sample @value{GDBN} session ++ ++* Invocation:: Getting in and out of @value{GDBN} ++* Commands:: @value{GDBN} commands ++* Running:: Running programs under @value{GDBN} ++* Stopping:: Stopping and continuing ++* Reverse Execution:: Running programs backward ++* Process Record and Replay:: Recording inferior's execution and replaying it ++* Stack:: Examining the stack ++* Source:: Examining source files ++* Data:: Examining data ++* Optimized Code:: Debugging optimized code ++* Macros:: Preprocessor Macros ++* Tracepoints:: Debugging remote targets non-intrusively ++* Overlays:: Debugging programs that use overlays ++ ++* Languages:: Using @value{GDBN} with different languages ++ ++* Symbols:: Examining the symbol table ++* Altering:: Altering execution ++* GDB Files:: @value{GDBN} files ++* Targets:: Specifying a debugging target ++* Remote Debugging:: Debugging remote programs ++* Configurations:: Configuration-specific information ++* Controlling GDB:: Controlling @value{GDBN} ++* Extending GDB:: Extending @value{GDBN} ++* Interpreters:: Command Interpreters ++* TUI:: @value{GDBN} Text User Interface ++* Emacs:: Using @value{GDBN} under @sc{gnu} Emacs ++* GDB/MI:: @value{GDBN}'s Machine Interface. ++* Annotations:: @value{GDBN}'s annotation interface. ++* JIT Interface:: Using the JIT debugging interface. ++* In-Process Agent:: In-Process Agent ++ ++* GDB Bugs:: Reporting bugs in @value{GDBN} ++ ++@ifset SYSTEM_READLINE ++* Command Line Editing: (rluserman). Command Line Editing ++* Using History Interactively: (history). Using History Interactively ++@end ifset ++@ifclear SYSTEM_READLINE ++* Command Line Editing:: Command Line Editing ++* Using History Interactively:: Using History Interactively ++@end ifclear ++* In Memoriam:: In Memoriam ++* Formatting Documentation:: How to format and print @value{GDBN} documentation ++* Installing GDB:: Installing GDB ++* Maintenance Commands:: Maintenance Commands ++* Remote Protocol:: GDB Remote Serial Protocol ++* Agent Expressions:: The GDB Agent Expression Mechanism ++* Target Descriptions:: How targets can describe themselves to ++ @value{GDBN} ++* Operating System Information:: Getting additional information from ++ the operating system ++* Trace File Format:: GDB trace file format ++* Index Section Format:: .gdb_index section format ++* Man Pages:: Manual pages ++* Copying:: GNU General Public License says ++ how you can copy and share GDB ++* GNU Free Documentation License:: The license for this documentation ++* Concept Index:: Index of @value{GDBN} concepts ++* Command and Variable Index:: Index of @value{GDBN} commands, variables, ++ functions, and Python data types ++@end menu ++ ++@end ifnottex ++ ++@contents ++ ++@node Summary ++@unnumbered Summary of @value{GDBN} ++ ++The purpose of a debugger such as @value{GDBN} is to allow you to see what is ++going on ``inside'' another program while it executes---or what another ++program was doing at the moment it crashed. ++ ++@value{GDBN} can do four main kinds of things (plus other things in support of ++these) to help you catch bugs in the act: ++ ++@itemize @bullet ++@item ++Start your program, specifying anything that might affect its behavior. ++ ++@item ++Make your program stop on specified conditions. ++ ++@item ++Examine what has happened, when your program has stopped. ++ ++@item ++Change things in your program, so you can experiment with correcting the ++effects of one bug and go on to learn about another. ++@end itemize ++ ++You can use @value{GDBN} to debug programs written in C and C@t{++}. ++For more information, see @ref{Supported Languages,,Supported Languages}. ++For more information, see @ref{C,,C and C++}. ++ ++Support for D is partial. For information on D, see ++@ref{D,,D}. ++ ++@cindex Modula-2 ++Support for Modula-2 is partial. For information on Modula-2, see ++@ref{Modula-2,,Modula-2}. ++ ++Support for OpenCL C is partial. For information on OpenCL C, see ++@ref{OpenCL C,,OpenCL C}. ++ ++@cindex Pascal ++Debugging Pascal programs which use sets, subranges, file variables, or ++nested functions does not currently work. @value{GDBN} does not support ++entering expressions, printing values, or similar features using Pascal ++syntax. ++ ++@cindex Fortran ++@value{GDBN} can be used to debug programs written in Fortran, although ++it may be necessary to refer to some variables with a trailing ++underscore. ++ ++@value{GDBN} can be used to debug programs written in Objective-C, ++using either the Apple/NeXT or the GNU Objective-C runtime. ++ ++@menu ++* Free Software:: Freely redistributable software ++* Free Documentation:: Free Software Needs Free Documentation ++* Contributors:: Contributors to GDB ++@end menu ++ ++@node Free Software ++@unnumberedsec Free Software ++ ++@value{GDBN} is @dfn{free software}, protected by the @sc{gnu} ++General Public License ++(GPL). The GPL gives you the freedom to copy or adapt a licensed ++program---but every person getting a copy also gets with it the ++freedom to modify that copy (which means that they must get access to ++the source code), and the freedom to distribute further copies. ++Typical software companies use copyrights to limit your freedoms; the ++Free Software Foundation uses the GPL to preserve these freedoms. ++ ++Fundamentally, the General Public License is a license which says that ++you have these freedoms and that you cannot take these freedoms away ++from anyone else. ++ ++@node Free Documentation ++@unnumberedsec Free Software Needs Free Documentation ++ ++The biggest deficiency in the free software community today is not in ++the software---it is the lack of good free documentation that we can ++include with the free software. Many of our most important ++programs do not come with free reference manuals and free introductory ++texts. Documentation is an essential part of any software package; ++when an important free software package does not come with a free ++manual and a free tutorial, that is a major gap. We have many such ++gaps today. ++ ++Consider Perl, for instance. The tutorial manuals that people ++normally use are non-free. How did this come about? Because the ++authors of those manuals published them with restrictive terms---no ++copying, no modification, source files not available---which exclude ++them from the free software world. ++ ++That wasn't the first time this sort of thing happened, and it was far ++from the last. Many times we have heard a GNU user eagerly describe a ++manual that he is writing, his intended contribution to the community, ++only to learn that he had ruined everything by signing a publication ++contract to make it non-free. ++ ++Free documentation, like free software, is a matter of freedom, not ++price. The problem with the non-free manual is not that publishers ++charge a price for printed copies---that in itself is fine. (The Free ++Software Foundation sells printed copies of manuals, too.) The ++problem is the restrictions on the use of the manual. Free manuals ++are available in source code form, and give you permission to copy and ++modify. Non-free manuals do not allow this. ++ ++The criteria of freedom for a free manual are roughly the same as for ++free software. Redistribution (including the normal kinds of ++commercial redistribution) must be permitted, so that the manual can ++accompany every copy of the program, both on-line and on paper. ++ ++Permission for modification of the technical content is crucial too. ++When people modify the software, adding or changing features, if they ++are conscientious they will change the manual too---so they can ++provide accurate and clear documentation for the modified program. A ++manual that leaves you no choice but to write a new manual to document ++a changed version of the program is not really available to our ++community. ++ ++Some kinds of limits on the way modification is handled are ++acceptable. For example, requirements to preserve the original ++author's copyright notice, the distribution terms, or the list of ++authors, are ok. It is also no problem to require modified versions ++to include notice that they were modified. Even entire sections that ++may not be deleted or changed are acceptable, as long as they deal ++with nontechnical topics (like this one). These kinds of restrictions ++are acceptable because they don't obstruct the community's normal use ++of the manual. ++ ++However, it must be possible to modify all the @emph{technical} ++content of the manual, and then distribute the result in all the usual ++media, through all the usual channels. Otherwise, the restrictions ++obstruct the use of the manual, it is not free, and we need another ++manual to replace it. ++ ++Please spread the word about this issue. Our community continues to ++lose manuals to proprietary publishing. If we spread the word that ++free software needs free reference manuals and free tutorials, perhaps ++the next person who wants to contribute by writing documentation will ++realize, before it is too late, that only free manuals contribute to ++the free software community. ++ ++If you are writing documentation, please insist on publishing it under ++the GNU Free Documentation License or another free documentation ++license. Remember that this decision requires your approval---you ++don't have to let the publisher decide. Some commercial publishers ++will use a free license if you insist, but they will not propose the ++option; it is up to you to raise the issue and say firmly that this is ++what you want. If the publisher you are dealing with refuses, please ++try other publishers. If you're not sure whether a proposed license ++is free, write to @email{licensing@@gnu.org}. ++ ++You can encourage commercial publishers to sell more free, copylefted ++manuals and tutorials by buying them, and particularly by buying ++copies from the publishers that paid for their writing or for major ++improvements. Meanwhile, try to avoid buying non-free documentation ++at all. Check the distribution terms of a manual before you buy it, ++and insist that whoever seeks your business must respect your freedom. ++Check the history of the book, and try to reward the publishers that ++have paid or pay the authors to work on it. ++ ++The Free Software Foundation maintains a list of free documentation ++published by other publishers, at ++@url{http://www.fsf.org/doc/other-free-books.html}. ++ ++@node Contributors ++@unnumberedsec Contributors to @value{GDBN} ++ ++Richard Stallman was the original author of @value{GDBN}, and of many ++other @sc{gnu} programs. Many others have contributed to its ++development. This section attempts to credit major contributors. One ++of the virtues of free software is that everyone is free to contribute ++to it; with regret, we cannot actually acknowledge everyone here. The ++file @file{ChangeLog} in the @value{GDBN} distribution approximates a ++blow-by-blow account. ++ ++Changes much prior to version 2.0 are lost in the mists of time. ++ ++@quotation ++@emph{Plea:} Additions to this section are particularly welcome. If you ++or your friends (or enemies, to be evenhanded) have been unfairly ++omitted from this list, we would like to add your names! ++@end quotation ++ ++So that they may not regard their many labors as thankless, we ++particularly thank those who shepherded @value{GDBN} through major ++releases: ++Andrew Cagney (releases 6.3, 6.2, 6.1, 6.0, 5.3, 5.2, 5.1 and 5.0); ++Jim Blandy (release 4.18); ++Jason Molenda (release 4.17); ++Stan Shebs (release 4.14); ++Fred Fish (releases 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, and 4.9); ++Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4); ++John Gilmore (releases 4.3, 4.2, 4.1, 4.0, and 3.9); ++Jim Kingdon (releases 3.5, 3.4, and 3.3); ++and Randy Smith (releases 3.2, 3.1, and 3.0). ++ ++Richard Stallman, assisted at various times by Peter TerMaat, Chris ++Hanson, and Richard Mlynarik, handled releases through 2.8. ++ ++Michael Tiemann is the author of most of the @sc{gnu} C@t{++} support ++in @value{GDBN}, with significant additional contributions from Per ++Bothner and Daniel Berlin. James Clark wrote the @sc{gnu} C@t{++} ++demangler. Early work on C@t{++} was by Peter TerMaat (who also did ++much general update work leading to release 3.0). ++ ++@value{GDBN} uses the BFD subroutine library to examine multiple ++object-file formats; BFD was a joint project of David V. ++Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore. ++ ++David Johnson wrote the original COFF support; Pace Willison did ++the original support for encapsulated COFF. ++ ++Brent Benson of Harris Computer Systems contributed DWARF 2 support. ++ ++Adam de Boor and Bradley Davis contributed the ISI Optimum V support. ++Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS ++support. ++Jean-Daniel Fekete contributed Sun 386i support. ++Chris Hanson improved the HP9000 support. ++Noboyuki Hikichi and Tomoyuki Hasei contributed Sony/News OS 3 support. ++David Johnson contributed Encore Umax support. ++Jyrki Kuoppala contributed Altos 3068 support. ++Jeff Law contributed HP PA and SOM support. ++Keith Packard contributed NS32K support. ++Doug Rabson contributed Acorn Risc Machine support. ++Bob Rusk contributed Harris Nighthawk CX-UX support. ++Chris Smith contributed Convex support (and Fortran debugging). ++Jonathan Stone contributed Pyramid support. ++Michael Tiemann contributed SPARC support. ++Tim Tucker contributed support for the Gould NP1 and Gould Powernode. ++Pace Willison contributed Intel 386 support. ++Jay Vosburgh contributed Symmetry support. ++Marko Mlinar contributed OpenRISC 1000 support. ++ ++Andreas Schwab contributed M68K @sc{gnu}/Linux support. ++ ++Rich Schaefer and Peter Schauer helped with support of SunOS shared ++libraries. ++ ++Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree ++about several machine instruction sets. ++ ++Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped develop ++remote debugging. Intel Corporation, Wind River Systems, AMD, and ARM ++contributed remote debugging modules for the i960, VxWorks, A29K UDI, ++and RDI targets, respectively. ++ ++Brian Fox is the author of the readline libraries providing ++command-line editing and command history. ++ ++Andrew Beers of SUNY Buffalo wrote the language-switching code, the ++Modula-2 support, and contributed the Languages chapter of this manual. ++ ++Fred Fish wrote most of the support for Unix System Vr4. ++He also enhanced the command-completion support to cover C@t{++} overloaded ++symbols. ++ ++Hitachi America (now Renesas America), Ltd. sponsored the support for ++H8/300, H8/500, and Super-H processors. ++ ++NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors. ++ ++Mitsubishi (now Renesas) sponsored the support for D10V, D30V, and M32R/D ++processors. ++ ++Toshiba sponsored the support for the TX39 Mips processor. ++ ++Matsushita sponsored the support for the MN10200 and MN10300 processors. ++ ++Fujitsu sponsored the support for SPARClite and FR30 processors. ++ ++Kung Hsu, Jeff Law, and Rick Sladkey added support for hardware ++watchpoints. ++ ++Michael Snyder added support for tracepoints. ++ ++Stu Grossman wrote gdbserver. ++ ++Jim Kingdon, Peter Schauer, Ian Taylor, and Stu Grossman made ++nearly innumerable bug fixes and cleanups throughout @value{GDBN}. ++ ++The following people at the Hewlett-Packard Company contributed ++support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0 ++(narrow mode), HP's implementation of kernel threads, HP's aC@t{++} ++compiler, and the Text User Interface (nee Terminal User Interface): ++Ben Krepp, Richard Title, John Bishop, Susan Macchia, Kathy Mann, ++Satish Pai, India Paul, Steve Rehrauer, and Elena Zannoni. Kim Haase ++provided HP-specific information in this manual. ++ ++DJ Delorie ported @value{GDBN} to MS-DOS, for the DJGPP project. ++Robert Hoehne made significant contributions to the DJGPP port. ++ ++Cygnus Solutions has sponsored @value{GDBN} maintenance and much of its ++development since 1991. Cygnus engineers who have worked on @value{GDBN} ++fulltime include Mark Alexander, Jim Blandy, Per Bothner, Kevin ++Buettner, Edith Epstein, Chris Faylor, Fred Fish, Martin Hunt, Jim ++Ingham, John Gilmore, Stu Grossman, Kung Hsu, Jim Kingdon, John Metzler, ++Fernando Nasser, Geoffrey Noer, Dawn Perchik, Rich Pixley, Zdenek ++Radouch, Keith Seitz, Stan Shebs, David Taylor, and Elena Zannoni. In ++addition, Dave Brolley, Ian Carmichael, Steve Chamberlain, Nick Clifton, ++JT Conklin, Stan Cox, DJ Delorie, Ulrich Drepper, Frank Eigler, Doug ++Evans, Sean Fagan, David Henkel-Wallace, Richard Henderson, Jeff ++Holcomb, Jeff Law, Jim Lemke, Tom Lord, Bob Manson, Michael Meissner, ++Jason Merrill, Catherine Moore, Drew Moseley, Ken Raeburn, Gavin ++Romig-Koch, Rob Savoye, Jamie Smith, Mike Stump, Ian Taylor, Angela ++Thomas, Michael Tiemann, Tom Tromey, Ron Unrau, Jim Wilson, and David ++Zuhn have made contributions both large and small. ++ ++Andrew Cagney, Fernando Nasser, and Elena Zannoni, while working for ++Cygnus Solutions, implemented the original @sc{gdb/mi} interface. ++ ++Jim Blandy added support for preprocessor macros, while working for Red ++Hat. ++ ++Andrew Cagney designed @value{GDBN}'s architecture vector. Many ++people including Andrew Cagney, Stephane Carrez, Randolph Chung, Nick ++Duffek, Richard Henderson, Mark Kettenis, Grace Sainsbury, Kei ++Sakamoto, Yoshinori Sato, Michael Snyder, Andreas Schwab, Jason ++Thorpe, Corinna Vinschen, Ulrich Weigand, and Elena Zannoni, helped ++with the migration of old architectures to this new framework. ++ ++Andrew Cagney completely re-designed and re-implemented @value{GDBN}'s ++unwinder framework, this consisting of a fresh new design featuring ++frame IDs, independent frame sniffers, and the sentinel frame. Mark ++Kettenis implemented the @sc{dwarf 2} unwinder, Jeff Johnston the ++libunwind unwinder, and Andrew Cagney the dummy, sentinel, tramp, and ++trad unwinders. The architecture-specific changes, each involving a ++complete rewrite of the architecture's frame code, were carried out by ++Jim Blandy, Joel Brobecker, Kevin Buettner, Andrew Cagney, Stephane ++Carrez, Randolph Chung, Orjan Friberg, Richard Henderson, Daniel ++Jacobowitz, Jeff Johnston, Mark Kettenis, Theodore A. Roth, Kei ++Sakamoto, Yoshinori Sato, Michael Snyder, Corinna Vinschen, and Ulrich ++Weigand. ++ ++Christian Zankel, Ross Morley, Bob Wilson, and Maxim Grigoriev from ++Tensilica, Inc.@: contributed support for Xtensa processors. Others ++who have worked on the Xtensa port of @value{GDBN} in the past include ++Steve Tjiang, John Newlin, and Scott Foehner. ++ ++Michael Eager and staff of Xilinx, Inc., contributed support for the ++Xilinx MicroBlaze architecture. ++ ++Initial support for the FreeBSD/mips target and native configuration ++was developed by SRI International and the University of Cambridge ++Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 ++("CTSRD"), as part of the DARPA CRASH research programme. ++ ++Initial support for the FreeBSD/riscv target and native configuration ++was developed by SRI International and the University of Cambridge ++Computer Laboratory (Department of Computer Science and Technology) ++under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the DARPA ++SSITH research programme. ++ ++The original port to the OpenRISC 1000 is believed to be due to ++Alessandro Forin and Per Bothner. More recent ports have been the work ++of Jeremy Bennett, Franck Jullien, Stefan Wallentowitz and ++Stafford Horne. ++ ++Weimin Pan, David Faust and Jose E. Marchesi contributed support for ++the Linux kernel BPF virtual architecture. This work was sponsored by ++Oracle. ++ ++@node Sample Session ++@chapter A Sample @value{GDBN} Session ++ ++You can use this manual at your leisure to read all about @value{GDBN}. ++However, a handful of commands are enough to get started using the ++debugger. This chapter illustrates those commands. ++ ++@iftex ++In this sample session, we emphasize user input like this: @b{input}, ++to make it easier to pick out from the surrounding output. ++@end iftex ++ ++@c FIXME: this example may not be appropriate for some configs, where ++@c FIXME...primary interest is in remote use. ++ ++One of the preliminary versions of @sc{gnu} @code{m4} (a generic macro ++processor) exhibits the following bug: sometimes, when we change its ++quote strings from the default, the commands used to capture one macro ++definition within another stop working. In the following short @code{m4} ++session, we define a macro @code{foo} which expands to @code{0000}; we ++then use the @code{m4} built-in @code{defn} to define @code{bar} as the ++same thing. However, when we change the open quote string to ++@code{} and the close quote string to @code{}, the same ++procedure fails to define a new synonym @code{baz}: ++ ++@smallexample ++$ @b{cd gnu/m4} ++$ @b{./m4} ++@b{define(foo,0000)} ++ ++@b{foo} ++0000 ++@b{define(bar,defn(`foo'))} ++ ++@b{bar} ++0000 ++@b{changequote(,)} ++ ++@b{define(baz,defn(foo))} ++@b{baz} ++@b{Ctrl-d} ++m4: End of input: 0: fatal error: EOF in string ++@end smallexample ++ ++@noindent ++Let us use @value{GDBN} to try to see what is going on. ++ ++@smallexample ++$ @b{@value{GDBP} m4} ++@c FIXME: this falsifies the exact text played out, to permit smallbook ++@c FIXME... format to come out better. ++@value{GDBN} is free software and you are welcome to distribute copies ++ of it under certain conditions; type "show copying" to see ++ the conditions. ++There is absolutely no warranty for @value{GDBN}; type "show warranty" ++ for details. ++ ++@value{GDBN} @value{GDBVN}, Copyright 1999 Free Software Foundation, Inc... ++(@value{GDBP}) ++@end smallexample ++ ++@noindent ++@value{GDBN} reads only enough symbol data to know where to find the ++rest when needed; as a result, the first prompt comes up very quickly. ++We now tell @value{GDBN} to use a narrower display width than usual, so ++that examples fit in this manual. ++ ++@smallexample ++(@value{GDBP}) @b{set width 70} ++@end smallexample ++ ++@noindent ++We need to see how the @code{m4} built-in @code{changequote} works. ++Having looked at the source, we know the relevant subroutine is ++@code{m4_changequote}, so we set a breakpoint there with the @value{GDBN} ++@code{break} command. ++ ++@smallexample ++(@value{GDBP}) @b{break m4_changequote} ++Breakpoint 1 at 0x62f4: file builtin.c, line 879. ++@end smallexample ++ ++@noindent ++Using the @code{run} command, we start @code{m4} running under @value{GDBN} ++control; as long as control does not reach the @code{m4_changequote} ++subroutine, the program runs as usual: ++ ++@smallexample ++(@value{GDBP}) @b{run} ++Starting program: /work/Editorial/gdb/gnu/m4/m4 ++@b{define(foo,0000)} ++ ++@b{foo} ++0000 ++@end smallexample ++ ++@noindent ++To trigger the breakpoint, we call @code{changequote}. @value{GDBN} ++suspends execution of @code{m4}, displaying information about the ++context where it stops. ++ ++@smallexample ++@b{changequote(,)} ++ ++Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) ++ at builtin.c:879 ++879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3)) ++@end smallexample ++ ++@noindent ++Now we use the command @code{n} (@code{next}) to advance execution to ++the next line of the current function. ++ ++@smallexample ++(@value{GDBP}) @b{n} ++882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ ++ : nil, ++@end smallexample ++ ++@noindent ++@code{set_quotes} looks like a promising subroutine. We can go into it ++by using the command @code{s} (@code{step}) instead of @code{next}. ++@code{step} goes to the next line to be executed in @emph{any} ++subroutine, so it steps into @code{set_quotes}. ++ ++@smallexample ++(@value{GDBP}) @b{s} ++set_quotes (lq=0x34c78 "", rq=0x34c88 "") ++ at input.c:530 ++530 if (lquote != def_lquote) ++@end smallexample ++ ++@noindent ++The display that shows the subroutine where @code{m4} is now ++suspended (and its arguments) is called a stack frame display. It ++shows a summary of the stack. We can use the @code{backtrace} ++command (which can also be spelled @code{bt}), to see where we are ++in the stack as a whole: the @code{backtrace} command displays a ++stack frame for each active subroutine. ++ ++@smallexample ++(@value{GDBP}) @b{bt} ++#0 set_quotes (lq=0x34c78 "", rq=0x34c88 "") ++ at input.c:530 ++#1 0x6344 in m4_changequote (argc=3, argv=0x33c70) ++ at builtin.c:882 ++#2 0x8174 in expand_macro (sym=0x33320) at macro.c:242 ++#3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30) ++ at macro.c:71 ++#4 0x79dc in expand_input () at macro.c:40 ++#5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195 ++@end smallexample ++ ++@noindent ++We step through a few more lines to see what happens. The first two ++times, we can use @samp{s}; the next two times we use @code{n} to avoid ++falling into the @code{xstrdup} subroutine. ++ ++@smallexample ++(@value{GDBP}) @b{s} ++0x3b5c 532 if (rquote != def_rquote) ++(@value{GDBP}) @b{s} ++0x3b80 535 lquote = (lq == nil || *lq == '\0') ? \ ++def_lquote : xstrdup(lq); ++(@value{GDBP}) @b{n} ++536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ ++ : xstrdup(rq); ++(@value{GDBP}) @b{n} ++538 len_lquote = strlen(rquote); ++@end smallexample ++ ++@noindent ++The last line displayed looks a little odd; we can examine the variables ++@code{lquote} and @code{rquote} to see if they are in fact the new left ++and right quotes we specified. We use the command @code{p} ++(@code{print}) to see their values. ++ ++@smallexample ++(@value{GDBP}) @b{p lquote} ++$1 = 0x35d40 "" ++(@value{GDBP}) @b{p rquote} ++$2 = 0x35d50 "" ++@end smallexample ++ ++@noindent ++@code{lquote} and @code{rquote} are indeed the new left and right quotes. ++To look at some context, we can display ten lines of source ++surrounding the current line with the @code{l} (@code{list}) command. ++ ++@smallexample ++(@value{GDBP}) @b{l} ++533 xfree(rquote); ++534 ++535 lquote = (lq == nil || *lq == '\0') ? def_lquote\ ++ : xstrdup (lq); ++536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ ++ : xstrdup (rq); ++537 ++538 len_lquote = strlen(rquote); ++539 len_rquote = strlen(lquote); ++540 @} ++541 ++542 void ++@end smallexample ++ ++@noindent ++Let us step past the two lines that set @code{len_lquote} and ++@code{len_rquote}, and then examine the values of those variables. ++ ++@smallexample ++(@value{GDBP}) @b{n} ++539 len_rquote = strlen(lquote); ++(@value{GDBP}) @b{n} ++540 @} ++(@value{GDBP}) @b{p len_lquote} ++$3 = 9 ++(@value{GDBP}) @b{p len_rquote} ++$4 = 7 ++@end smallexample ++ ++@noindent ++That certainly looks wrong, assuming @code{len_lquote} and ++@code{len_rquote} are meant to be the lengths of @code{lquote} and ++@code{rquote} respectively. We can set them to better values using ++the @code{p} command, since it can print the value of ++any expression---and that expression can include subroutine calls and ++assignments. ++ ++@smallexample ++(@value{GDBP}) @b{p len_lquote=strlen(lquote)} ++$5 = 7 ++(@value{GDBP}) @b{p len_rquote=strlen(rquote)} ++$6 = 9 ++@end smallexample ++ ++@noindent ++Is that enough to fix the problem of using the new quotes with the ++@code{m4} built-in @code{defn}? We can allow @code{m4} to continue ++executing with the @code{c} (@code{continue}) command, and then try the ++example that caused trouble initially: ++ ++@smallexample ++(@value{GDBP}) @b{c} ++Continuing. ++ ++@b{define(baz,defn(foo))} ++ ++baz ++0000 ++@end smallexample ++ ++@noindent ++Success! The new quotes now work just as well as the default ones. The ++problem seems to have been just the two typos defining the wrong ++lengths. We allow @code{m4} exit by giving it an EOF as input: ++ ++@smallexample ++@b{Ctrl-d} ++Program exited normally. ++@end smallexample ++ ++@noindent ++The message @samp{Program exited normally.} is from @value{GDBN}; it ++indicates @code{m4} has finished executing. We can end our @value{GDBN} ++session with the @value{GDBN} @code{quit} command. ++ ++@smallexample ++(@value{GDBP}) @b{quit} ++@end smallexample ++ ++@node Invocation ++@chapter Getting In and Out of @value{GDBN} ++ ++This chapter discusses how to start @value{GDBN}, and how to get out of it. ++The essentials are: ++@itemize @bullet ++@item ++type @samp{@value{GDBP}} to start @value{GDBN}. ++@item ++type @kbd{quit} or @kbd{Ctrl-d} to exit. ++@end itemize ++ ++@menu ++* Invoking GDB:: How to start @value{GDBN} ++* Quitting GDB:: How to quit @value{GDBN} ++* Shell Commands:: How to use shell commands inside @value{GDBN} ++* Logging Output:: How to log @value{GDBN}'s output to a file ++@end menu ++ ++@node Invoking GDB ++@section Invoking @value{GDBN} ++ ++Invoke @value{GDBN} by running the program @code{@value{GDBP}}. Once started, ++@value{GDBN} reads commands from the terminal until you tell it to exit. ++ ++You can also run @code{@value{GDBP}} with a variety of arguments and options, ++to specify more of your debugging environment at the outset. ++ ++The command-line options described here are designed ++to cover a variety of situations; in some environments, some of these ++options may effectively be unavailable. ++ ++The most usual way to start @value{GDBN} is with one argument, ++specifying an executable program: ++ ++@smallexample ++@value{GDBP} @var{program} ++@end smallexample ++ ++@noindent ++You can also start with both an executable program and a core file ++specified: ++ ++@smallexample ++@value{GDBP} @var{program} @var{core} ++@end smallexample ++ ++You can, instead, specify a process ID as a second argument or use option ++@code{-p}, if you want to debug a running process: ++ ++@smallexample ++@value{GDBP} @var{program} 1234 ++@value{GDBP} -p 1234 ++@end smallexample ++ ++@noindent ++would attach @value{GDBN} to process @code{1234}. With option @option{-p} you ++can omit the @var{program} filename. ++ ++Taking advantage of the second command-line argument requires a fairly ++complete operating system; when you use @value{GDBN} as a remote ++debugger attached to a bare board, there may not be any notion of ++``process'', and there is often no way to get a core dump. @value{GDBN} ++will warn you if it is unable to attach or to read core dumps. ++ ++You can optionally have @code{@value{GDBP}} pass any arguments after the ++executable file to the inferior using @code{--args}. This option stops ++option processing. ++@smallexample ++@value{GDBP} --args gcc -O2 -c foo.c ++@end smallexample ++This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set ++@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}. ++ ++You can run @code{@value{GDBP}} without printing the front material, which describes ++@value{GDBN}'s non-warranty, by specifying @code{--silent} ++(or @code{-q}/@code{--quiet}): ++ ++@smallexample ++@value{GDBP} --silent ++@end smallexample ++ ++@noindent ++You can further control how @value{GDBN} starts up by using command-line ++options. @value{GDBN} itself can remind you of the options available. ++ ++@noindent ++Type ++ ++@smallexample ++@value{GDBP} -help ++@end smallexample ++ ++@noindent ++to display all available options and briefly describe their use ++(@samp{@value{GDBP} -h} is a shorter equivalent). ++ ++All options and command line arguments you give are processed ++in sequential order. The order makes a difference when the ++@samp{-x} option is used. ++ ++ ++@menu ++* File Options:: Choosing files ++* Mode Options:: Choosing modes ++* Startup:: What @value{GDBN} does during startup ++@end menu ++ ++@node File Options ++@subsection Choosing Files ++ ++When @value{GDBN} starts, it reads any arguments other than options as ++specifying an executable file and core file (or process ID). This is ++the same as if the arguments were specified by the @samp{-se} and ++@samp{-c} (or @samp{-p}) options respectively. (@value{GDBN} reads the ++first argument that does not have an associated option flag as ++equivalent to the @samp{-se} option followed by that argument; and the ++second argument that does not have an associated option flag, if any, as ++equivalent to the @samp{-c}/@samp{-p} option followed by that argument.) ++If the second argument begins with a decimal digit, @value{GDBN} will ++first attempt to attach to it as a process, and if that fails, attempt ++to open it as a corefile. If you have a corefile whose name begins with ++a digit, you can prevent @value{GDBN} from treating it as a pid by ++prefixing it with @file{./}, e.g.@: @file{./12345}. ++ ++If @value{GDBN} has not been configured to included core file support, ++such as for most embedded targets, then it will complain about a second ++argument and ignore it. ++ ++Many options have both long and short forms; both are shown in the ++following list. @value{GDBN} also recognizes the long forms if you truncate ++them, so long as enough of the option is present to be unambiguous. ++(If you prefer, you can flag option arguments with @samp{--} rather ++than @samp{-}, though we illustrate the more usual convention.) ++ ++@c NOTE: the @cindex entries here use double dashes ON PURPOSE. This ++@c way, both those who look for -foo and --foo in the index, will find ++@c it. ++ ++@table @code ++@item -symbols @var{file} ++@itemx -s @var{file} ++@cindex @code{--symbols} ++@cindex @code{-s} ++Read symbol table from file @var{file}. ++ ++@item -exec @var{file} ++@itemx -e @var{file} ++@cindex @code{--exec} ++@cindex @code{-e} ++Use file @var{file} as the executable file to execute when appropriate, ++and for examining pure data in conjunction with a core dump. ++ ++@item -se @var{file} ++@cindex @code{--se} ++Read symbol table from file @var{file} and use it as the executable ++file. ++ ++@item -core @var{file} ++@itemx -c @var{file} ++@cindex @code{--core} ++@cindex @code{-c} ++Use file @var{file} as a core dump to examine. ++ ++@item -pid @var{number} ++@itemx -p @var{number} ++@cindex @code{--pid} ++@cindex @code{-p} ++Connect to process ID @var{number}, as with the @code{attach} command. ++ ++@item -command @var{file} ++@itemx -x @var{file} ++@cindex @code{--command} ++@cindex @code{-x} ++Execute commands from file @var{file}. The contents of this file is ++evaluated exactly as the @code{source} command would. ++@xref{Command Files,, Command files}. ++ ++@item -eval-command @var{command} ++@itemx -ex @var{command} ++@cindex @code{--eval-command} ++@cindex @code{-ex} ++Execute a single @value{GDBN} command. ++ ++This option may be used multiple times to call multiple commands. It may ++also be interleaved with @samp{-command} as required. ++ ++@smallexample ++@value{GDBP} -ex 'target sim' -ex 'load' \ ++ -x setbreakpoints -ex 'run' a.out ++@end smallexample ++ ++@item -init-command @var{file} ++@itemx -ix @var{file} ++@cindex @code{--init-command} ++@cindex @code{-ix} ++Execute commands from file @var{file} before loading the inferior (but ++after loading gdbinit files). ++@xref{Startup}. ++ ++@item -init-eval-command @var{command} ++@itemx -iex @var{command} ++@cindex @code{--init-eval-command} ++@cindex @code{-iex} ++Execute a single @value{GDBN} command before loading the inferior (but ++after loading gdbinit files). ++@xref{Startup}. ++ ++@item -directory @var{directory} ++@itemx -d @var{directory} ++@cindex @code{--directory} ++@cindex @code{-d} ++Add @var{directory} to the path to search for source and script files. ++ ++@item -r ++@itemx -readnow ++@cindex @code{--readnow} ++@cindex @code{-r} ++Read each symbol file's entire symbol table immediately, rather than ++the default, which is to read it incrementally as it is needed. ++This makes startup slower, but makes future operations faster. ++ ++@item --readnever ++@anchor{--readnever} ++@cindex @code{--readnever}, command-line option ++Do not read each symbol file's symbolic debug information. This makes ++startup faster but at the expense of not being able to perform ++symbolic debugging. DWARF unwind information is also not read, ++meaning backtraces may become incomplete or inaccurate. One use of ++this is when a user simply wants to do the following sequence: attach, ++dump core, detach. Loading the debugging information in this case is ++an unnecessary cause of delay. ++@end table ++ ++@node Mode Options ++@subsection Choosing Modes ++ ++You can run @value{GDBN} in various alternative modes---for example, in ++batch mode or quiet mode. ++ ++@table @code ++@anchor{-nx} ++@item -nx ++@itemx -n ++@cindex @code{--nx} ++@cindex @code{-n} ++Do not execute commands found in any initialization file. ++There are three init files, loaded in the following order: ++ ++@table @code ++@item @file{system.gdbinit} ++This is the system-wide init file. ++Its location is specified with the @code{--with-system-gdbinit} ++configure option (@pxref{System-wide configuration}). ++It is loaded first when @value{GDBN} starts, before command line options ++have been processed. ++@item @file{system.gdbinit.d} ++This is the system-wide init directory. ++Its location is specified with the @code{--with-system-gdbinit-dir} ++configure option (@pxref{System-wide configuration}). ++Files in this directory are loaded in alphabetical order immediately after ++system.gdbinit (if enabled) when @value{GDBN} starts, before command line ++options have been processed. Files need to have a recognized scripting ++language extension (@file{.py}/@file{.scm}) or be named with a @file{.gdb} ++extension to be interpreted as regular @value{GDBN} commands. @value{GDBN} ++will not recurse into any subdirectories of this directory. ++@item @file{~/.gdbinit} ++This is the init file in your home directory. ++It is loaded next, after @file{system.gdbinit}, and before ++command options have been processed. ++@item @file{./.gdbinit} ++This is the init file in the current directory. ++It is loaded last, after command line options other than @code{-x} and ++@code{-ex} have been processed. Command line options @code{-x} and ++@code{-ex} are processed last, after @file{./.gdbinit} has been loaded. ++@end table ++ ++For further documentation on startup processing, @xref{Startup}. ++For documentation on how to write command files, ++@xref{Command Files,,Command Files}. ++ ++@anchor{-nh} ++@item -nh ++@cindex @code{--nh} ++Do not execute commands found in @file{~/.gdbinit}, the init file ++in your home directory. ++@xref{Startup}. ++ ++@item -quiet ++@itemx -silent ++@itemx -q ++@cindex @code{--quiet} ++@cindex @code{--silent} ++@cindex @code{-q} ++``Quiet''. Do not print the introductory and copyright messages. These ++messages are also suppressed in batch mode. ++ ++@item -batch ++@cindex @code{--batch} ++Run in batch mode. Exit with status @code{0} after processing all the ++command files specified with @samp{-x} (and all commands from ++initialization files, if not inhibited with @samp{-n}). Exit with ++nonzero status if an error occurs in executing the @value{GDBN} commands ++in the command files. Batch mode also disables pagination, sets unlimited ++terminal width and height @pxref{Screen Size}, and acts as if @kbd{set confirm ++off} were in effect (@pxref{Messages/Warnings}). ++ ++Batch mode may be useful for running @value{GDBN} as a filter, for ++example to download and run a program on another computer; in order to ++make this more useful, the message ++ ++@smallexample ++Program exited normally. ++@end smallexample ++ ++@noindent ++(which is ordinarily issued whenever a program running under ++@value{GDBN} control terminates) is not issued when running in batch ++mode. ++ ++@item -batch-silent ++@cindex @code{--batch-silent} ++Run in batch mode exactly like @samp{-batch}, but totally silently. All ++@value{GDBN} output to @code{stdout} is prevented (@code{stderr} is ++unaffected). This is much quieter than @samp{-silent} and would be useless ++for an interactive session. ++ ++This is particularly useful when using targets that give @samp{Loading section} ++messages, for example. ++ ++Note that targets that give their output via @value{GDBN}, as opposed to ++writing directly to @code{stdout}, will also be made silent. ++ ++@item -return-child-result ++@cindex @code{--return-child-result} ++The return code from @value{GDBN} will be the return code from the child ++process (the process being debugged), with the following exceptions: ++ ++@itemize @bullet ++@item ++@value{GDBN} exits abnormally. E.g., due to an incorrect argument or an ++internal error. In this case the exit code is the same as it would have been ++without @samp{-return-child-result}. ++@item ++The user quits with an explicit value. E.g., @samp{quit 1}. ++@item ++The child process never runs, or is not allowed to terminate, in which case ++the exit code will be -1. ++@end itemize ++ ++This option is useful in conjunction with @samp{-batch} or @samp{-batch-silent}, ++when @value{GDBN} is being used as a remote program loader or simulator ++interface. ++ ++@item -nowindows ++@itemx -nw ++@cindex @code{--nowindows} ++@cindex @code{-nw} ++``No windows''. If @value{GDBN} comes with a graphical user interface ++(GUI) built in, then this option tells @value{GDBN} to only use the command-line ++interface. If no GUI is available, this option has no effect. ++ ++@item -windows ++@itemx -w ++@cindex @code{--windows} ++@cindex @code{-w} ++If @value{GDBN} includes a GUI, then this option requires it to be ++used if possible. ++ ++@item -cd @var{directory} ++@cindex @code{--cd} ++Run @value{GDBN} using @var{directory} as its working directory, ++instead of the current directory. ++ ++@item -data-directory @var{directory} ++@itemx -D @var{directory} ++@cindex @code{--data-directory} ++@cindex @code{-D} ++Run @value{GDBN} using @var{directory} as its data directory. ++The data directory is where @value{GDBN} searches for its ++auxiliary files. @xref{Data Files}. ++ ++@item -fullname ++@itemx -f ++@cindex @code{--fullname} ++@cindex @code{-f} ++@sc{gnu} Emacs sets this option when it runs @value{GDBN} as a ++subprocess. It tells @value{GDBN} to output the full file name and line ++number in a standard, recognizable fashion each time a stack frame is ++displayed (which includes each time your program stops). This ++recognizable format looks like two @samp{\032} characters, followed by ++the file name, line number and character position separated by colons, ++and a newline. The Emacs-to-@value{GDBN} interface program uses the two ++@samp{\032} characters as a signal to display the source code for the ++frame. ++ ++@item -annotate @var{level} ++@cindex @code{--annotate} ++This option sets the @dfn{annotation level} inside @value{GDBN}. Its ++effect is identical to using @samp{set annotate @var{level}} ++(@pxref{Annotations}). The annotation @var{level} controls how much ++information @value{GDBN} prints together with its prompt, values of ++expressions, source lines, and other types of output. Level 0 is the ++normal, level 1 is for use when @value{GDBN} is run as a subprocess of ++@sc{gnu} Emacs, level 3 is the maximum annotation suitable for programs ++that control @value{GDBN}, and level 2 has been deprecated. ++ ++The annotation mechanism has largely been superseded by @sc{gdb/mi} ++(@pxref{GDB/MI}). ++ ++@item --args ++@cindex @code{--args} ++Change interpretation of command line so that arguments following the ++executable file are passed as command line arguments to the inferior. ++This option stops option processing. ++ ++@item -baud @var{bps} ++@itemx -b @var{bps} ++@cindex @code{--baud} ++@cindex @code{-b} ++Set the line speed (baud rate or bits per second) of any serial ++interface used by @value{GDBN} for remote debugging. ++ ++@item -l @var{timeout} ++@cindex @code{-l} ++Set the timeout (in seconds) of any communication used by @value{GDBN} ++for remote debugging. ++ ++@item -tty @var{device} ++@itemx -t @var{device} ++@cindex @code{--tty} ++@cindex @code{-t} ++Run using @var{device} for your program's standard input and output. ++@c FIXME: kingdon thinks there is more to -tty. Investigate. ++ ++@c resolve the situation of these eventually ++@item -tui ++@cindex @code{--tui} ++Activate the @dfn{Text User Interface} when starting. The Text User ++Interface manages several text windows on the terminal, showing ++source, assembly, registers and @value{GDBN} command outputs ++(@pxref{TUI, ,@value{GDBN} Text User Interface}). Do not use this ++option if you run @value{GDBN} from Emacs (@pxref{Emacs, , ++Using @value{GDBN} under @sc{gnu} Emacs}). ++ ++@item -interpreter @var{interp} ++@cindex @code{--interpreter} ++Use the interpreter @var{interp} for interface with the controlling ++program or device. This option is meant to be set by programs which ++communicate with @value{GDBN} using it as a back end. ++@xref{Interpreters, , Command Interpreters}. ++ ++@samp{--interpreter=mi} (or @samp{--interpreter=mi3}) causes ++@value{GDBN} to use the @dfn{@sc{gdb/mi} interface} version 3 (@pxref{GDB/MI, , ++The @sc{gdb/mi} Interface}) included since @value{GDBN} version 9.1. @sc{gdb/mi} ++version 2 (@code{mi2}), included in @value{GDBN} 6.0 and version 1 (@code{mi1}), ++included in @value{GDBN} 5.3, are also available. Earlier @sc{gdb/mi} ++interfaces are no longer supported. ++ ++@item -write ++@cindex @code{--write} ++Open the executable and core files for both reading and writing. This ++is equivalent to the @samp{set write on} command inside @value{GDBN} ++(@pxref{Patching}). ++ ++@item -statistics ++@cindex @code{--statistics} ++This option causes @value{GDBN} to print statistics about time and ++memory usage after it completes each command and returns to the prompt. ++ ++@item -version ++@cindex @code{--version} ++This option causes @value{GDBN} to print its version number and ++no-warranty blurb, and exit. ++ ++@item -configuration ++@cindex @code{--configuration} ++This option causes @value{GDBN} to print details about its build-time ++configuration parameters, and then exit. These details can be ++important when reporting @value{GDBN} bugs (@pxref{GDB Bugs}). ++ ++@end table ++ ++@node Startup ++@subsection What @value{GDBN} Does During Startup ++@cindex @value{GDBN} startup ++ ++Here's the description of what @value{GDBN} does during session startup: ++ ++@enumerate ++@item ++Sets up the command interpreter as specified by the command line ++(@pxref{Mode Options, interpreter}). ++ ++@item ++@cindex init file ++Reads the system-wide @dfn{init file} (if @option{--with-system-gdbinit} was ++used when building @value{GDBN}; @pxref{System-wide configuration, ++ ,System-wide configuration and settings}) and the files in the system-wide ++gdbinit directory (if @option{--with-system-gdbinit-dir} was used) and executes ++all the commands in those files. The files need to be named with a @file{.gdb} ++extension to be interpreted as @value{GDBN} commands, or they can be written ++in a supported scripting language with an appropriate file extension. ++ ++@anchor{Home Directory Init File} ++@item ++Reads the init file (if any) in your home directory@footnote{On ++DOS/Windows systems, the home directory is the one pointed to by the ++@code{HOME} environment variable.} and executes all the commands in ++that file. ++ ++@anchor{Option -init-eval-command} ++@item ++Executes commands and command files specified by the @samp{-iex} and ++@samp{-ix} options in their specified order. Usually you should use the ++@samp{-ex} and @samp{-x} options instead, but this way you can apply ++settings before @value{GDBN} init files get executed and before inferior ++gets loaded. ++ ++@item ++Processes command line options and operands. ++ ++@anchor{Init File in the Current Directory during Startup} ++@item ++Reads and executes the commands from init file (if any) in the current ++working directory as long as @samp{set auto-load local-gdbinit} is set to ++@samp{on} (@pxref{Init File in the Current Directory}). ++This is only done if the current directory is ++different from your home directory. Thus, you can have more than one ++init file, one generic in your home directory, and another, specific ++to the program you are debugging, in the directory where you invoke ++@value{GDBN}. ++ ++@item ++If the command line specified a program to debug, or a process to ++attach to, or a core file, @value{GDBN} loads any auto-loaded ++scripts provided for the program or for its loaded shared libraries. ++@xref{Auto-loading}. ++ ++If you wish to disable the auto-loading during startup, ++you must do something like the following: ++ ++@smallexample ++$ gdb -iex "set auto-load python-scripts off" myprogram ++@end smallexample ++ ++Option @samp{-ex} does not work because the auto-loading is then turned ++off too late. ++ ++@item ++Executes commands and command files specified by the @samp{-ex} and ++@samp{-x} options in their specified order. @xref{Command Files}, for ++more details about @value{GDBN} command files. ++ ++@item ++Reads the command history recorded in the @dfn{history file}. ++@xref{Command History}, for more details about the command history and the ++files where @value{GDBN} records it. ++@end enumerate ++ ++Init files use the same syntax as @dfn{command files} (@pxref{Command ++Files}) and are processed by @value{GDBN} in the same way. The init ++file in your home directory can set options (such as @samp{set ++complaints}) that affect subsequent processing of command line options ++and operands. Init files are not executed if you use the @samp{-nx} ++option (@pxref{Mode Options, ,Choosing Modes}). ++ ++To display the list of init files loaded by gdb at startup, you ++can use @kbd{gdb --help}. ++ ++@cindex init file name ++@cindex @file{.gdbinit} ++@cindex @file{gdb.ini} ++The @value{GDBN} init files are normally called @file{.gdbinit}. ++The DJGPP port of @value{GDBN} uses the name @file{gdb.ini}, due to ++the limitations of file names imposed by DOS filesystems. The Windows ++port of @value{GDBN} uses the standard name, but if it finds a ++@file{gdb.ini} file in your home directory, it warns you about that ++and suggests to rename the file to the standard name. ++ ++ ++@node Quitting GDB ++@section Quitting @value{GDBN} ++@cindex exiting @value{GDBN} ++@cindex leaving @value{GDBN} ++ ++@table @code ++@kindex quit @r{[}@var{expression}@r{]} ++@kindex q @r{(@code{quit})} ++@item quit @r{[}@var{expression}@r{]} ++@itemx q ++To exit @value{GDBN}, use the @code{quit} command (abbreviated ++@code{q}), or type an end-of-file character (usually @kbd{Ctrl-d}). If you ++do not supply @var{expression}, @value{GDBN} will terminate normally; ++otherwise it will terminate using the result of @var{expression} as the ++error code. ++@end table ++ ++@cindex interrupt ++An interrupt (often @kbd{Ctrl-c}) does not exit from @value{GDBN}, but rather ++terminates the action of any @value{GDBN} command that is in progress and ++returns to @value{GDBN} command level. It is safe to type the interrupt ++character at any time because @value{GDBN} does not allow it to take effect ++until a time when it is safe. ++ ++If you have been using @value{GDBN} to control an attached process or ++device, you can release it with the @code{detach} command ++(@pxref{Attach, ,Debugging an Already-running Process}). ++ ++@node Shell Commands ++@section Shell Commands ++ ++If you need to execute occasional shell commands during your ++debugging session, there is no need to leave or suspend @value{GDBN}; you can ++just use the @code{shell} command. ++ ++@table @code ++@kindex shell ++@kindex ! ++@cindex shell escape ++@item shell @var{command-string} ++@itemx !@var{command-string} ++Invoke a standard shell to execute @var{command-string}. ++Note that no space is needed between @code{!} and @var{command-string}. ++On GNU and Unix systems, the environment variable @code{SHELL}, if it ++exists, determines which shell to run. Otherwise @value{GDBN} uses ++the default shell (@file{/bin/sh} on GNU and Unix systems, ++@file{cmd.exe} on MS-Windows, @file{COMMAND.COM} on MS-DOS, etc.). ++@end table ++ ++The utility @code{make} is often needed in development environments. ++You do not have to use the @code{shell} command for this purpose in ++@value{GDBN}: ++ ++@table @code ++@kindex make ++@cindex calling make ++@item make @var{make-args} ++Execute the @code{make} program with the specified ++arguments. This is equivalent to @samp{shell make @var{make-args}}. ++@end table ++ ++@table @code ++@kindex pipe ++@kindex | ++@cindex send the output of a gdb command to a shell command ++@anchor{pipe} ++@item pipe [@var{command}] | @var{shell_command} ++@itemx | [@var{command}] | @var{shell_command} ++@itemx pipe -d @var{delim} @var{command} @var{delim} @var{shell_command} ++@itemx | -d @var{delim} @var{command} @var{delim} @var{shell_command} ++Executes @var{command} and sends its output to @var{shell_command}. ++Note that no space is needed around @code{|}. ++If no @var{command} is provided, the last command executed is repeated. ++ ++In case the @var{command} contains a @code{|}, the option @code{-d @var{delim}} ++can be used to specify an alternate delimiter string @var{delim} that separates ++the @var{command} from the @var{shell_command}. ++ ++Example: ++@smallexample ++@group ++(gdb) p var ++$1 = @{ ++ black = 144, ++ red = 233, ++ green = 377, ++ blue = 610, ++ white = 987 ++@} ++@end group ++@group ++(gdb) pipe p var|wc ++ 7 19 80 ++(gdb) |p var|wc -l ++7 ++@end group ++@group ++(gdb) p /x var ++$4 = @{ ++ black = 0x90, ++ red = 0xe9, ++ green = 0x179, ++ blue = 0x262, ++ white = 0x3db ++@} ++(gdb) ||grep red ++ red => 0xe9, ++@end group ++@group ++(gdb) | -d ! echo this contains a | char\n ! sed -e 's/|/PIPE/' ++this contains a PIPE char ++(gdb) | -d xxx echo this contains a | char!\n xxx sed -e 's/|/PIPE/' ++this contains a PIPE char! ++(gdb) ++@end group ++@end smallexample ++@end table ++ ++The convenience variables @code{$_shell_exitcode} and @code{$_shell_exitsignal} ++can be used to examine the exit status of the last shell command launched ++by @code{shell}, @code{make}, @code{pipe} and @code{|}. ++@xref{Convenience Vars,, Convenience Variables}. ++ ++@node Logging Output ++@section Logging Output ++@cindex logging @value{GDBN} output ++@cindex save @value{GDBN} output to a file ++ ++You may want to save the output of @value{GDBN} commands to a file. ++There are several commands to control @value{GDBN}'s logging. ++ ++@table @code ++@kindex set logging ++@item set logging on ++Enable logging. ++@item set logging off ++Disable logging. ++@cindex logging file name ++@item set logging file @var{file} ++Change the name of the current logfile. The default logfile is @file{gdb.txt}. ++@item set logging overwrite [on|off] ++By default, @value{GDBN} will append to the logfile. Set @code{overwrite} if ++you want @code{set logging on} to overwrite the logfile instead. ++@item set logging redirect [on|off] ++By default, @value{GDBN} output will go to both the terminal and the logfile. ++Set @code{redirect} if you want output to go only to the log file. ++@item set logging debugredirect [on|off] ++By default, @value{GDBN} debug output will go to both the terminal and the logfile. ++Set @code{debugredirect} if you want debug output to go only to the log file. ++@kindex show logging ++@item show logging ++Show the current values of the logging settings. ++@end table ++ ++You can also redirect the output of a @value{GDBN} command to a ++shell command. @xref{pipe}. ++@node Commands ++@chapter @value{GDBN} Commands ++ ++You can abbreviate a @value{GDBN} command to the first few letters of the command ++name, if that abbreviation is unambiguous; and you can repeat certain ++@value{GDBN} commands by typing just @key{RET}. You can also use the @key{TAB} ++key to get @value{GDBN} to fill out the rest of a word in a command (or to ++show you the alternatives available, if there is more than one possibility). ++ ++@menu ++* Command Syntax:: How to give commands to @value{GDBN} ++* Command Settings:: How to change default behavior of commands ++* Completion:: Command completion ++* Command Options:: Command options ++* Command aliases default args:: Automatically prepend default arguments to user-defined aliases ++* Help:: How to ask @value{GDBN} for help ++@end menu ++ ++@node Command Syntax ++@section Command Syntax ++ ++A @value{GDBN} command is a single line of input. There is no limit on ++how long it can be. It starts with a command name, which is followed by ++arguments whose meaning depends on the command name. For example, the ++command @code{step} accepts an argument which is the number of times to ++step, as in @samp{step 5}. You can also use the @code{step} command ++with no arguments. Some commands do not allow any arguments. ++ ++@cindex abbreviation ++@value{GDBN} command names may always be truncated if that abbreviation is ++unambiguous. Other possible command abbreviations are listed in the ++documentation for individual commands. In some cases, even ambiguous ++abbreviations are allowed; for example, @code{s} is specially defined as ++equivalent to @code{step} even though there are other commands whose ++names start with @code{s}. You can test abbreviations by using them as ++arguments to the @code{help} command. ++ ++@cindex repeating commands ++@kindex RET @r{(repeat last command)} ++A blank line as input to @value{GDBN} (typing just @key{RET}) means to ++repeat the previous command. Certain commands (for example, @code{run}) ++will not repeat this way; these are commands whose unintentional ++repetition might cause trouble and which you are unlikely to want to ++repeat. User-defined commands can disable this feature; see ++@ref{Define, dont-repeat}. ++ ++The @code{list} and @code{x} commands, when you repeat them with ++@key{RET}, construct new arguments rather than repeating ++exactly as typed. This permits easy scanning of source or memory. ++ ++@value{GDBN} can also use @key{RET} in another way: to partition lengthy ++output, in a way similar to the common utility @code{more} ++(@pxref{Screen Size,,Screen Size}). Since it is easy to press one ++@key{RET} too many in this situation, @value{GDBN} disables command ++repetition after any command that generates this sort of display. ++ ++@kindex # @r{(a comment)} ++@cindex comment ++Any text from a @kbd{#} to the end of the line is a comment; it does ++nothing. This is useful mainly in command files (@pxref{Command ++Files,,Command Files}). ++ ++@cindex repeating command sequences ++@kindex Ctrl-o @r{(operate-and-get-next)} ++The @kbd{Ctrl-o} binding is useful for repeating a complex sequence of ++commands. This command accepts the current line, like @key{RET}, and ++then fetches the next line relative to the current line from the history ++for editing. ++ ++ ++@node Command Settings ++@section Command Settings ++@cindex default behavior of commands, changing ++@cindex default settings, changing ++ ++Many commands change their behavior according to command-specific ++variables or settings. These settings can be changed with the ++@code{set} subcommands. For example, the @code{print} command ++(@pxref{Data, ,Examining Data}) prints arrays differently depending on ++settings changeable with the commands @code{set print elements ++NUMBER-OF-ELEMENTS} and @code{set print array-indexes}, among others. ++ ++You can change these settings to your preference in the gdbinit files ++loaded at @value{GDBN} startup. @xref{Startup}. ++ ++The settings can also be changed interactively during the debugging ++session. For example, to change the limit of array elements to print, ++you can do the following: ++@smallexample ++(@value{GDBN}) set print elements 10 ++(@value{GDBN}) print some_array ++$1 = @{0, 10, 20, 30, 40, 50, 60, 70, 80, 90...@} ++@end smallexample ++ ++The above @code{set print elements 10} command changes the number of ++elements to print from the default of 200 to 10. If you only intend ++this limit of 10 to be used for printing @code{some_array}, then you ++must restore the limit back to 200, with @code{set print elements ++200}. ++ ++Some commands allow overriding settings with command options. For ++example, the @code{print} command supports a number of options that ++allow overriding relevant global print settings as set by @code{set ++print} subcommands. @xref{print options}. The example above could be ++rewritten as: ++@smallexample ++(@value{GDBN}) print -elements 10 -- some_array ++$1 = @{0, 10, 20, 30, 40, 50, 60, 70, 80, 90...@} ++@end smallexample ++ ++Alternatively, you can use the @code{with} command to change a setting ++temporarily, for the duration of a command invocation. ++ ++@table @code ++@kindex with command ++@kindex w @r{(@code{with})} ++@cindex settings ++@cindex temporarily change settings ++@item with @var{setting} [@var{value}] [-- @var{command}] ++@itemx w @var{setting} [@var{value}] [-- @var{command}] ++Temporarily set @var{setting} to @var{value} for the duration of ++@var{command}. ++ ++@var{setting} is any setting you can change with the @code{set} ++subcommands. @var{value} is the value to assign to @code{setting} ++while running @code{command}. ++ ++If no @var{command} is provided, the last command executed is ++repeated. ++ ++If a @var{command} is provided, it must be preceded by a double dash ++(@code{--}) separator. This is required because some settings accept ++free-form arguments, such as expressions or filenames. ++ ++For example, the command ++@smallexample ++(@value{GDBN}) with print array on -- print some_array ++@end smallexample ++@noindent ++is equivalent to the following 3 commands: ++@smallexample ++(@value{GDBN}) set print array on ++(@value{GDBN}) print some_array ++(@value{GDBN}) set print array off ++@end smallexample ++ ++The @code{with} command is particularly useful when you want to ++override a setting while running user-defined commands, or commands ++defined in Python or Guile. @xref{Extending GDB,, Extending GDB}. ++ ++@smallexample ++(@value{GDBN}) with print pretty on -- my_complex_command ++@end smallexample ++ ++To change several settings for the same command, you can nest ++@code{with} commands. For example, @code{with language ada -- with ++print elements 10} temporarily changes the language to Ada and sets a ++limit of 10 elements to print for arrays and strings. ++ ++@end table ++ ++@node Completion ++@section Command Completion ++ ++@cindex completion ++@cindex word completion ++@value{GDBN} can fill in the rest of a word in a command for you, if there is ++only one possibility; it can also show you what the valid possibilities ++are for the next word in a command, at any time. This works for @value{GDBN} ++commands, @value{GDBN} subcommands, command options, and the names of symbols ++in your program. ++ ++Press the @key{TAB} key whenever you want @value{GDBN} to fill out the rest ++of a word. If there is only one possibility, @value{GDBN} fills in the ++word, and waits for you to finish the command (or press @key{RET} to ++enter it). For example, if you type ++ ++@c FIXME "@key" does not distinguish its argument sufficiently to permit ++@c complete accuracy in these examples; space introduced for clarity. ++@c If texinfo enhancements make it unnecessary, it would be nice to ++@c replace " @key" by "@key" in the following... ++@smallexample ++(@value{GDBP}) info bre @key{TAB} ++@end smallexample ++ ++@noindent ++@value{GDBN} fills in the rest of the word @samp{breakpoints}, since that is ++the only @code{info} subcommand beginning with @samp{bre}: ++ ++@smallexample ++(@value{GDBP}) info breakpoints ++@end smallexample ++ ++@noindent ++You can either press @key{RET} at this point, to run the @code{info ++breakpoints} command, or backspace and enter something else, if ++@samp{breakpoints} does not look like the command you expected. (If you ++were sure you wanted @code{info breakpoints} in the first place, you ++might as well just type @key{RET} immediately after @samp{info bre}, ++to exploit command abbreviations rather than command completion). ++ ++If there is more than one possibility for the next word when you press ++@key{TAB}, @value{GDBN} sounds a bell. You can either supply more ++characters and try again, or just press @key{TAB} a second time; ++@value{GDBN} displays all the possible completions for that word. For ++example, you might want to set a breakpoint on a subroutine whose name ++begins with @samp{make_}, but when you type @kbd{b make_@key{TAB}} @value{GDBN} ++just sounds the bell. Typing @key{TAB} again displays all the ++function names in your program that begin with those characters, for ++example: ++ ++@smallexample ++(@value{GDBP}) b make_ @key{TAB} ++@exdent @value{GDBN} sounds bell; press @key{TAB} again, to see: ++make_a_section_from_file make_environ ++make_abs_section make_function_type ++make_blockvector make_pointer_type ++make_cleanup make_reference_type ++make_command make_symbol_completion_list ++(@value{GDBP}) b make_ ++@end smallexample ++ ++@noindent ++After displaying the available possibilities, @value{GDBN} copies your ++partial input (@samp{b make_} in the example) so you can finish the ++command. ++ ++If you just want to see the list of alternatives in the first place, you ++can press @kbd{M-?} rather than pressing @key{TAB} twice. @kbd{M-?} ++means @kbd{@key{META} ?}. You can type this either by holding down a ++key designated as the @key{META} shift on your keyboard (if there is ++one) while typing @kbd{?}, or as @key{ESC} followed by @kbd{?}. ++ ++If the number of possible completions is large, @value{GDBN} will ++print as much of the list as it has collected, as well as a message ++indicating that the list may be truncated. ++ ++@smallexample ++(@value{GDBP}) b m@key{TAB}@key{TAB} ++main ++<... the rest of the possible completions ...> ++*** List may be truncated, max-completions reached. *** ++(@value{GDBP}) b m ++@end smallexample ++ ++@noindent ++This behavior can be controlled with the following commands: ++ ++@table @code ++@kindex set max-completions ++@item set max-completions @var{limit} ++@itemx set max-completions unlimited ++Set the maximum number of completion candidates. @value{GDBN} will ++stop looking for more completions once it collects this many candidates. ++This is useful when completing on things like function names as collecting ++all the possible candidates can be time consuming. ++The default value is 200. A value of zero disables tab-completion. ++Note that setting either no limit or a very large limit can make ++completion slow. ++@kindex show max-completions ++@item show max-completions ++Show the maximum number of candidates that @value{GDBN} will collect and show ++during completion. ++@end table ++ ++@cindex quotes in commands ++@cindex completion of quoted strings ++Sometimes the string you need, while logically a ``word'', may contain ++parentheses or other characters that @value{GDBN} normally excludes from ++its notion of a word. To permit word completion to work in this ++situation, you may enclose words in @code{'} (single quote marks) in ++@value{GDBN} commands. ++ ++A likely situation where you might need this is in typing an ++expression that involves a C@t{++} symbol name with template ++parameters. This is because when completing expressions, GDB treats ++the @samp{<} character as word delimiter, assuming that it's the ++less-than comparison operator (@pxref{C Operators, , C and C@t{++} ++Operators}). ++ ++For example, when you want to call a C@t{++} template function ++interactively using the @code{print} or @code{call} commands, you may ++need to distinguish whether you mean the version of @code{name} that ++was specialized for @code{int}, @code{name()}, or the version ++that was specialized for @code{float}, @code{name()}. To use ++the word-completion facilities in this situation, type a single quote ++@code{'} at the beginning of the function name. This alerts ++@value{GDBN} that it may need to consider more information than usual ++when you press @key{TAB} or @kbd{M-?} to request word completion: ++ ++@smallexample ++(@value{GDBP}) p 'func< @kbd{M-?} ++func() func() ++(@value{GDBP}) p 'func< ++@end smallexample ++ ++When setting breakpoints however (@pxref{Specify Location}), you don't ++usually need to type a quote before the function name, because ++@value{GDBN} understands that you want to set a breakpoint on a ++function: ++ ++@smallexample ++(@value{GDBP}) b func< @kbd{M-?} ++func() func() ++(@value{GDBP}) b func< ++@end smallexample ++ ++This is true even in the case of typing the name of C@t{++} overloaded ++functions (multiple definitions of the same function, distinguished by ++argument type). For example, when you want to set a breakpoint you ++don't need to distinguish whether you mean the version of @code{name} ++that takes an @code{int} parameter, @code{name(int)}, or the version ++that takes a @code{float} parameter, @code{name(float)}. ++ ++@smallexample ++(@value{GDBP}) b bubble( @kbd{M-?} ++bubble(int) bubble(double) ++(@value{GDBP}) b bubble(dou @kbd{M-?} ++bubble(double) ++@end smallexample ++ ++See @ref{quoting names} for a description of other scenarios that ++require quoting. ++ ++For more information about overloaded functions, see @ref{C Plus Plus ++Expressions, ,C@t{++} Expressions}. You can use the command @code{set ++overload-resolution off} to disable overload resolution; ++see @ref{Debugging C Plus Plus, ,@value{GDBN} Features for C@t{++}}. ++ ++@cindex completion of structure field names ++@cindex structure field name completion ++@cindex completion of union field names ++@cindex union field name completion ++When completing in an expression which looks up a field in a ++structure, @value{GDBN} also tries@footnote{The completer can be ++confused by certain kinds of invalid expressions. Also, it only ++examines the static type of the expression, not the dynamic type.} to ++limit completions to the field names available in the type of the ++left-hand-side: ++ ++@smallexample ++(@value{GDBP}) p gdb_stdout.@kbd{M-?} ++magic to_fputs to_rewind ++to_data to_isatty to_write ++to_delete to_put to_write_async_safe ++to_flush to_read ++@end smallexample ++ ++@noindent ++This is because the @code{gdb_stdout} is a variable of the type ++@code{struct ui_file} that is defined in @value{GDBN} sources as ++follows: ++ ++@smallexample ++struct ui_file ++@{ ++ int *magic; ++ ui_file_flush_ftype *to_flush; ++ ui_file_write_ftype *to_write; ++ ui_file_write_async_safe_ftype *to_write_async_safe; ++ ui_file_fputs_ftype *to_fputs; ++ ui_file_read_ftype *to_read; ++ ui_file_delete_ftype *to_delete; ++ ui_file_isatty_ftype *to_isatty; ++ ui_file_rewind_ftype *to_rewind; ++ ui_file_put_ftype *to_put; ++ void *to_data; ++@} ++@end smallexample ++ ++@node Command Options ++@section Command options ++ ++@cindex command options ++Some commands accept options starting with a leading dash. For ++example, @code{print -pretty}. Similarly to command names, you can ++abbreviate a @value{GDBN} option to the first few letters of the ++option name, if that abbreviation is unambiguous, and you can also use ++the @key{TAB} key to get @value{GDBN} to fill out the rest of a word ++in an option (or to show you the alternatives available, if there is ++more than one possibility). ++ ++@cindex command options, raw input ++Some commands take raw input as argument. For example, the print ++command processes arbitrary expressions in any of the languages ++supported by @value{GDBN}. With such commands, because raw input may ++start with a leading dash that would be confused with an option or any ++of its abbreviations, e.g.@: @code{print -p} (short for @code{print ++-pretty} or printing negative @code{p}?), if you specify any command ++option, then you must use a double-dash (@code{--}) delimiter to ++indicate the end of options. ++ ++@cindex command options, boolean ++ ++Some options are described as accepting an argument which can be ++either @code{on} or @code{off}. These are known as @dfn{boolean ++options}. Similarly to boolean settings commands---@code{on} and ++@code{off} are the typical values, but any of @code{1}, @code{yes} and ++@code{enable} can also be used as ``true'' value, and any of @code{0}, ++@code{no} and @code{disable} can also be used as ``false'' value. You ++can also omit a ``true'' value, as it is implied by default. ++ ++For example, these are equivalent: ++ ++@smallexample ++(@value{GDBP}) print -object on -pretty off -element unlimited -- *myptr ++(@value{GDBP}) p -o -p 0 -e u -- *myptr ++@end smallexample ++ ++You can discover the set of options some command accepts by completing ++on @code{-} after the command name. For example: ++ ++@smallexample ++(@value{GDBP}) print -@key{TAB}@key{TAB} ++-address -max-depth -raw-values -union ++-array -null-stop -repeats -vtbl ++-array-indexes -object -static-members ++-elements -pretty -symbol ++@end smallexample ++ ++Completion will in some cases guide you with a suggestion of what kind ++of argument an option expects. For example: ++ ++@smallexample ++(@value{GDBP}) print -elements @key{TAB}@key{TAB} ++NUMBER unlimited ++@end smallexample ++ ++Here, the option expects a number (e.g., @code{100}), not literal ++@code{NUMBER}. Such metasyntactical arguments are always presented in ++uppercase. ++ ++(For more on using the @code{print} command, see @ref{Data, ,Examining ++Data}.) ++ ++@node Command aliases default args ++@section Automatically prepend default arguments to user-defined aliases ++ ++You can tell @value{GDBN} to always prepend some default arguments to ++the list of arguments provided explicitly by the user when using a ++user-defined alias. ++ ++If you repeatedly use the same arguments or options for a command, you ++can define an alias for this command and tell @value{GDBN} to ++automatically prepend these arguments or options to the list of ++arguments you type explicitly when using the alias@footnote{@value{GDBN} ++could easily accept default arguments for pre-defined commands and aliases, ++but it was deemed this would be confusing, and so is not allowed.}. ++ ++For example, if you often use the command @code{thread apply all} ++specifying to work on the threads in ascending order and to continue in case it ++encounters an error, you can tell @value{GDBN} to automatically preprend ++the @code{-ascending} and @code{-c} options by using: ++ ++@smallexample ++(@value{GDBP}) alias thread apply asc-all = thread apply all -ascending -c ++@end smallexample ++ ++Once you have defined this alias with its default args, any time you type ++the @code{thread apply asc-all} followed by @code{some arguments}, ++@value{GDBN} will execute @code{thread apply all -ascending -c some arguments}. ++ ++To have even less to type, you can also define a one word alias: ++@smallexample ++(@value{GDBP}) alias t_a_c = thread apply all -ascending -c ++@end smallexample ++ ++As usual, unambiguous abbreviations can be used for @var{alias} ++and @var{default-args}. ++ ++The different aliases of a command do not share their default args. ++For example, you define a new alias @code{bt_ALL} showing all possible ++information and another alias @code{bt_SMALL} showing very limited information ++using: ++@smallexample ++(@value{GDBP}) alias bt_ALL = backtrace -entry-values both -frame-arg all \ ++ -past-main -past-entry -full ++(@value{GDBP}) alias bt_SMALL = backtrace -entry-values no -frame-arg none \ ++ -past-main off -past-entry off ++@end smallexample ++ ++(For more on using the @code{alias} command, see @ref{Aliases}.) ++ ++Default args are not limited to the arguments and options of @var{command}, ++but can specify nested commands if @var{command} accepts such a nested command ++as argument. ++For example, the below defines @code{faalocalsoftype} that lists the ++frames having locals of a certain type, together with the matching ++local vars: ++@smallexample ++(@value{GDBP}) alias faalocalsoftype = frame apply all info locals -q -t ++(@value{GDBP}) faalocalsoftype int ++#1 0x55554f5e in sleeper_or_burner (v=0xdf50) at sleepers.c:86 ++i = 0 ++ret = 21845 ++@end smallexample ++ ++This is also very useful to define an alias for a set of nested @code{with} ++commands to have a particular combination of temporary settings. For example, ++the below defines the alias @code{pp10} that pretty prints an expression ++argument, with a maximum of 10 elements if the expression is a string or ++an array: ++@smallexample ++(@value{GDBP}) alias pp10 = with print pretty -- with print elements 10 -- print ++@end smallexample ++This defines the alias @code{pp10} as being a sequence of 3 commands. ++The first part @code{with print pretty --} temporarily activates the setting ++@code{set print pretty}, then launches the command that follows the separator ++@code{--}. ++The command following the first part is also a @code{with} command that ++temporarily changes the setting @code{set print elements} to 10, then ++launches the command that follows the second separator @code{--}. ++The third part @code{print} is the command the @code{pp10} alias will launch, ++using the temporary values of the settings and the arguments explicitly given ++by the user. ++For more information about the @code{with} command usage, ++see @ref{Command Settings}. ++ ++@node Help ++@section Getting Help ++@cindex online documentation ++@kindex help ++ ++You can always ask @value{GDBN} itself for information on its commands, ++using the command @code{help}. ++ ++@table @code ++@kindex h @r{(@code{help})} ++@item help ++@itemx h ++You can use @code{help} (abbreviated @code{h}) with no arguments to ++display a short list of named classes of commands: ++ ++@smallexample ++(@value{GDBP}) help ++List of classes of commands: ++ ++aliases -- User-defined aliases of other commands ++breakpoints -- Making program stop at certain points ++data -- Examining data ++files -- Specifying and examining files ++internals -- Maintenance commands ++obscure -- Obscure features ++running -- Running the program ++stack -- Examining the stack ++status -- Status inquiries ++support -- Support facilities ++tracepoints -- Tracing of program execution without ++ stopping the program ++user-defined -- User-defined commands ++ ++Type "help" followed by a class name for a list of ++commands in that class. ++Type "help" followed by command name for full ++documentation. ++Command name abbreviations are allowed if unambiguous. ++(@value{GDBP}) ++@end smallexample ++@c the above line break eliminates huge line overfull... ++ ++@item help @var{class} ++Using one of the general help classes as an argument, you can get a ++list of the individual commands in that class. If a command has ++aliases, the aliases are given after the command name, separated by ++commas. If an alias has default arguments, the full definition of ++the alias is given after the first line. ++For example, here is the help display for the class @code{status}: ++ ++@smallexample ++(@value{GDBP}) help status ++Status inquiries. ++ ++List of commands: ++ ++@c Line break in "show" line falsifies real output, but needed ++@c to fit in smallbook page size. ++info, inf, i -- Generic command for showing things ++ about the program being debugged ++info address, iamain -- Describe where symbol SYM is stored. ++ alias iamain = info address main ++info all-registers -- List of all registers and their contents, ++ for selected stack frame. ++... ++show, info set -- Generic command for showing things ++ about the debugger ++ ++Type "help" followed by command name for full ++documentation. ++Command name abbreviations are allowed if unambiguous. ++(@value{GDBP}) ++@end smallexample ++ ++@item help @var{command} ++With a command name as @code{help} argument, @value{GDBN} displays a ++short paragraph on how to use that command. If that command has ++one or more aliases, @value{GDBN} will display a first line with ++the command name and all its aliases separated by commas. ++This first line will be followed by the full definition of all aliases ++having default arguments. ++ ++@kindex apropos ++@item apropos [-v] @var{regexp} ++The @code{apropos} command searches through all of the @value{GDBN} ++commands, and their documentation, for the regular expression specified in ++@var{args}. It prints out all matches found. The optional flag @samp{-v}, ++which stands for @samp{verbose}, indicates to output the full documentation ++of the matching commands and highlight the parts of the documentation ++matching @var{regexp}. For example: ++ ++@smallexample ++apropos alias ++@end smallexample ++ ++@noindent ++results in: ++ ++@smallexample ++@group ++alias -- Define a new command that is an alias of an existing command ++aliases -- User-defined aliases of other commands ++@end group ++@end smallexample ++ ++@noindent ++while ++ ++@smallexample ++apropos -v cut.*thread apply ++@end smallexample ++ ++@noindent ++results in the below output, where @samp{cut for 'thread apply} ++is highlighted if styling is enabled. ++ ++@smallexample ++@group ++taas -- Apply a command to all threads (ignoring errors ++and empty output). ++Usage: taas COMMAND ++shortcut for 'thread apply all -s COMMAND' ++ ++tfaas -- Apply a command to all frames of all threads ++(ignoring errors and empty output). ++Usage: tfaas COMMAND ++shortcut for 'thread apply all -s frame apply all -s COMMAND' ++@end group ++@end smallexample ++ ++@kindex complete ++@item complete @var{args} ++The @code{complete @var{args}} command lists all the possible completions ++for the beginning of a command. Use @var{args} to specify the beginning of the ++command you want completed. For example: ++ ++@smallexample ++complete i ++@end smallexample ++ ++@noindent results in: ++ ++@smallexample ++@group ++if ++ignore ++info ++inspect ++@end group ++@end smallexample ++ ++@noindent This is intended for use by @sc{gnu} Emacs. ++@end table ++ ++In addition to @code{help}, you can use the @value{GDBN} commands @code{info} ++and @code{show} to inquire about the state of your program, or the state ++of @value{GDBN} itself. Each command supports many topics of inquiry; this ++manual introduces each of them in the appropriate context. The listings ++under @code{info} and under @code{show} in the Command, Variable, and ++Function Index point to all the sub-commands. @xref{Command and Variable ++Index}. ++ ++@c @group ++@table @code ++@kindex info ++@kindex i @r{(@code{info})} ++@item info ++This command (abbreviated @code{i}) is for describing the state of your ++program. For example, you can show the arguments passed to a function ++with @code{info args}, list the registers currently in use with @code{info ++registers}, or list the breakpoints you have set with @code{info breakpoints}. ++You can get a complete list of the @code{info} sub-commands with ++@w{@code{help info}}. ++ ++@kindex set ++@item set ++You can assign the result of an expression to an environment variable with ++@code{set}. For example, you can set the @value{GDBN} prompt to a $-sign with ++@code{set prompt $}. ++ ++@kindex show ++@item show ++In contrast to @code{info}, @code{show} is for describing the state of ++@value{GDBN} itself. ++You can change most of the things you can @code{show}, by using the ++related command @code{set}; for example, you can control what number ++system is used for displays with @code{set radix}, or simply inquire ++which is currently in use with @code{show radix}. ++ ++@kindex info set ++To display all the settable parameters and their current ++values, you can use @code{show} with no arguments; you may also use ++@code{info set}. Both commands produce the same display. ++@c FIXME: "info set" violates the rule that "info" is for state of ++@c FIXME...program. Ck w/ GNU: "info set" to be called something else, ++@c FIXME...or change desc of rule---eg "state of prog and debugging session"? ++@end table ++@c @end group ++ ++Here are several miscellaneous @code{show} subcommands, all of which are ++exceptional in lacking corresponding @code{set} commands: ++ ++@table @code ++@kindex show version ++@cindex @value{GDBN} version number ++@item show version ++Show what version of @value{GDBN} is running. You should include this ++information in @value{GDBN} bug-reports. If multiple versions of ++@value{GDBN} are in use at your site, you may need to determine which ++version of @value{GDBN} you are running; as @value{GDBN} evolves, new ++commands are introduced, and old ones may wither away. Also, many ++system vendors ship variant versions of @value{GDBN}, and there are ++variant versions of @value{GDBN} in @sc{gnu}/Linux distributions as well. ++The version number is the same as the one announced when you start ++@value{GDBN}. ++ ++@kindex show copying ++@kindex info copying ++@cindex display @value{GDBN} copyright ++@item show copying ++@itemx info copying ++Display information about permission for copying @value{GDBN}. ++ ++@kindex show warranty ++@kindex info warranty ++@item show warranty ++@itemx info warranty ++Display the @sc{gnu} ``NO WARRANTY'' statement, or a warranty, ++if your version of @value{GDBN} comes with one. ++ ++@kindex show configuration ++@item show configuration ++Display detailed information about the way @value{GDBN} was configured ++when it was built. This displays the optional arguments passed to the ++@file{configure} script and also configuration parameters detected ++automatically by @command{configure}. When reporting a @value{GDBN} ++bug (@pxref{GDB Bugs}), it is important to include this information in ++your report. ++ ++@end table ++ ++@node Running ++@chapter Running Programs Under @value{GDBN} ++ ++When you run a program under @value{GDBN}, you must first generate ++debugging information when you compile it. ++ ++You may start @value{GDBN} with its arguments, if any, in an environment ++of your choice. If you are doing native debugging, you may redirect ++your program's input and output, debug an already running process, or ++kill a child process. ++ ++@menu ++* Compilation:: Compiling for debugging ++* Starting:: Starting your program ++* Arguments:: Your program's arguments ++* Environment:: Your program's environment ++ ++* Working Directory:: Your program's working directory ++* Input/Output:: Your program's input and output ++* Attach:: Debugging an already-running process ++* Kill Process:: Killing the child process ++* Inferiors Connections and Programs:: Debugging multiple inferiors ++ connections and programs ++* Threads:: Debugging programs with multiple threads ++* Forks:: Debugging forks ++* Checkpoint/Restart:: Setting a @emph{bookmark} to return to later ++@end menu ++ ++@node Compilation ++@section Compiling for Debugging ++ ++In order to debug a program effectively, you need to generate ++debugging information when you compile it. This debugging information ++is stored in the object file; it describes the data type of each ++variable or function and the correspondence between source line numbers ++and addresses in the executable code. ++ ++To request debugging information, specify the @samp{-g} option when you run ++the compiler. ++ ++Programs that are to be shipped to your customers are compiled with ++optimizations, using the @samp{-O} compiler option. However, some ++compilers are unable to handle the @samp{-g} and @samp{-O} options ++together. Using those compilers, you cannot generate optimized ++executables containing debugging information. ++ ++@value{NGCC}, the @sc{gnu} C/C@t{++} compiler, supports @samp{-g} with or ++without @samp{-O}, making it possible to debug optimized code. We ++recommend that you @emph{always} use @samp{-g} whenever you compile a ++program. You may think your program is correct, but there is no sense ++in pushing your luck. For more information, see @ref{Optimized Code}. ++ ++Older versions of the @sc{gnu} C compiler permitted a variant option ++@w{@samp{-gg}} for debugging information. @value{GDBN} no longer supports this ++format; if your @sc{gnu} C compiler has this option, do not use it. ++ ++@value{GDBN} knows about preprocessor macros and can show you their ++expansion (@pxref{Macros}). Most compilers do not include information ++about preprocessor macros in the debugging information if you specify ++the @option{-g} flag alone. Version 3.1 and later of @value{NGCC}, ++the @sc{gnu} C compiler, provides macro information if you are using ++the DWARF debugging format, and specify the option @option{-g3}. ++ ++@xref{Debugging Options,,Options for Debugging Your Program or GCC, ++gcc, Using the @sc{gnu} Compiler Collection (GCC)}, for more ++information on @value{NGCC} options affecting debug information. ++ ++You will have the best debugging experience if you use the latest ++version of the DWARF debugging format that your compiler supports. ++DWARF is currently the most expressive and best supported debugging ++format in @value{GDBN}. ++ ++@need 2000 ++@node Starting ++@section Starting your Program ++@cindex starting ++@cindex running ++ ++@table @code ++@kindex run ++@kindex r @r{(@code{run})} ++@item run ++@itemx r ++Use the @code{run} command to start your program under @value{GDBN}. ++You must first specify the program name with an argument to ++@value{GDBN} (@pxref{Invocation, ,Getting In and Out of ++@value{GDBN}}), or by using the @code{file} or @code{exec-file} ++command (@pxref{Files, ,Commands to Specify Files}). ++ ++@end table ++ ++If you are running your program in an execution environment that ++supports processes, @code{run} creates an inferior process and makes ++that process run your program. In some environments without processes, ++@code{run} jumps to the start of your program. Other targets, ++like @samp{remote}, are always running. If you get an error ++message like this one: ++ ++@smallexample ++The "remote" target does not support "run". ++Try "help target" or "continue". ++@end smallexample ++ ++@noindent ++then use @code{continue} to run your program. You may need @code{load} ++first (@pxref{load}). ++ ++The execution of a program is affected by certain information it ++receives from its superior. @value{GDBN} provides ways to specify this ++information, which you must do @emph{before} starting your program. (You ++can change it after starting your program, but such changes only affect ++your program the next time you start it.) This information may be ++divided into four categories: ++ ++@table @asis ++@item The @emph{arguments.} ++Specify the arguments to give your program as the arguments of the ++@code{run} command. If a shell is available on your target, the shell ++is used to pass the arguments, so that you may use normal conventions ++(such as wildcard expansion or variable substitution) in describing ++the arguments. ++In Unix systems, you can control which shell is used with the ++@code{SHELL} environment variable. If you do not define @code{SHELL}, ++@value{GDBN} uses the default shell (@file{/bin/sh}). You can disable ++use of any shell with the @code{set startup-with-shell} command (see ++below for details). ++ ++@item The @emph{environment.} ++Your program normally inherits its environment from @value{GDBN}, but you can ++use the @value{GDBN} commands @code{set environment} and @code{unset ++environment} to change parts of the environment that affect ++your program. @xref{Environment, ,Your Program's Environment}. ++ ++@item The @emph{working directory.} ++You can set your program's working directory with the command ++@kbd{set cwd}. If you do not set any working directory with this ++command, your program will inherit @value{GDBN}'s working directory if ++native debugging, or the remote server's working directory if remote ++debugging. @xref{Working Directory, ,Your Program's Working ++Directory}. ++ ++@item The @emph{standard input and output.} ++Your program normally uses the same device for standard input and ++standard output as @value{GDBN} is using. You can redirect input and output ++in the @code{run} command line, or you can use the @code{tty} command to ++set a different device for your program. ++@xref{Input/Output, ,Your Program's Input and Output}. ++ ++@cindex pipes ++@emph{Warning:} While input and output redirection work, you cannot use ++pipes to pass the output of the program you are debugging to another ++program; if you attempt this, @value{GDBN} is likely to wind up debugging the ++wrong program. ++@end table ++ ++When you issue the @code{run} command, your program begins to execute ++immediately. @xref{Stopping, ,Stopping and Continuing}, for discussion ++of how to arrange for your program to stop. Once your program has ++stopped, you may call functions in your program, using the @code{print} ++or @code{call} commands. @xref{Data, ,Examining Data}. ++ ++If the modification time of your symbol file has changed since the last ++time @value{GDBN} read its symbols, @value{GDBN} discards its symbol ++table, and reads it again. When it does this, @value{GDBN} tries to retain ++your current breakpoints. ++ ++@table @code ++@kindex start ++@item start ++@cindex run to main procedure ++The name of the main procedure can vary from language to language. ++With C or C@t{++}, the main procedure name is always @code{main}, but ++other languages such as Ada do not require a specific name for their ++main procedure. The debugger provides a convenient way to start the ++execution of the program and to stop at the beginning of the main ++procedure, depending on the language used. ++ ++The @samp{start} command does the equivalent of setting a temporary ++breakpoint at the beginning of the main procedure and then invoking ++the @samp{run} command. ++ ++@cindex elaboration phase ++Some programs contain an @dfn{elaboration} phase where some startup code is ++executed before the main procedure is called. This depends on the ++languages used to write your program. In C@t{++}, for instance, ++constructors for static and global objects are executed before ++@code{main} is called. It is therefore possible that the debugger stops ++before reaching the main procedure. However, the temporary breakpoint ++will remain to halt execution. ++ ++Specify the arguments to give to your program as arguments to the ++@samp{start} command. These arguments will be given verbatim to the ++underlying @samp{run} command. Note that the same arguments will be ++reused if no argument is provided during subsequent calls to ++@samp{start} or @samp{run}. ++ ++It is sometimes necessary to debug the program during elaboration. In ++these cases, using the @code{start} command would stop the execution ++of your program too late, as the program would have already completed ++the elaboration phase. Under these circumstances, either insert ++breakpoints in your elaboration code before running your program or ++use the @code{starti} command. ++ ++@kindex starti ++@item starti ++@cindex run to first instruction ++The @samp{starti} command does the equivalent of setting a temporary ++breakpoint at the first instruction of a program's execution and then ++invoking the @samp{run} command. For programs containing an ++elaboration phase, the @code{starti} command will stop execution at ++the start of the elaboration phase. ++ ++@anchor{set exec-wrapper} ++@kindex set exec-wrapper ++@item set exec-wrapper @var{wrapper} ++@itemx show exec-wrapper ++@itemx unset exec-wrapper ++When @samp{exec-wrapper} is set, the specified wrapper is used to ++launch programs for debugging. @value{GDBN} starts your program ++with a shell command of the form @kbd{exec @var{wrapper} ++@var{program}}. Quoting is added to @var{program} and its ++arguments, but not to @var{wrapper}, so you should add quotes if ++appropriate for your shell. The wrapper runs until it executes ++your program, and then @value{GDBN} takes control. ++ ++You can use any program that eventually calls @code{execve} with ++its arguments as a wrapper. Several standard Unix utilities do ++this, e.g.@: @code{env} and @code{nohup}. Any Unix shell script ending ++with @code{exec "$@@"} will also work. ++ ++For example, you can use @code{env} to pass an environment variable to ++the debugged program, without setting the variable in your shell's ++environment: ++ ++@smallexample ++(@value{GDBP}) set exec-wrapper env 'LD_PRELOAD=libtest.so' ++(@value{GDBP}) run ++@end smallexample ++ ++This command is available when debugging locally on most targets, excluding ++@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino. ++ ++@kindex set startup-with-shell ++@anchor{set startup-with-shell} ++@item set startup-with-shell ++@itemx set startup-with-shell on ++@itemx set startup-with-shell off ++@itemx show startup-with-shell ++On Unix systems, by default, if a shell is available on your target, ++@value{GDBN}) uses it to start your program. Arguments of the ++@code{run} command are passed to the shell, which does variable ++substitution, expands wildcard characters and performs redirection of ++I/O. In some circumstances, it may be useful to disable such use of a ++shell, for example, when debugging the shell itself or diagnosing ++startup failures such as: ++ ++@smallexample ++(@value{GDBP}) run ++Starting program: ./a.out ++During startup program terminated with signal SIGSEGV, Segmentation fault. ++@end smallexample ++ ++@noindent ++which indicates the shell or the wrapper specified with ++@samp{exec-wrapper} crashed, not your program. Most often, this is ++caused by something odd in your shell's non-interactive mode ++initialization file---such as @file{.cshrc} for C-shell, ++$@file{.zshenv} for the Z shell, or the file specified in the ++@samp{BASH_ENV} environment variable for BASH. ++ ++@anchor{set auto-connect-native-target} ++@kindex set auto-connect-native-target ++@item set auto-connect-native-target ++@itemx set auto-connect-native-target on ++@itemx set auto-connect-native-target off ++@itemx show auto-connect-native-target ++ ++By default, if the current inferior is not connected to any target yet ++(e.g., with @code{target remote}), the @code{run} command starts your ++program as a native process under @value{GDBN}, on your local machine. ++If you're sure you don't want to debug programs on your local machine, ++you can tell @value{GDBN} to not connect to the native target ++automatically with the @code{set auto-connect-native-target off} ++command. ++ ++If @code{on}, which is the default, and if the current inferior is not ++connected to a target already, the @code{run} command automaticaly ++connects to the native target, if one is available. ++ ++If @code{off}, and if the current inferior is not connected to a ++target already, the @code{run} command fails with an error: ++ ++@smallexample ++(@value{GDBP}) run ++Don't know how to run. Try "help target". ++@end smallexample ++ ++If the current inferior is already connected to a target, @value{GDBN} ++always uses it with the @code{run} command. ++ ++In any case, you can explicitly connect to the native target with the ++@code{target native} command. For example, ++ ++@smallexample ++(@value{GDBP}) set auto-connect-native-target off ++(@value{GDBP}) run ++Don't know how to run. Try "help target". ++(@value{GDBP}) target native ++(@value{GDBP}) run ++Starting program: ./a.out ++[Inferior 1 (process 10421) exited normally] ++@end smallexample ++ ++In case you connected explicitly to the @code{native} target, ++@value{GDBN} remains connected even if all inferiors exit, ready for ++the next @code{run} command. Use the @code{disconnect} command to ++disconnect. ++ ++Examples of other commands that likewise respect the ++@code{auto-connect-native-target} setting: @code{attach}, @code{info ++proc}, @code{info os}. ++ ++@kindex set disable-randomization ++@item set disable-randomization ++@itemx set disable-randomization on ++This option (enabled by default in @value{GDBN}) will turn off the native ++randomization of the virtual address space of the started program. This option ++is useful for multiple debugging sessions to make the execution better ++reproducible and memory addresses reusable across debugging sessions. ++ ++This feature is implemented only on certain targets, including @sc{gnu}/Linux. ++On @sc{gnu}/Linux you can get the same behavior using ++ ++@smallexample ++(@value{GDBP}) set exec-wrapper setarch `uname -m` -R ++@end smallexample ++ ++@item set disable-randomization off ++Leave the behavior of the started executable unchanged. Some bugs rear their ++ugly heads only when the program is loaded at certain addresses. If your bug ++disappears when you run the program under @value{GDBN}, that might be because ++@value{GDBN} by default disables the address randomization on platforms, such ++as @sc{gnu}/Linux, which do that for stand-alone programs. Use @kbd{set ++disable-randomization off} to try to reproduce such elusive bugs. ++ ++On targets where it is available, virtual address space randomization ++protects the programs against certain kinds of security attacks. In these ++cases the attacker needs to know the exact location of a concrete executable ++code. Randomizing its location makes it impossible to inject jumps misusing ++a code at its expected addresses. ++ ++Prelinking shared libraries provides a startup performance advantage but it ++makes addresses in these libraries predictable for privileged processes by ++having just unprivileged access at the target system. Reading the shared ++library binary gives enough information for assembling the malicious code ++misusing it. Still even a prelinked shared library can get loaded at a new ++random address just requiring the regular relocation process during the ++startup. Shared libraries not already prelinked are always loaded at ++a randomly chosen address. ++ ++Position independent executables (PIE) contain position independent code ++similar to the shared libraries and therefore such executables get loaded at ++a randomly chosen address upon startup. PIE executables always load even ++already prelinked shared libraries at a random address. You can build such ++executable using @command{gcc -fPIE -pie}. ++ ++Heap (malloc storage), stack and custom mmap areas are always placed randomly ++(as long as the randomization is enabled). ++ ++@item show disable-randomization ++Show the current setting of the explicit disable of the native randomization of ++the virtual address space of the started program. ++ ++@end table ++ ++@node Arguments ++@section Your Program's Arguments ++ ++@cindex arguments (to your program) ++The arguments to your program can be specified by the arguments of the ++@code{run} command. ++They are passed to a shell, which expands wildcard characters and ++performs redirection of I/O, and thence to your program. Your ++@code{SHELL} environment variable (if it exists) specifies what shell ++@value{GDBN} uses. If you do not define @code{SHELL}, @value{GDBN} uses ++the default shell (@file{/bin/sh} on Unix). ++ ++On non-Unix systems, the program is usually invoked directly by ++@value{GDBN}, which emulates I/O redirection via the appropriate system ++calls, and the wildcard characters are expanded by the startup code of ++the program, not by the shell. ++ ++@code{run} with no arguments uses the same arguments used by the previous ++@code{run}, or those set by the @code{set args} command. ++ ++@table @code ++@kindex set args ++@item set args ++Specify the arguments to be used the next time your program is run. If ++@code{set args} has no arguments, @code{run} executes your program ++with no arguments. Once you have run your program with arguments, ++using @code{set args} before the next @code{run} is the only way to run ++it again without arguments. ++ ++@kindex show args ++@item show args ++Show the arguments to give your program when it is started. ++@end table ++ ++@node Environment ++@section Your Program's Environment ++ ++@cindex environment (of your program) ++The @dfn{environment} consists of a set of environment variables and ++their values. Environment variables conventionally record such things as ++your user name, your home directory, your terminal type, and your search ++path for programs to run. Usually you set up environment variables with ++the shell and they are inherited by all the other programs you run. When ++debugging, it can be useful to try running your program with a modified ++environment without having to start @value{GDBN} over again. ++ ++@table @code ++@kindex path ++@item path @var{directory} ++Add @var{directory} to the front of the @code{PATH} environment variable ++(the search path for executables) that will be passed to your program. ++The value of @code{PATH} used by @value{GDBN} does not change. ++You may specify several directory names, separated by whitespace or by a ++system-dependent separator character (@samp{:} on Unix, @samp{;} on ++MS-DOS and MS-Windows). If @var{directory} is already in the path, it ++is moved to the front, so it is searched sooner. ++ ++You can use the string @samp{$cwd} to refer to whatever is the current ++working directory at the time @value{GDBN} searches the path. If you ++use @samp{.} instead, it refers to the directory where you executed the ++@code{path} command. @value{GDBN} replaces @samp{.} in the ++@var{directory} argument (with the current path) before adding ++@var{directory} to the search path. ++@c 'path' is explicitly nonrepeatable, but RMS points out it is silly to ++@c document that, since repeating it would be a no-op. ++ ++@kindex show paths ++@item show paths ++Display the list of search paths for executables (the @code{PATH} ++environment variable). ++ ++@kindex show environment ++@item show environment @r{[}@var{varname}@r{]} ++Print the value of environment variable @var{varname} to be given to ++your program when it starts. If you do not supply @var{varname}, ++print the names and values of all environment variables to be given to ++your program. You can abbreviate @code{environment} as @code{env}. ++ ++@kindex set environment ++@anchor{set environment} ++@item set environment @var{varname} @r{[}=@var{value}@r{]} ++Set environment variable @var{varname} to @var{value}. The value ++changes for your program (and the shell @value{GDBN} uses to launch ++it), not for @value{GDBN} itself. The @var{value} may be any string; the ++values of environment variables are just strings, and any ++interpretation is supplied by your program itself. The @var{value} ++parameter is optional; if it is eliminated, the variable is set to a ++null value. ++@c "any string" here does not include leading, trailing ++@c blanks. Gnu asks: does anyone care? ++ ++For example, this command: ++ ++@smallexample ++set env USER = foo ++@end smallexample ++ ++@noindent ++tells the debugged program, when subsequently run, that its user is named ++@samp{foo}. (The spaces around @samp{=} are used for clarity here; they ++are not actually required.) ++ ++Note that on Unix systems, @value{GDBN} runs your program via a shell, ++which also inherits the environment set with @code{set environment}. ++If necessary, you can avoid that by using the @samp{env} program as a ++wrapper instead of using @code{set environment}. @xref{set ++exec-wrapper}, for an example doing just that. ++ ++Environment variables that are set by the user are also transmitted to ++@command{gdbserver} to be used when starting the remote inferior. ++@pxref{QEnvironmentHexEncoded}. ++ ++@kindex unset environment ++@anchor{unset environment} ++@item unset environment @var{varname} ++Remove variable @var{varname} from the environment to be passed to your ++program. This is different from @samp{set env @var{varname} =}; ++@code{unset environment} removes the variable from the environment, ++rather than assigning it an empty value. ++ ++Environment variables that are unset by the user are also unset on ++@command{gdbserver} when starting the remote inferior. ++@pxref{QEnvironmentUnset}. ++@end table ++ ++@emph{Warning:} On Unix systems, @value{GDBN} runs your program using ++the shell indicated by your @code{SHELL} environment variable if it ++exists (or @code{/bin/sh} if not). If your @code{SHELL} variable ++names a shell that runs an initialization file when started ++non-interactively---such as @file{.cshrc} for C-shell, $@file{.zshenv} ++for the Z shell, or the file specified in the @samp{BASH_ENV} ++environment variable for BASH---any variables you set in that file ++affect your program. You may wish to move setting of environment ++variables to files that are only run when you sign on, such as ++@file{.login} or @file{.profile}. ++ ++@node Working Directory ++@section Your Program's Working Directory ++ ++@cindex working directory (of your program) ++Each time you start your program with @code{run}, the inferior will be ++initialized with the current working directory specified by the ++@kbd{set cwd} command. If no directory has been specified by this ++command, then the inferior will inherit @value{GDBN}'s current working ++directory as its working directory if native debugging, or it will ++inherit the remote server's current working directory if remote ++debugging. ++ ++@table @code ++@kindex set cwd ++@cindex change inferior's working directory ++@anchor{set cwd command} ++@item set cwd @r{[}@var{directory}@r{]} ++Set the inferior's working directory to @var{directory}, which will be ++@code{glob}-expanded in order to resolve tildes (@file{~}). If no ++argument has been specified, the command clears the setting and resets ++it to an empty state. This setting has no effect on @value{GDBN}'s ++working directory, and it only takes effect the next time you start ++the inferior. The @file{~} in @var{directory} is a short for the ++@dfn{home directory}, usually pointed to by the @env{HOME} environment ++variable. On MS-Windows, if @env{HOME} is not defined, @value{GDBN} ++uses the concatenation of @env{HOMEDRIVE} and @env{HOMEPATH} as ++fallback. ++ ++You can also change @value{GDBN}'s current working directory by using ++the @code{cd} command. ++@xref{cd command}. ++ ++@kindex show cwd ++@cindex show inferior's working directory ++@item show cwd ++Show the inferior's working directory. If no directory has been ++specified by @kbd{set cwd}, then the default inferior's working ++directory is the same as @value{GDBN}'s working directory. ++ ++@kindex cd ++@cindex change @value{GDBN}'s working directory ++@anchor{cd command} ++@item cd @r{[}@var{directory}@r{]} ++Set the @value{GDBN} working directory to @var{directory}. If not ++given, @var{directory} uses @file{'~'}. ++ ++The @value{GDBN} working directory serves as a default for the ++commands that specify files for @value{GDBN} to operate on. ++@xref{Files, ,Commands to Specify Files}. ++@xref{set cwd command}. ++ ++@kindex pwd ++@item pwd ++Print the @value{GDBN} working directory. ++@end table ++ ++It is generally impossible to find the current working directory of ++the process being debugged (since a program can change its directory ++during its run). If you work on a system where @value{GDBN} supports ++the @code{info proc} command (@pxref{Process Information}), you can ++use the @code{info proc} command to find out the ++current working directory of the debuggee. ++ ++@node Input/Output ++@section Your Program's Input and Output ++ ++@cindex redirection ++@cindex i/o ++@cindex terminal ++By default, the program you run under @value{GDBN} does input and output to ++the same terminal that @value{GDBN} uses. @value{GDBN} switches the terminal ++to its own terminal modes to interact with you, but it records the terminal ++modes your program was using and switches back to them when you continue ++running your program. ++ ++@table @code ++@kindex info terminal ++@item info terminal ++Displays information recorded by @value{GDBN} about the terminal modes your ++program is using. ++@end table ++ ++You can redirect your program's input and/or output using shell ++redirection with the @code{run} command. For example, ++ ++@smallexample ++run > outfile ++@end smallexample ++ ++@noindent ++starts your program, diverting its output to the file @file{outfile}. ++ ++@kindex tty ++@cindex controlling terminal ++Another way to specify where your program should do input and output is ++with the @code{tty} command. This command accepts a file name as ++argument, and causes this file to be the default for future @code{run} ++commands. It also resets the controlling terminal for the child ++process, for future @code{run} commands. For example, ++ ++@smallexample ++tty /dev/ttyb ++@end smallexample ++ ++@noindent ++directs that processes started with subsequent @code{run} commands ++default to do input and output on the terminal @file{/dev/ttyb} and have ++that as their controlling terminal. ++ ++An explicit redirection in @code{run} overrides the @code{tty} command's ++effect on the input/output device, but not its effect on the controlling ++terminal. ++ ++When you use the @code{tty} command or redirect input in the @code{run} ++command, only the input @emph{for your program} is affected. The input ++for @value{GDBN} still comes from your terminal. @code{tty} is an alias ++for @code{set inferior-tty}. ++ ++@cindex inferior tty ++@cindex set inferior controlling terminal ++You can use the @code{show inferior-tty} command to tell @value{GDBN} to ++display the name of the terminal that will be used for future runs of your ++program. ++ ++@table @code ++@item set inferior-tty [ @var{tty} ] ++@kindex set inferior-tty ++Set the tty for the program being debugged to @var{tty}. Omitting @var{tty} ++restores the default behavior, which is to use the same terminal as ++@value{GDBN}. ++ ++@item show inferior-tty ++@kindex show inferior-tty ++Show the current tty for the program being debugged. ++@end table ++ ++@node Attach ++@section Debugging an Already-running Process ++@kindex attach ++@cindex attach ++ ++@table @code ++@item attach @var{process-id} ++This command attaches to a running process---one that was started ++outside @value{GDBN}. (@code{info files} shows your active ++targets.) The command takes as argument a process ID. The usual way to ++find out the @var{process-id} of a Unix process is with the @code{ps} utility, ++or with the @samp{jobs -l} shell command. ++ ++@code{attach} does not repeat if you press @key{RET} a second time after ++executing the command. ++@end table ++ ++To use @code{attach}, your program must be running in an environment ++which supports processes; for example, @code{attach} does not work for ++programs on bare-board targets that lack an operating system. You must ++also have permission to send the process a signal. ++ ++When you use @code{attach}, the debugger finds the program running in ++the process first by looking in the current working directory, then (if ++the program is not found) by using the source file search path ++(@pxref{Source Path, ,Specifying Source Directories}). You can also use ++the @code{file} command to load the program. @xref{Files, ,Commands to ++Specify Files}. ++ ++@anchor{set exec-file-mismatch} ++If the debugger can determine that the executable file running in the ++process it is attaching to does not match the current exec-file loaded ++by @value{GDBN}, the option @code{exec-file-mismatch} specifies how to ++handle the mismatch. @value{GDBN} tries to compare the files by ++comparing their build IDs (@pxref{build ID}), if available. ++ ++@table @code ++@kindex exec-file-mismatch ++@cindex set exec-file-mismatch ++@item set exec-file-mismatch @samp{ask|warn|off} ++ ++Whether to detect mismatch between the current executable file loaded ++by @value{GDBN} and the executable file used to start the process. If ++@samp{ask}, the default, display a warning and ask the user whether to ++load the process executable file; if @samp{warn}, just display a ++warning; if @samp{off}, don't attempt to detect a mismatch. ++If the user confirms loading the process executable file, then its symbols ++will be loaded as well. ++ ++@cindex show exec-file-mismatch ++@item show exec-file-mismatch ++Show the current value of @code{exec-file-mismatch}. ++ ++@end table ++ ++The first thing @value{GDBN} does after arranging to debug the specified ++process is to stop it. You can examine and modify an attached process ++with all the @value{GDBN} commands that are ordinarily available when ++you start processes with @code{run}. You can insert breakpoints; you ++can step and continue; you can modify storage. If you would rather the ++process continue running, you may use the @code{continue} command after ++attaching @value{GDBN} to the process. ++ ++@table @code ++@kindex detach ++@item detach ++When you have finished debugging the attached process, you can use the ++@code{detach} command to release it from @value{GDBN} control. Detaching ++the process continues its execution. After the @code{detach} command, ++that process and @value{GDBN} become completely independent once more, and you ++are ready to @code{attach} another process or start one with @code{run}. ++@code{detach} does not repeat if you press @key{RET} again after ++executing the command. ++@end table ++ ++If you exit @value{GDBN} while you have an attached process, you detach ++that process. If you use the @code{run} command, you kill that process. ++By default, @value{GDBN} asks for confirmation if you try to do either of these ++things; you can control whether or not you need to confirm by using the ++@code{set confirm} command (@pxref{Messages/Warnings, ,Optional Warnings and ++Messages}). ++ ++@node Kill Process ++@section Killing the Child Process ++ ++@table @code ++@kindex kill ++@item kill ++Kill the child process in which your program is running under @value{GDBN}. ++@end table ++ ++This command is useful if you wish to debug a core dump instead of a ++running process. @value{GDBN} ignores any core dump file while your program ++is running. ++ ++On some operating systems, a program cannot be executed outside @value{GDBN} ++while you have breakpoints set on it inside @value{GDBN}. You can use the ++@code{kill} command in this situation to permit running your program ++outside the debugger. ++ ++The @code{kill} command is also useful if you wish to recompile and ++relink your program, since on many systems it is impossible to modify an ++executable file while it is running in a process. In this case, when you ++next type @code{run}, @value{GDBN} notices that the file has changed, and ++reads the symbol table again (while trying to preserve your current ++breakpoint settings). ++ ++@node Inferiors Connections and Programs ++@section Debugging Multiple Inferiors Connections and Programs ++ ++@value{GDBN} lets you run and debug multiple programs in a single ++session. In addition, @value{GDBN} on some systems may let you run ++several programs simultaneously (otherwise you have to exit from one ++before starting another). On some systems @value{GDBN} may even let ++you debug several programs simultaneously on different remote systems. ++In the most general case, you can have multiple threads of execution ++in each of multiple processes, launched from multiple executables, ++running on different machines. ++ ++@cindex inferior ++@value{GDBN} represents the state of each program execution with an ++object called an @dfn{inferior}. An inferior typically corresponds to ++a process, but is more general and applies also to targets that do not ++have processes. Inferiors may be created before a process runs, and ++may be retained after a process exits. Inferiors have unique ++identifiers that are different from process ids. Usually each ++inferior will also have its own distinct address space, although some ++embedded targets may have several inferiors running in different parts ++of a single address space. Each inferior may in turn have multiple ++threads running in it. ++ ++To find out what inferiors exist at any moment, use @w{@code{info ++inferiors}}: ++ ++@table @code ++@kindex info inferiors [ @var{id}@dots{} ] ++@item info inferiors ++Print a list of all inferiors currently being managed by @value{GDBN}. ++By default all inferiors are printed, but the argument @var{id}@dots{} ++-- a space separated list of inferior numbers -- can be used to limit ++the display to just the requested inferiors. ++ ++@value{GDBN} displays for each inferior (in this order): ++ ++@enumerate ++@item ++the inferior number assigned by @value{GDBN} ++ ++@item ++the target system's inferior identifier ++ ++@item ++the target connection the inferior is bound to, including the unique ++connection number assigned by @value{GDBN}, and the protocol used by ++the connection. ++ ++@item ++the name of the executable the inferior is running. ++ ++@end enumerate ++ ++@noindent ++An asterisk @samp{*} preceding the @value{GDBN} inferior number ++indicates the current inferior. ++ ++For example, ++@end table ++@c end table here to get a little more width for example ++ ++@smallexample ++(@value{GDBP}) info inferiors ++ Num Description Connection Executable ++* 1 process 3401 1 (native) goodbye ++ 2 process 2307 2 (extended-remote host:10000) hello ++@end smallexample ++ ++To find out what open target connections exist at any moment, use ++@w{@code{info connections}}: ++ ++@table @code ++@kindex info connections [ @var{id}@dots{} ] ++@item info connections ++Print a list of all open target connections currently being managed by ++@value{GDBN}. By default all connections are printed, but the ++argument @var{id}@dots{} -- a space separated list of connections ++numbers -- can be used to limit the display to just the requested ++connections. ++ ++@value{GDBN} displays for each connection (in this order): ++ ++@enumerate ++@item ++the connection number assigned by @value{GDBN}. ++ ++@item ++the protocol used by the connection. ++ ++@item ++a textual description of the protocol used by the connection. ++ ++@end enumerate ++ ++@noindent ++An asterisk @samp{*} preceding the connection number indicates the ++connection of the current inferior. ++ ++For example, ++@end table ++@c end table here to get a little more width for example ++ ++@smallexample ++(@value{GDBP}) info connections ++ Num What Description ++* 1 extended-remote host:10000 Extended remote serial target in gdb-specific protocol ++ 2 native Native process ++ 3 core Local core dump file ++@end smallexample ++ ++To switch focus between inferiors, use the @code{inferior} command: ++ ++@table @code ++@kindex inferior @var{infno} ++@item inferior @var{infno} ++Make inferior number @var{infno} the current inferior. The argument ++@var{infno} is the inferior number assigned by @value{GDBN}, as shown ++in the first field of the @samp{info inferiors} display. ++@end table ++ ++@vindex $_inferior@r{, convenience variable} ++The debugger convenience variable @samp{$_inferior} contains the ++number of the current inferior. You may find this useful in writing ++breakpoint conditional expressions, command scripts, and so forth. ++@xref{Convenience Vars,, Convenience Variables}, for general ++information on convenience variables. ++ ++You can get multiple executables into a debugging session via the ++@code{add-inferior} and @w{@code{clone-inferior}} commands. On some ++systems @value{GDBN} can add inferiors to the debug session ++automatically by following calls to @code{fork} and @code{exec}. To ++remove inferiors from the debugging session use the ++@w{@code{remove-inferiors}} command. ++ ++@table @code ++@kindex add-inferior ++@item add-inferior [ -copies @var{n} ] [ -exec @var{executable} ] [-no-connection ] ++Adds @var{n} inferiors to be run using @var{executable} as the ++executable; @var{n} defaults to 1. If no executable is specified, ++the inferiors begins empty, with no program. You can still assign or ++change the program assigned to the inferior at any time by using the ++@code{file} command with the executable name as its argument. ++ ++By default, the new inferior begins connected to the same target ++connection as the current inferior. For example, if the current ++inferior was connected to @code{gdbserver} with @code{target remote}, ++then the new inferior will be connected to the same @code{gdbserver} ++instance. The @samp{-no-connection} option starts the new inferior ++with no connection yet. You can then for example use the @code{target ++remote} command to connect to some other @code{gdbserver} instance, ++use @code{run} to spawn a local program, etc. ++ ++@kindex clone-inferior ++@item clone-inferior [ -copies @var{n} ] [ @var{infno} ] ++Adds @var{n} inferiors ready to execute the same program as inferior ++@var{infno}; @var{n} defaults to 1, and @var{infno} defaults to the ++number of the current inferior. This is a convenient command when you ++want to run another instance of the inferior you are debugging. ++ ++@smallexample ++(@value{GDBP}) info inferiors ++ Num Description Connection Executable ++* 1 process 29964 1 (native) helloworld ++(@value{GDBP}) clone-inferior ++Added inferior 2. ++1 inferiors added. ++(@value{GDBP}) info inferiors ++ Num Description Connection Executable ++* 1 process 29964 1 (native) helloworld ++ 2 1 (native) helloworld ++@end smallexample ++ ++You can now simply switch focus to inferior 2 and run it. ++ ++@kindex remove-inferiors ++@item remove-inferiors @var{infno}@dots{} ++Removes the inferior or inferiors @var{infno}@dots{}. It is not ++possible to remove an inferior that is running with this command. For ++those, use the @code{kill} or @code{detach} command first. ++ ++@end table ++ ++To quit debugging one of the running inferiors that is not the current ++inferior, you can either detach from it by using the @w{@code{detach ++inferior}} command (allowing it to run independently), or kill it ++using the @w{@code{kill inferiors}} command: ++ ++@table @code ++@kindex detach inferiors @var{infno}@dots{} ++@item detach inferior @var{infno}@dots{} ++Detach from the inferior or inferiors identified by @value{GDBN} ++inferior number(s) @var{infno}@dots{}. Note that the inferior's entry ++still stays on the list of inferiors shown by @code{info inferiors}, ++but its Description will show @samp{}. ++ ++@kindex kill inferiors @var{infno}@dots{} ++@item kill inferiors @var{infno}@dots{} ++Kill the inferior or inferiors identified by @value{GDBN} inferior ++number(s) @var{infno}@dots{}. Note that the inferior's entry still ++stays on the list of inferiors shown by @code{info inferiors}, but its ++Description will show @samp{}. ++@end table ++ ++After the successful completion of a command such as @code{detach}, ++@code{detach inferiors}, @code{kill} or @code{kill inferiors}, or after ++a normal process exit, the inferior is still valid and listed with ++@code{info inferiors}, ready to be restarted. ++ ++ ++To be notified when inferiors are started or exit under @value{GDBN}'s ++control use @w{@code{set print inferior-events}}: ++ ++@table @code ++@kindex set print inferior-events ++@cindex print messages on inferior start and exit ++@item set print inferior-events ++@itemx set print inferior-events on ++@itemx set print inferior-events off ++The @code{set print inferior-events} command allows you to enable or ++disable printing of messages when @value{GDBN} notices that new ++inferiors have started or that inferiors have exited or have been ++detached. By default, these messages will not be printed. ++ ++@kindex show print inferior-events ++@item show print inferior-events ++Show whether messages will be printed when @value{GDBN} detects that ++inferiors have started, exited or have been detached. ++@end table ++ ++Many commands will work the same with multiple programs as with a ++single program: e.g., @code{print myglobal} will simply display the ++value of @code{myglobal} in the current inferior. ++ ++ ++Occasionally, when debugging @value{GDBN} itself, it may be useful to ++get more info about the relationship of inferiors, programs, address ++spaces in a debug session. You can do that with the @w{@code{maint ++info program-spaces}} command. ++ ++@table @code ++@kindex maint info program-spaces ++@item maint info program-spaces ++Print a list of all program spaces currently being managed by ++@value{GDBN}. ++ ++@value{GDBN} displays for each program space (in this order): ++ ++@enumerate ++@item ++the program space number assigned by @value{GDBN} ++ ++@item ++the name of the executable loaded into the program space, with e.g., ++the @code{file} command. ++ ++@end enumerate ++ ++@noindent ++An asterisk @samp{*} preceding the @value{GDBN} program space number ++indicates the current program space. ++ ++In addition, below each program space line, @value{GDBN} prints extra ++information that isn't suitable to display in tabular form. For ++example, the list of inferiors bound to the program space. ++ ++@smallexample ++(@value{GDBP}) maint info program-spaces ++ Id Executable ++* 1 hello ++ 2 goodbye ++ Bound inferiors: ID 1 (process 21561) ++@end smallexample ++ ++Here we can see that no inferior is running the program @code{hello}, ++while @code{process 21561} is running the program @code{goodbye}. On ++some targets, it is possible that multiple inferiors are bound to the ++same program space. The most common example is that of debugging both ++the parent and child processes of a @code{vfork} call. For example, ++ ++@smallexample ++(@value{GDBP}) maint info program-spaces ++ Id Executable ++* 1 vfork-test ++ Bound inferiors: ID 2 (process 18050), ID 1 (process 18045) ++@end smallexample ++ ++Here, both inferior 2 and inferior 1 are running in the same program ++space as a result of inferior 1 having executed a @code{vfork} call. ++@end table ++ ++@node Threads ++@section Debugging Programs with Multiple Threads ++ ++@cindex threads of execution ++@cindex multiple threads ++@cindex switching threads ++In some operating systems, such as GNU/Linux and Solaris, a single program ++may have more than one @dfn{thread} of execution. The precise semantics ++of threads differ from one operating system to another, but in general ++the threads of a single program are akin to multiple processes---except ++that they share one address space (that is, they can all examine and ++modify the same variables). On the other hand, each thread has its own ++registers and execution stack, and perhaps private memory. ++ ++@value{GDBN} provides these facilities for debugging multi-thread ++programs: ++ ++@itemize @bullet ++@item automatic notification of new threads ++@item @samp{thread @var{thread-id}}, a command to switch among threads ++@item @samp{info threads}, a command to inquire about existing threads ++@item @samp{thread apply [@var{thread-id-list} | all] @var{args}}, ++a command to apply a command to a list of threads ++@item thread-specific breakpoints ++@item @samp{set print thread-events}, which controls printing of ++messages on thread start and exit. ++@item @samp{set libthread-db-search-path @var{path}}, which lets ++the user specify which @code{libthread_db} to use if the default choice ++isn't compatible with the program. ++@end itemize ++ ++@cindex focus of debugging ++@cindex current thread ++The @value{GDBN} thread debugging facility allows you to observe all ++threads while your program runs---but whenever @value{GDBN} takes ++control, one thread in particular is always the focus of debugging. ++This thread is called the @dfn{current thread}. Debugging commands show ++program information from the perspective of the current thread. ++ ++@cindex @code{New} @var{systag} message ++@cindex thread identifier (system) ++@c FIXME-implementors!! It would be more helpful if the [New...] message ++@c included GDB's numeric thread handle, so you could just go to that ++@c thread without first checking `info threads'. ++Whenever @value{GDBN} detects a new thread in your program, it displays ++the target system's identification for the thread with a message in the ++form @samp{[New @var{systag}]}, where @var{systag} is a thread identifier ++whose form varies depending on the particular system. For example, on ++@sc{gnu}/Linux, you might see ++ ++@smallexample ++[New Thread 0x41e02940 (LWP 25582)] ++@end smallexample ++ ++@noindent ++when @value{GDBN} notices a new thread. In contrast, on other systems, ++the @var{systag} is simply something like @samp{process 368}, with no ++further qualifier. ++ ++@c FIXME!! (1) Does the [New...] message appear even for the very first ++@c thread of a program, or does it only appear for the ++@c second---i.e.@: when it becomes obvious we have a multithread ++@c program? ++@c (2) *Is* there necessarily a first thread always? Or do some ++@c multithread systems permit starting a program with multiple ++@c threads ab initio? ++ ++@anchor{thread numbers} ++@cindex thread number, per inferior ++@cindex thread identifier (GDB) ++For debugging purposes, @value{GDBN} associates its own thread number ++---always a single integer---with each thread of an inferior. This ++number is unique between all threads of an inferior, but not unique ++between threads of different inferiors. ++ ++@cindex qualified thread ID ++You can refer to a given thread in an inferior using the qualified ++@var{inferior-num}.@var{thread-num} syntax, also known as ++@dfn{qualified thread ID}, with @var{inferior-num} being the inferior ++number and @var{thread-num} being the thread number of the given ++inferior. For example, thread @code{2.3} refers to thread number 3 of ++inferior 2. If you omit @var{inferior-num} (e.g., @code{thread 3}), ++then @value{GDBN} infers you're referring to a thread of the current ++inferior. ++ ++Until you create a second inferior, @value{GDBN} does not show the ++@var{inferior-num} part of thread IDs, even though you can always use ++the full @var{inferior-num}.@var{thread-num} form to refer to threads ++of inferior 1, the initial inferior. ++ ++@anchor{thread ID lists} ++@cindex thread ID lists ++Some commands accept a space-separated @dfn{thread ID list} as ++argument. A list element can be: ++ ++@enumerate ++@item ++A thread ID as shown in the first field of the @samp{info threads} ++display, with or without an inferior qualifier. E.g., @samp{2.1} or ++@samp{1}. ++ ++@item ++A range of thread numbers, again with or without an inferior ++qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or ++@var{thr1}-@var{thr2}. E.g., @samp{1.2-4} or @samp{2-4}. ++ ++@item ++All threads of an inferior, specified with a star wildcard, with or ++without an inferior qualifier, as in @var{inf}.@code{*} (e.g., ++@samp{1.*}) or @code{*}. The former refers to all threads of the ++given inferior, and the latter form without an inferior qualifier ++refers to all threads of the current inferior. ++ ++@end enumerate ++ ++For example, if the current inferior is 1, and inferior 7 has one ++thread with ID 7.1, the thread list @samp{1 2-3 4.5 6.7-9 7.*} ++includes threads 1 to 3 of inferior 1, thread 5 of inferior 4, threads ++7 to 9 of inferior 6 and all threads of inferior 7. That is, in ++expanded qualified form, the same as @samp{1.1 1.2 1.3 4.5 6.7 6.8 6.9 ++7.1}. ++ ++ ++@anchor{global thread numbers} ++@cindex global thread number ++@cindex global thread identifier (GDB) ++In addition to a @emph{per-inferior} number, each thread is also ++assigned a unique @emph{global} number, also known as @dfn{global ++thread ID}, a single integer. Unlike the thread number component of ++the thread ID, no two threads have the same global ID, even when ++you're debugging multiple inferiors. ++ ++From @value{GDBN}'s perspective, a process always has at least one ++thread. In other words, @value{GDBN} assigns a thread number to the ++program's ``main thread'' even if the program is not multi-threaded. ++ ++@vindex $_thread@r{, convenience variable} ++@vindex $_gthread@r{, convenience variable} ++The debugger convenience variables @samp{$_thread} and ++@samp{$_gthread} contain, respectively, the per-inferior thread number ++and the global thread number of the current thread. You may find this ++useful in writing breakpoint conditional expressions, command scripts, ++and so forth. @xref{Convenience Vars,, Convenience Variables}, for ++general information on convenience variables. ++ ++If @value{GDBN} detects the program is multi-threaded, it augments the ++usual message about stopping at a breakpoint with the ID and name of ++the thread that hit the breakpoint. ++ ++@smallexample ++Thread 2 "client" hit Breakpoint 1, send_message () at client.c:68 ++@end smallexample ++ ++Likewise when the program receives a signal: ++ ++@smallexample ++Thread 1 "main" received signal SIGINT, Interrupt. ++@end smallexample ++ ++@table @code ++@kindex info threads ++@item info threads @r{[}@var{thread-id-list}@r{]} ++ ++Display information about one or more threads. With no arguments ++displays information about all threads. You can specify the list of ++threads that you want to display using the thread ID list syntax ++(@pxref{thread ID lists}). ++ ++@value{GDBN} displays for each thread (in this order): ++ ++@enumerate ++@item ++the per-inferior thread number assigned by @value{GDBN} ++ ++@item ++the global thread number assigned by @value{GDBN}, if the @samp{-gid} ++option was specified ++ ++@item ++the target system's thread identifier (@var{systag}) ++ ++@item ++the thread's name, if one is known. A thread can either be named by ++the user (see @code{thread name}, below), or, in some cases, by the ++program itself. ++ ++@item ++the current stack frame summary for that thread ++@end enumerate ++ ++@noindent ++An asterisk @samp{*} to the left of the @value{GDBN} thread number ++indicates the current thread. ++ ++For example, ++@end table ++@c end table here to get a little more width for example ++ ++@smallexample ++(@value{GDBP}) info threads ++ Id Target Id Frame ++* 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) ++ 2 process 35 thread 23 0x34e5 in sigpause () ++ 3 process 35 thread 27 0x34e5 in sigpause () ++ at threadtest.c:68 ++@end smallexample ++ ++If you're debugging multiple inferiors, @value{GDBN} displays thread ++IDs using the qualified @var{inferior-num}.@var{thread-num} format. ++Otherwise, only @var{thread-num} is shown. ++ ++If you specify the @samp{-gid} option, @value{GDBN} displays a column ++indicating each thread's global thread ID: ++ ++@smallexample ++(@value{GDBP}) info threads ++ Id GId Target Id Frame ++ 1.1 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) ++ 1.2 3 process 35 thread 23 0x34e5 in sigpause () ++ 1.3 4 process 35 thread 27 0x34e5 in sigpause () ++* 2.1 2 process 65 thread 1 main (argc=1, argv=0x7ffffff8) ++@end smallexample ++ ++On Solaris, you can display more information about user threads with a ++Solaris-specific command: ++ ++@table @code ++@item maint info sol-threads ++@kindex maint info sol-threads ++@cindex thread info (Solaris) ++Display info on Solaris user threads. ++@end table ++ ++@table @code ++@kindex thread @var{thread-id} ++@item thread @var{thread-id} ++Make thread ID @var{thread-id} the current thread. The command ++argument @var{thread-id} is the @value{GDBN} thread ID, as shown in ++the first field of the @samp{info threads} display, with or without an ++inferior qualifier (e.g., @samp{2.1} or @samp{1}). ++ ++@value{GDBN} responds by displaying the system identifier of the ++thread you selected, and its current stack frame summary: ++ ++@smallexample ++(@value{GDBP}) thread 2 ++[Switching to thread 2 (Thread 0xb7fdab70 (LWP 12747))] ++#0 some_function (ignore=0x0) at example.c:8 ++8 printf ("hello\n"); ++@end smallexample ++ ++@noindent ++As with the @samp{[New @dots{}]} message, the form of the text after ++@samp{Switching to} depends on your system's conventions for identifying ++threads. ++ ++@anchor{thread apply all} ++@kindex thread apply ++@cindex apply command to several threads ++@item thread apply [@var{thread-id-list} | all [-ascending]] [@var{flag}]@dots{} @var{command} ++The @code{thread apply} command allows you to apply the named ++@var{command} to one or more threads. Specify the threads that you ++want affected using the thread ID list syntax (@pxref{thread ID ++lists}), or specify @code{all} to apply to all threads. To apply a ++command to all threads in descending order, type @kbd{thread apply all ++@var{command}}. To apply a command to all threads in ascending order, ++type @kbd{thread apply all -ascending @var{command}}. ++ ++The @var{flag} arguments control what output to produce and how to handle ++errors raised when applying @var{command} to a thread. @var{flag} ++must start with a @code{-} directly followed by one letter in ++@code{qcs}. If several flags are provided, they must be given ++individually, such as @code{-c -q}. ++ ++By default, @value{GDBN} displays some thread information before the ++output produced by @var{command}, and an error raised during the ++execution of a @var{command} will abort @code{thread apply}. The ++following flags can be used to fine-tune this behavior: ++ ++@table @code ++@item -c ++The flag @code{-c}, which stands for @samp{continue}, causes any ++errors in @var{command} to be displayed, and the execution of ++@code{thread apply} then continues. ++@item -s ++The flag @code{-s}, which stands for @samp{silent}, causes any errors ++or empty output produced by a @var{command} to be silently ignored. ++That is, the execution continues, but the thread information and errors ++are not printed. ++@item -q ++The flag @code{-q} (@samp{quiet}) disables printing the thread ++information. ++@end table ++ ++Flags @code{-c} and @code{-s} cannot be used together. ++ ++@kindex taas ++@cindex apply command to all threads (ignoring errors and empty output) ++@item taas [@var{option}]@dots{} @var{command} ++Shortcut for @code{thread apply all -s [@var{option}]@dots{} @var{command}}. ++Applies @var{command} on all threads, ignoring errors and empty output. ++ ++The @code{taas} command accepts the same options as the @code{thread ++apply all} command. @xref{thread apply all}. ++ ++@kindex tfaas ++@cindex apply a command to all frames of all threads (ignoring errors and empty output) ++@item tfaas [@var{option}]@dots{} @var{command} ++Shortcut for @code{thread apply all -s -- frame apply all -s [@var{option}]@dots{} @var{command}}. ++Applies @var{command} on all frames of all threads, ignoring errors ++and empty output. Note that the flag @code{-s} is specified twice: ++The first @code{-s} ensures that @code{thread apply} only shows the thread ++information of the threads for which @code{frame apply} produces ++some output. The second @code{-s} is needed to ensure that @code{frame ++apply} shows the frame information of a frame only if the ++@var{command} successfully produced some output. ++ ++It can for example be used to print a local variable or a function ++argument without knowing the thread or frame where this variable or argument ++is, using: ++@smallexample ++(@value{GDBP}) tfaas p some_local_var_i_do_not_remember_where_it_is ++@end smallexample ++ ++The @code{tfaas} command accepts the same options as the @code{frame ++apply} command. @xref{Frame Apply,,frame apply}. ++ ++@kindex thread name ++@cindex name a thread ++@item thread name [@var{name}] ++This command assigns a name to the current thread. If no argument is ++given, any existing user-specified name is removed. The thread name ++appears in the @samp{info threads} display. ++ ++On some systems, such as @sc{gnu}/Linux, @value{GDBN} is able to ++determine the name of the thread as given by the OS. On these ++systems, a name specified with @samp{thread name} will override the ++system-give name, and removing the user-specified name will cause ++@value{GDBN} to once again display the system-specified name. ++ ++@kindex thread find ++@cindex search for a thread ++@item thread find [@var{regexp}] ++Search for and display thread ids whose name or @var{systag} ++matches the supplied regular expression. ++ ++As well as being the complement to the @samp{thread name} command, ++this command also allows you to identify a thread by its target ++@var{systag}. For instance, on @sc{gnu}/Linux, the target @var{systag} ++is the LWP id. ++ ++@smallexample ++(@value{GDBN}) thread find 26688 ++Thread 4 has target id 'Thread 0x41e02940 (LWP 26688)' ++(@value{GDBN}) info thread 4 ++ Id Target Id Frame ++ 4 Thread 0x41e02940 (LWP 26688) 0x00000031ca6cd372 in select () ++@end smallexample ++ ++@kindex set print thread-events ++@cindex print messages on thread start and exit ++@item set print thread-events ++@itemx set print thread-events on ++@itemx set print thread-events off ++The @code{set print thread-events} command allows you to enable or ++disable printing of messages when @value{GDBN} notices that new threads have ++started or that threads have exited. By default, these messages will ++be printed if detection of these events is supported by the target. ++Note that these messages cannot be disabled on all targets. ++ ++@kindex show print thread-events ++@item show print thread-events ++Show whether messages will be printed when @value{GDBN} detects that threads ++have started and exited. ++@end table ++ ++@xref{Thread Stops,,Stopping and Starting Multi-thread Programs}, for ++more information about how @value{GDBN} behaves when you stop and start ++programs with multiple threads. ++ ++@xref{Set Watchpoints,,Setting Watchpoints}, for information about ++watchpoints in programs with multiple threads. ++ ++@anchor{set libthread-db-search-path} ++@table @code ++@kindex set libthread-db-search-path ++@cindex search path for @code{libthread_db} ++@item set libthread-db-search-path @r{[}@var{path}@r{]} ++If this variable is set, @var{path} is a colon-separated list of ++directories @value{GDBN} will use to search for @code{libthread_db}. ++If you omit @var{path}, @samp{libthread-db-search-path} will be reset to ++its default value (@code{$sdir:$pdir} on @sc{gnu}/Linux and Solaris systems). ++Internally, the default value comes from the @code{LIBTHREAD_DB_SEARCH_PATH} ++macro. ++ ++On @sc{gnu}/Linux and Solaris systems, @value{GDBN} uses a ``helper'' ++@code{libthread_db} library to obtain information about threads in the ++inferior process. @value{GDBN} will use @samp{libthread-db-search-path} ++to find @code{libthread_db}. @value{GDBN} also consults first if inferior ++specific thread debugging library loading is enabled ++by @samp{set auto-load libthread-db} (@pxref{libthread_db.so.1 file}). ++ ++A special entry @samp{$sdir} for @samp{libthread-db-search-path} ++refers to the default system directories that are ++normally searched for loading shared libraries. The @samp{$sdir} entry ++is the only kind not needing to be enabled by @samp{set auto-load libthread-db} ++(@pxref{libthread_db.so.1 file}). ++ ++A special entry @samp{$pdir} for @samp{libthread-db-search-path} ++refers to the directory from which @code{libpthread} ++was loaded in the inferior process. ++ ++For any @code{libthread_db} library @value{GDBN} finds in above directories, ++@value{GDBN} attempts to initialize it with the current inferior process. ++If this initialization fails (which could happen because of a version ++mismatch between @code{libthread_db} and @code{libpthread}), @value{GDBN} ++will unload @code{libthread_db}, and continue with the next directory. ++If none of @code{libthread_db} libraries initialize successfully, ++@value{GDBN} will issue a warning and thread debugging will be disabled. ++ ++Setting @code{libthread-db-search-path} is currently implemented ++only on some platforms. ++ ++@kindex show libthread-db-search-path ++@item show libthread-db-search-path ++Display current libthread_db search path. ++ ++@kindex set debug libthread-db ++@kindex show debug libthread-db ++@cindex debugging @code{libthread_db} ++@item set debug libthread-db ++@itemx show debug libthread-db ++Turns on or off display of @code{libthread_db}-related events. ++Use @code{1} to enable, @code{0} to disable. ++@end table ++ ++@node Forks ++@section Debugging Forks ++ ++@cindex fork, debugging programs which call ++@cindex multiple processes ++@cindex processes, multiple ++On most systems, @value{GDBN} has no special support for debugging ++programs which create additional processes using the @code{fork} ++function. When a program forks, @value{GDBN} will continue to debug the ++parent process and the child process will run unimpeded. If you have ++set a breakpoint in any code which the child then executes, the child ++will get a @code{SIGTRAP} signal which (unless it catches the signal) ++will cause it to terminate. ++ ++However, if you want to debug the child process there is a workaround ++which isn't too painful. Put a call to @code{sleep} in the code which ++the child process executes after the fork. It may be useful to sleep ++only if a certain environment variable is set, or a certain file exists, ++so that the delay need not occur when you don't want to run @value{GDBN} ++on the child. While the child is sleeping, use the @code{ps} program to ++get its process ID. Then tell @value{GDBN} (a new invocation of ++@value{GDBN} if you are also debugging the parent process) to attach to ++the child process (@pxref{Attach}). From that point on you can debug ++the child process just like any other process which you attached to. ++ ++On some systems, @value{GDBN} provides support for debugging programs ++that create additional processes using the @code{fork} or @code{vfork} ++functions. On @sc{gnu}/Linux platforms, this feature is supported ++with kernel version 2.5.46 and later. ++ ++The fork debugging commands are supported in native mode and when ++connected to @code{gdbserver} in either @code{target remote} mode or ++@code{target extended-remote} mode. ++ ++By default, when a program forks, @value{GDBN} will continue to debug ++the parent process and the child process will run unimpeded. ++ ++If you want to follow the child process instead of the parent process, ++use the command @w{@code{set follow-fork-mode}}. ++ ++@table @code ++@kindex set follow-fork-mode ++@item set follow-fork-mode @var{mode} ++Set the debugger response to a program call of @code{fork} or ++@code{vfork}. A call to @code{fork} or @code{vfork} creates a new ++process. The @var{mode} argument can be: ++ ++@table @code ++@item parent ++The original process is debugged after a fork. The child process runs ++unimpeded. This is the default. ++ ++@item child ++The new process is debugged after a fork. The parent process runs ++unimpeded. ++ ++@end table ++ ++@kindex show follow-fork-mode ++@item show follow-fork-mode ++Display the current debugger response to a @code{fork} or @code{vfork} call. ++@end table ++ ++@cindex debugging multiple processes ++On Linux, if you want to debug both the parent and child processes, use the ++command @w{@code{set detach-on-fork}}. ++ ++@table @code ++@kindex set detach-on-fork ++@item set detach-on-fork @var{mode} ++Tells gdb whether to detach one of the processes after a fork, or ++retain debugger control over them both. ++ ++@table @code ++@item on ++The child process (or parent process, depending on the value of ++@code{follow-fork-mode}) will be detached and allowed to run ++independently. This is the default. ++ ++@item off ++Both processes will be held under the control of @value{GDBN}. ++One process (child or parent, depending on the value of ++@code{follow-fork-mode}) is debugged as usual, while the other ++is held suspended. ++ ++@end table ++ ++@kindex show detach-on-fork ++@item show detach-on-fork ++Show whether detach-on-fork mode is on/off. ++@end table ++ ++If you choose to set @samp{detach-on-fork} mode off, then @value{GDBN} ++will retain control of all forked processes (including nested forks). ++You can list the forked processes under the control of @value{GDBN} by ++using the @w{@code{info inferiors}} command, and switch from one fork ++to another by using the @code{inferior} command (@pxref{Inferiors Connections and ++Programs, ,Debugging Multiple Inferiors Connections and Programs}). ++ ++To quit debugging one of the forked processes, you can either detach ++from it by using the @w{@code{detach inferiors}} command (allowing it ++to run independently), or kill it using the @w{@code{kill inferiors}} ++command. @xref{Inferiors Connections and Programs, ,Debugging ++Multiple Inferiors Connections and Programs}. ++ ++If you ask to debug a child process and a @code{vfork} is followed by an ++@code{exec}, @value{GDBN} executes the new target up to the first ++breakpoint in the new target. If you have a breakpoint set on ++@code{main} in your original program, the breakpoint will also be set on ++the child process's @code{main}. ++ ++On some systems, when a child process is spawned by @code{vfork}, you ++cannot debug the child or parent until an @code{exec} call completes. ++ ++If you issue a @code{run} command to @value{GDBN} after an @code{exec} ++call executes, the new target restarts. To restart the parent ++process, use the @code{file} command with the parent executable name ++as its argument. By default, after an @code{exec} call executes, ++@value{GDBN} discards the symbols of the previous executable image. ++You can change this behaviour with the @w{@code{set follow-exec-mode}} ++command. ++ ++@table @code ++@kindex set follow-exec-mode ++@item set follow-exec-mode @var{mode} ++ ++Set debugger response to a program call of @code{exec}. An ++@code{exec} call replaces the program image of a process. ++ ++@code{follow-exec-mode} can be: ++ ++@table @code ++@item new ++@value{GDBN} creates a new inferior and rebinds the process to this ++new inferior. The program the process was running before the ++@code{exec} call can be restarted afterwards by restarting the ++original inferior. ++ ++For example: ++ ++@smallexample ++(@value{GDBP}) info inferiors ++(gdb) info inferior ++ Id Description Executable ++* 1 prog1 ++(@value{GDBP}) run ++process 12020 is executing new program: prog2 ++Program exited normally. ++(@value{GDBP}) info inferiors ++ Id Description Executable ++ 1 prog1 ++* 2 prog2 ++@end smallexample ++ ++@item same ++@value{GDBN} keeps the process bound to the same inferior. The new ++executable image replaces the previous executable loaded in the ++inferior. Restarting the inferior after the @code{exec} call, with ++e.g., the @code{run} command, restarts the executable the process was ++running after the @code{exec} call. This is the default mode. ++ ++For example: ++ ++@smallexample ++(@value{GDBP}) info inferiors ++ Id Description Executable ++* 1 prog1 ++(@value{GDBP}) run ++process 12020 is executing new program: prog2 ++Program exited normally. ++(@value{GDBP}) info inferiors ++ Id Description Executable ++* 1 prog2 ++@end smallexample ++ ++@end table ++@end table ++ ++@code{follow-exec-mode} is supported in native mode and ++@code{target extended-remote} mode. ++ ++You can use the @code{catch} command to make @value{GDBN} stop whenever ++a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set ++Catchpoints, ,Setting Catchpoints}. ++ ++@node Checkpoint/Restart ++@section Setting a @emph{Bookmark} to Return to Later ++ ++@cindex checkpoint ++@cindex restart ++@cindex bookmark ++@cindex snapshot of a process ++@cindex rewind program state ++ ++On certain operating systems@footnote{Currently, only ++@sc{gnu}/Linux.}, @value{GDBN} is able to save a @dfn{snapshot} of a ++program's state, called a @dfn{checkpoint}, and come back to it ++later. ++ ++Returning to a checkpoint effectively undoes everything that has ++happened in the program since the @code{checkpoint} was saved. This ++includes changes in memory, registers, and even (within some limits) ++system state. Effectively, it is like going back in time to the ++moment when the checkpoint was saved. ++ ++Thus, if you're stepping thru a program and you think you're ++getting close to the point where things go wrong, you can save ++a checkpoint. Then, if you accidentally go too far and miss ++the critical statement, instead of having to restart your program ++from the beginning, you can just go back to the checkpoint and ++start again from there. ++ ++This can be especially useful if it takes a lot of time or ++steps to reach the point where you think the bug occurs. ++ ++To use the @code{checkpoint}/@code{restart} method of debugging: ++ ++@table @code ++@kindex checkpoint ++@item checkpoint ++Save a snapshot of the debugged program's current execution state. ++The @code{checkpoint} command takes no arguments, but each checkpoint ++is assigned a small integer id, similar to a breakpoint id. ++ ++@kindex info checkpoints ++@item info checkpoints ++List the checkpoints that have been saved in the current debugging ++session. For each checkpoint, the following information will be ++listed: ++ ++@table @code ++@item Checkpoint ID ++@item Process ID ++@item Code Address ++@item Source line, or label ++@end table ++ ++@kindex restart @var{checkpoint-id} ++@item restart @var{checkpoint-id} ++Restore the program state that was saved as checkpoint number ++@var{checkpoint-id}. All program variables, registers, stack frames ++etc.@: will be returned to the values that they had when the checkpoint ++was saved. In essence, gdb will ``wind back the clock'' to the point ++in time when the checkpoint was saved. ++ ++Note that breakpoints, @value{GDBN} variables, command history etc. ++are not affected by restoring a checkpoint. In general, a checkpoint ++only restores things that reside in the program being debugged, not in ++the debugger. ++ ++@kindex delete checkpoint @var{checkpoint-id} ++@item delete checkpoint @var{checkpoint-id} ++Delete the previously-saved checkpoint identified by @var{checkpoint-id}. ++ ++@end table ++ ++Returning to a previously saved checkpoint will restore the user state ++of the program being debugged, plus a significant subset of the system ++(OS) state, including file pointers. It won't ``un-write'' data from ++a file, but it will rewind the file pointer to the previous location, ++so that the previously written data can be overwritten. For files ++opened in read mode, the pointer will also be restored so that the ++previously read data can be read again. ++ ++Of course, characters that have been sent to a printer (or other ++external device) cannot be ``snatched back'', and characters received ++from eg.@: a serial device can be removed from internal program buffers, ++but they cannot be ``pushed back'' into the serial pipeline, ready to ++be received again. Similarly, the actual contents of files that have ++been changed cannot be restored (at this time). ++ ++However, within those constraints, you actually can ``rewind'' your ++program to a previously saved point in time, and begin debugging it ++again --- and you can change the course of events so as to debug a ++different execution path this time. ++ ++@cindex checkpoints and process id ++Finally, there is one bit of internal program state that will be ++different when you return to a checkpoint --- the program's process ++id. Each checkpoint will have a unique process id (or @var{pid}), ++and each will be different from the program's original @var{pid}. ++If your program has saved a local copy of its process id, this could ++potentially pose a problem. ++ ++@subsection A Non-obvious Benefit of Using Checkpoints ++ ++On some systems such as @sc{gnu}/Linux, address space randomization ++is performed on new processes for security reasons. This makes it ++difficult or impossible to set a breakpoint, or watchpoint, on an ++absolute address if you have to restart the program, since the ++absolute location of a symbol will change from one execution to the ++next. ++ ++A checkpoint, however, is an @emph{identical} copy of a process. ++Therefore if you create a checkpoint at (eg.@:) the start of main, ++and simply return to that checkpoint instead of restarting the ++process, you can avoid the effects of address randomization and ++your symbols will all stay in the same place. ++ ++@node Stopping ++@chapter Stopping and Continuing ++ ++The principal purposes of using a debugger are so that you can stop your ++program before it terminates; or so that, if your program runs into ++trouble, you can investigate and find out why. ++ ++Inside @value{GDBN}, your program may stop for any of several reasons, ++such as a signal, a breakpoint, or reaching a new line after a ++@value{GDBN} command such as @code{step}. You may then examine and ++change variables, set new breakpoints or remove old ones, and then ++continue execution. Usually, the messages shown by @value{GDBN} provide ++ample explanation of the status of your program---but you can also ++explicitly request this information at any time. ++ ++@table @code ++@kindex info program ++@item info program ++Display information about the status of your program: whether it is ++running or not, what process it is, and why it stopped. ++@end table ++ ++@menu ++* Breakpoints:: Breakpoints, watchpoints, and catchpoints ++* Continuing and Stepping:: Resuming execution ++* Skipping Over Functions and Files:: ++ Skipping over functions and files ++* Signals:: Signals ++* Thread Stops:: Stopping and starting multi-thread programs ++@end menu ++ ++@node Breakpoints ++@section Breakpoints, Watchpoints, and Catchpoints ++ ++@cindex breakpoints ++A @dfn{breakpoint} makes your program stop whenever a certain point in ++the program is reached. For each breakpoint, you can add conditions to ++control in finer detail whether your program stops. You can set ++breakpoints with the @code{break} command and its variants (@pxref{Set ++Breaks, ,Setting Breakpoints}), to specify the place where your program ++should stop by line number, function name or exact address in the ++program. ++ ++On some systems, you can set breakpoints in shared libraries before ++the executable is run. ++ ++@cindex watchpoints ++@cindex data breakpoints ++@cindex memory tracing ++@cindex breakpoint on memory address ++@cindex breakpoint on variable modification ++A @dfn{watchpoint} is a special breakpoint that stops your program ++when the value of an expression changes. The expression may be a value ++of a variable, or it could involve values of one or more variables ++combined by operators, such as @samp{a + b}. This is sometimes called ++@dfn{data breakpoints}. You must use a different command to set ++watchpoints (@pxref{Set Watchpoints, ,Setting Watchpoints}), but aside ++from that, you can manage a watchpoint like any other breakpoint: you ++enable, disable, and delete both breakpoints and watchpoints using the ++same commands. ++ ++You can arrange to have values from your program displayed automatically ++whenever @value{GDBN} stops at a breakpoint. @xref{Auto Display,, ++Automatic Display}. ++ ++@cindex catchpoints ++@cindex breakpoint on events ++A @dfn{catchpoint} is another special breakpoint that stops your program ++when a certain kind of event occurs, such as the throwing of a C@t{++} ++exception or the loading of a library. As with watchpoints, you use a ++different command to set a catchpoint (@pxref{Set Catchpoints, ,Setting ++Catchpoints}), but aside from that, you can manage a catchpoint like any ++other breakpoint. (To stop when your program receives a signal, use the ++@code{handle} command; see @ref{Signals, ,Signals}.) ++ ++@cindex breakpoint numbers ++@cindex numbers for breakpoints ++@value{GDBN} assigns a number to each breakpoint, watchpoint, or ++catchpoint when you create it; these numbers are successive integers ++starting with one. In many of the commands for controlling various ++features of breakpoints you use the breakpoint number to say which ++breakpoint you want to change. Each breakpoint may be @dfn{enabled} or ++@dfn{disabled}; if disabled, it has no effect on your program until you ++enable it again. ++ ++@cindex breakpoint ranges ++@cindex breakpoint lists ++@cindex ranges of breakpoints ++@cindex lists of breakpoints ++Some @value{GDBN} commands accept a space-separated list of breakpoints ++on which to operate. A list element can be either a single breakpoint number, ++like @samp{5}, or a range of such numbers, like @samp{5-7}. ++When a breakpoint list is given to a command, all breakpoints in that list ++are operated on. ++ ++@menu ++* Set Breaks:: Setting breakpoints ++* Set Watchpoints:: Setting watchpoints ++* Set Catchpoints:: Setting catchpoints ++* Delete Breaks:: Deleting breakpoints ++* Disabling:: Disabling breakpoints ++* Conditions:: Break conditions ++* Break Commands:: Breakpoint command lists ++* Dynamic Printf:: Dynamic printf ++* Save Breakpoints:: How to save breakpoints in a file ++* Static Probe Points:: Listing static probe points ++* Error in Breakpoints:: ``Cannot insert breakpoints'' ++* Breakpoint-related Warnings:: ``Breakpoint address adjusted...'' ++@end menu ++ ++@node Set Breaks ++@subsection Setting Breakpoints ++ ++@c FIXME LMB what does GDB do if no code on line of breakpt? ++@c consider in particular declaration with/without initialization. ++@c ++@c FIXME 2 is there stuff on this already? break at fun start, already init? ++ ++@kindex break ++@kindex b @r{(@code{break})} ++@vindex $bpnum@r{, convenience variable} ++@cindex latest breakpoint ++Breakpoints are set with the @code{break} command (abbreviated ++@code{b}). The debugger convenience variable @samp{$bpnum} records the ++number of the breakpoint you've set most recently; see @ref{Convenience ++Vars,, Convenience Variables}, for a discussion of what you can do with ++convenience variables. ++ ++@table @code ++@item break @var{location} ++Set a breakpoint at the given @var{location}, which can specify a ++function name, a line number, or an address of an instruction. ++(@xref{Specify Location}, for a list of all the possible ways to ++specify a @var{location}.) The breakpoint will stop your program just ++before it executes any of the code in the specified @var{location}. ++ ++When using source languages that permit overloading of symbols, such as ++C@t{++}, a function name may refer to more than one possible place to break. ++@xref{Ambiguous Expressions,,Ambiguous Expressions}, for a discussion of ++that situation. ++ ++It is also possible to insert a breakpoint that will stop the program ++only if a specific thread (@pxref{Thread-Specific Breakpoints}) ++or a specific task (@pxref{Ada Tasks}) hits that breakpoint. ++ ++@item break ++When called without any arguments, @code{break} sets a breakpoint at ++the next instruction to be executed in the selected stack frame ++(@pxref{Stack, ,Examining the Stack}). In any selected frame but the ++innermost, this makes your program stop as soon as control ++returns to that frame. This is similar to the effect of a ++@code{finish} command in the frame inside the selected frame---except ++that @code{finish} does not leave an active breakpoint. If you use ++@code{break} without an argument in the innermost frame, @value{GDBN} stops ++the next time it reaches the current location; this may be useful ++inside loops. ++ ++@value{GDBN} normally ignores breakpoints when it resumes execution, until at ++least one instruction has been executed. If it did not do this, you ++would be unable to proceed past a breakpoint without first disabling the ++breakpoint. This rule applies whether or not the breakpoint already ++existed when your program stopped. ++ ++@item break @dots{} if @var{cond} ++Set a breakpoint with condition @var{cond}; evaluate the expression ++@var{cond} each time the breakpoint is reached, and stop only if the ++value is nonzero---that is, if @var{cond} evaluates as true. ++@samp{@dots{}} stands for one of the possible arguments described ++above (or no argument) specifying where to break. @xref{Conditions, ++,Break Conditions}, for more information on breakpoint conditions. ++ ++@kindex tbreak ++@item tbreak @var{args} ++Set a breakpoint enabled only for one stop. The @var{args} are the ++same as for the @code{break} command, and the breakpoint is set in the same ++way, but the breakpoint is automatically deleted after the first time your ++program stops there. @xref{Disabling, ,Disabling Breakpoints}. ++ ++@kindex hbreak ++@cindex hardware breakpoints ++@item hbreak @var{args} ++Set a hardware-assisted breakpoint. The @var{args} are the same as for the ++@code{break} command and the breakpoint is set in the same way, but the ++breakpoint requires hardware support and some target hardware may not ++have this support. The main purpose of this is EPROM/ROM code ++debugging, so you can set a breakpoint at an instruction without ++changing the instruction. This can be used with the new trap-generation ++provided by SPARClite DSU and most x86-based targets. These targets ++will generate traps when a program accesses some data or instruction ++address that is assigned to the debug registers. However the hardware ++breakpoint registers can take a limited number of breakpoints. For ++example, on the DSU, only two data breakpoints can be set at a time, and ++@value{GDBN} will reject this command if more than two are used. Delete ++or disable unused hardware breakpoints before setting new ones ++(@pxref{Disabling, ,Disabling Breakpoints}). ++@xref{Conditions, ,Break Conditions}. ++For remote targets, you can restrict the number of hardware ++breakpoints @value{GDBN} will use, see @ref{set remote ++hardware-breakpoint-limit}. ++ ++@kindex thbreak ++@item thbreak @var{args} ++Set a hardware-assisted breakpoint enabled only for one stop. The @var{args} ++are the same as for the @code{hbreak} command and the breakpoint is set in ++the same way. However, like the @code{tbreak} command, ++the breakpoint is automatically deleted after the ++first time your program stops there. Also, like the @code{hbreak} ++command, the breakpoint requires hardware support and some target hardware ++may not have this support. @xref{Disabling, ,Disabling Breakpoints}. ++See also @ref{Conditions, ,Break Conditions}. ++ ++@kindex rbreak ++@cindex regular expression ++@cindex breakpoints at functions matching a regexp ++@cindex set breakpoints in many functions ++@item rbreak @var{regex} ++Set breakpoints on all functions matching the regular expression ++@var{regex}. This command sets an unconditional breakpoint on all ++matches, printing a list of all breakpoints it set. Once these ++breakpoints are set, they are treated just like the breakpoints set with ++the @code{break} command. You can delete them, disable them, or make ++them conditional the same way as any other breakpoint. ++ ++In programs using different languages, @value{GDBN} chooses the syntax ++to print the list of all breakpoints it sets according to the ++@samp{set language} value: using @samp{set language auto} ++(see @ref{Automatically, ,Set Language Automatically}) means to use the ++language of the breakpoint's function, other values mean to use ++the manually specified language (see @ref{Manually, ,Set Language Manually}). ++ ++The syntax of the regular expression is the standard one used with tools ++like @file{grep}. Note that this is different from the syntax used by ++shells, so for instance @code{foo*} matches all functions that include ++an @code{fo} followed by zero or more @code{o}s. There is an implicit ++@code{.*} leading and trailing the regular expression you supply, so to ++match only functions that begin with @code{foo}, use @code{^foo}. ++ ++@cindex non-member C@t{++} functions, set breakpoint in ++When debugging C@t{++} programs, @code{rbreak} is useful for setting ++breakpoints on overloaded functions that are not members of any special ++classes. ++ ++@cindex set breakpoints on all functions ++The @code{rbreak} command can be used to set breakpoints in ++@strong{all} the functions in a program, like this: ++ ++@smallexample ++(@value{GDBP}) rbreak . ++@end smallexample ++ ++@item rbreak @var{file}:@var{regex} ++If @code{rbreak} is called with a filename qualification, it limits ++the search for functions matching the given regular expression to the ++specified @var{file}. This can be used, for example, to set breakpoints on ++every function in a given file: ++ ++@smallexample ++(@value{GDBP}) rbreak file.c:. ++@end smallexample ++ ++The colon separating the filename qualifier from the regex may ++optionally be surrounded by spaces. ++ ++@kindex info breakpoints ++@cindex @code{$_} and @code{info breakpoints} ++@item info breakpoints @r{[}@var{list}@dots{}@r{]} ++@itemx info break @r{[}@var{list}@dots{}@r{]} ++Print a table of all breakpoints, watchpoints, and catchpoints set and ++not deleted. Optional argument @var{n} means print information only ++about the specified breakpoint(s) (or watchpoint(s) or catchpoint(s)). ++For each breakpoint, following columns are printed: ++ ++@table @emph ++@item Breakpoint Numbers ++@item Type ++Breakpoint, watchpoint, or catchpoint. ++@item Disposition ++Whether the breakpoint is marked to be disabled or deleted when hit. ++@item Enabled or Disabled ++Enabled breakpoints are marked with @samp{y}. @samp{n} marks breakpoints ++that are not enabled. ++@item Address ++Where the breakpoint is in your program, as a memory address. For a ++pending breakpoint whose address is not yet known, this field will ++contain @samp{}. Such breakpoint won't fire until a shared ++library that has the symbol or line referred by breakpoint is loaded. ++See below for details. A breakpoint with several locations will ++have @samp{} in this field---see below for details. ++@item What ++Where the breakpoint is in the source for your program, as a file and ++line number. For a pending breakpoint, the original string passed to ++the breakpoint command will be listed as it cannot be resolved until ++the appropriate shared library is loaded in the future. ++@end table ++ ++@noindent ++If a breakpoint is conditional, there are two evaluation modes: ``host'' and ++``target''. If mode is ``host'', breakpoint condition evaluation is done by ++@value{GDBN} on the host's side. If it is ``target'', then the condition ++is evaluated by the target. The @code{info break} command shows ++the condition on the line following the affected breakpoint, together with ++its condition evaluation mode in between parentheses. ++ ++Breakpoint commands, if any, are listed after that. A pending breakpoint is ++allowed to have a condition specified for it. The condition is not parsed for ++validity until a shared library is loaded that allows the pending ++breakpoint to resolve to a valid location. ++ ++@noindent ++@code{info break} with a breakpoint ++number @var{n} as argument lists only that breakpoint. The ++convenience variable @code{$_} and the default examining-address for ++the @code{x} command are set to the address of the last breakpoint ++listed (@pxref{Memory, ,Examining Memory}). ++ ++@noindent ++@code{info break} displays a count of the number of times the breakpoint ++has been hit. This is especially useful in conjunction with the ++@code{ignore} command. You can ignore a large number of breakpoint ++hits, look at the breakpoint info to see how many times the breakpoint ++was hit, and then run again, ignoring one less than that number. This ++will get you quickly to the last hit of that breakpoint. ++ ++@noindent ++For a breakpoints with an enable count (xref) greater than 1, ++@code{info break} also displays that count. ++ ++@end table ++ ++@value{GDBN} allows you to set any number of breakpoints at the same place in ++your program. There is nothing silly or meaningless about this. When ++the breakpoints are conditional, this is even useful ++(@pxref{Conditions, ,Break Conditions}). ++ ++@cindex multiple locations, breakpoints ++@cindex breakpoints, multiple locations ++It is possible that a breakpoint corresponds to several locations ++in your program. Examples of this situation are: ++ ++@itemize @bullet ++@item ++Multiple functions in the program may have the same name. ++ ++@item ++For a C@t{++} constructor, the @value{NGCC} compiler generates several ++instances of the function body, used in different cases. ++ ++@item ++For a C@t{++} template function, a given line in the function can ++correspond to any number of instantiations. ++ ++@item ++For an inlined function, a given source line can correspond to ++several places where that function is inlined. ++@end itemize ++ ++In all those cases, @value{GDBN} will insert a breakpoint at all ++the relevant locations. ++ ++A breakpoint with multiple locations is displayed in the breakpoint ++table using several rows---one header row, followed by one row for ++each breakpoint location. The header row has @samp{} in the ++address column. The rows for individual locations contain the actual ++addresses for locations, and show the functions to which those ++locations belong. The number column for a location is of the form ++@var{breakpoint-number}.@var{location-number}. ++ ++For example: ++ ++@smallexample ++Num Type Disp Enb Address What ++1 breakpoint keep y ++ stop only if i==1 ++ breakpoint already hit 1 time ++1.1 y 0x080486a2 in void foo() at t.cc:8 ++1.2 y 0x080486ca in void foo() at t.cc:8 ++@end smallexample ++ ++You cannot delete the individual locations from a breakpoint. However, ++each location can be individually enabled or disabled by passing ++@var{breakpoint-number}.@var{location-number} as argument to the ++@code{enable} and @code{disable} commands. It's also possible to ++@code{enable} and @code{disable} a range of @var{location-number} ++locations using a @var{breakpoint-number} and two @var{location-number}s, ++in increasing order, separated by a hyphen, like ++@kbd{@var{breakpoint-number}.@var{location-number1}-@var{location-number2}}, ++in which case @value{GDBN} acts on all the locations in the range (inclusive). ++Disabling or enabling the parent breakpoint (@pxref{Disabling}) affects ++all of the locations that belong to that breakpoint. ++ ++@cindex pending breakpoints ++It's quite common to have a breakpoint inside a shared library. ++Shared libraries can be loaded and unloaded explicitly, ++and possibly repeatedly, as the program is executed. To support ++this use case, @value{GDBN} updates breakpoint locations whenever ++any shared library is loaded or unloaded. Typically, you would ++set a breakpoint in a shared library at the beginning of your ++debugging session, when the library is not loaded, and when the ++symbols from the library are not available. When you try to set ++breakpoint, @value{GDBN} will ask you if you want to set ++a so called @dfn{pending breakpoint}---breakpoint whose address ++is not yet resolved. ++ ++After the program is run, whenever a new shared library is loaded, ++@value{GDBN} reevaluates all the breakpoints. When a newly loaded ++shared library contains the symbol or line referred to by some ++pending breakpoint, that breakpoint is resolved and becomes an ++ordinary breakpoint. When a library is unloaded, all breakpoints ++that refer to its symbols or source lines become pending again. ++ ++This logic works for breakpoints with multiple locations, too. For ++example, if you have a breakpoint in a C@t{++} template function, and ++a newly loaded shared library has an instantiation of that template, ++a new location is added to the list of locations for the breakpoint. ++ ++Except for having unresolved address, pending breakpoints do not ++differ from regular breakpoints. You can set conditions or commands, ++enable and disable them and perform other breakpoint operations. ++ ++@value{GDBN} provides some additional commands for controlling what ++happens when the @samp{break} command cannot resolve breakpoint ++address specification to an address: ++ ++@kindex set breakpoint pending ++@kindex show breakpoint pending ++@table @code ++@item set breakpoint pending auto ++This is the default behavior. When @value{GDBN} cannot find the breakpoint ++location, it queries you whether a pending breakpoint should be created. ++ ++@item set breakpoint pending on ++This indicates that an unrecognized breakpoint location should automatically ++result in a pending breakpoint being created. ++ ++@item set breakpoint pending off ++This indicates that pending breakpoints are not to be created. Any ++unrecognized breakpoint location results in an error. This setting does ++not affect any pending breakpoints previously created. ++ ++@item show breakpoint pending ++Show the current behavior setting for creating pending breakpoints. ++@end table ++ ++The settings above only affect the @code{break} command and its ++variants. Once breakpoint is set, it will be automatically updated ++as shared libraries are loaded and unloaded. ++ ++@cindex automatic hardware breakpoints ++For some targets, @value{GDBN} can automatically decide if hardware or ++software breakpoints should be used, depending on whether the ++breakpoint address is read-only or read-write. This applies to ++breakpoints set with the @code{break} command as well as to internal ++breakpoints set by commands like @code{next} and @code{finish}. For ++breakpoints set with @code{hbreak}, @value{GDBN} will always use hardware ++breakpoints. ++ ++You can control this automatic behaviour with the following commands: ++ ++@kindex set breakpoint auto-hw ++@kindex show breakpoint auto-hw ++@table @code ++@item set breakpoint auto-hw on ++This is the default behavior. When @value{GDBN} sets a breakpoint, it ++will try to use the target memory map to decide if software or hardware ++breakpoint must be used. ++ ++@item set breakpoint auto-hw off ++This indicates @value{GDBN} should not automatically select breakpoint ++type. If the target provides a memory map, @value{GDBN} will warn when ++trying to set software breakpoint at a read-only address. ++@end table ++ ++@value{GDBN} normally implements breakpoints by replacing the program code ++at the breakpoint address with a special instruction, which, when ++executed, given control to the debugger. By default, the program ++code is so modified only when the program is resumed. As soon as ++the program stops, @value{GDBN} restores the original instructions. This ++behaviour guards against leaving breakpoints inserted in the ++target should gdb abrubptly disconnect. However, with slow remote ++targets, inserting and removing breakpoint can reduce the performance. ++This behavior can be controlled with the following commands:: ++ ++@kindex set breakpoint always-inserted ++@kindex show breakpoint always-inserted ++@table @code ++@item set breakpoint always-inserted off ++All breakpoints, including newly added by the user, are inserted in ++the target only when the target is resumed. All breakpoints are ++removed from the target when it stops. This is the default mode. ++ ++@item set breakpoint always-inserted on ++Causes all breakpoints to be inserted in the target at all times. If ++the user adds a new breakpoint, or changes an existing breakpoint, the ++breakpoints in the target are updated immediately. A breakpoint is ++removed from the target only when breakpoint itself is deleted. ++@end table ++ ++@value{GDBN} handles conditional breakpoints by evaluating these conditions ++when a breakpoint breaks. If the condition is true, then the process being ++debugged stops, otherwise the process is resumed. ++ ++If the target supports evaluating conditions on its end, @value{GDBN} may ++download the breakpoint, together with its conditions, to it. ++ ++This feature can be controlled via the following commands: ++ ++@kindex set breakpoint condition-evaluation ++@kindex show breakpoint condition-evaluation ++@table @code ++@item set breakpoint condition-evaluation host ++This option commands @value{GDBN} to evaluate the breakpoint ++conditions on the host's side. Unconditional breakpoints are sent to ++the target which in turn receives the triggers and reports them back to GDB ++for condition evaluation. This is the standard evaluation mode. ++ ++@item set breakpoint condition-evaluation target ++This option commands @value{GDBN} to download breakpoint conditions ++to the target at the moment of their insertion. The target ++is responsible for evaluating the conditional expression and reporting ++breakpoint stop events back to @value{GDBN} whenever the condition ++is true. Due to limitations of target-side evaluation, some conditions ++cannot be evaluated there, e.g., conditions that depend on local data ++that is only known to the host. Examples include ++conditional expressions involving convenience variables, complex types ++that cannot be handled by the agent expression parser and expressions ++that are too long to be sent over to the target, specially when the ++target is a remote system. In these cases, the conditions will be ++evaluated by @value{GDBN}. ++ ++@item set breakpoint condition-evaluation auto ++This is the default mode. If the target supports evaluating breakpoint ++conditions on its end, @value{GDBN} will download breakpoint conditions to ++the target (limitations mentioned previously apply). If the target does ++not support breakpoint condition evaluation, then @value{GDBN} will fallback ++to evaluating all these conditions on the host's side. ++@end table ++ ++ ++@cindex negative breakpoint numbers ++@cindex internal @value{GDBN} breakpoints ++@value{GDBN} itself sometimes sets breakpoints in your program for ++special purposes, such as proper handling of @code{longjmp} (in C ++programs). These internal breakpoints are assigned negative numbers, ++starting with @code{-1}; @samp{info breakpoints} does not display them. ++You can see these breakpoints with the @value{GDBN} maintenance command ++@samp{maint info breakpoints} (@pxref{maint info breakpoints}). ++ ++ ++@node Set Watchpoints ++@subsection Setting Watchpoints ++ ++@cindex setting watchpoints ++You can use a watchpoint to stop execution whenever the value of an ++expression changes, without having to predict a particular place where ++this may happen. (This is sometimes called a @dfn{data breakpoint}.) ++The expression may be as simple as the value of a single variable, or ++as complex as many variables combined by operators. Examples include: ++ ++@itemize @bullet ++@item ++A reference to the value of a single variable. ++ ++@item ++An address cast to an appropriate data type. For example, ++@samp{*(int *)0x12345678} will watch a 4-byte region at the specified ++address (assuming an @code{int} occupies 4 bytes). ++ ++@item ++An arbitrarily complex expression, such as @samp{a*b + c/d}. The ++expression can use any operators valid in the program's native ++language (@pxref{Languages}). ++@end itemize ++ ++You can set a watchpoint on an expression even if the expression can ++not be evaluated yet. For instance, you can set a watchpoint on ++@samp{*global_ptr} before @samp{global_ptr} is initialized. ++@value{GDBN} will stop when your program sets @samp{global_ptr} and ++the expression produces a valid value. If the expression becomes ++valid in some other way than changing a variable (e.g.@: if the memory ++pointed to by @samp{*global_ptr} becomes readable as the result of a ++@code{malloc} call), @value{GDBN} may not stop until the next time ++the expression changes. ++ ++@cindex software watchpoints ++@cindex hardware watchpoints ++Depending on your system, watchpoints may be implemented in software or ++hardware. @value{GDBN} does software watchpointing by single-stepping your ++program and testing the variable's value each time, which is hundreds of ++times slower than normal execution. (But this may still be worth it, to ++catch errors where you have no clue what part of your program is the ++culprit.) ++ ++On some systems, such as most PowerPC or x86-based targets, ++@value{GDBN} includes support for hardware watchpoints, which do not ++slow down the running of your program. ++ ++@table @code ++@kindex watch ++@item watch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{thread-id}@r{]} @r{[}mask @var{maskvalue}@r{]} ++Set a watchpoint for an expression. @value{GDBN} will break when the ++expression @var{expr} is written into by the program and its value ++changes. The simplest (and the most popular) use of this command is ++to watch the value of a single variable: ++ ++@smallexample ++(@value{GDBP}) watch foo ++@end smallexample ++ ++If the command includes a @code{@r{[}thread @var{thread-id}@r{]}} ++argument, @value{GDBN} breaks only when the thread identified by ++@var{thread-id} changes the value of @var{expr}. If any other threads ++change the value of @var{expr}, @value{GDBN} will not break. Note ++that watchpoints restricted to a single thread in this way only work ++with Hardware Watchpoints. ++ ++Ordinarily a watchpoint respects the scope of variables in @var{expr} ++(see below). The @code{-location} argument tells @value{GDBN} to ++instead watch the memory referred to by @var{expr}. In this case, ++@value{GDBN} will evaluate @var{expr}, take the address of the result, ++and watch the memory at that address. The type of the result is used ++to determine the size of the watched memory. If the expression's ++result does not have an address, then @value{GDBN} will print an ++error. ++ ++The @code{@r{[}mask @var{maskvalue}@r{]}} argument allows creation ++of masked watchpoints, if the current architecture supports this ++feature (e.g., PowerPC Embedded architecture, see @ref{PowerPC ++Embedded}.) A @dfn{masked watchpoint} specifies a mask in addition ++to an address to watch. The mask specifies that some bits of an address ++(the bits which are reset in the mask) should be ignored when matching ++the address accessed by the inferior against the watchpoint address. ++Thus, a masked watchpoint watches many addresses simultaneously---those ++addresses whose unmasked bits are identical to the unmasked bits in the ++watchpoint address. The @code{mask} argument implies @code{-location}. ++Examples: ++ ++@smallexample ++(@value{GDBP}) watch foo mask 0xffff00ff ++(@value{GDBP}) watch *0xdeadbeef mask 0xffffff00 ++@end smallexample ++ ++@kindex rwatch ++@item rwatch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{thread-id}@r{]} @r{[}mask @var{maskvalue}@r{]} ++Set a watchpoint that will break when the value of @var{expr} is read ++by the program. ++ ++@kindex awatch ++@item awatch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{thread-id}@r{]} @r{[}mask @var{maskvalue}@r{]} ++Set a watchpoint that will break when @var{expr} is either read from ++or written into by the program. ++ ++@kindex info watchpoints @r{[}@var{list}@dots{}@r{]} ++@item info watchpoints @r{[}@var{list}@dots{}@r{]} ++This command prints a list of watchpoints, using the same format as ++@code{info break} (@pxref{Set Breaks}). ++@end table ++ ++If you watch for a change in a numerically entered address you need to ++dereference it, as the address itself is just a constant number which will ++never change. @value{GDBN} refuses to create a watchpoint that watches ++a never-changing value: ++ ++@smallexample ++(@value{GDBP}) watch 0x600850 ++Cannot watch constant value 0x600850. ++(@value{GDBP}) watch *(int *) 0x600850 ++Watchpoint 1: *(int *) 6293584 ++@end smallexample ++ ++@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware ++watchpoints execute very quickly, and the debugger reports a change in ++value at the exact instruction where the change occurs. If @value{GDBN} ++cannot set a hardware watchpoint, it sets a software watchpoint, which ++executes more slowly and reports the change in value at the next ++@emph{statement}, not the instruction, after the change occurs. ++ ++@cindex use only software watchpoints ++You can force @value{GDBN} to use only software watchpoints with the ++@kbd{set can-use-hw-watchpoints 0} command. With this variable set to ++zero, @value{GDBN} will never try to use hardware watchpoints, even if ++the underlying system supports them. (Note that hardware-assisted ++watchpoints that were set @emph{before} setting ++@code{can-use-hw-watchpoints} to zero will still use the hardware ++mechanism of watching expression values.) ++ ++@table @code ++@item set can-use-hw-watchpoints ++@kindex set can-use-hw-watchpoints ++Set whether or not to use hardware watchpoints. ++ ++@item show can-use-hw-watchpoints ++@kindex show can-use-hw-watchpoints ++Show the current mode of using hardware watchpoints. ++@end table ++ ++For remote targets, you can restrict the number of hardware ++watchpoints @value{GDBN} will use, see @ref{set remote ++hardware-breakpoint-limit}. ++ ++When you issue the @code{watch} command, @value{GDBN} reports ++ ++@smallexample ++Hardware watchpoint @var{num}: @var{expr} ++@end smallexample ++ ++@noindent ++if it was able to set a hardware watchpoint. ++ ++Currently, the @code{awatch} and @code{rwatch} commands can only set ++hardware watchpoints, because accesses to data that don't change the ++value of the watched expression cannot be detected without examining ++every instruction as it is being executed, and @value{GDBN} does not do ++that currently. If @value{GDBN} finds that it is unable to set a ++hardware breakpoint with the @code{awatch} or @code{rwatch} command, it ++will print a message like this: ++ ++@smallexample ++Expression cannot be implemented with read/access watchpoint. ++@end smallexample ++ ++Sometimes, @value{GDBN} cannot set a hardware watchpoint because the ++data type of the watched expression is wider than what a hardware ++watchpoint on the target machine can handle. For example, some systems ++can only watch regions that are up to 4 bytes wide; on such systems you ++cannot set hardware watchpoints for an expression that yields a ++double-precision floating-point number (which is typically 8 bytes ++wide). As a work-around, it might be possible to break the large region ++into a series of smaller ones and watch them with separate watchpoints. ++ ++If you set too many hardware watchpoints, @value{GDBN} might be unable ++to insert all of them when you resume the execution of your program. ++Since the precise number of active watchpoints is unknown until such ++time as the program is about to be resumed, @value{GDBN} might not be ++able to warn you about this when you set the watchpoints, and the ++warning will be printed only when the program is resumed: ++ ++@smallexample ++Hardware watchpoint @var{num}: Could not insert watchpoint ++@end smallexample ++ ++@noindent ++If this happens, delete or disable some of the watchpoints. ++ ++Watching complex expressions that reference many variables can also ++exhaust the resources available for hardware-assisted watchpoints. ++That's because @value{GDBN} needs to watch every variable in the ++expression with separately allocated resources. ++ ++If you call a function interactively using @code{print} or @code{call}, ++any watchpoints you have set will be inactive until @value{GDBN} reaches another ++kind of breakpoint or the call completes. ++ ++@value{GDBN} automatically deletes watchpoints that watch local ++(automatic) variables, or expressions that involve such variables, when ++they go out of scope, that is, when the execution leaves the block in ++which these variables were defined. In particular, when the program ++being debugged terminates, @emph{all} local variables go out of scope, ++and so only watchpoints that watch global variables remain set. If you ++rerun the program, you will need to set all such watchpoints again. One ++way of doing that would be to set a code breakpoint at the entry to the ++@code{main} function and when it breaks, set all the watchpoints. ++ ++@cindex watchpoints and threads ++@cindex threads and watchpoints ++In multi-threaded programs, watchpoints will detect changes to the ++watched expression from every thread. ++ ++@quotation ++@emph{Warning:} In multi-threaded programs, software watchpoints ++have only limited usefulness. If @value{GDBN} creates a software ++watchpoint, it can only watch the value of an expression @emph{in a ++single thread}. If you are confident that the expression can only ++change due to the current thread's activity (and if you are also ++confident that no other thread can become current), then you can use ++software watchpoints as usual. However, @value{GDBN} may not notice ++when a non-current thread's activity changes the expression. (Hardware ++watchpoints, in contrast, watch an expression in all threads.) ++@end quotation ++ ++@xref{set remote hardware-watchpoint-limit}. ++ ++@node Set Catchpoints ++@subsection Setting Catchpoints ++@cindex catchpoints, setting ++@cindex exception handlers ++@cindex event handling ++ ++You can use @dfn{catchpoints} to cause the debugger to stop for certain ++kinds of program events, such as C@t{++} exceptions or the loading of a ++shared library. Use the @code{catch} command to set a catchpoint. ++ ++@table @code ++@kindex catch ++@item catch @var{event} ++Stop when @var{event} occurs. The @var{event} can be any of the following: ++ ++@table @code ++@item throw @r{[}@var{regexp}@r{]} ++@itemx rethrow @r{[}@var{regexp}@r{]} ++@itemx catch @r{[}@var{regexp}@r{]} ++@kindex catch throw ++@kindex catch rethrow ++@kindex catch catch ++@cindex stop on C@t{++} exceptions ++The throwing, re-throwing, or catching of a C@t{++} exception. ++ ++If @var{regexp} is given, then only exceptions whose type matches the ++regular expression will be caught. ++ ++@vindex $_exception@r{, convenience variable} ++The convenience variable @code{$_exception} is available at an ++exception-related catchpoint, on some systems. This holds the ++exception being thrown. ++ ++There are currently some limitations to C@t{++} exception handling in ++@value{GDBN}: ++ ++@itemize @bullet ++@item ++The support for these commands is system-dependent. Currently, only ++systems using the @samp{gnu-v3} C@t{++} ABI (@pxref{ABI}) are ++supported. ++ ++@item ++The regular expression feature and the @code{$_exception} convenience ++variable rely on the presence of some SDT probes in @code{libstdc++}. ++If these probes are not present, then these features cannot be used. ++These probes were first available in the GCC 4.8 release, but whether ++or not they are available in your GCC also depends on how it was ++built. ++ ++@item ++The @code{$_exception} convenience variable is only valid at the ++instruction at which an exception-related catchpoint is set. ++ ++@item ++When an exception-related catchpoint is hit, @value{GDBN} stops at a ++location in the system library which implements runtime exception ++support for C@t{++}, usually @code{libstdc++}. You can use @code{up} ++(@pxref{Selection}) to get to your code. ++ ++@item ++If you call a function interactively, @value{GDBN} normally returns ++control to you when the function has finished executing. If the call ++raises an exception, however, the call may bypass the mechanism that ++returns control to you and cause your program either to abort or to ++simply continue running until it hits a breakpoint, catches a signal ++that @value{GDBN} is listening for, or exits. This is the case even if ++you set a catchpoint for the exception; catchpoints on exceptions are ++disabled within interactive calls. @xref{Calling}, for information on ++controlling this with @code{set unwind-on-terminating-exception}. ++ ++@item ++You cannot raise an exception interactively. ++ ++@item ++You cannot install an exception handler interactively. ++@end itemize ++ ++@item exception @r{[}@var{name}@r{]} ++@kindex catch exception ++@cindex Ada exception catching ++@cindex catch Ada exceptions ++An Ada exception being raised. If an exception name is specified ++at the end of the command (eg @code{catch exception Program_Error}), ++the debugger will stop only when this specific exception is raised. ++Otherwise, the debugger stops execution when any Ada exception is raised. ++ ++When inserting an exception catchpoint on a user-defined exception whose ++name is identical to one of the exceptions defined by the language, the ++fully qualified name must be used as the exception name. Otherwise, ++@value{GDBN} will assume that it should stop on the pre-defined exception ++rather than the user-defined one. For instance, assuming an exception ++called @code{Constraint_Error} is defined in package @code{Pck}, then ++the command to use to catch such exceptions is @kbd{catch exception ++Pck.Constraint_Error}. ++ ++@vindex $_ada_exception@r{, convenience variable} ++The convenience variable @code{$_ada_exception} holds the address of ++the exception being thrown. This can be useful when setting a ++condition for such a catchpoint. ++ ++@item exception unhandled ++@kindex catch exception unhandled ++An exception that was raised but is not handled by the program. The ++convenience variable @code{$_ada_exception} is set as for @code{catch ++exception}. ++ ++@item handlers @r{[}@var{name}@r{]} ++@kindex catch handlers ++@cindex Ada exception handlers catching ++@cindex catch Ada exceptions when handled ++An Ada exception being handled. If an exception name is ++specified at the end of the command ++ (eg @kbd{catch handlers Program_Error}), the debugger will stop ++only when this specific exception is handled. ++Otherwise, the debugger stops execution when any Ada exception is handled. ++ ++When inserting a handlers catchpoint on a user-defined ++exception whose name is identical to one of the exceptions ++defined by the language, the fully qualified name must be used ++as the exception name. Otherwise, @value{GDBN} will assume that it ++should stop on the pre-defined exception rather than the ++user-defined one. For instance, assuming an exception called ++ @code{Constraint_Error} is defined in package @code{Pck}, then the ++command to use to catch such exceptions handling is ++@kbd{catch handlers Pck.Constraint_Error}. ++ ++The convenience variable @code{$_ada_exception} is set as for ++@code{catch exception}. ++ ++@item assert ++@kindex catch assert ++A failed Ada assertion. Note that the convenience variable ++@code{$_ada_exception} is @emph{not} set by this catchpoint. ++ ++@item exec ++@kindex catch exec ++@cindex break on fork/exec ++A call to @code{exec}. ++ ++@anchor{catch syscall} ++@item syscall ++@itemx syscall @r{[}@var{name} @r{|} @var{number} @r{|} @r{group:}@var{groupname} @r{|} @r{g:}@var{groupname}@r{]} @dots{} ++@kindex catch syscall ++@cindex break on a system call. ++A call to or return from a system call, a.k.a.@: @dfn{syscall}. A ++syscall is a mechanism for application programs to request a service ++from the operating system (OS) or one of the OS system services. ++@value{GDBN} can catch some or all of the syscalls issued by the ++debuggee, and show the related information for each syscall. If no ++argument is specified, calls to and returns from all system calls ++will be caught. ++ ++@var{name} can be any system call name that is valid for the ++underlying OS. Just what syscalls are valid depends on the OS. On ++GNU and Unix systems, you can find the full list of valid syscall ++names on @file{/usr/include/asm/unistd.h}. ++ ++@c For MS-Windows, the syscall names and the corresponding numbers ++@c can be found, e.g., on this URL: ++@c http://www.metasploit.com/users/opcode/syscalls.html ++@c but we don't support Windows syscalls yet. ++ ++Normally, @value{GDBN} knows in advance which syscalls are valid for ++each OS, so you can use the @value{GDBN} command-line completion ++facilities (@pxref{Completion,, command completion}) to list the ++available choices. ++ ++You may also specify the system call numerically. A syscall's ++number is the value passed to the OS's syscall dispatcher to ++identify the requested service. When you specify the syscall by its ++name, @value{GDBN} uses its database of syscalls to convert the name ++into the corresponding numeric code, but using the number directly ++may be useful if @value{GDBN}'s database does not have the complete ++list of syscalls on your system (e.g., because @value{GDBN} lags ++behind the OS upgrades). ++ ++You may specify a group of related syscalls to be caught at once using ++the @code{group:} syntax (@code{g:} is a shorter equivalent). For ++instance, on some platforms @value{GDBN} allows you to catch all ++network related syscalls, by passing the argument @code{group:network} ++to @code{catch syscall}. Note that not all syscall groups are ++available in every system. You can use the command completion ++facilities (@pxref{Completion,, command completion}) to list the ++syscall groups available on your environment. ++ ++The example below illustrates how this command works if you don't provide ++arguments to it: ++ ++@smallexample ++(@value{GDBP}) catch syscall ++Catchpoint 1 (syscall) ++(@value{GDBP}) r ++Starting program: /tmp/catch-syscall ++ ++Catchpoint 1 (call to syscall 'close'), \ ++ 0xffffe424 in __kernel_vsyscall () ++(@value{GDBP}) c ++Continuing. ++ ++Catchpoint 1 (returned from syscall 'close'), \ ++ 0xffffe424 in __kernel_vsyscall () ++(@value{GDBP}) ++@end smallexample ++ ++Here is an example of catching a system call by name: ++ ++@smallexample ++(@value{GDBP}) catch syscall chroot ++Catchpoint 1 (syscall 'chroot' [61]) ++(@value{GDBP}) r ++Starting program: /tmp/catch-syscall ++ ++Catchpoint 1 (call to syscall 'chroot'), \ ++ 0xffffe424 in __kernel_vsyscall () ++(@value{GDBP}) c ++Continuing. ++ ++Catchpoint 1 (returned from syscall 'chroot'), \ ++ 0xffffe424 in __kernel_vsyscall () ++(@value{GDBP}) ++@end smallexample ++ ++An example of specifying a system call numerically. In the case ++below, the syscall number has a corresponding entry in the XML ++file, so @value{GDBN} finds its name and prints it: ++ ++@smallexample ++(@value{GDBP}) catch syscall 252 ++Catchpoint 1 (syscall(s) 'exit_group') ++(@value{GDBP}) r ++Starting program: /tmp/catch-syscall ++ ++Catchpoint 1 (call to syscall 'exit_group'), \ ++ 0xffffe424 in __kernel_vsyscall () ++(@value{GDBP}) c ++Continuing. ++ ++Program exited normally. ++(@value{GDBP}) ++@end smallexample ++ ++Here is an example of catching a syscall group: ++ ++@smallexample ++(@value{GDBP}) catch syscall group:process ++Catchpoint 1 (syscalls 'exit' [1] 'fork' [2] 'waitpid' [7] ++'execve' [11] 'wait4' [114] 'clone' [120] 'vfork' [190] ++'exit_group' [252] 'waitid' [284] 'unshare' [310]) ++(@value{GDBP}) r ++Starting program: /tmp/catch-syscall ++ ++Catchpoint 1 (call to syscall fork), 0x00007ffff7df4e27 in open64 () ++ from /lib64/ld-linux-x86-64.so.2 ++ ++(@value{GDBP}) c ++Continuing. ++@end smallexample ++ ++However, there can be situations when there is no corresponding name ++in XML file for that syscall number. In this case, @value{GDBN} prints ++a warning message saying that it was not able to find the syscall name, ++but the catchpoint will be set anyway. See the example below: ++ ++@smallexample ++(@value{GDBP}) catch syscall 764 ++warning: The number '764' does not represent a known syscall. ++Catchpoint 2 (syscall 764) ++(@value{GDBP}) ++@end smallexample ++ ++If you configure @value{GDBN} using the @samp{--without-expat} option, ++it will not be able to display syscall names. Also, if your ++architecture does not have an XML file describing its system calls, ++you will not be able to see the syscall names. It is important to ++notice that these two features are used for accessing the syscall ++name database. In either case, you will see a warning like this: ++ ++@smallexample ++(@value{GDBP}) catch syscall ++warning: Could not open "syscalls/i386-linux.xml" ++warning: Could not load the syscall XML file 'syscalls/i386-linux.xml'. ++GDB will not be able to display syscall names. ++Catchpoint 1 (syscall) ++(@value{GDBP}) ++@end smallexample ++ ++Of course, the file name will change depending on your architecture and system. ++ ++Still using the example above, you can also try to catch a syscall by its ++number. In this case, you would see something like: ++ ++@smallexample ++(@value{GDBP}) catch syscall 252 ++Catchpoint 1 (syscall(s) 252) ++@end smallexample ++ ++Again, in this case @value{GDBN} would not be able to display syscall's names. ++ ++@item fork ++@kindex catch fork ++A call to @code{fork}. ++ ++@item vfork ++@kindex catch vfork ++A call to @code{vfork}. ++ ++@item load @r{[}@var{regexp}@r{]} ++@itemx unload @r{[}@var{regexp}@r{]} ++@kindex catch load ++@kindex catch unload ++The loading or unloading of a shared library. If @var{regexp} is ++given, then the catchpoint will stop only if the regular expression ++matches one of the affected libraries. ++ ++@item signal @r{[}@var{signal}@dots{} @r{|} @samp{all}@r{]} ++@kindex catch signal ++The delivery of a signal. ++ ++With no arguments, this catchpoint will catch any signal that is not ++used internally by @value{GDBN}, specifically, all signals except ++@samp{SIGTRAP} and @samp{SIGINT}. ++ ++With the argument @samp{all}, all signals, including those used by ++@value{GDBN}, will be caught. This argument cannot be used with other ++signal names. ++ ++Otherwise, the arguments are a list of signal names as given to ++@code{handle} (@pxref{Signals}). Only signals specified in this list ++will be caught. ++ ++One reason that @code{catch signal} can be more useful than ++@code{handle} is that you can attach commands and conditions to the ++catchpoint. ++ ++When a signal is caught by a catchpoint, the signal's @code{stop} and ++@code{print} settings, as specified by @code{handle}, are ignored. ++However, whether the signal is still delivered to the inferior depends ++on the @code{pass} setting; this can be changed in the catchpoint's ++commands. ++ ++@end table ++ ++@item tcatch @var{event} ++@kindex tcatch ++Set a catchpoint that is enabled only for one stop. The catchpoint is ++automatically deleted after the first time the event is caught. ++ ++@end table ++ ++Use the @code{info break} command to list the current catchpoints. ++ ++ ++@node Delete Breaks ++@subsection Deleting Breakpoints ++ ++@cindex clearing breakpoints, watchpoints, catchpoints ++@cindex deleting breakpoints, watchpoints, catchpoints ++It is often necessary to eliminate a breakpoint, watchpoint, or ++catchpoint once it has done its job and you no longer want your program ++to stop there. This is called @dfn{deleting} the breakpoint. A ++breakpoint that has been deleted no longer exists; it is forgotten. ++ ++With the @code{clear} command you can delete breakpoints according to ++where they are in your program. With the @code{delete} command you can ++delete individual breakpoints, watchpoints, or catchpoints by specifying ++their breakpoint numbers. ++ ++It is not necessary to delete a breakpoint to proceed past it. @value{GDBN} ++automatically ignores breakpoints on the first instruction to be executed ++when you continue execution without changing the execution address. ++ ++@table @code ++@kindex clear ++@item clear ++Delete any breakpoints at the next instruction to be executed in the ++selected stack frame (@pxref{Selection, ,Selecting a Frame}). When ++the innermost frame is selected, this is a good way to delete a ++breakpoint where your program just stopped. ++ ++@item clear @var{location} ++Delete any breakpoints set at the specified @var{location}. ++@xref{Specify Location}, for the various forms of @var{location}; the ++most useful ones are listed below: ++ ++@table @code ++@item clear @var{function} ++@itemx clear @var{filename}:@var{function} ++Delete any breakpoints set at entry to the named @var{function}. ++ ++@item clear @var{linenum} ++@itemx clear @var{filename}:@var{linenum} ++Delete any breakpoints set at or within the code of the specified ++@var{linenum} of the specified @var{filename}. ++@end table ++ ++@cindex delete breakpoints ++@kindex delete ++@kindex d @r{(@code{delete})} ++@item delete @r{[}breakpoints@r{]} @r{[}@var{list}@dots{}@r{]} ++Delete the breakpoints, watchpoints, or catchpoints of the breakpoint ++list specified as argument. If no argument is specified, delete all ++breakpoints (@value{GDBN} asks confirmation, unless you have @code{set ++confirm off}). You can abbreviate this command as @code{d}. ++@end table ++ ++@node Disabling ++@subsection Disabling Breakpoints ++ ++@cindex enable/disable a breakpoint ++Rather than deleting a breakpoint, watchpoint, or catchpoint, you might ++prefer to @dfn{disable} it. This makes the breakpoint inoperative as if ++it had been deleted, but remembers the information on the breakpoint so ++that you can @dfn{enable} it again later. ++ ++You disable and enable breakpoints, watchpoints, and catchpoints with ++the @code{enable} and @code{disable} commands, optionally specifying ++one or more breakpoint numbers as arguments. Use @code{info break} to ++print a list of all breakpoints, watchpoints, and catchpoints if you ++do not know which numbers to use. ++ ++Disabling and enabling a breakpoint that has multiple locations ++affects all of its locations. ++ ++A breakpoint, watchpoint, or catchpoint can have any of several ++different states of enablement: ++ ++@itemize @bullet ++@item ++Enabled. The breakpoint stops your program. A breakpoint set ++with the @code{break} command starts out in this state. ++@item ++Disabled. The breakpoint has no effect on your program. ++@item ++Enabled once. The breakpoint stops your program, but then becomes ++disabled. ++@item ++Enabled for a count. The breakpoint stops your program for the next ++N times, then becomes disabled. ++@item ++Enabled for deletion. The breakpoint stops your program, but ++immediately after it does so it is deleted permanently. A breakpoint ++set with the @code{tbreak} command starts out in this state. ++@end itemize ++ ++You can use the following commands to enable or disable breakpoints, ++watchpoints, and catchpoints: ++ ++@table @code ++@kindex disable ++@kindex dis @r{(@code{disable})} ++@item disable @r{[}breakpoints@r{]} @r{[}@var{list}@dots{}@r{]} ++Disable the specified breakpoints---or all breakpoints, if none are ++listed. A disabled breakpoint has no effect but is not forgotten. All ++options such as ignore-counts, conditions and commands are remembered in ++case the breakpoint is enabled again later. You may abbreviate ++@code{disable} as @code{dis}. ++ ++@kindex enable ++@item enable @r{[}breakpoints@r{]} @r{[}@var{list}@dots{}@r{]} ++Enable the specified breakpoints (or all defined breakpoints). They ++become effective once again in stopping your program. ++ ++@item enable @r{[}breakpoints@r{]} once @var{list}@dots{} ++Enable the specified breakpoints temporarily. @value{GDBN} disables any ++of these breakpoints immediately after stopping your program. ++ ++@item enable @r{[}breakpoints@r{]} count @var{count} @var{list}@dots{} ++Enable the specified breakpoints temporarily. @value{GDBN} records ++@var{count} with each of the specified breakpoints, and decrements a ++breakpoint's count when it is hit. When any count reaches 0, ++@value{GDBN} disables that breakpoint. If a breakpoint has an ignore ++count (@pxref{Conditions, ,Break Conditions}), that will be ++decremented to 0 before @var{count} is affected. ++ ++@item enable @r{[}breakpoints@r{]} delete @var{list}@dots{} ++Enable the specified breakpoints to work once, then die. @value{GDBN} ++deletes any of these breakpoints as soon as your program stops there. ++Breakpoints set by the @code{tbreak} command start out in this state. ++@end table ++ ++@c FIXME: I think the following ``Except for [...] @code{tbreak}'' is ++@c confusing: tbreak is also initially enabled. ++Except for a breakpoint set with @code{tbreak} (@pxref{Set Breaks, ++,Setting Breakpoints}), breakpoints that you set are initially enabled; ++subsequently, they become disabled or enabled only when you use one of ++the commands above. (The command @code{until} can set and delete a ++breakpoint of its own, but it does not change the state of your other ++breakpoints; see @ref{Continuing and Stepping, ,Continuing and ++Stepping}.) ++ ++@node Conditions ++@subsection Break Conditions ++@cindex conditional breakpoints ++@cindex breakpoint conditions ++ ++@c FIXME what is scope of break condition expr? Context where wanted? ++@c in particular for a watchpoint? ++The simplest sort of breakpoint breaks every time your program reaches a ++specified place. You can also specify a @dfn{condition} for a ++breakpoint. A condition is just a Boolean expression in your ++programming language (@pxref{Expressions, ,Expressions}). A breakpoint with ++a condition evaluates the expression each time your program reaches it, ++and your program stops only if the condition is @emph{true}. ++ ++This is the converse of using assertions for program validation; in that ++situation, you want to stop when the assertion is violated---that is, ++when the condition is false. In C, if you want to test an assertion expressed ++by the condition @var{assert}, you should set the condition ++@samp{! @var{assert}} on the appropriate breakpoint. ++ ++Conditions are also accepted for watchpoints; you may not need them, ++since a watchpoint is inspecting the value of an expression anyhow---but ++it might be simpler, say, to just set a watchpoint on a variable name, ++and specify a condition that tests whether the new value is an interesting ++one. ++ ++Break conditions can have side effects, and may even call functions in ++your program. This can be useful, for example, to activate functions ++that log program progress, or to use your own print functions to ++format special data structures. The effects are completely predictable ++unless there is another enabled breakpoint at the same address. (In ++that case, @value{GDBN} might see the other breakpoint first and stop your ++program without checking the condition of this one.) Note that ++breakpoint commands are usually more convenient and flexible than break ++conditions for the ++purpose of performing side effects when a breakpoint is reached ++(@pxref{Break Commands, ,Breakpoint Command Lists}). ++ ++Breakpoint conditions can also be evaluated on the target's side if ++the target supports it. Instead of evaluating the conditions locally, ++@value{GDBN} encodes the expression into an agent expression ++(@pxref{Agent Expressions}) suitable for execution on the target, ++independently of @value{GDBN}. Global variables become raw memory ++locations, locals become stack accesses, and so forth. ++ ++In this case, @value{GDBN} will only be notified of a breakpoint trigger ++when its condition evaluates to true. This mechanism may provide faster ++response times depending on the performance characteristics of the target ++since it does not need to keep @value{GDBN} informed about ++every breakpoint trigger, even those with false conditions. ++ ++Break conditions can be specified when a breakpoint is set, by using ++@samp{if} in the arguments to the @code{break} command. @xref{Set ++Breaks, ,Setting Breakpoints}. They can also be changed at any time ++with the @code{condition} command. ++ ++You can also use the @code{if} keyword with the @code{watch} command. ++The @code{catch} command does not recognize the @code{if} keyword; ++@code{condition} is the only way to impose a further condition on a ++catchpoint. ++ ++@table @code ++@kindex condition ++@item condition @var{bnum} @var{expression} ++Specify @var{expression} as the break condition for breakpoint, ++watchpoint, or catchpoint number @var{bnum}. After you set a condition, ++breakpoint @var{bnum} stops your program only if the value of ++@var{expression} is true (nonzero, in C). When you use ++@code{condition}, @value{GDBN} checks @var{expression} immediately for ++syntactic correctness, and to determine whether symbols in it have ++referents in the context of your breakpoint. If @var{expression} uses ++symbols not referenced in the context of the breakpoint, @value{GDBN} ++prints an error message: ++ ++@smallexample ++No symbol "foo" in current context. ++@end smallexample ++ ++@noindent ++@value{GDBN} does ++not actually evaluate @var{expression} at the time the @code{condition} ++command (or a command that sets a breakpoint with a condition, like ++@code{break if @dots{}}) is given, however. @xref{Expressions, ,Expressions}. ++ ++@item condition @var{bnum} ++Remove the condition from breakpoint number @var{bnum}. It becomes ++an ordinary unconditional breakpoint. ++@end table ++ ++@cindex ignore count (of breakpoint) ++A special case of a breakpoint condition is to stop only when the ++breakpoint has been reached a certain number of times. This is so ++useful that there is a special way to do it, using the @dfn{ignore ++count} of the breakpoint. Every breakpoint has an ignore count, which ++is an integer. Most of the time, the ignore count is zero, and ++therefore has no effect. But if your program reaches a breakpoint whose ++ignore count is positive, then instead of stopping, it just decrements ++the ignore count by one and continues. As a result, if the ignore count ++value is @var{n}, the breakpoint does not stop the next @var{n} times ++your program reaches it. ++ ++@table @code ++@kindex ignore ++@item ignore @var{bnum} @var{count} ++Set the ignore count of breakpoint number @var{bnum} to @var{count}. ++The next @var{count} times the breakpoint is reached, your program's ++execution does not stop; other than to decrement the ignore count, @value{GDBN} ++takes no action. ++ ++To make the breakpoint stop the next time it is reached, specify ++a count of zero. ++ ++When you use @code{continue} to resume execution of your program from a ++breakpoint, you can specify an ignore count directly as an argument to ++@code{continue}, rather than using @code{ignore}. @xref{Continuing and ++Stepping,,Continuing and Stepping}. ++ ++If a breakpoint has a positive ignore count and a condition, the ++condition is not checked. Once the ignore count reaches zero, ++@value{GDBN} resumes checking the condition. ++ ++You could achieve the effect of the ignore count with a condition such ++as @w{@samp{$foo-- <= 0}} using a debugger convenience variable that ++is decremented each time. @xref{Convenience Vars, ,Convenience ++Variables}. ++@end table ++ ++Ignore counts apply to breakpoints, watchpoints, and catchpoints. ++ ++ ++@node Break Commands ++@subsection Breakpoint Command Lists ++ ++@cindex breakpoint commands ++You can give any breakpoint (or watchpoint or catchpoint) a series of ++commands to execute when your program stops due to that breakpoint. For ++example, you might want to print the values of certain expressions, or ++enable other breakpoints. ++ ++@table @code ++@kindex commands ++@kindex end@r{ (breakpoint commands)} ++@item commands @r{[}@var{list}@dots{}@r{]} ++@itemx @dots{} @var{command-list} @dots{} ++@itemx end ++Specify a list of commands for the given breakpoints. The commands ++themselves appear on the following lines. Type a line containing just ++@code{end} to terminate the commands. ++ ++To remove all commands from a breakpoint, type @code{commands} and ++follow it immediately with @code{end}; that is, give no commands. ++ ++With no argument, @code{commands} refers to the last breakpoint, ++watchpoint, or catchpoint set (not to the breakpoint most recently ++encountered). If the most recent breakpoints were set with a single ++command, then the @code{commands} will apply to all the breakpoints ++set by that command. This applies to breakpoints set by ++@code{rbreak}, and also applies when a single @code{break} command ++creates multiple breakpoints (@pxref{Ambiguous Expressions,,Ambiguous ++Expressions}). ++@end table ++ ++Pressing @key{RET} as a means of repeating the last @value{GDBN} command is ++disabled within a @var{command-list}. ++ ++You can use breakpoint commands to start your program up again. Simply ++use the @code{continue} command, or @code{step}, or any other command ++that resumes execution. ++ ++Any other commands in the command list, after a command that resumes ++execution, are ignored. This is because any time you resume execution ++(even with a simple @code{next} or @code{step}), you may encounter ++another breakpoint---which could have its own command list, leading to ++ambiguities about which list to execute. ++ ++@kindex silent ++If the first command you specify in a command list is @code{silent}, the ++usual message about stopping at a breakpoint is not printed. This may ++be desirable for breakpoints that are to print a specific message and ++then continue. If none of the remaining commands print anything, you ++see no sign that the breakpoint was reached. @code{silent} is ++meaningful only at the beginning of a breakpoint command list. ++ ++The commands @code{echo}, @code{output}, and @code{printf} allow you to ++print precisely controlled output, and are often useful in silent ++breakpoints. @xref{Output, ,Commands for Controlled Output}. ++ ++For example, here is how you could use breakpoint commands to print the ++value of @code{x} at entry to @code{foo} whenever @code{x} is positive. ++ ++@smallexample ++break foo if x>0 ++commands ++silent ++printf "x is %d\n",x ++cont ++end ++@end smallexample ++ ++One application for breakpoint commands is to compensate for one bug so ++you can test for another. Put a breakpoint just after the erroneous line ++of code, give it a condition to detect the case in which something ++erroneous has been done, and give it commands to assign correct values ++to any variables that need them. End with the @code{continue} command ++so that your program does not stop, and start with the @code{silent} ++command so that no output is produced. Here is an example: ++ ++@smallexample ++break 403 ++commands ++silent ++set x = y + 4 ++cont ++end ++@end smallexample ++ ++@node Dynamic Printf ++@subsection Dynamic Printf ++ ++@cindex dynamic printf ++@cindex dprintf ++The dynamic printf command @code{dprintf} combines a breakpoint with ++formatted printing of your program's data to give you the effect of ++inserting @code{printf} calls into your program on-the-fly, without ++having to recompile it. ++ ++In its most basic form, the output goes to the GDB console. However, ++you can set the variable @code{dprintf-style} for alternate handling. ++For instance, you can ask to format the output by calling your ++program's @code{printf} function. This has the advantage that the ++characters go to the program's output device, so they can recorded in ++redirects to files and so forth. ++ ++If you are doing remote debugging with a stub or agent, you can also ++ask to have the printf handled by the remote agent. In addition to ++ensuring that the output goes to the remote program's device along ++with any other output the program might produce, you can also ask that ++the dprintf remain active even after disconnecting from the remote ++target. Using the stub/agent is also more efficient, as it can do ++everything without needing to communicate with @value{GDBN}. ++ ++@table @code ++@kindex dprintf ++@item dprintf @var{location},@var{template},@var{expression}[,@var{expression}@dots{}] ++Whenever execution reaches @var{location}, print the values of one or ++more @var{expressions} under the control of the string @var{template}. ++To print several values, separate them with commas. ++ ++@item set dprintf-style @var{style} ++Set the dprintf output to be handled in one of several different ++styles enumerated below. A change of style affects all existing ++dynamic printfs immediately. (If you need individual control over the ++print commands, simply define normal breakpoints with ++explicitly-supplied command lists.) ++ ++@table @code ++@item gdb ++@kindex dprintf-style gdb ++Handle the output using the @value{GDBN} @code{printf} command. ++ ++@item call ++@kindex dprintf-style call ++Handle the output by calling a function in your program (normally ++@code{printf}). ++ ++@item agent ++@kindex dprintf-style agent ++Have the remote debugging agent (such as @code{gdbserver}) handle ++the output itself. This style is only available for agents that ++support running commands on the target. ++@end table ++ ++@item set dprintf-function @var{function} ++Set the function to call if the dprintf style is @code{call}. By ++default its value is @code{printf}. You may set it to any expression. ++that @value{GDBN} can evaluate to a function, as per the @code{call} ++command. ++ ++@item set dprintf-channel @var{channel} ++Set a ``channel'' for dprintf. If set to a non-empty value, ++@value{GDBN} will evaluate it as an expression and pass the result as ++a first argument to the @code{dprintf-function}, in the manner of ++@code{fprintf} and similar functions. Otherwise, the dprintf format ++string will be the first argument, in the manner of @code{printf}. ++ ++As an example, if you wanted @code{dprintf} output to go to a logfile ++that is a standard I/O stream assigned to the variable @code{mylog}, ++you could do the following: ++ ++@example ++(gdb) set dprintf-style call ++(gdb) set dprintf-function fprintf ++(gdb) set dprintf-channel mylog ++(gdb) dprintf 25,"at line 25, glob=%d\n",glob ++Dprintf 1 at 0x123456: file main.c, line 25. ++(gdb) info break ++1 dprintf keep y 0x00123456 in main at main.c:25 ++ call (void) fprintf (mylog,"at line 25, glob=%d\n",glob) ++ continue ++(gdb) ++@end example ++ ++Note that the @code{info break} displays the dynamic printf commands ++as normal breakpoint commands; you can thus easily see the effect of ++the variable settings. ++ ++@item set disconnected-dprintf on ++@itemx set disconnected-dprintf off ++@kindex set disconnected-dprintf ++Choose whether @code{dprintf} commands should continue to run if ++@value{GDBN} has disconnected from the target. This only applies ++if the @code{dprintf-style} is @code{agent}. ++ ++@item show disconnected-dprintf off ++@kindex show disconnected-dprintf ++Show the current choice for disconnected @code{dprintf}. ++ ++@end table ++ ++@value{GDBN} does not check the validity of function and channel, ++relying on you to supply values that are meaningful for the contexts ++in which they are being used. For instance, the function and channel ++may be the values of local variables, but if that is the case, then ++all enabled dynamic prints must be at locations within the scope of ++those locals. If evaluation fails, @value{GDBN} will report an error. ++ ++@node Save Breakpoints ++@subsection How to save breakpoints to a file ++ ++To save breakpoint definitions to a file use the @w{@code{save ++breakpoints}} command. ++ ++@table @code ++@kindex save breakpoints ++@cindex save breakpoints to a file for future sessions ++@item save breakpoints [@var{filename}] ++This command saves all current breakpoint definitions together with ++their commands and ignore counts, into a file @file{@var{filename}} ++suitable for use in a later debugging session. This includes all ++types of breakpoints (breakpoints, watchpoints, catchpoints, ++tracepoints). To read the saved breakpoint definitions, use the ++@code{source} command (@pxref{Command Files}). Note that watchpoints ++with expressions involving local variables may fail to be recreated ++because it may not be possible to access the context where the ++watchpoint is valid anymore. Because the saved breakpoint definitions ++are simply a sequence of @value{GDBN} commands that recreate the ++breakpoints, you can edit the file in your favorite editing program, ++and remove the breakpoint definitions you're not interested in, or ++that can no longer be recreated. ++@end table ++ ++@node Static Probe Points ++@subsection Static Probe Points ++ ++@cindex static probe point, SystemTap ++@cindex static probe point, DTrace ++@value{GDBN} supports @dfn{SDT} probes in the code. @acronym{SDT} stands ++for Statically Defined Tracing, and the probes are designed to have a tiny ++runtime code and data footprint, and no dynamic relocations. ++ ++Currently, the following types of probes are supported on ++ELF-compatible systems: ++ ++@itemize @bullet ++ ++@item @code{SystemTap} (@uref{http://sourceware.org/systemtap/}) ++@acronym{SDT} probes@footnote{See ++@uref{http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps} ++for more information on how to add @code{SystemTap} @acronym{SDT} ++probes in your applications.}. @code{SystemTap} probes are usable ++from assembly, C and C@t{++} languages@footnote{See ++@uref{http://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation} ++for a good reference on how the @acronym{SDT} probes are implemented.}. ++ ++@item @code{DTrace} (@uref{http://oss.oracle.com/projects/DTrace}) ++@acronym{USDT} probes. @code{DTrace} probes are usable from C and ++C@t{++} languages. ++@end itemize ++ ++@cindex semaphores on static probe points ++Some @code{SystemTap} probes have an associated semaphore variable; ++for instance, this happens automatically if you defined your probe ++using a DTrace-style @file{.d} file. If your probe has a semaphore, ++@value{GDBN} will automatically enable it when you specify a ++breakpoint using the @samp{-probe-stap} notation. But, if you put a ++breakpoint at a probe's location by some other method (e.g., ++@code{break file:line}), then @value{GDBN} will not automatically set ++the semaphore. @code{DTrace} probes do not support semaphores. ++ ++You can examine the available static static probes using @code{info ++probes}, with optional arguments: ++ ++@table @code ++@kindex info probes ++@item info probes @r{[}@var{type}@r{]} @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]} ++If given, @var{type} is either @code{stap} for listing ++@code{SystemTap} probes or @code{dtrace} for listing @code{DTrace} ++probes. If omitted all probes are listed regardless of their types. ++ ++If given, @var{provider} is a regular expression used to match against provider ++names when selecting which probes to list. If omitted, probes by all ++probes from all providers are listed. ++ ++If given, @var{name} is a regular expression to match against probe names ++when selecting which probes to list. If omitted, probe names are not ++considered when deciding whether to display them. ++ ++If given, @var{objfile} is a regular expression used to select which ++object files (executable or shared libraries) to examine. If not ++given, all object files are considered. ++ ++@item info probes all ++List the available static probes, from all types. ++@end table ++ ++@cindex enabling and disabling probes ++Some probe points can be enabled and/or disabled. The effect of ++enabling or disabling a probe depends on the type of probe being ++handled. Some @code{DTrace} probes can be enabled or ++disabled, but @code{SystemTap} probes cannot be disabled. ++ ++You can enable (or disable) one or more probes using the following ++commands, with optional arguments: ++ ++@table @code ++@kindex enable probes ++@item enable probes @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]} ++If given, @var{provider} is a regular expression used to match against ++provider names when selecting which probes to enable. If omitted, ++all probes from all providers are enabled. ++ ++If given, @var{name} is a regular expression to match against probe ++names when selecting which probes to enable. If omitted, probe names ++are not considered when deciding whether to enable them. ++ ++If given, @var{objfile} is a regular expression used to select which ++object files (executable or shared libraries) to examine. If not ++given, all object files are considered. ++ ++@kindex disable probes ++@item disable probes @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]} ++See the @code{enable probes} command above for a description of the ++optional arguments accepted by this command. ++@end table ++ ++@vindex $_probe_arg@r{, convenience variable} ++A probe may specify up to twelve arguments. These are available at the ++point at which the probe is defined---that is, when the current PC is ++at the probe's location. The arguments are available using the ++convenience variables (@pxref{Convenience Vars}) ++@code{$_probe_arg0}@dots{}@code{$_probe_arg11}. In @code{SystemTap} ++probes each probe argument is an integer of the appropriate size; ++types are not preserved. In @code{DTrace} probes types are preserved ++provided that they are recognized as such by @value{GDBN}; otherwise ++the value of the probe argument will be a long integer. The ++convenience variable @code{$_probe_argc} holds the number of arguments ++at the current probe point. ++ ++These variables are always available, but attempts to access them at ++any location other than a probe point will cause @value{GDBN} to give ++an error message. ++ ++ ++@c @ifclear BARETARGET ++@node Error in Breakpoints ++@subsection ``Cannot insert breakpoints'' ++ ++If you request too many active hardware-assisted breakpoints and ++watchpoints, you will see this error message: ++ ++@c FIXME: the precise wording of this message may change; the relevant ++@c source change is not committed yet (Sep 3, 1999). ++@smallexample ++Stopped; cannot insert breakpoints. ++You may have requested too many hardware breakpoints and watchpoints. ++@end smallexample ++ ++@noindent ++This message is printed when you attempt to resume the program, since ++only then @value{GDBN} knows exactly how many hardware breakpoints and ++watchpoints it needs to insert. ++ ++When this message is printed, you need to disable or remove some of the ++hardware-assisted breakpoints and watchpoints, and then continue. ++ ++@node Breakpoint-related Warnings ++@subsection ``Breakpoint address adjusted...'' ++@cindex breakpoint address adjusted ++ ++Some processor architectures place constraints on the addresses at ++which breakpoints may be placed. For architectures thus constrained, ++@value{GDBN} will attempt to adjust the breakpoint's address to comply ++with the constraints dictated by the architecture. ++ ++One example of such an architecture is the Fujitsu FR-V. The FR-V is ++a VLIW architecture in which a number of RISC-like instructions may be ++bundled together for parallel execution. The FR-V architecture ++constrains the location of a breakpoint instruction within such a ++bundle to the instruction with the lowest address. @value{GDBN} ++honors this constraint by adjusting a breakpoint's address to the ++first in the bundle. ++ ++It is not uncommon for optimized code to have bundles which contain ++instructions from different source statements, thus it may happen that ++a breakpoint's address will be adjusted from one source statement to ++another. Since this adjustment may significantly alter @value{GDBN}'s ++breakpoint related behavior from what the user expects, a warning is ++printed when the breakpoint is first set and also when the breakpoint ++is hit. ++ ++A warning like the one below is printed when setting a breakpoint ++that's been subject to address adjustment: ++ ++@smallexample ++warning: Breakpoint address adjusted from 0x00010414 to 0x00010410. ++@end smallexample ++ ++Such warnings are printed both for user settable and @value{GDBN}'s ++internal breakpoints. If you see one of these warnings, you should ++verify that a breakpoint set at the adjusted address will have the ++desired affect. If not, the breakpoint in question may be removed and ++other breakpoints may be set which will have the desired behavior. ++E.g., it may be sufficient to place the breakpoint at a later ++instruction. A conditional breakpoint may also be useful in some ++cases to prevent the breakpoint from triggering too often. ++ ++@value{GDBN} will also issue a warning when stopping at one of these ++adjusted breakpoints: ++ ++@smallexample ++warning: Breakpoint 1 address previously adjusted from 0x00010414 ++to 0x00010410. ++@end smallexample ++ ++When this warning is encountered, it may be too late to take remedial ++action except in cases where the breakpoint is hit earlier or more ++frequently than expected. ++ ++@node Continuing and Stepping ++@section Continuing and Stepping ++ ++@cindex stepping ++@cindex continuing ++@cindex resuming execution ++@dfn{Continuing} means resuming program execution until your program ++completes normally. In contrast, @dfn{stepping} means executing just ++one more ``step'' of your program, where ``step'' may mean either one ++line of source code, or one machine instruction (depending on what ++particular command you use). Either when continuing or when stepping, ++your program may stop even sooner, due to a breakpoint or a signal. (If ++it stops due to a signal, you may want to use @code{handle}, or use ++@samp{signal 0} to resume execution (@pxref{Signals, ,Signals}), ++or you may step into the signal's handler (@pxref{stepping and signal ++handlers}).) ++ ++@table @code ++@kindex continue ++@kindex c @r{(@code{continue})} ++@kindex fg @r{(resume foreground execution)} ++@item continue @r{[}@var{ignore-count}@r{]} ++@itemx c @r{[}@var{ignore-count}@r{]} ++@itemx fg @r{[}@var{ignore-count}@r{]} ++Resume program execution, at the address where your program last stopped; ++any breakpoints set at that address are bypassed. The optional argument ++@var{ignore-count} allows you to specify a further number of times to ++ignore a breakpoint at this location; its effect is like that of ++@code{ignore} (@pxref{Conditions, ,Break Conditions}). ++ ++The argument @var{ignore-count} is meaningful only when your program ++stopped due to a breakpoint. At other times, the argument to ++@code{continue} is ignored. ++ ++The synonyms @code{c} and @code{fg} (for @dfn{foreground}, as the ++debugged program is deemed to be the foreground program) are provided ++purely for convenience, and have exactly the same behavior as ++@code{continue}. ++@end table ++ ++To resume execution at a different place, you can use @code{return} ++(@pxref{Returning, ,Returning from a Function}) to go back to the ++calling function; or @code{jump} (@pxref{Jumping, ,Continuing at a ++Different Address}) to go to an arbitrary location in your program. ++ ++A typical technique for using stepping is to set a breakpoint ++(@pxref{Breakpoints, ,Breakpoints; Watchpoints; and Catchpoints}) at the ++beginning of the function or the section of your program where a problem ++is believed to lie, run your program until it stops at that breakpoint, ++and then step through the suspect area, examining the variables that are ++interesting, until you see the problem happen. ++ ++@table @code ++@kindex step ++@kindex s @r{(@code{step})} ++@item step ++Continue running your program until control reaches a different source ++line, then stop it and return control to @value{GDBN}. This command is ++abbreviated @code{s}. ++ ++@quotation ++@c "without debugging information" is imprecise; actually "without line ++@c numbers in the debugging information". (gcc -g1 has debugging info but ++@c not line numbers). But it seems complex to try to make that ++@c distinction here. ++@emph{Warning:} If you use the @code{step} command while control is ++within a function that was compiled without debugging information, ++execution proceeds until control reaches a function that does have ++debugging information. Likewise, it will not step into a function which ++is compiled without debugging information. To step through functions ++without debugging information, use the @code{stepi} command, described ++below. ++@end quotation ++ ++The @code{step} command only stops at the first instruction of a source ++line. This prevents the multiple stops that could otherwise occur in ++@code{switch} statements, @code{for} loops, etc. @code{step} continues ++to stop if a function that has debugging information is called within ++the line. In other words, @code{step} @emph{steps inside} any functions ++called within the line. ++ ++Also, the @code{step} command only enters a function if there is line ++number information for the function. Otherwise it acts like the ++@code{next} command. This avoids problems when using @code{cc -gl} ++on @acronym{MIPS} machines. Previously, @code{step} entered subroutines if there ++was any debugging information about the routine. ++ ++@item step @var{count} ++Continue running as in @code{step}, but do so @var{count} times. If a ++breakpoint is reached, or a signal not related to stepping occurs before ++@var{count} steps, stepping stops right away. ++ ++@kindex next ++@kindex n @r{(@code{next})} ++@item next @r{[}@var{count}@r{]} ++Continue to the next source line in the current (innermost) stack frame. ++This is similar to @code{step}, but function calls that appear within ++the line of code are executed without stopping. Execution stops when ++control reaches a different line of code at the original stack level ++that was executing when you gave the @code{next} command. This command ++is abbreviated @code{n}. ++ ++An argument @var{count} is a repeat count, as for @code{step}. ++ ++ ++@c FIX ME!! Do we delete this, or is there a way it fits in with ++@c the following paragraph? --- Vctoria ++@c ++@c @code{next} within a function that lacks debugging information acts like ++@c @code{step}, but any function calls appearing within the code of the ++@c function are executed without stopping. ++ ++The @code{next} command only stops at the first instruction of a ++source line. This prevents multiple stops that could otherwise occur in ++@code{switch} statements, @code{for} loops, etc. ++ ++@kindex set step-mode ++@item set step-mode ++@cindex functions without line info, and stepping ++@cindex stepping into functions with no line info ++@itemx set step-mode on ++The @code{set step-mode on} command causes the @code{step} command to ++stop at the first instruction of a function which contains no debug line ++information rather than stepping over it. ++ ++This is useful in cases where you may be interested in inspecting the ++machine instructions of a function which has no symbolic info and do not ++want @value{GDBN} to automatically skip over this function. ++ ++@item set step-mode off ++Causes the @code{step} command to step over any functions which contains no ++debug information. This is the default. ++ ++@item show step-mode ++Show whether @value{GDBN} will stop in or step over functions without ++source line debug information. ++ ++@kindex finish ++@kindex fin @r{(@code{finish})} ++@item finish ++Continue running until just after function in the selected stack frame ++returns. Print the returned value (if any). This command can be ++abbreviated as @code{fin}. ++ ++Contrast this with the @code{return} command (@pxref{Returning, ++,Returning from a Function}). ++ ++@kindex set print finish ++@kindex show print finish ++@item set print finish @r{[}on|off@r{]} ++@itemx show print finish ++By default the @code{finish} command will show the value that is ++returned by the function. This can be disabled using @code{set print ++finish off}. When disabled, the value is still entered into the value ++history (@pxref{Value History}), but not displayed. ++ ++@kindex until ++@kindex u @r{(@code{until})} ++@cindex run until specified location ++@item until ++@itemx u ++Continue running until a source line past the current line, in the ++current stack frame, is reached. This command is used to avoid single ++stepping through a loop more than once. It is like the @code{next} ++command, except that when @code{until} encounters a jump, it ++automatically continues execution until the program counter is greater ++than the address of the jump. ++ ++This means that when you reach the end of a loop after single stepping ++though it, @code{until} makes your program continue execution until it ++exits the loop. In contrast, a @code{next} command at the end of a loop ++simply steps back to the beginning of the loop, which forces you to step ++through the next iteration. ++ ++@code{until} always stops your program if it attempts to exit the current ++stack frame. ++ ++@code{until} may produce somewhat counterintuitive results if the order ++of machine code does not match the order of the source lines. For ++example, in the following excerpt from a debugging session, the @code{f} ++(@code{frame}) command shows that execution is stopped at line ++@code{206}; yet when we use @code{until}, we get to line @code{195}: ++ ++@smallexample ++(@value{GDBP}) f ++#0 main (argc=4, argv=0xf7fffae8) at m4.c:206 ++206 expand_input(); ++(@value{GDBP}) until ++195 for ( ; argc > 0; NEXTARG) @{ ++@end smallexample ++ ++This happened because, for execution efficiency, the compiler had ++generated code for the loop closure test at the end, rather than the ++start, of the loop---even though the test in a C @code{for}-loop is ++written before the body of the loop. The @code{until} command appeared ++to step back to the beginning of the loop when it advanced to this ++expression; however, it has not really gone to an earlier ++statement---not in terms of the actual machine code. ++ ++@code{until} with no argument works by means of single ++instruction stepping, and hence is slower than @code{until} with an ++argument. ++ ++@item until @var{location} ++@itemx u @var{location} ++Continue running your program until either the specified @var{location} is ++reached, or the current stack frame returns. The location is any of ++the forms described in @ref{Specify Location}. ++This form of the command uses temporary breakpoints, and ++hence is quicker than @code{until} without an argument. The specified ++location is actually reached only if it is in the current frame. This ++implies that @code{until} can be used to skip over recursive function ++invocations. For instance in the code below, if the current location is ++line @code{96}, issuing @code{until 99} will execute the program up to ++line @code{99} in the same invocation of factorial, i.e., after the inner ++invocations have returned. ++ ++@smallexample ++94 int factorial (int value) ++95 @{ ++96 if (value > 1) @{ ++97 value *= factorial (value - 1); ++98 @} ++99 return (value); ++100 @} ++@end smallexample ++ ++ ++@kindex advance @var{location} ++@item advance @var{location} ++Continue running the program up to the given @var{location}. An argument is ++required, which should be of one of the forms described in ++@ref{Specify Location}. ++Execution will also stop upon exit from the current stack ++frame. This command is similar to @code{until}, but @code{advance} will ++not skip over recursive function calls, and the target location doesn't ++have to be in the same frame as the current one. ++ ++ ++@kindex stepi ++@kindex si @r{(@code{stepi})} ++@item stepi ++@itemx stepi @var{arg} ++@itemx si ++Execute one machine instruction, then stop and return to the debugger. ++ ++It is often useful to do @samp{display/i $pc} when stepping by machine ++instructions. This makes @value{GDBN} automatically display the next ++instruction to be executed, each time your program stops. @xref{Auto ++Display,, Automatic Display}. ++ ++An argument is a repeat count, as in @code{step}. ++ ++@need 750 ++@kindex nexti ++@kindex ni @r{(@code{nexti})} ++@item nexti ++@itemx nexti @var{arg} ++@itemx ni ++Execute one machine instruction, but if it is a function call, ++proceed until the function returns. ++ ++An argument is a repeat count, as in @code{next}. ++ ++@end table ++ ++@anchor{range stepping} ++@cindex range stepping ++@cindex target-assisted range stepping ++By default, and if available, @value{GDBN} makes use of ++target-assisted @dfn{range stepping}. In other words, whenever you ++use a stepping command (e.g., @code{step}, @code{next}), @value{GDBN} ++tells the target to step the corresponding range of instruction ++addresses instead of issuing multiple single-steps. This speeds up ++line stepping, particularly for remote targets. Ideally, there should ++be no reason you would want to turn range stepping off. However, it's ++possible that a bug in the debug info, a bug in the remote stub (for ++remote targets), or even a bug in @value{GDBN} could make line ++stepping behave incorrectly when target-assisted range stepping is ++enabled. You can use the following command to turn off range stepping ++if necessary: ++ ++@table @code ++@kindex set range-stepping ++@kindex show range-stepping ++@item set range-stepping ++@itemx show range-stepping ++Control whether range stepping is enabled. ++ ++If @code{on}, and the target supports it, @value{GDBN} tells the ++target to step a range of addresses itself, instead of issuing ++multiple single-steps. If @code{off}, @value{GDBN} always issues ++single-steps, even if range stepping is supported by the target. The ++default is @code{on}. ++ ++@end table ++ ++@node Skipping Over Functions and Files ++@section Skipping Over Functions and Files ++@cindex skipping over functions and files ++ ++The program you are debugging may contain some functions which are ++uninteresting to debug. The @code{skip} command lets you tell @value{GDBN} to ++skip a function, all functions in a file or a particular function in ++a particular file when stepping. ++ ++For example, consider the following C function: ++ ++@smallexample ++101 int func() ++102 @{ ++103 foo(boring()); ++104 bar(boring()); ++105 @} ++@end smallexample ++ ++@noindent ++Suppose you wish to step into the functions @code{foo} and @code{bar}, but you ++are not interested in stepping through @code{boring}. If you run @code{step} ++at line 103, you'll enter @code{boring()}, but if you run @code{next}, you'll ++step over both @code{foo} and @code{boring}! ++ ++One solution is to @code{step} into @code{boring} and use the @code{finish} ++command to immediately exit it. But this can become tedious if @code{boring} ++is called from many places. ++ ++A more flexible solution is to execute @kbd{skip boring}. This instructs ++@value{GDBN} never to step into @code{boring}. Now when you execute ++@code{step} at line 103, you'll step over @code{boring} and directly into ++@code{foo}. ++ ++Functions may be skipped by providing either a function name, linespec ++(@pxref{Specify Location}), regular expression that matches the function's ++name, file name or a @code{glob}-style pattern that matches the file name. ++ ++On Posix systems the form of the regular expression is ++``Extended Regular Expressions''. See for example @samp{man 7 regex} ++on @sc{gnu}/Linux systems. On non-Posix systems the form of the regular ++expression is whatever is provided by the @code{regcomp} function of ++the underlying system. ++See for example @samp{man 7 glob} on @sc{gnu}/Linux systems for a ++description of @code{glob}-style patterns. ++ ++@table @code ++@kindex skip ++@item skip @r{[}@var{options}@r{]} ++The basic form of the @code{skip} command takes zero or more options ++that specify what to skip. ++The @var{options} argument is any useful combination of the following: ++ ++@table @code ++@item -file @var{file} ++@itemx -fi @var{file} ++Functions in @var{file} will be skipped over when stepping. ++ ++@item -gfile @var{file-glob-pattern} ++@itemx -gfi @var{file-glob-pattern} ++@cindex skipping over files via glob-style patterns ++Functions in files matching @var{file-glob-pattern} will be skipped ++over when stepping. ++ ++@smallexample ++(gdb) skip -gfi utils/*.c ++@end smallexample ++ ++@item -function @var{linespec} ++@itemx -fu @var{linespec} ++Functions named by @var{linespec} or the function containing the line ++named by @var{linespec} will be skipped over when stepping. ++@xref{Specify Location}. ++ ++@item -rfunction @var{regexp} ++@itemx -rfu @var{regexp} ++@cindex skipping over functions via regular expressions ++Functions whose name matches @var{regexp} will be skipped over when stepping. ++ ++This form is useful for complex function names. ++For example, there is generally no need to step into C@t{++} @code{std::string} ++constructors or destructors. Plus with C@t{++} templates it can be hard to ++write out the full name of the function, and often it doesn't matter what ++the template arguments are. Specifying the function to be skipped as a ++regular expression makes this easier. ++ ++@smallexample ++(gdb) skip -rfu ^std::(allocator|basic_string)<.*>::~?\1 *\( ++@end smallexample ++ ++If you want to skip every templated C@t{++} constructor and destructor ++in the @code{std} namespace you can do: ++ ++@smallexample ++(gdb) skip -rfu ^std::([a-zA-z0-9_]+)<.*>::~?\1 *\( ++@end smallexample ++@end table ++ ++If no options are specified, the function you're currently debugging ++will be skipped. ++ ++@kindex skip function ++@item skip function @r{[}@var{linespec}@r{]} ++After running this command, the function named by @var{linespec} or the ++function containing the line named by @var{linespec} will be skipped over when ++stepping. @xref{Specify Location}. ++ ++If you do not specify @var{linespec}, the function you're currently debugging ++will be skipped. ++ ++(If you have a function called @code{file} that you want to skip, use ++@kbd{skip function file}.) ++ ++@kindex skip file ++@item skip file @r{[}@var{filename}@r{]} ++After running this command, any function whose source lives in @var{filename} ++will be skipped over when stepping. ++ ++@smallexample ++(gdb) skip file boring.c ++File boring.c will be skipped when stepping. ++@end smallexample ++ ++If you do not specify @var{filename}, functions whose source lives in the file ++you're currently debugging will be skipped. ++@end table ++ ++Skips can be listed, deleted, disabled, and enabled, much like breakpoints. ++These are the commands for managing your list of skips: ++ ++@table @code ++@kindex info skip ++@item info skip @r{[}@var{range}@r{]} ++Print details about the specified skip(s). If @var{range} is not specified, ++print a table with details about all functions and files marked for skipping. ++@code{info skip} prints the following information about each skip: ++ ++@table @emph ++@item Identifier ++A number identifying this skip. ++@item Enabled or Disabled ++Enabled skips are marked with @samp{y}. ++Disabled skips are marked with @samp{n}. ++@item Glob ++If the file name is a @samp{glob} pattern this is @samp{y}. ++Otherwise it is @samp{n}. ++@item File ++The name or @samp{glob} pattern of the file to be skipped. ++If no file is specified this is @samp{}. ++@item RE ++If the function name is a @samp{regular expression} this is @samp{y}. ++Otherwise it is @samp{n}. ++@item Function ++The name or regular expression of the function to skip. ++If no function is specified this is @samp{}. ++@end table ++ ++@kindex skip delete ++@item skip delete @r{[}@var{range}@r{]} ++Delete the specified skip(s). If @var{range} is not specified, delete all ++skips. ++ ++@kindex skip enable ++@item skip enable @r{[}@var{range}@r{]} ++Enable the specified skip(s). If @var{range} is not specified, enable all ++skips. ++ ++@kindex skip disable ++@item skip disable @r{[}@var{range}@r{]} ++Disable the specified skip(s). If @var{range} is not specified, disable all ++skips. ++ ++@kindex set debug skip ++@item set debug skip @r{[}on|off@r{]} ++Set whether to print the debug output about skipping files and functions. ++ ++@kindex show debug skip ++@item show debug skip ++Show whether the debug output about skipping files and functions is printed. ++ ++@end table ++ ++@node Signals ++@section Signals ++@cindex signals ++ ++A signal is an asynchronous event that can happen in a program. The ++operating system defines the possible kinds of signals, and gives each ++kind a name and a number. For example, in Unix @code{SIGINT} is the ++signal a program gets when you type an interrupt character (often @kbd{Ctrl-c}); ++@code{SIGSEGV} is the signal a program gets from referencing a place in ++memory far away from all the areas in use; @code{SIGALRM} occurs when ++the alarm clock timer goes off (which happens only if your program has ++requested an alarm). ++ ++@cindex fatal signals ++Some signals, including @code{SIGALRM}, are a normal part of the ++functioning of your program. Others, such as @code{SIGSEGV}, indicate ++errors; these signals are @dfn{fatal} (they kill your program immediately) if the ++program has not specified in advance some other way to handle the signal. ++@code{SIGINT} does not indicate an error in your program, but it is normally ++fatal so it can carry out the purpose of the interrupt: to kill the program. ++ ++@value{GDBN} has the ability to detect any occurrence of a signal in your ++program. You can tell @value{GDBN} in advance what to do for each kind of ++signal. ++ ++@cindex handling signals ++Normally, @value{GDBN} is set up to let the non-erroneous signals like ++@code{SIGALRM} be silently passed to your program ++(so as not to interfere with their role in the program's functioning) ++but to stop your program immediately whenever an error signal happens. ++You can change these settings with the @code{handle} command. ++ ++@table @code ++@kindex info signals ++@kindex info handle ++@item info signals ++@itemx info handle ++Print a table of all the kinds of signals and how @value{GDBN} has been told to ++handle each one. You can use this to see the signal numbers of all ++the defined types of signals. ++ ++@item info signals @var{sig} ++Similar, but print information only about the specified signal number. ++ ++@code{info handle} is an alias for @code{info signals}. ++ ++@item catch signal @r{[}@var{signal}@dots{} @r{|} @samp{all}@r{]} ++Set a catchpoint for the indicated signals. @xref{Set Catchpoints}, ++for details about this command. ++ ++@kindex handle ++@item handle @var{signal} @r{[}@var{keywords}@dots{}@r{]} ++Change the way @value{GDBN} handles signal @var{signal}. The @var{signal} ++can be the number of a signal or its name (with or without the ++@samp{SIG} at the beginning); a list of signal numbers of the form ++@samp{@var{low}-@var{high}}; or the word @samp{all}, meaning all the ++known signals. Optional arguments @var{keywords}, described below, ++say what change to make. ++@end table ++ ++@c @group ++The keywords allowed by the @code{handle} command can be abbreviated. ++Their full names are: ++ ++@table @code ++@item nostop ++@value{GDBN} should not stop your program when this signal happens. It may ++still print a message telling you that the signal has come in. ++ ++@item stop ++@value{GDBN} should stop your program when this signal happens. This implies ++the @code{print} keyword as well. ++ ++@item print ++@value{GDBN} should print a message when this signal happens. ++ ++@item noprint ++@value{GDBN} should not mention the occurrence of the signal at all. This ++implies the @code{nostop} keyword as well. ++ ++@item pass ++@itemx noignore ++@value{GDBN} should allow your program to see this signal; your program ++can handle the signal, or else it may terminate if the signal is fatal ++and not handled. @code{pass} and @code{noignore} are synonyms. ++ ++@item nopass ++@itemx ignore ++@value{GDBN} should not allow your program to see this signal. ++@code{nopass} and @code{ignore} are synonyms. ++@end table ++@c @end group ++ ++When a signal stops your program, the signal is not visible to the ++program until you ++continue. Your program sees the signal then, if @code{pass} is in ++effect for the signal in question @emph{at that time}. In other words, ++after @value{GDBN} reports a signal, you can use the @code{handle} ++command with @code{pass} or @code{nopass} to control whether your ++program sees that signal when you continue. ++ ++The default is set to @code{nostop}, @code{noprint}, @code{pass} for ++non-erroneous signals such as @code{SIGALRM}, @code{SIGWINCH} and ++@code{SIGCHLD}, and to @code{stop}, @code{print}, @code{pass} for the ++erroneous signals. ++ ++You can also use the @code{signal} command to prevent your program from ++seeing a signal, or cause it to see a signal it normally would not see, ++or to give it any signal at any time. For example, if your program stopped ++due to some sort of memory reference error, you might store correct ++values into the erroneous variables and continue, hoping to see more ++execution; but your program would probably terminate immediately as ++a result of the fatal signal once it saw the signal. To prevent this, ++you can continue with @samp{signal 0}. @xref{Signaling, ,Giving your ++Program a Signal}. ++ ++@cindex stepping and signal handlers ++@anchor{stepping and signal handlers} ++ ++@value{GDBN} optimizes for stepping the mainline code. If a signal ++that has @code{handle nostop} and @code{handle pass} set arrives while ++a stepping command (e.g., @code{stepi}, @code{step}, @code{next}) is ++in progress, @value{GDBN} lets the signal handler run and then resumes ++stepping the mainline code once the signal handler returns. In other ++words, @value{GDBN} steps over the signal handler. This prevents ++signals that you've specified as not interesting (with @code{handle ++nostop}) from changing the focus of debugging unexpectedly. Note that ++the signal handler itself may still hit a breakpoint, stop for another ++signal that has @code{handle stop} in effect, or for any other event ++that normally results in stopping the stepping command sooner. Also ++note that @value{GDBN} still informs you that the program received a ++signal if @code{handle print} is set. ++ ++@anchor{stepping into signal handlers} ++ ++If you set @code{handle pass} for a signal, and your program sets up a ++handler for it, then issuing a stepping command, such as @code{step} ++or @code{stepi}, when your program is stopped due to the signal will ++step @emph{into} the signal handler (if the target supports that). ++ ++Likewise, if you use the @code{queue-signal} command to queue a signal ++to be delivered to the current thread when execution of the thread ++resumes (@pxref{Signaling, ,Giving your Program a Signal}), then a ++stepping command will step into the signal handler. ++ ++Here's an example, using @code{stepi} to step to the first instruction ++of @code{SIGUSR1}'s handler: ++ ++@smallexample ++(@value{GDBP}) handle SIGUSR1 ++Signal Stop Print Pass to program Description ++SIGUSR1 Yes Yes Yes User defined signal 1 ++(@value{GDBP}) c ++Continuing. ++ ++Program received signal SIGUSR1, User defined signal 1. ++main () sigusr1.c:28 ++28 p = 0; ++(@value{GDBP}) si ++sigusr1_handler () at sigusr1.c:9 ++9 @{ ++@end smallexample ++ ++The same, but using @code{queue-signal} instead of waiting for the ++program to receive the signal first: ++ ++@smallexample ++(@value{GDBP}) n ++28 p = 0; ++(@value{GDBP}) queue-signal SIGUSR1 ++(@value{GDBP}) si ++sigusr1_handler () at sigusr1.c:9 ++9 @{ ++(@value{GDBP}) ++@end smallexample ++ ++@cindex extra signal information ++@anchor{extra signal information} ++ ++On some targets, @value{GDBN} can inspect extra signal information ++associated with the intercepted signal, before it is actually ++delivered to the program being debugged. This information is exported ++by the convenience variable @code{$_siginfo}, and consists of data ++that is passed by the kernel to the signal handler at the time of the ++receipt of a signal. The data type of the information itself is ++target dependent. You can see the data type using the @code{ptype ++$_siginfo} command. On Unix systems, it typically corresponds to the ++standard @code{siginfo_t} type, as defined in the @file{signal.h} ++system header. ++ ++Here's an example, on a @sc{gnu}/Linux system, printing the stray ++referenced address that raised a segmentation fault. ++ ++@smallexample ++@group ++(@value{GDBP}) continue ++Program received signal SIGSEGV, Segmentation fault. ++0x0000000000400766 in main () ++69 *(int *)p = 0; ++(@value{GDBP}) ptype $_siginfo ++type = struct @{ ++ int si_signo; ++ int si_errno; ++ int si_code; ++ union @{ ++ int _pad[28]; ++ struct @{...@} _kill; ++ struct @{...@} _timer; ++ struct @{...@} _rt; ++ struct @{...@} _sigchld; ++ struct @{...@} _sigfault; ++ struct @{...@} _sigpoll; ++ @} _sifields; ++@} ++(@value{GDBP}) ptype $_siginfo._sifields._sigfault ++type = struct @{ ++ void *si_addr; ++@} ++(@value{GDBP}) p $_siginfo._sifields._sigfault.si_addr ++$1 = (void *) 0x7ffff7ff7000 ++@end group ++@end smallexample ++ ++Depending on target support, @code{$_siginfo} may also be writable. ++ ++@cindex Intel MPX boundary violations ++@cindex boundary violations, Intel MPX ++On some targets, a @code{SIGSEGV} can be caused by a boundary ++violation, i.e., accessing an address outside of the allowed range. ++In those cases @value{GDBN} may displays additional information, ++depending on how @value{GDBN} has been told to handle the signal. ++With @code{handle stop SIGSEGV}, @value{GDBN} displays the violation ++kind: "Upper" or "Lower", the memory address accessed and the ++bounds, while with @code{handle nostop SIGSEGV} no additional ++information is displayed. ++ ++The usual output of a segfault is: ++@smallexample ++Program received signal SIGSEGV, Segmentation fault ++0x0000000000400d7c in upper () at i386-mpx-sigsegv.c:68 ++68 value = *(p + len); ++@end smallexample ++ ++While a bound violation is presented as: ++@smallexample ++Program received signal SIGSEGV, Segmentation fault ++Upper bound violation while accessing address 0x7fffffffc3b3 ++Bounds: [lower = 0x7fffffffc390, upper = 0x7fffffffc3a3] ++0x0000000000400d7c in upper () at i386-mpx-sigsegv.c:68 ++68 value = *(p + len); ++@end smallexample ++ ++@node Thread Stops ++@section Stopping and Starting Multi-thread Programs ++ ++@cindex stopped threads ++@cindex threads, stopped ++ ++@cindex continuing threads ++@cindex threads, continuing ++ ++@value{GDBN} supports debugging programs with multiple threads ++(@pxref{Threads,, Debugging Programs with Multiple Threads}). There ++are two modes of controlling execution of your program within the ++debugger. In the default mode, referred to as @dfn{all-stop mode}, ++when any thread in your program stops (for example, at a breakpoint ++or while being stepped), all other threads in the program are also stopped by ++@value{GDBN}. On some targets, @value{GDBN} also supports ++@dfn{non-stop mode}, in which other threads can continue to run freely while ++you examine the stopped thread in the debugger. ++ ++@menu ++* All-Stop Mode:: All threads stop when GDB takes control ++* Non-Stop Mode:: Other threads continue to execute ++* Background Execution:: Running your program asynchronously ++* Thread-Specific Breakpoints:: Controlling breakpoints ++* Interrupted System Calls:: GDB may interfere with system calls ++* Observer Mode:: GDB does not alter program behavior ++@end menu ++ ++@node All-Stop Mode ++@subsection All-Stop Mode ++ ++@cindex all-stop mode ++ ++In all-stop mode, whenever your program stops under @value{GDBN} for any reason, ++@emph{all} threads of execution stop, not just the current thread. This ++allows you to examine the overall state of the program, including ++switching between threads, without worrying that things may change ++underfoot. ++ ++Conversely, whenever you restart the program, @emph{all} threads start ++executing. @emph{This is true even when single-stepping} with commands ++like @code{step} or @code{next}. ++ ++In particular, @value{GDBN} cannot single-step all threads in lockstep. ++Since thread scheduling is up to your debugging target's operating ++system (not controlled by @value{GDBN}), other threads may ++execute more than one statement while the current thread completes a ++single step. Moreover, in general other threads stop in the middle of a ++statement, rather than at a clean statement boundary, when the program ++stops. ++ ++You might even find your program stopped in another thread after ++continuing or even single-stepping. This happens whenever some other ++thread runs into a breakpoint, a signal, or an exception before the ++first thread completes whatever you requested. ++ ++@cindex automatic thread selection ++@cindex switching threads automatically ++@cindex threads, automatic switching ++Whenever @value{GDBN} stops your program, due to a breakpoint or a ++signal, it automatically selects the thread where that breakpoint or ++signal happened. @value{GDBN} alerts you to the context switch with a ++message such as @samp{[Switching to Thread @var{n}]} to identify the ++thread. ++ ++On some OSes, you can modify @value{GDBN}'s default behavior by ++locking the OS scheduler to allow only a single thread to run. ++ ++@table @code ++@item set scheduler-locking @var{mode} ++@cindex scheduler locking mode ++@cindex lock scheduler ++Set the scheduler locking mode. It applies to normal execution, ++record mode, and replay mode. If it is @code{off}, then there is no ++locking and any thread may run at any time. If @code{on}, then only ++the current thread may run when the inferior is resumed. The ++@code{step} mode optimizes for single-stepping; it prevents other ++threads from preempting the current thread while you are stepping, so ++that the focus of debugging does not change unexpectedly. Other ++threads never get a chance to run when you step, and they are ++completely free to run when you use commands like @samp{continue}, ++@samp{until}, or @samp{finish}. However, unless another thread hits a ++breakpoint during its timeslice, @value{GDBN} does not change the ++current thread away from the thread that you are debugging. The ++@code{replay} mode behaves like @code{off} in record mode and like ++@code{on} in replay mode. ++ ++@item show scheduler-locking ++Display the current scheduler locking mode. ++@end table ++ ++@cindex resume threads of multiple processes simultaneously ++By default, when you issue one of the execution commands such as ++@code{continue}, @code{next} or @code{step}, @value{GDBN} allows only ++threads of the current inferior to run. For example, if @value{GDBN} ++is attached to two inferiors, each with two threads, the ++@code{continue} command resumes only the two threads of the current ++inferior. This is useful, for example, when you debug a program that ++forks and you want to hold the parent stopped (so that, for instance, ++it doesn't run to exit), while you debug the child. In other ++situations, you may not be interested in inspecting the current state ++of any of the processes @value{GDBN} is attached to, and you may want ++to resume them all until some breakpoint is hit. In the latter case, ++you can instruct @value{GDBN} to allow all threads of all the ++inferiors to run with the @w{@code{set schedule-multiple}} command. ++ ++@table @code ++@kindex set schedule-multiple ++@item set schedule-multiple ++Set the mode for allowing threads of multiple processes to be resumed ++when an execution command is issued. When @code{on}, all threads of ++all processes are allowed to run. When @code{off}, only the threads ++of the current process are resumed. The default is @code{off}. The ++@code{scheduler-locking} mode takes precedence when set to @code{on}, ++or while you are stepping and set to @code{step}. ++ ++@item show schedule-multiple ++Display the current mode for resuming the execution of threads of ++multiple processes. ++@end table ++ ++@node Non-Stop Mode ++@subsection Non-Stop Mode ++ ++@cindex non-stop mode ++ ++@c This section is really only a place-holder, and needs to be expanded ++@c with more details. ++ ++For some multi-threaded targets, @value{GDBN} supports an optional ++mode of operation in which you can examine stopped program threads in ++the debugger while other threads continue to execute freely. This ++minimizes intrusion when debugging live systems, such as programs ++where some threads have real-time constraints or must continue to ++respond to external events. This is referred to as @dfn{non-stop} mode. ++ ++In non-stop mode, when a thread stops to report a debugging event, ++@emph{only} that thread is stopped; @value{GDBN} does not stop other ++threads as well, in contrast to the all-stop mode behavior. Additionally, ++execution commands such as @code{continue} and @code{step} apply by default ++only to the current thread in non-stop mode, rather than all threads as ++in all-stop mode. This allows you to control threads explicitly in ++ways that are not possible in all-stop mode --- for example, stepping ++one thread while allowing others to run freely, stepping ++one thread while holding all others stopped, or stepping several threads ++independently and simultaneously. ++ ++To enter non-stop mode, use this sequence of commands before you run ++or attach to your program: ++ ++@smallexample ++# If using the CLI, pagination breaks non-stop. ++set pagination off ++ ++# Finally, turn it on! ++set non-stop on ++@end smallexample ++ ++You can use these commands to manipulate the non-stop mode setting: ++ ++@table @code ++@kindex set non-stop ++@item set non-stop on ++Enable selection of non-stop mode. ++@item set non-stop off ++Disable selection of non-stop mode. ++@kindex show non-stop ++@item show non-stop ++Show the current non-stop enablement setting. ++@end table ++ ++Note these commands only reflect whether non-stop mode is enabled, ++not whether the currently-executing program is being run in non-stop mode. ++In particular, the @code{set non-stop} preference is only consulted when ++@value{GDBN} starts or connects to the target program, and it is generally ++not possible to switch modes once debugging has started. Furthermore, ++since not all targets support non-stop mode, even when you have enabled ++non-stop mode, @value{GDBN} may still fall back to all-stop operation by ++default. ++ ++In non-stop mode, all execution commands apply only to the current thread ++by default. That is, @code{continue} only continues one thread. ++To continue all threads, issue @code{continue -a} or @code{c -a}. ++ ++You can use @value{GDBN}'s background execution commands ++(@pxref{Background Execution}) to run some threads in the background ++while you continue to examine or step others from @value{GDBN}. ++The MI execution commands (@pxref{GDB/MI Program Execution}) are ++always executed asynchronously in non-stop mode. ++ ++Suspending execution is done with the @code{interrupt} command when ++running in the background, or @kbd{Ctrl-c} during foreground execution. ++In all-stop mode, this stops the whole process; ++but in non-stop mode the interrupt applies only to the current thread. ++To stop the whole program, use @code{interrupt -a}. ++ ++Other execution commands do not currently support the @code{-a} option. ++ ++In non-stop mode, when a thread stops, @value{GDBN} doesn't automatically make ++that thread current, as it does in all-stop mode. This is because the ++thread stop notifications are asynchronous with respect to @value{GDBN}'s ++command interpreter, and it would be confusing if @value{GDBN} unexpectedly ++changed to a different thread just as you entered a command to operate on the ++previously current thread. ++ ++@node Background Execution ++@subsection Background Execution ++ ++@cindex foreground execution ++@cindex background execution ++@cindex asynchronous execution ++@cindex execution, foreground, background and asynchronous ++ ++@value{GDBN}'s execution commands have two variants: the normal ++foreground (synchronous) behavior, and a background ++(asynchronous) behavior. In foreground execution, @value{GDBN} waits for ++the program to report that some thread has stopped before prompting for ++another command. In background execution, @value{GDBN} immediately gives ++a command prompt so that you can issue other commands while your program runs. ++ ++If the target doesn't support async mode, @value{GDBN} issues an error ++message if you attempt to use the background execution commands. ++ ++@cindex @code{&}, background execution of commands ++To specify background execution, add a @code{&} to the command. For example, ++the background form of the @code{continue} command is @code{continue&}, or ++just @code{c&}. The execution commands that accept background execution ++are: ++ ++@table @code ++@kindex run& ++@item run ++@xref{Starting, , Starting your Program}. ++ ++@item attach ++@kindex attach& ++@xref{Attach, , Debugging an Already-running Process}. ++ ++@item step ++@kindex step& ++@xref{Continuing and Stepping, step}. ++ ++@item stepi ++@kindex stepi& ++@xref{Continuing and Stepping, stepi}. ++ ++@item next ++@kindex next& ++@xref{Continuing and Stepping, next}. ++ ++@item nexti ++@kindex nexti& ++@xref{Continuing and Stepping, nexti}. ++ ++@item continue ++@kindex continue& ++@xref{Continuing and Stepping, continue}. ++ ++@item finish ++@kindex finish& ++@xref{Continuing and Stepping, finish}. ++ ++@item until ++@kindex until& ++@xref{Continuing and Stepping, until}. ++ ++@end table ++ ++Background execution is especially useful in conjunction with non-stop ++mode for debugging programs with multiple threads; see @ref{Non-Stop Mode}. ++However, you can also use these commands in the normal all-stop mode with ++the restriction that you cannot issue another execution command until the ++previous one finishes. Examples of commands that are valid in all-stop ++mode while the program is running include @code{help} and @code{info break}. ++ ++You can interrupt your program while it is running in the background by ++using the @code{interrupt} command. ++ ++@table @code ++@kindex interrupt ++@item interrupt ++@itemx interrupt -a ++ ++Suspend execution of the running program. In all-stop mode, ++@code{interrupt} stops the whole process, but in non-stop mode, it stops ++only the current thread. To stop the whole program in non-stop mode, ++use @code{interrupt -a}. ++@end table ++ ++@node Thread-Specific Breakpoints ++@subsection Thread-Specific Breakpoints ++ ++When your program has multiple threads (@pxref{Threads,, Debugging ++Programs with Multiple Threads}), you can choose whether to set ++breakpoints on all threads, or on a particular thread. ++ ++@table @code ++@cindex breakpoints and threads ++@cindex thread breakpoints ++@kindex break @dots{} thread @var{thread-id} ++@item break @var{location} thread @var{thread-id} ++@itemx break @var{location} thread @var{thread-id} if @dots{} ++@var{location} specifies source lines; there are several ways of ++writing them (@pxref{Specify Location}), but the effect is always to ++specify some source line. ++ ++Use the qualifier @samp{thread @var{thread-id}} with a breakpoint command ++to specify that you only want @value{GDBN} to stop the program when a ++particular thread reaches this breakpoint. The @var{thread-id} specifier ++is one of the thread identifiers assigned by @value{GDBN}, shown ++in the first column of the @samp{info threads} display. ++ ++If you do not specify @samp{thread @var{thread-id}} when you set a ++breakpoint, the breakpoint applies to @emph{all} threads of your ++program. ++ ++You can use the @code{thread} qualifier on conditional breakpoints as ++well; in this case, place @samp{thread @var{thread-id}} before or ++after the breakpoint condition, like this: ++ ++@smallexample ++(@value{GDBP}) break frik.c:13 thread 28 if bartab > lim ++@end smallexample ++ ++@end table ++ ++Thread-specific breakpoints are automatically deleted when ++@value{GDBN} detects the corresponding thread is no longer in the ++thread list. For example: ++ ++@smallexample ++(@value{GDBP}) c ++Thread-specific breakpoint 3 deleted - thread 28 no longer in the thread list. ++@end smallexample ++ ++There are several ways for a thread to disappear, such as a regular ++thread exit, but also when you detach from the process with the ++@code{detach} command (@pxref{Attach, ,Debugging an Already-running ++Process}), or if @value{GDBN} loses the remote connection ++(@pxref{Remote Debugging}), etc. Note that with some targets, ++@value{GDBN} is only able to detect a thread has exited when the user ++explictly asks for the thread list with the @code{info threads} ++command. ++ ++@node Interrupted System Calls ++@subsection Interrupted System Calls ++ ++@cindex thread breakpoints and system calls ++@cindex system calls and thread breakpoints ++@cindex premature return from system calls ++There is an unfortunate side effect when using @value{GDBN} to debug ++multi-threaded programs. If one thread stops for a ++breakpoint, or for some other reason, and another thread is blocked in a ++system call, then the system call may return prematurely. This is a ++consequence of the interaction between multiple threads and the signals ++that @value{GDBN} uses to implement breakpoints and other events that ++stop execution. ++ ++To handle this problem, your program should check the return value of ++each system call and react appropriately. This is good programming ++style anyways. ++ ++For example, do not write code like this: ++ ++@smallexample ++ sleep (10); ++@end smallexample ++ ++The call to @code{sleep} will return early if a different thread stops ++at a breakpoint or for some other reason. ++ ++Instead, write this: ++ ++@smallexample ++ int unslept = 10; ++ while (unslept > 0) ++ unslept = sleep (unslept); ++@end smallexample ++ ++A system call is allowed to return early, so the system is still ++conforming to its specification. But @value{GDBN} does cause your ++multi-threaded program to behave differently than it would without ++@value{GDBN}. ++ ++Also, @value{GDBN} uses internal breakpoints in the thread library to ++monitor certain events such as thread creation and thread destruction. ++When such an event happens, a system call in another thread may return ++prematurely, even though your program does not appear to stop. ++ ++@node Observer Mode ++@subsection Observer Mode ++ ++If you want to build on non-stop mode and observe program behavior ++without any chance of disruption by @value{GDBN}, you can set ++variables to disable all of the debugger's attempts to modify state, ++whether by writing memory, inserting breakpoints, etc. These operate ++at a low level, intercepting operations from all commands. ++ ++When all of these are set to @code{off}, then @value{GDBN} is said to ++be @dfn{observer mode}. As a convenience, the variable ++@code{observer} can be set to disable these, plus enable non-stop ++mode. ++ ++Note that @value{GDBN} will not prevent you from making nonsensical ++combinations of these settings. For instance, if you have enabled ++@code{may-insert-breakpoints} but disabled @code{may-write-memory}, ++then breakpoints that work by writing trap instructions into the code ++stream will still not be able to be placed. ++ ++@table @code ++ ++@kindex observer ++@item set observer on ++@itemx set observer off ++When set to @code{on}, this disables all the permission variables ++below (except for @code{insert-fast-tracepoints}), plus enables ++non-stop debugging. Setting this to @code{off} switches back to ++normal debugging, though remaining in non-stop mode. ++ ++@item show observer ++Show whether observer mode is on or off. ++ ++@kindex may-write-registers ++@item set may-write-registers on ++@itemx set may-write-registers off ++This controls whether @value{GDBN} will attempt to alter the values of ++registers, such as with assignment expressions in @code{print}, or the ++@code{jump} command. It defaults to @code{on}. ++ ++@item show may-write-registers ++Show the current permission to write registers. ++ ++@kindex may-write-memory ++@item set may-write-memory on ++@itemx set may-write-memory off ++This controls whether @value{GDBN} will attempt to alter the contents ++of memory, such as with assignment expressions in @code{print}. It ++defaults to @code{on}. ++ ++@item show may-write-memory ++Show the current permission to write memory. ++ ++@kindex may-insert-breakpoints ++@item set may-insert-breakpoints on ++@itemx set may-insert-breakpoints off ++This controls whether @value{GDBN} will attempt to insert breakpoints. ++This affects all breakpoints, including internal breakpoints defined ++by @value{GDBN}. It defaults to @code{on}. ++ ++@item show may-insert-breakpoints ++Show the current permission to insert breakpoints. ++ ++@kindex may-insert-tracepoints ++@item set may-insert-tracepoints on ++@itemx set may-insert-tracepoints off ++This controls whether @value{GDBN} will attempt to insert (regular) ++tracepoints at the beginning of a tracing experiment. It affects only ++non-fast tracepoints, fast tracepoints being under the control of ++@code{may-insert-fast-tracepoints}. It defaults to @code{on}. ++ ++@item show may-insert-tracepoints ++Show the current permission to insert tracepoints. ++ ++@kindex may-insert-fast-tracepoints ++@item set may-insert-fast-tracepoints on ++@itemx set may-insert-fast-tracepoints off ++This controls whether @value{GDBN} will attempt to insert fast ++tracepoints at the beginning of a tracing experiment. It affects only ++fast tracepoints, regular (non-fast) tracepoints being under the ++control of @code{may-insert-tracepoints}. It defaults to @code{on}. ++ ++@item show may-insert-fast-tracepoints ++Show the current permission to insert fast tracepoints. ++ ++@kindex may-interrupt ++@item set may-interrupt on ++@itemx set may-interrupt off ++This controls whether @value{GDBN} will attempt to interrupt or stop ++program execution. When this variable is @code{off}, the ++@code{interrupt} command will have no effect, nor will ++@kbd{Ctrl-c}. It defaults to @code{on}. ++ ++@item show may-interrupt ++Show the current permission to interrupt or stop the program. ++ ++@end table ++ ++@node Reverse Execution ++@chapter Running programs backward ++@cindex reverse execution ++@cindex running programs backward ++ ++When you are debugging a program, it is not unusual to realize that ++you have gone too far, and some event of interest has already happened. ++If the target environment supports it, @value{GDBN} can allow you to ++``rewind'' the program by running it backward. ++ ++A target environment that supports reverse execution should be able ++to ``undo'' the changes in machine state that have taken place as the ++program was executing normally. Variables, registers etc.@: should ++revert to their previous values. Obviously this requires a great ++deal of sophistication on the part of the target environment; not ++all target environments can support reverse execution. ++ ++When a program is executed in reverse, the instructions that ++have most recently been executed are ``un-executed'', in reverse ++order. The program counter runs backward, following the previous ++thread of execution in reverse. As each instruction is ``un-executed'', ++the values of memory and/or registers that were changed by that ++instruction are reverted to their previous states. After executing ++a piece of source code in reverse, all side effects of that code ++should be ``undone'', and all variables should be returned to their ++prior values@footnote{ ++Note that some side effects are easier to undo than others. For instance, ++memory and registers are relatively easy, but device I/O is hard. Some ++targets may be able undo things like device I/O, and some may not. ++ ++The contract between @value{GDBN} and the reverse executing target ++requires only that the target do something reasonable when ++@value{GDBN} tells it to execute backwards, and then report the ++results back to @value{GDBN}. Whatever the target reports back to ++@value{GDBN}, @value{GDBN} will report back to the user. @value{GDBN} ++assumes that the memory and registers that the target reports are in a ++consistent state, but @value{GDBN} accepts whatever it is given. ++}. ++ ++On some platforms, @value{GDBN} has built-in support for reverse ++execution, activated with the @code{record} or @code{record btrace} ++commands. @xref{Process Record and Replay}. Some remote targets, ++typically full system emulators, support reverse execution directly ++without requiring any special command. ++ ++If you are debugging in a target environment that supports ++reverse execution, @value{GDBN} provides the following commands. ++ ++@table @code ++@kindex reverse-continue ++@kindex rc @r{(@code{reverse-continue})} ++@item reverse-continue @r{[}@var{ignore-count}@r{]} ++@itemx rc @r{[}@var{ignore-count}@r{]} ++Beginning at the point where your program last stopped, start executing ++in reverse. Reverse execution will stop for breakpoints and synchronous ++exceptions (signals), just like normal execution. Behavior of ++asynchronous signals depends on the target environment. ++ ++@kindex reverse-step ++@kindex rs @r{(@code{step})} ++@item reverse-step @r{[}@var{count}@r{]} ++Run the program backward until control reaches the start of a ++different source line; then stop it, and return control to @value{GDBN}. ++ ++Like the @code{step} command, @code{reverse-step} will only stop ++at the beginning of a source line. It ``un-executes'' the previously ++executed source line. If the previous source line included calls to ++debuggable functions, @code{reverse-step} will step (backward) into ++the called function, stopping at the beginning of the @emph{last} ++statement in the called function (typically a return statement). ++ ++Also, as with the @code{step} command, if non-debuggable functions are ++called, @code{reverse-step} will run thru them backward without stopping. ++ ++@kindex reverse-stepi ++@kindex rsi @r{(@code{reverse-stepi})} ++@item reverse-stepi @r{[}@var{count}@r{]} ++Reverse-execute one machine instruction. Note that the instruction ++to be reverse-executed is @emph{not} the one pointed to by the program ++counter, but the instruction executed prior to that one. For instance, ++if the last instruction was a jump, @code{reverse-stepi} will take you ++back from the destination of the jump to the jump instruction itself. ++ ++@kindex reverse-next ++@kindex rn @r{(@code{reverse-next})} ++@item reverse-next @r{[}@var{count}@r{]} ++Run backward to the beginning of the previous line executed in ++the current (innermost) stack frame. If the line contains function ++calls, they will be ``un-executed'' without stopping. Starting from ++the first line of a function, @code{reverse-next} will take you back ++to the caller of that function, @emph{before} the function was called, ++just as the normal @code{next} command would take you from the last ++line of a function back to its return to its caller ++@footnote{Unless the code is too heavily optimized.}. ++ ++@kindex reverse-nexti ++@kindex rni @r{(@code{reverse-nexti})} ++@item reverse-nexti @r{[}@var{count}@r{]} ++Like @code{nexti}, @code{reverse-nexti} executes a single instruction ++in reverse, except that called functions are ``un-executed'' atomically. ++That is, if the previously executed instruction was a return from ++another function, @code{reverse-nexti} will continue to execute ++in reverse until the call to that function (from the current stack ++frame) is reached. ++ ++@kindex reverse-finish ++@item reverse-finish ++Just as the @code{finish} command takes you to the point where the ++current function returns, @code{reverse-finish} takes you to the point ++where it was called. Instead of ending up at the end of the current ++function invocation, you end up at the beginning. ++ ++@kindex set exec-direction ++@item set exec-direction ++Set the direction of target execution. ++@item set exec-direction reverse ++@cindex execute forward or backward in time ++@value{GDBN} will perform all execution commands in reverse, until the ++exec-direction mode is changed to ``forward''. Affected commands include ++@code{step, stepi, next, nexti, continue, and finish}. The @code{return} ++command cannot be used in reverse mode. ++@item set exec-direction forward ++@value{GDBN} will perform all execution commands in the normal fashion. ++This is the default. ++@end table ++ ++ ++@node Process Record and Replay ++@chapter Recording Inferior's Execution and Replaying It ++@cindex process record and replay ++@cindex recording inferior's execution and replaying it ++ ++On some platforms, @value{GDBN} provides a special @dfn{process record ++and replay} target that can record a log of the process execution, and ++replay it later with both forward and reverse execution commands. ++ ++@cindex replay mode ++When this target is in use, if the execution log includes the record ++for the next instruction, @value{GDBN} will debug in @dfn{replay ++mode}. In the replay mode, the inferior does not really execute code ++instructions. Instead, all the events that normally happen during ++code execution are taken from the execution log. While code is not ++really executed in replay mode, the values of registers (including the ++program counter register) and the memory of the inferior are still ++changed as they normally would. Their contents are taken from the ++execution log. ++ ++@cindex record mode ++If the record for the next instruction is not in the execution log, ++@value{GDBN} will debug in @dfn{record mode}. In this mode, the ++inferior executes normally, and @value{GDBN} records the execution log ++for future replay. ++ ++The process record and replay target supports reverse execution ++(@pxref{Reverse Execution}), even if the platform on which the ++inferior runs does not. However, the reverse execution is limited in ++this case by the range of the instructions recorded in the execution ++log. In other words, reverse execution on platforms that don't ++support it directly can only be done in the replay mode. ++ ++When debugging in the reverse direction, @value{GDBN} will work in ++replay mode as long as the execution log includes the record for the ++previous instruction; otherwise, it will work in record mode, if the ++platform supports reverse execution, or stop if not. ++ ++Currently, process record and replay is supported on ARM, Aarch64, ++Moxie, PowerPC, PowerPC64, S/390, and x86 (i386/amd64) running ++GNU/Linux. Process record and replay can be used both when native ++debugging, and when remote debugging via @code{gdbserver}. ++ ++For architecture environments that support process record and replay, ++@value{GDBN} provides the following commands: ++ ++@table @code ++@kindex target record ++@kindex target record-full ++@kindex target record-btrace ++@kindex record ++@kindex record full ++@kindex record btrace ++@kindex record btrace bts ++@kindex record btrace pt ++@kindex record bts ++@kindex record pt ++@kindex rec ++@kindex rec full ++@kindex rec btrace ++@kindex rec btrace bts ++@kindex rec btrace pt ++@kindex rec bts ++@kindex rec pt ++@item record @var{method} ++This command starts the process record and replay target. The ++recording method can be specified as parameter. Without a parameter ++the command uses the @code{full} recording method. The following ++recording methods are available: ++ ++@table @code ++@item full ++Full record/replay recording using @value{GDBN}'s software record and ++replay implementation. This method allows replaying and reverse ++execution. ++ ++@item btrace @var{format} ++Hardware-supported instruction recording, supported on Intel ++processors. This method does not record data. Further, the data is ++collected in a ring buffer so old data will be overwritten when the ++buffer is full. It allows limited reverse execution. Variables and ++registers are not available during reverse execution. In remote ++debugging, recording continues on disconnect. Recorded data can be ++inspected after reconnecting. The recording may be stopped using ++@code{record stop}. ++ ++The recording format can be specified as parameter. Without a parameter ++the command chooses the recording format. The following recording ++formats are available: ++ ++@table @code ++@item bts ++@cindex branch trace store ++Use the @dfn{Branch Trace Store} (@acronym{BTS}) recording format. In ++this format, the processor stores a from/to record for each executed ++branch in the btrace ring buffer. ++ ++@item pt ++@cindex Intel Processor Trace ++Use the @dfn{Intel Processor Trace} recording format. In this ++format, the processor stores the execution trace in a compressed form ++that is afterwards decoded by @value{GDBN}. ++ ++The trace can be recorded with very low overhead. The compressed ++trace format also allows small trace buffers to already contain a big ++number of instructions compared to @acronym{BTS}. ++ ++Decoding the recorded execution trace, on the other hand, is more ++expensive than decoding @acronym{BTS} trace. This is mostly due to the ++increased number of instructions to process. You should increase the ++buffer-size with care. ++@end table ++ ++Not all recording formats may be available on all processors. ++@end table ++ ++The process record and replay target can only debug a process that is ++already running. Therefore, you need first to start the process with ++the @kbd{run} or @kbd{start} commands, and then start the recording ++with the @kbd{record @var{method}} command. ++ ++@cindex displaced stepping, and process record and replay ++Displaced stepping (@pxref{Maintenance Commands,, displaced stepping}) ++will be automatically disabled when process record and replay target ++is started. That's because the process record and replay target ++doesn't support displaced stepping. ++ ++@cindex non-stop mode, and process record and replay ++@cindex asynchronous execution, and process record and replay ++If the inferior is in the non-stop mode (@pxref{Non-Stop Mode}) or in ++the asynchronous execution mode (@pxref{Background Execution}), not ++all recording methods are available. The @code{full} recording method ++does not support these two modes. ++ ++@kindex record stop ++@kindex rec s ++@item record stop ++Stop the process record and replay target. When process record and ++replay target stops, the entire execution log will be deleted and the ++inferior will either be terminated, or will remain in its final state. ++ ++When you stop the process record and replay target in record mode (at ++the end of the execution log), the inferior will be stopped at the ++next instruction that would have been recorded. In other words, if ++you record for a while and then stop recording, the inferior process ++will be left in the same state as if the recording never happened. ++ ++On the other hand, if the process record and replay target is stopped ++while in replay mode (that is, not at the end of the execution log, ++but at some earlier point), the inferior process will become ``live'' ++at that earlier state, and it will then be possible to continue the ++usual ``live'' debugging of the process from that state. ++ ++When the inferior process exits, or @value{GDBN} detaches from it, ++process record and replay target will automatically stop itself. ++ ++@kindex record goto ++@item record goto ++Go to a specific location in the execution log. There are several ++ways to specify the location to go to: ++ ++@table @code ++@item record goto begin ++@itemx record goto start ++Go to the beginning of the execution log. ++ ++@item record goto end ++Go to the end of the execution log. ++ ++@item record goto @var{n} ++Go to instruction number @var{n} in the execution log. ++@end table ++ ++@kindex record save ++@item record save @var{filename} ++Save the execution log to a file @file{@var{filename}}. ++Default filename is @file{gdb_record.@var{process_id}}, where ++@var{process_id} is the process ID of the inferior. ++ ++This command may not be available for all recording methods. ++ ++@kindex record restore ++@item record restore @var{filename} ++Restore the execution log from a file @file{@var{filename}}. ++File must have been created with @code{record save}. ++ ++@kindex set record full ++@item set record full insn-number-max @var{limit} ++@itemx set record full insn-number-max unlimited ++Set the limit of instructions to be recorded for the @code{full} ++recording method. Default value is 200000. ++ ++If @var{limit} is a positive number, then @value{GDBN} will start ++deleting instructions from the log once the number of the record ++instructions becomes greater than @var{limit}. For every new recorded ++instruction, @value{GDBN} will delete the earliest recorded ++instruction to keep the number of recorded instructions at the limit. ++(Since deleting recorded instructions loses information, @value{GDBN} ++lets you control what happens when the limit is reached, by means of ++the @code{stop-at-limit} option, described below.) ++ ++If @var{limit} is @code{unlimited} or zero, @value{GDBN} will never ++delete recorded instructions from the execution log. The number of ++recorded instructions is limited only by the available memory. ++ ++@kindex show record full ++@item show record full insn-number-max ++Show the limit of instructions to be recorded with the @code{full} ++recording method. ++ ++@item set record full stop-at-limit ++Control the behavior of the @code{full} recording method when the ++number of recorded instructions reaches the limit. If ON (the ++default), @value{GDBN} will stop when the limit is reached for the ++first time and ask you whether you want to stop the inferior or ++continue running it and recording the execution log. If you decide ++to continue recording, each new recorded instruction will cause the ++oldest one to be deleted. ++ ++If this option is OFF, @value{GDBN} will automatically delete the ++oldest record to make room for each new one, without asking. ++ ++@item show record full stop-at-limit ++Show the current setting of @code{stop-at-limit}. ++ ++@item set record full memory-query ++Control the behavior when @value{GDBN} is unable to record memory ++changes caused by an instruction for the @code{full} recording method. ++If ON, @value{GDBN} will query whether to stop the inferior in that ++case. ++ ++If this option is OFF (the default), @value{GDBN} will automatically ++ignore the effect of such instructions on memory. Later, when ++@value{GDBN} replays this execution log, it will mark the log of this ++instruction as not accessible, and it will not affect the replay ++results. ++ ++@item show record full memory-query ++Show the current setting of @code{memory-query}. ++ ++@kindex set record btrace ++The @code{btrace} record target does not trace data. As a ++convenience, when replaying, @value{GDBN} reads read-only memory off ++the live program directly, assuming that the addresses of the ++read-only areas don't change. This for example makes it possible to ++disassemble code while replaying, but not to print variables. ++In some cases, being able to inspect variables might be useful. ++You can use the following command for that: ++ ++@item set record btrace replay-memory-access ++Control the behavior of the @code{btrace} recording method when ++accessing memory during replay. If @code{read-only} (the default), ++@value{GDBN} will only allow accesses to read-only memory. ++If @code{read-write}, @value{GDBN} will allow accesses to read-only ++and to read-write memory. Beware that the accessed memory corresponds ++to the live target and not necessarily to the current replay ++position. ++ ++@item set record btrace cpu @var{identifier} ++Set the processor to be used for enabling workarounds for processor ++errata when decoding the trace. ++ ++Processor errata are defects in processor operation, caused by its ++design or manufacture. They can cause a trace not to match the ++specification. This, in turn, may cause trace decode to fail. ++@value{GDBN} can detect erroneous trace packets and correct them, thus ++avoiding the decoding failures. These corrections are known as ++@dfn{errata workarounds}, and are enabled based on the processor on ++which the trace was recorded. ++ ++By default, @value{GDBN} attempts to detect the processor ++automatically, and apply the necessary workarounds for it. However, ++you may need to specify the processor if @value{GDBN} does not yet ++support it. This command allows you to do that, and also allows to ++disable the workarounds. ++ ++The argument @var{identifier} identifies the @sc{cpu} and is of the ++form: @code{@var{vendor}:@var{processor identifier}}. In addition, ++there are two special identifiers, @code{none} and @code{auto} ++(default). ++ ++The following vendor identifiers and corresponding processor ++identifiers are currently supported: ++ ++@multitable @columnfractions .1 .9 ++ ++@item @code{intel} ++@tab @var{family}/@var{model}[/@var{stepping}] ++ ++@end multitable ++ ++On GNU/Linux systems, the processor @var{family}, @var{model}, and ++@var{stepping} can be obtained from @code{/proc/cpuinfo}. ++ ++If @var{identifier} is @code{auto}, enable errata workarounds for the ++processor on which the trace was recorded. If @var{identifier} is ++@code{none}, errata workarounds are disabled. ++ ++For example, when using an old @value{GDBN} on a new system, decode ++may fail because @value{GDBN} does not support the new processor. It ++often suffices to specify an older processor that @value{GDBN} ++supports. ++ ++@smallexample ++(gdb) info record ++Active record target: record-btrace ++Recording format: Intel Processor Trace. ++Buffer size: 16kB. ++Failed to configure the Intel Processor Trace decoder: unknown cpu. ++(gdb) set record btrace cpu intel:6/158 ++(gdb) info record ++Active record target: record-btrace ++Recording format: Intel Processor Trace. ++Buffer size: 16kB. ++Recorded 84872 instructions in 3189 functions (0 gaps) for thread 1 (...). ++@end smallexample ++ ++@kindex show record btrace ++@item show record btrace replay-memory-access ++Show the current setting of @code{replay-memory-access}. ++ ++@item show record btrace cpu ++Show the processor to be used for enabling trace decode errata ++workarounds. ++ ++@kindex set record btrace bts ++@item set record btrace bts buffer-size @var{size} ++@itemx set record btrace bts buffer-size unlimited ++Set the requested ring buffer size for branch tracing in @acronym{BTS} ++format. Default is 64KB. ++ ++If @var{size} is a positive number, then @value{GDBN} will try to ++allocate a buffer of at least @var{size} bytes for each new thread ++that uses the btrace recording method and the @acronym{BTS} format. ++The actually obtained buffer size may differ from the requested ++@var{size}. Use the @code{info record} command to see the actual ++buffer size for each thread that uses the btrace recording method and ++the @acronym{BTS} format. ++ ++If @var{limit} is @code{unlimited} or zero, @value{GDBN} will try to ++allocate a buffer of 4MB. ++ ++Bigger buffers mean longer traces. On the other hand, @value{GDBN} will ++also need longer to process the branch trace data before it can be used. ++ ++@item show record btrace bts buffer-size @var{size} ++Show the current setting of the requested ring buffer size for branch ++tracing in @acronym{BTS} format. ++ ++@kindex set record btrace pt ++@item set record btrace pt buffer-size @var{size} ++@itemx set record btrace pt buffer-size unlimited ++Set the requested ring buffer size for branch tracing in Intel ++Processor Trace format. Default is 16KB. ++ ++If @var{size} is a positive number, then @value{GDBN} will try to ++allocate a buffer of at least @var{size} bytes for each new thread ++that uses the btrace recording method and the Intel Processor Trace ++format. The actually obtained buffer size may differ from the ++requested @var{size}. Use the @code{info record} command to see the ++actual buffer size for each thread. ++ ++If @var{limit} is @code{unlimited} or zero, @value{GDBN} will try to ++allocate a buffer of 4MB. ++ ++Bigger buffers mean longer traces. On the other hand, @value{GDBN} will ++also need longer to process the branch trace data before it can be used. ++ ++@item show record btrace pt buffer-size @var{size} ++Show the current setting of the requested ring buffer size for branch ++tracing in Intel Processor Trace format. ++ ++@kindex info record ++@item info record ++Show various statistics about the recording depending on the recording ++method: ++ ++@table @code ++@item full ++For the @code{full} recording method, it shows the state of process ++record and its in-memory execution log buffer, including: ++ ++@itemize @bullet ++@item ++Whether in record mode or replay mode. ++@item ++Lowest recorded instruction number (counting from when the current execution log started recording instructions). ++@item ++Highest recorded instruction number. ++@item ++Current instruction about to be replayed (if in replay mode). ++@item ++Number of instructions contained in the execution log. ++@item ++Maximum number of instructions that may be contained in the execution log. ++@end itemize ++ ++@item btrace ++For the @code{btrace} recording method, it shows: ++ ++@itemize @bullet ++@item ++Recording format. ++@item ++Number of instructions that have been recorded. ++@item ++Number of blocks of sequential control-flow formed by the recorded ++instructions. ++@item ++Whether in record mode or replay mode. ++@end itemize ++ ++For the @code{bts} recording format, it also shows: ++@itemize @bullet ++@item ++Size of the perf ring buffer. ++@end itemize ++ ++For the @code{pt} recording format, it also shows: ++@itemize @bullet ++@item ++Size of the perf ring buffer. ++@end itemize ++@end table ++ ++@kindex record delete ++@kindex rec del ++@item record delete ++When record target runs in replay mode (``in the past''), delete the ++subsequent execution log and begin to record a new execution log starting ++from the current address. This means you will abandon the previously ++recorded ``future'' and begin recording a new ``future''. ++ ++@kindex record instruction-history ++@kindex rec instruction-history ++@item record instruction-history ++Disassembles instructions from the recorded execution log. By ++default, ten instructions are disassembled. This can be changed using ++the @code{set record instruction-history-size} command. Instructions ++are printed in execution order. ++ ++It can also print mixed source+disassembly if you specify the the ++@code{/m} or @code{/s} modifier, and print the raw instructions in hex ++as well as in symbolic form by specifying the @code{/r} modifier. ++ ++The current position marker is printed for the instruction at the ++current program counter value. This instruction can appear multiple ++times in the trace and the current position marker will be printed ++every time. To omit the current position marker, specify the ++@code{/p} modifier. ++ ++To better align the printed instructions when the trace contains ++instructions from more than one function, the function name may be ++omitted by specifying the @code{/f} modifier. ++ ++Speculatively executed instructions are prefixed with @samp{?}. This ++feature is not available for all recording formats. ++ ++There are several ways to specify what part of the execution log to ++disassemble: ++ ++@table @code ++@item record instruction-history @var{insn} ++Disassembles ten instructions starting from instruction number ++@var{insn}. ++ ++@item record instruction-history @var{insn}, +/-@var{n} ++Disassembles @var{n} instructions around instruction number ++@var{insn}. If @var{n} is preceded with @code{+}, disassembles ++@var{n} instructions after instruction number @var{insn}. If ++@var{n} is preceded with @code{-}, disassembles @var{n} ++instructions before instruction number @var{insn}. ++ ++@item record instruction-history ++Disassembles ten more instructions after the last disassembly. ++ ++@item record instruction-history - ++Disassembles ten more instructions before the last disassembly. ++ ++@item record instruction-history @var{begin}, @var{end} ++Disassembles instructions beginning with instruction number ++@var{begin} until instruction number @var{end}. The instruction ++number @var{end} is included. ++@end table ++ ++This command may not be available for all recording methods. ++ ++@kindex set record ++@item set record instruction-history-size @var{size} ++@itemx set record instruction-history-size unlimited ++Define how many instructions to disassemble in the @code{record ++instruction-history} command. The default value is 10. ++A @var{size} of @code{unlimited} means unlimited instructions. ++ ++@kindex show record ++@item show record instruction-history-size ++Show how many instructions to disassemble in the @code{record ++instruction-history} command. ++ ++@kindex record function-call-history ++@kindex rec function-call-history ++@item record function-call-history ++Prints the execution history at function granularity. It prints one ++line for each sequence of instructions that belong to the same ++function giving the name of that function, the source lines ++for this instruction sequence (if the @code{/l} modifier is ++specified), and the instructions numbers that form the sequence (if ++the @code{/i} modifier is specified). The function names are indented ++to reflect the call stack depth if the @code{/c} modifier is ++specified. The @code{/l}, @code{/i}, and @code{/c} modifiers can be ++given together. ++ ++@smallexample ++(@value{GDBP}) @b{list 1, 10} ++1 void foo (void) ++2 @{ ++3 @} ++4 ++5 void bar (void) ++6 @{ ++7 ... ++8 foo (); ++9 ... ++10 @} ++(@value{GDBP}) @b{record function-call-history /ilc} ++1 bar inst 1,4 at foo.c:6,8 ++2 foo inst 5,10 at foo.c:2,3 ++3 bar inst 11,13 at foo.c:9,10 ++@end smallexample ++ ++By default, ten lines are printed. This can be changed using the ++@code{set record function-call-history-size} command. Functions are ++printed in execution order. There are several ways to specify what ++to print: ++ ++@table @code ++@item record function-call-history @var{func} ++Prints ten functions starting from function number @var{func}. ++ ++@item record function-call-history @var{func}, +/-@var{n} ++Prints @var{n} functions around function number @var{func}. If ++@var{n} is preceded with @code{+}, prints @var{n} functions after ++function number @var{func}. If @var{n} is preceded with @code{-}, ++prints @var{n} functions before function number @var{func}. ++ ++@item record function-call-history ++Prints ten more functions after the last ten-line print. ++ ++@item record function-call-history - ++Prints ten more functions before the last ten-line print. ++ ++@item record function-call-history @var{begin}, @var{end} ++Prints functions beginning with function number @var{begin} until ++function number @var{end}. The function number @var{end} is included. ++@end table ++ ++This command may not be available for all recording methods. ++ ++@item set record function-call-history-size @var{size} ++@itemx set record function-call-history-size unlimited ++Define how many lines to print in the ++@code{record function-call-history} command. The default value is 10. ++A size of @code{unlimited} means unlimited lines. ++ ++@item show record function-call-history-size ++Show how many lines to print in the ++@code{record function-call-history} command. ++@end table ++ ++ ++@node Stack ++@chapter Examining the Stack ++ ++When your program has stopped, the first thing you need to know is where it ++stopped and how it got there. ++ ++@cindex call stack ++Each time your program performs a function call, information about the call ++is generated. ++That information includes the location of the call in your program, ++the arguments of the call, ++and the local variables of the function being called. ++The information is saved in a block of data called a @dfn{stack frame}. ++The stack frames are allocated in a region of memory called the @dfn{call ++stack}. ++ ++When your program stops, the @value{GDBN} commands for examining the ++stack allow you to see all of this information. ++ ++@cindex selected frame ++One of the stack frames is @dfn{selected} by @value{GDBN} and many ++@value{GDBN} commands refer implicitly to the selected frame. In ++particular, whenever you ask @value{GDBN} for the value of a variable in ++your program, the value is found in the selected frame. There are ++special @value{GDBN} commands to select whichever frame you are ++interested in. @xref{Selection, ,Selecting a Frame}. ++ ++When your program stops, @value{GDBN} automatically selects the ++currently executing frame and describes it briefly, similar to the ++@code{frame} command (@pxref{Frame Info, ,Information about a Frame}). ++ ++@menu ++* Frames:: Stack frames ++* Backtrace:: Backtraces ++* Selection:: Selecting a frame ++* Frame Info:: Information on a frame ++* Frame Apply:: Applying a command to several frames ++* Frame Filter Management:: Managing frame filters ++ ++@end menu ++ ++@node Frames ++@section Stack Frames ++ ++@cindex frame, definition ++@cindex stack frame ++The call stack is divided up into contiguous pieces called @dfn{stack ++frames}, or @dfn{frames} for short; each frame is the data associated ++with one call to one function. The frame contains the arguments given ++to the function, the function's local variables, and the address at ++which the function is executing. ++ ++@cindex initial frame ++@cindex outermost frame ++@cindex innermost frame ++When your program is started, the stack has only one frame, that of the ++function @code{main}. This is called the @dfn{initial} frame or the ++@dfn{outermost} frame. Each time a function is called, a new frame is ++made. Each time a function returns, the frame for that function invocation ++is eliminated. If a function is recursive, there can be many frames for ++the same function. The frame for the function in which execution is ++actually occurring is called the @dfn{innermost} frame. This is the most ++recently created of all the stack frames that still exist. ++ ++@cindex frame pointer ++Inside your program, stack frames are identified by their addresses. A ++stack frame consists of many bytes, each of which has its own address; each ++kind of computer has a convention for choosing one byte whose ++address serves as the address of the frame. Usually this address is kept ++in a register called the @dfn{frame pointer register} ++(@pxref{Registers, $fp}) while execution is going on in that frame. ++ ++@cindex frame level ++@cindex frame number ++@value{GDBN} labels each existing stack frame with a @dfn{level}, a ++number that is zero for the innermost frame, one for the frame that ++called it, and so on upward. These level numbers give you a way of ++designating stack frames in @value{GDBN} commands. The terms ++@dfn{frame number} and @dfn{frame level} can be used interchangeably to ++describe this number. ++ ++@c The -fomit-frame-pointer below perennially causes hbox overflow ++@c underflow problems. ++@cindex frameless execution ++Some compilers provide a way to compile functions so that they operate ++without stack frames. (For example, the @value{NGCC} option ++@smallexample ++@samp{-fomit-frame-pointer} ++@end smallexample ++generates functions without a frame.) ++This is occasionally done with heavily used library functions to save ++the frame setup time. @value{GDBN} has limited facilities for dealing ++with these function invocations. If the innermost function invocation ++has no stack frame, @value{GDBN} nevertheless regards it as though ++it had a separate frame, which is numbered zero as usual, allowing ++correct tracing of the function call chain. However, @value{GDBN} has ++no provision for frameless functions elsewhere in the stack. ++ ++@node Backtrace ++@section Backtraces ++ ++@cindex traceback ++@cindex call stack traces ++A backtrace is a summary of how your program got where it is. It shows one ++line per frame, for many frames, starting with the currently executing ++frame (frame zero), followed by its caller (frame one), and on up the ++stack. ++ ++@anchor{backtrace-command} ++@kindex backtrace ++@kindex bt @r{(@code{backtrace})} ++To print a backtrace of the entire stack, use the @code{backtrace} ++command, or its alias @code{bt}. This command will print one line per ++frame for frames in the stack. By default, all stack frames are ++printed. You can stop the backtrace at any time by typing the system ++interrupt character, normally @kbd{Ctrl-c}. ++ ++@table @code ++@item backtrace [@var{option}]@dots{} [@var{qualifier}]@dots{} [@var{count}] ++@itemx bt [@var{option}]@dots{} [@var{qualifier}]@dots{} [@var{count}] ++Print the backtrace of the entire stack. ++ ++The optional @var{count} can be one of the following: ++ ++@table @code ++@item @var{n} ++@itemx @var{n} ++Print only the innermost @var{n} frames, where @var{n} is a positive ++number. ++ ++@item -@var{n} ++@itemx -@var{n} ++Print only the outermost @var{n} frames, where @var{n} is a positive ++number. ++@end table ++ ++Options: ++ ++@table @code ++@item -full ++Print the values of the local variables also. This can be combined ++with the optional @var{count} to limit the number of frames shown. ++ ++@item -no-filters ++Do not run Python frame filters on this backtrace. @xref{Frame ++Filter API}, for more information. Additionally use @ref{disable ++frame-filter all} to turn off all frame filters. This is only ++relevant when @value{GDBN} has been configured with @code{Python} ++support. ++ ++@item -hide ++A Python frame filter might decide to ``elide'' some frames. Normally ++such elided frames are still printed, but they are indented relative ++to the filtered frames that cause them to be elided. The @code{-hide} ++option causes elided frames to not be printed at all. ++@end table ++ ++The @code{backtrace} command also supports a number of options that ++allow overriding relevant global print settings as set by @code{set ++backtrace} and @code{set print} subcommands: ++ ++@table @code ++@item -past-main [@code{on}|@code{off}] ++Set whether backtraces should continue past @code{main}. Related setting: ++@ref{set backtrace past-main}. ++ ++@item -past-entry [@code{on}|@code{off}] ++Set whether backtraces should continue past the entry point of a program. ++Related setting: @ref{set backtrace past-entry}. ++ ++@item -entry-values @code{no}|@code{only}|@code{preferred}|@code{if-needed}|@code{both}|@code{compact}|@code{default} ++Set printing of function arguments at function entry. ++Related setting: @ref{set print entry-values}. ++ ++@item -frame-arguments @code{all}|@code{scalars}|@code{none} ++Set printing of non-scalar frame arguments. ++Related setting: @ref{set print frame-arguments}. ++ ++@item -raw-frame-arguments [@code{on}|@code{off}] ++Set whether to print frame arguments in raw form. ++Related setting: @ref{set print raw-frame-arguments}. ++ ++@item -frame-info @code{auto}|@code{source-line}|@code{location}|@code{source-and-location}|@code{location-and-address}|@code{short-location} ++Set printing of frame information. ++Related setting: @ref{set print frame-info}. ++@end table ++ ++The optional @var{qualifier} is maintained for backward compatibility. ++It can be one of the following: ++ ++@table @code ++@item full ++Equivalent to the @code{-full} option. ++ ++@item no-filters ++Equivalent to the @code{-no-filters} option. ++ ++@item hide ++Equivalent to the @code{-hide} option. ++@end table ++ ++@end table ++ ++@kindex where ++@kindex info stack ++The names @code{where} and @code{info stack} (abbreviated @code{info s}) ++are additional aliases for @code{backtrace}. ++ ++@cindex multiple threads, backtrace ++In a multi-threaded program, @value{GDBN} by default shows the ++backtrace only for the current thread. To display the backtrace for ++several or all of the threads, use the command @code{thread apply} ++(@pxref{Threads, thread apply}). For example, if you type @kbd{thread ++apply all backtrace}, @value{GDBN} will display the backtrace for all ++the threads; this is handy when you debug a core dump of a ++multi-threaded program. ++ ++Each line in the backtrace shows the frame number and the function name. ++The program counter value is also shown---unless you use @code{set ++print address off}. The backtrace also shows the source file name and ++line number, as well as the arguments to the function. The program ++counter value is omitted if it is at the beginning of the code for that ++line number. ++ ++Here is an example of a backtrace. It was made with the command ++@samp{bt 3}, so it shows the innermost three frames. ++ ++@smallexample ++@group ++#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) ++ at builtin.c:993 ++#1 0x6e38 in expand_macro (sym=0x2b600, data=...) at macro.c:242 ++#2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08) ++ at macro.c:71 ++(More stack frames follow...) ++@end group ++@end smallexample ++ ++@noindent ++The display for frame zero does not begin with a program counter ++value, indicating that your program has stopped at the beginning of the ++code for line @code{993} of @code{builtin.c}. ++ ++@noindent ++The value of parameter @code{data} in frame 1 has been replaced by ++@code{@dots{}}. By default, @value{GDBN} prints the value of a parameter ++only if it is a scalar (integer, pointer, enumeration, etc). See command ++@kbd{set print frame-arguments} in @ref{Print Settings} for more details ++on how to configure the way function parameter values are printed. ++The command @kbd{set print frame-info} (@pxref{Print Settings}) controls ++what frame information is printed. ++ ++@cindex optimized out, in backtrace ++@cindex function call arguments, optimized out ++If your program was compiled with optimizations, some compilers will ++optimize away arguments passed to functions if those arguments are ++never used after the call. Such optimizations generate code that ++passes arguments through registers, but doesn't store those arguments ++in the stack frame. @value{GDBN} has no way of displaying such ++arguments in stack frames other than the innermost one. Here's what ++such a backtrace might look like: ++ ++@smallexample ++@group ++#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) ++ at builtin.c:993 ++#1 0x6e38 in expand_macro (sym=) at macro.c:242 ++#2 0x6840 in expand_token (obs=0x0, t=, td=0xf7fffb08) ++ at macro.c:71 ++(More stack frames follow...) ++@end group ++@end smallexample ++ ++@noindent ++The values of arguments that were not saved in their stack frames are ++shown as @samp{}. ++ ++If you need to display the values of such optimized-out arguments, ++either deduce that from other variables whose values depend on the one ++you are interested in, or recompile without optimizations. ++ ++@cindex backtrace beyond @code{main} function ++@cindex program entry point ++@cindex startup code, and backtrace ++Most programs have a standard user entry point---a place where system ++libraries and startup code transition into user code. For C this is ++@code{main}@footnote{ ++Note that embedded programs (the so-called ``free-standing'' ++environment) are not required to have a @code{main} function as the ++entry point. They could even have multiple entry points.}. ++When @value{GDBN} finds the entry function in a backtrace ++it will terminate the backtrace, to avoid tracing into highly ++system-specific (and generally uninteresting) code. ++ ++If you need to examine the startup code, or limit the number of levels ++in a backtrace, you can change this behavior: ++ ++@table @code ++@item set backtrace past-main ++@itemx set backtrace past-main on ++@anchor{set backtrace past-main} ++@kindex set backtrace ++Backtraces will continue past the user entry point. ++ ++@item set backtrace past-main off ++Backtraces will stop when they encounter the user entry point. This is the ++default. ++ ++@item show backtrace past-main ++@kindex show backtrace ++Display the current user entry point backtrace policy. ++ ++@item set backtrace past-entry ++@itemx set backtrace past-entry on ++@anchor{set backtrace past-entry} ++Backtraces will continue past the internal entry point of an application. ++This entry point is encoded by the linker when the application is built, ++and is likely before the user entry point @code{main} (or equivalent) is called. ++ ++@item set backtrace past-entry off ++Backtraces will stop when they encounter the internal entry point of an ++application. This is the default. ++ ++@item show backtrace past-entry ++Display the current internal entry point backtrace policy. ++ ++@item set backtrace limit @var{n} ++@itemx set backtrace limit 0 ++@itemx set backtrace limit unlimited ++@anchor{set backtrace limit} ++@cindex backtrace limit ++Limit the backtrace to @var{n} levels. A value of @code{unlimited} ++or zero means unlimited levels. ++ ++@item show backtrace limit ++Display the current limit on backtrace levels. ++@end table ++ ++You can control how file names are displayed. ++ ++@table @code ++@item set filename-display ++@itemx set filename-display relative ++@cindex filename-display ++Display file names relative to the compilation directory. This is the default. ++ ++@item set filename-display basename ++Display only basename of a filename. ++ ++@item set filename-display absolute ++Display an absolute filename. ++ ++@item show filename-display ++Show the current way to display filenames. ++@end table ++ ++@node Selection ++@section Selecting a Frame ++ ++Most commands for examining the stack and other data in your program work on ++whichever stack frame is selected at the moment. Here are the commands for ++selecting a stack frame; all of them finish by printing a brief description ++of the stack frame just selected. ++ ++@table @code ++@kindex frame@r{, selecting} ++@kindex f @r{(@code{frame})} ++@item frame @r{[} @var{frame-selection-spec} @r{]} ++@item f @r{[} @var{frame-selection-spec} @r{]} ++The @command{frame} command allows different stack frames to be ++selected. The @var{frame-selection-spec} can be any of the following: ++ ++@table @code ++@kindex frame level ++@item @var{num} ++@item level @var{num} ++Select frame level @var{num}. Recall that frame zero is the innermost ++(currently executing) frame, frame one is the frame that called the ++innermost one, and so on. The highest level frame is usually the one ++for @code{main}. ++ ++As this is the most common method of navigating the frame stack, the ++string @command{level} can be omitted. For example, the following two ++commands are equivalent: ++ ++@smallexample ++(@value{GDBP}) frame 3 ++(@value{GDBP}) frame level 3 ++@end smallexample ++ ++@kindex frame address ++@item address @var{stack-address} ++Select the frame with stack address @var{stack-address}. The ++@var{stack-address} for a frame can be seen in the output of ++@command{info frame}, for example: ++ ++@smallexample ++(gdb) info frame ++Stack level 1, frame at 0x7fffffffda30: ++ rip = 0x40066d in b (amd64-entry-value.cc:59); saved rip 0x4004c5 ++ tail call frame, caller of frame at 0x7fffffffda30 ++ source language c++. ++ Arglist at unknown address. ++ Locals at unknown address, Previous frame's sp is 0x7fffffffda30 ++@end smallexample ++ ++The @var{stack-address} for this frame is @code{0x7fffffffda30} as ++indicated by the line: ++ ++@smallexample ++Stack level 1, frame at 0x7fffffffda30: ++@end smallexample ++ ++@kindex frame function ++@item function @var{function-name} ++Select the stack frame for function @var{function-name}. If there are ++multiple stack frames for function @var{function-name} then the inner ++most stack frame is selected. ++ ++@kindex frame view ++@item view @var{stack-address} @r{[} @var{pc-addr} @r{]} ++View a frame that is not part of @value{GDBN}'s backtrace. The frame ++viewed has stack address @var{stack-addr}, and optionally, a program ++counter address of @var{pc-addr}. ++ ++This is useful mainly if the chaining of stack frames has been ++damaged by a bug, making it impossible for @value{GDBN} to assign ++numbers properly to all frames. In addition, this can be useful ++when your program has multiple stacks and switches between them. ++ ++When viewing a frame outside the current backtrace using ++@command{frame view} then you can always return to the original ++stack using one of the previous stack frame selection instructions, ++for example @command{frame level 0}. ++ ++@end table ++ ++@kindex up ++@item up @var{n} ++Move @var{n} frames up the stack; @var{n} defaults to 1. For positive ++numbers @var{n}, this advances toward the outermost frame, to higher ++frame numbers, to frames that have existed longer. ++ ++@kindex down ++@kindex do @r{(@code{down})} ++@item down @var{n} ++Move @var{n} frames down the stack; @var{n} defaults to 1. For ++positive numbers @var{n}, this advances toward the innermost frame, to ++lower frame numbers, to frames that were created more recently. ++You may abbreviate @code{down} as @code{do}. ++@end table ++ ++All of these commands end by printing two lines of output describing the ++frame. The first line shows the frame number, the function name, the ++arguments, and the source file and line number of execution in that ++frame. The second line shows the text of that source line. ++ ++@need 1000 ++For example: ++ ++@smallexample ++@group ++(@value{GDBP}) up ++#1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc) ++ at env.c:10 ++10 read_input_file (argv[i]); ++@end group ++@end smallexample ++ ++After such a printout, the @code{list} command with no arguments ++prints ten lines centered on the point of execution in the frame. ++You can also edit the program at the point of execution with your favorite ++editing program by typing @code{edit}. ++@xref{List, ,Printing Source Lines}, ++for details. ++ ++@table @code ++@kindex select-frame ++@item select-frame @r{[} @var{frame-selection-spec} @r{]} ++The @code{select-frame} command is a variant of @code{frame} that does ++not display the new frame after selecting it. This command is ++intended primarily for use in @value{GDBN} command scripts, where the ++output might be unnecessary and distracting. The ++@var{frame-selection-spec} is as for the @command{frame} command ++described in @ref{Selection, ,Selecting a Frame}. ++ ++@kindex down-silently ++@kindex up-silently ++@item up-silently @var{n} ++@itemx down-silently @var{n} ++These two commands are variants of @code{up} and @code{down}, ++respectively; they differ in that they do their work silently, without ++causing display of the new frame. They are intended primarily for use ++in @value{GDBN} command scripts, where the output might be unnecessary and ++distracting. ++@end table ++ ++@node Frame Info ++@section Information About a Frame ++ ++There are several other commands to print information about the selected ++stack frame. ++ ++@table @code ++@item frame ++@itemx f ++When used without any argument, this command does not change which ++frame is selected, but prints a brief description of the currently ++selected stack frame. It can be abbreviated @code{f}. With an ++argument, this command is used to select a stack frame. ++@xref{Selection, ,Selecting a Frame}. ++ ++@kindex info frame ++@kindex info f @r{(@code{info frame})} ++@item info frame ++@itemx info f ++This command prints a verbose description of the selected stack frame, ++including: ++ ++@itemize @bullet ++@item ++the address of the frame ++@item ++the address of the next frame down (called by this frame) ++@item ++the address of the next frame up (caller of this frame) ++@item ++the language in which the source code corresponding to this frame is written ++@item ++the address of the frame's arguments ++@item ++the address of the frame's local variables ++@item ++the program counter saved in it (the address of execution in the caller frame) ++@item ++which registers were saved in the frame ++@end itemize ++ ++@noindent The verbose description is useful when ++something has gone wrong that has made the stack format fail to fit ++the usual conventions. ++ ++@item info frame @r{[} @var{frame-selection-spec} @r{]} ++@itemx info f @r{[} @var{frame-selection-spec} @r{]} ++Print a verbose description of the frame selected by ++@var{frame-selection-spec}. The @var{frame-selection-spec} is the ++same as for the @command{frame} command (@pxref{Selection, ,Selecting ++a Frame}). The selected frame remains unchanged by this command. ++ ++@kindex info args ++@item info args [-q] ++Print the arguments of the selected frame, each on a separate line. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no argument ++have been printed. ++ ++@item info args [-q] [-t @var{type_regexp}] [@var{regexp}] ++Like @kbd{info args}, but only print the arguments selected ++with the provided regexp(s). ++ ++If @var{regexp} is provided, print only the arguments whose names ++match the regular expression @var{regexp}. ++ ++If @var{type_regexp} is provided, print only the arguments whose ++types, as printed by the @code{whatis} command, match ++the regular expression @var{type_regexp}. ++If @var{type_regexp} contains space(s), it should be enclosed in ++quote characters. If needed, use backslash to escape the meaning ++of special characters or quotes. ++ ++If both @var{regexp} and @var{type_regexp} are provided, an argument ++is printed only if its name matches @var{regexp} and its type matches ++@var{type_regexp}. ++ ++@item info locals [-q] ++@kindex info locals ++Print the local variables of the selected frame, each on a separate ++line. These are all variables (declared either static or automatic) ++accessible at the point of execution of the selected frame. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no local variables ++have been printed. ++ ++@item info locals [-q] [-t @var{type_regexp}] [@var{regexp}] ++Like @kbd{info locals}, but only print the local variables selected ++with the provided regexp(s). ++ ++If @var{regexp} is provided, print only the local variables whose names ++match the regular expression @var{regexp}. ++ ++If @var{type_regexp} is provided, print only the local variables whose ++types, as printed by the @code{whatis} command, match ++the regular expression @var{type_regexp}. ++If @var{type_regexp} contains space(s), it should be enclosed in ++quote characters. If needed, use backslash to escape the meaning ++of special characters or quotes. ++ ++If both @var{regexp} and @var{type_regexp} are provided, a local variable ++is printed only if its name matches @var{regexp} and its type matches ++@var{type_regexp}. ++ ++The command @kbd{info locals -q -t @var{type_regexp}} can usefully be ++combined with the commands @kbd{frame apply} and @kbd{thread apply}. ++For example, your program might use Resource Acquisition Is ++Initialization types (RAII) such as @code{lock_something_t}: each ++local variable of type @code{lock_something_t} automatically places a ++lock that is destroyed when the variable goes out of scope. You can ++then list all acquired locks in your program by doing ++@smallexample ++thread apply all -s frame apply all -s info locals -q -t lock_something_t ++@end smallexample ++@noindent ++or the equivalent shorter form ++@smallexample ++tfaas i lo -q -t lock_something_t ++@end smallexample ++ ++@end table ++ ++@node Frame Apply ++@section Applying a Command to Several Frames. ++@kindex frame apply ++@cindex apply command to several frames ++@table @code ++@item frame apply [all | @var{count} | @var{-count} | level @var{level}@dots{}] [@var{option}]@dots{} @var{command} ++The @code{frame apply} command allows you to apply the named ++@var{command} to one or more frames. ++ ++@table @code ++@item @code{all} ++Specify @code{all} to apply @var{command} to all frames. ++ ++@item @var{count} ++Use @var{count} to apply @var{command} to the innermost @var{count} ++frames, where @var{count} is a positive number. ++ ++@item @var{-count} ++Use @var{-count} to apply @var{command} to the outermost @var{count} ++frames, where @var{count} is a positive number. ++ ++@item @code{level} ++Use @code{level} to apply @var{command} to the set of frames identified ++by the @var{level} list. @var{level} is a frame level or a range of frame ++levels as @var{level1}-@var{level2}. The frame level is the number shown ++in the first field of the @samp{backtrace} command output. ++E.g., @samp{2-4 6-8 3} indicates to apply @var{command} for the frames ++at levels 2, 3, 4, 6, 7, 8, and then again on frame at level 3. ++ ++@end table ++ ++Note that the frames on which @code{frame apply} applies a command are ++also influenced by the @code{set backtrace} settings such as @code{set ++backtrace past-main} and @code{set backtrace limit N}. ++@xref{Backtrace,,Backtraces}. ++ ++The @code{frame apply} command also supports a number of options that ++allow overriding relevant @code{set backtrace} settings: ++ ++@table @code ++@item -past-main [@code{on}|@code{off}] ++Whether backtraces should continue past @code{main}. ++Related setting: @ref{set backtrace past-main}. ++ ++@item -past-entry [@code{on}|@code{off}] ++Whether backtraces should continue past the entry point of a program. ++Related setting: @ref{set backtrace past-entry}. ++@end table ++ ++By default, @value{GDBN} displays some frame information before the ++output produced by @var{command}, and an error raised during the ++execution of a @var{command} will abort @code{frame apply}. The ++following options can be used to fine-tune these behaviors: ++ ++@table @code ++@item -c ++The flag @code{-c}, which stands for @samp{continue}, causes any ++errors in @var{command} to be displayed, and the execution of ++@code{frame apply} then continues. ++@item -s ++The flag @code{-s}, which stands for @samp{silent}, causes any errors ++or empty output produced by a @var{command} to be silently ignored. ++That is, the execution continues, but the frame information and errors ++are not printed. ++@item -q ++The flag @code{-q} (@samp{quiet}) disables printing the frame ++information. ++@end table ++ ++The following example shows how the flags @code{-c} and @code{-s} are ++working when applying the command @code{p j} to all frames, where ++variable @code{j} can only be successfully printed in the outermost ++@code{#1 main} frame. ++ ++@smallexample ++@group ++(gdb) frame apply all p j ++#0 some_function (i=5) at fun.c:4 ++No symbol "j" in current context. ++(gdb) frame apply all -c p j ++#0 some_function (i=5) at fun.c:4 ++No symbol "j" in current context. ++#1 0x565555fb in main (argc=1, argv=0xffffd2c4) at fun.c:11 ++$1 = 5 ++(gdb) frame apply all -s p j ++#1 0x565555fb in main (argc=1, argv=0xffffd2c4) at fun.c:11 ++$2 = 5 ++(gdb) ++@end group ++@end smallexample ++ ++By default, @samp{frame apply}, prints the frame location ++information before the command output: ++ ++@smallexample ++@group ++(gdb) frame apply all p $sp ++#0 some_function (i=5) at fun.c:4 ++$4 = (void *) 0xffffd1e0 ++#1 0x565555fb in main (argc=1, argv=0xffffd2c4) at fun.c:11 ++$5 = (void *) 0xffffd1f0 ++(gdb) ++@end group ++@end smallexample ++ ++If the flag @code{-q} is given, no frame information is printed: ++@smallexample ++@group ++(gdb) frame apply all -q p $sp ++$12 = (void *) 0xffffd1e0 ++$13 = (void *) 0xffffd1f0 ++(gdb) ++@end group ++@end smallexample ++ ++@end table ++ ++@table @code ++ ++@kindex faas ++@cindex apply a command to all frames (ignoring errors and empty output) ++@item faas @var{command} ++Shortcut for @code{frame apply all -s @var{command}}. ++Applies @var{command} on all frames, ignoring errors and empty output. ++ ++It can for example be used to print a local variable or a function ++argument without knowing the frame where this variable or argument ++is, using: ++@smallexample ++(@value{GDBP}) faas p some_local_var_i_do_not_remember_where_it_is ++@end smallexample ++ ++The @code{faas} command accepts the same options as the @code{frame ++apply} command. @xref{Frame Apply,,frame apply}. ++ ++Note that the command @code{tfaas @var{command}} applies @var{command} ++on all frames of all threads. See @xref{Threads,,Threads}. ++@end table ++ ++ ++@node Frame Filter Management ++@section Management of Frame Filters. ++@cindex managing frame filters ++ ++Frame filters are Python based utilities to manage and decorate the ++output of frames. @xref{Frame Filter API}, for further information. ++ ++Managing frame filters is performed by several commands available ++within @value{GDBN}, detailed here. ++ ++@table @code ++@kindex info frame-filter ++@item info frame-filter ++Print a list of installed frame filters from all dictionaries, showing ++their name, priority and enabled status. ++ ++@kindex disable frame-filter ++@anchor{disable frame-filter all} ++@item disable frame-filter @var{filter-dictionary} @var{filter-name} ++Disable a frame filter in the dictionary matching ++@var{filter-dictionary} and @var{filter-name}. The ++@var{filter-dictionary} may be @code{all}, @code{global}, ++@code{progspace}, or the name of the object file where the frame filter ++dictionary resides. When @code{all} is specified, all frame filters ++across all dictionaries are disabled. The @var{filter-name} is the name ++of the frame filter and is used when @code{all} is not the option for ++@var{filter-dictionary}. A disabled frame-filter is not deleted, it ++may be enabled again later. ++ ++@kindex enable frame-filter ++@item enable frame-filter @var{filter-dictionary} @var{filter-name} ++Enable a frame filter in the dictionary matching ++@var{filter-dictionary} and @var{filter-name}. The ++@var{filter-dictionary} may be @code{all}, @code{global}, ++@code{progspace} or the name of the object file where the frame filter ++dictionary resides. When @code{all} is specified, all frame filters across ++all dictionaries are enabled. The @var{filter-name} is the name of the frame ++filter and is used when @code{all} is not the option for ++@var{filter-dictionary}. ++ ++Example: ++ ++@smallexample ++(gdb) info frame-filter ++ ++global frame-filters: ++ Priority Enabled Name ++ 1000 No PrimaryFunctionFilter ++ 100 Yes Reverse ++ ++progspace /build/test frame-filters: ++ Priority Enabled Name ++ 100 Yes ProgspaceFilter ++ ++objfile /build/test frame-filters: ++ Priority Enabled Name ++ 999 Yes BuildProgramFilter ++ ++(gdb) disable frame-filter /build/test BuildProgramFilter ++(gdb) info frame-filter ++ ++global frame-filters: ++ Priority Enabled Name ++ 1000 No PrimaryFunctionFilter ++ 100 Yes Reverse ++ ++progspace /build/test frame-filters: ++ Priority Enabled Name ++ 100 Yes ProgspaceFilter ++ ++objfile /build/test frame-filters: ++ Priority Enabled Name ++ 999 No BuildProgramFilter ++ ++(gdb) enable frame-filter global PrimaryFunctionFilter ++(gdb) info frame-filter ++ ++global frame-filters: ++ Priority Enabled Name ++ 1000 Yes PrimaryFunctionFilter ++ 100 Yes Reverse ++ ++progspace /build/test frame-filters: ++ Priority Enabled Name ++ 100 Yes ProgspaceFilter ++ ++objfile /build/test frame-filters: ++ Priority Enabled Name ++ 999 No BuildProgramFilter ++@end smallexample ++ ++@kindex set frame-filter priority ++@item set frame-filter priority @var{filter-dictionary} @var{filter-name} @var{priority} ++Set the @var{priority} of a frame filter in the dictionary matching ++@var{filter-dictionary}, and the frame filter name matching ++@var{filter-name}. The @var{filter-dictionary} may be @code{global}, ++@code{progspace} or the name of the object file where the frame filter ++dictionary resides. The @var{priority} is an integer. ++ ++@kindex show frame-filter priority ++@item show frame-filter priority @var{filter-dictionary} @var{filter-name} ++Show the @var{priority} of a frame filter in the dictionary matching ++@var{filter-dictionary}, and the frame filter name matching ++@var{filter-name}. The @var{filter-dictionary} may be @code{global}, ++@code{progspace} or the name of the object file where the frame filter ++dictionary resides. ++ ++Example: ++ ++@smallexample ++(gdb) info frame-filter ++ ++global frame-filters: ++ Priority Enabled Name ++ 1000 Yes PrimaryFunctionFilter ++ 100 Yes Reverse ++ ++progspace /build/test frame-filters: ++ Priority Enabled Name ++ 100 Yes ProgspaceFilter ++ ++objfile /build/test frame-filters: ++ Priority Enabled Name ++ 999 No BuildProgramFilter ++ ++(gdb) set frame-filter priority global Reverse 50 ++(gdb) info frame-filter ++ ++global frame-filters: ++ Priority Enabled Name ++ 1000 Yes PrimaryFunctionFilter ++ 50 Yes Reverse ++ ++progspace /build/test frame-filters: ++ Priority Enabled Name ++ 100 Yes ProgspaceFilter ++ ++objfile /build/test frame-filters: ++ Priority Enabled Name ++ 999 No BuildProgramFilter ++@end smallexample ++@end table ++ ++@node Source ++@chapter Examining Source Files ++ ++@value{GDBN} can print parts of your program's source, since the debugging ++information recorded in the program tells @value{GDBN} what source files were ++used to build it. When your program stops, @value{GDBN} spontaneously prints ++the line where it stopped. Likewise, when you select a stack frame ++(@pxref{Selection, ,Selecting a Frame}), @value{GDBN} prints the line where ++execution in that frame has stopped. You can print other portions of ++source files by explicit command. ++ ++If you use @value{GDBN} through its @sc{gnu} Emacs interface, you may ++prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using ++@value{GDBN} under @sc{gnu} Emacs}. ++ ++@menu ++* List:: Printing source lines ++* Specify Location:: How to specify code locations ++* Edit:: Editing source files ++* Search:: Searching source files ++* Source Path:: Specifying source directories ++* Machine Code:: Source and machine code ++@end menu ++ ++@node List ++@section Printing Source Lines ++ ++@kindex list ++@kindex l @r{(@code{list})} ++To print lines from a source file, use the @code{list} command ++(abbreviated @code{l}). By default, ten lines are printed. ++There are several ways to specify what part of the file you want to ++print; see @ref{Specify Location}, for the full list. ++ ++Here are the forms of the @code{list} command most commonly used: ++ ++@table @code ++@item list @var{linenum} ++Print lines centered around line number @var{linenum} in the ++current source file. ++ ++@item list @var{function} ++Print lines centered around the beginning of function ++@var{function}. ++ ++@item list ++Print more lines. If the last lines printed were printed with a ++@code{list} command, this prints lines following the last lines ++printed; however, if the last line printed was a solitary line printed ++as part of displaying a stack frame (@pxref{Stack, ,Examining the ++Stack}), this prints lines centered around that line. ++ ++@item list - ++Print lines just before the lines last printed. ++@end table ++ ++@cindex @code{list}, how many lines to display ++By default, @value{GDBN} prints ten source lines with any of these forms of ++the @code{list} command. You can change this using @code{set listsize}: ++ ++@table @code ++@kindex set listsize ++@item set listsize @var{count} ++@itemx set listsize unlimited ++Make the @code{list} command display @var{count} source lines (unless ++the @code{list} argument explicitly specifies some other number). ++Setting @var{count} to @code{unlimited} or 0 means there's no limit. ++ ++@kindex show listsize ++@item show listsize ++Display the number of lines that @code{list} prints. ++@end table ++ ++Repeating a @code{list} command with @key{RET} discards the argument, ++so it is equivalent to typing just @code{list}. This is more useful ++than listing the same lines again. An exception is made for an ++argument of @samp{-}; that argument is preserved in repetition so that ++each repetition moves up in the source file. ++ ++In general, the @code{list} command expects you to supply zero, one or two ++@dfn{locations}. Locations specify source lines; there are several ways ++of writing them (@pxref{Specify Location}), but the effect is always ++to specify some source line. ++ ++Here is a complete description of the possible arguments for @code{list}: ++ ++@table @code ++@item list @var{location} ++Print lines centered around the line specified by @var{location}. ++ ++@item list @var{first},@var{last} ++Print lines from @var{first} to @var{last}. Both arguments are ++locations. When a @code{list} command has two locations, and the ++source file of the second location is omitted, this refers to ++the same source file as the first location. ++ ++@item list ,@var{last} ++Print lines ending with @var{last}. ++ ++@item list @var{first}, ++Print lines starting with @var{first}. ++ ++@item list + ++Print lines just after the lines last printed. ++ ++@item list - ++Print lines just before the lines last printed. ++ ++@item list ++As described in the preceding table. ++@end table ++ ++@node Specify Location ++@section Specifying a Location ++@cindex specifying location ++@cindex location ++@cindex source location ++ ++@menu ++* Linespec Locations:: Linespec locations ++* Explicit Locations:: Explicit locations ++* Address Locations:: Address locations ++@end menu ++ ++Several @value{GDBN} commands accept arguments that specify a location ++of your program's code. Since @value{GDBN} is a source-level ++debugger, a location usually specifies some line in the source code. ++Locations may be specified using three different formats: ++linespec locations, explicit locations, or address locations. ++ ++@node Linespec Locations ++@subsection Linespec Locations ++@cindex linespec locations ++ ++A @dfn{linespec} is a colon-separated list of source location parameters such ++as file name, function name, etc. Here are all the different ways of ++specifying a linespec: ++ ++@table @code ++@item @var{linenum} ++Specifies the line number @var{linenum} of the current source file. ++ ++@item -@var{offset} ++@itemx +@var{offset} ++Specifies the line @var{offset} lines before or after the @dfn{current ++line}. For the @code{list} command, the current line is the last one ++printed; for the breakpoint commands, this is the line at which ++execution stopped in the currently selected @dfn{stack frame} ++(@pxref{Frames, ,Frames}, for a description of stack frames.) When ++used as the second of the two linespecs in a @code{list} command, ++this specifies the line @var{offset} lines up or down from the first ++linespec. ++ ++@item @var{filename}:@var{linenum} ++Specifies the line @var{linenum} in the source file @var{filename}. ++If @var{filename} is a relative file name, then it will match any ++source file name with the same trailing components. For example, if ++@var{filename} is @samp{gcc/expr.c}, then it will match source file ++name of @file{/build/trunk/gcc/expr.c}, but not ++@file{/build/trunk/libcpp/expr.c} or @file{/build/trunk/gcc/x-expr.c}. ++ ++@item @var{function} ++Specifies the line that begins the body of the function @var{function}. ++For example, in C, this is the line with the open brace. ++ ++By default, in C@t{++} and Ada, @var{function} is interpreted as ++specifying all functions named @var{function} in all scopes. For ++C@t{++}, this means in all namespaces and classes. For Ada, this ++means in all packages. ++ ++For example, assuming a program with C@t{++} symbols named ++@code{A::B::func} and @code{B::func}, both commands @w{@kbd{break ++func}} and @w{@kbd{break B::func}} set a breakpoint on both symbols. ++ ++Commands that accept a linespec let you override this with the ++@code{-qualified} option. For example, @w{@kbd{break -qualified ++func}} sets a breakpoint on a free-function named @code{func} ignoring ++any C@t{++} class methods and namespace functions called @code{func}. ++ ++@xref{Explicit Locations}. ++ ++@item @var{function}:@var{label} ++Specifies the line where @var{label} appears in @var{function}. ++ ++@item @var{filename}:@var{function} ++Specifies the line that begins the body of the function @var{function} ++in the file @var{filename}. You only need the file name with a ++function name to avoid ambiguity when there are identically named ++functions in different source files. ++ ++@item @var{label} ++Specifies the line at which the label named @var{label} appears ++in the function corresponding to the currently selected stack frame. ++If there is no current selected stack frame (for instance, if the inferior ++is not running), then @value{GDBN} will not search for a label. ++ ++@cindex breakpoint at static probe point ++@item -pstap|-probe-stap @r{[}@var{objfile}:@r{[}@var{provider}:@r{]}@r{]}@var{name} ++The @sc{gnu}/Linux tool @code{SystemTap} provides a way for ++applications to embed static probes. @xref{Static Probe Points}, for more ++information on finding and using static probes. This form of linespec ++specifies the location of such a static probe. ++ ++If @var{objfile} is given, only probes coming from that shared library ++or executable matching @var{objfile} as a regular expression are considered. ++If @var{provider} is given, then only probes from that provider are considered. ++If several probes match the spec, @value{GDBN} will insert a breakpoint at ++each one of those probes. ++@end table ++ ++@node Explicit Locations ++@subsection Explicit Locations ++@cindex explicit locations ++ ++@dfn{Explicit locations} allow the user to directly specify the source ++location's parameters using option-value pairs. ++ ++Explicit locations are useful when several functions, labels, or ++file names have the same name (base name for files) in the program's ++sources. In these cases, explicit locations point to the source ++line you meant more accurately and unambiguously. Also, using ++explicit locations might be faster in large programs. ++ ++For example, the linespec @samp{foo:bar} may refer to a function @code{bar} ++defined in the file named @file{foo} or the label @code{bar} in a function ++named @code{foo}. @value{GDBN} must search either the file system or ++the symbol table to know. ++ ++The list of valid explicit location options is summarized in the ++following table: ++ ++@table @code ++@item -source @var{filename} ++The value specifies the source file name. To differentiate between ++files with the same base name, prepend as many directories as is necessary ++to uniquely identify the desired file, e.g., @file{foo/bar/baz.c}. Otherwise ++@value{GDBN} will use the first file it finds with the given base ++name. This option requires the use of either @code{-function} or @code{-line}. ++ ++@item -function @var{function} ++The value specifies the name of a function. Operations ++on function locations unmodified by other options (such as @code{-label} ++or @code{-line}) refer to the line that begins the body of the function. ++In C, for example, this is the line with the open brace. ++ ++By default, in C@t{++} and Ada, @var{function} is interpreted as ++specifying all functions named @var{function} in all scopes. For ++C@t{++}, this means in all namespaces and classes. For Ada, this ++means in all packages. ++ ++For example, assuming a program with C@t{++} symbols named ++@code{A::B::func} and @code{B::func}, both commands @w{@kbd{break ++-function func}} and @w{@kbd{break -function B::func}} set a ++breakpoint on both symbols. ++ ++You can use the @kbd{-qualified} flag to override this (see below). ++ ++@item -qualified ++ ++This flag makes @value{GDBN} interpret a function name specified with ++@kbd{-function} as a complete fully-qualified name. ++ ++For example, assuming a C@t{++} program with symbols named ++@code{A::B::func} and @code{B::func}, the @w{@kbd{break -qualified ++-function B::func}} command sets a breakpoint on @code{B::func}, only. ++ ++(Note: the @kbd{-qualified} option can precede a linespec as well ++(@pxref{Linespec Locations}), so the particular example above could be ++simplified as @w{@kbd{break -qualified B::func}}.) ++ ++@item -label @var{label} ++The value specifies the name of a label. When the function ++name is not specified, the label is searched in the function of the currently ++selected stack frame. ++ ++@item -line @var{number} ++The value specifies a line offset for the location. The offset may either ++be absolute (@code{-line 3}) or relative (@code{-line +3}), depending on ++the command. When specified without any other options, the line offset is ++relative to the current line. ++@end table ++ ++Explicit location options may be abbreviated by omitting any non-unique ++trailing characters from the option name, e.g., @w{@kbd{break -s main.c -li 3}}. ++ ++@node Address Locations ++@subsection Address Locations ++@cindex address locations ++ ++@dfn{Address locations} indicate a specific program address. They have ++the generalized form *@var{address}. ++ ++For line-oriented commands, such as @code{list} and @code{edit}, this ++specifies a source line that contains @var{address}. For @code{break} and ++other breakpoint-oriented commands, this can be used to set breakpoints in ++parts of your program which do not have debugging information or ++source files. ++ ++Here @var{address} may be any expression valid in the current working ++language (@pxref{Languages, working language}) that specifies a code ++address. In addition, as a convenience, @value{GDBN} extends the ++semantics of expressions used in locations to cover several situations ++that frequently occur during debugging. Here are the various forms ++of @var{address}: ++ ++@table @code ++@item @var{expression} ++Any expression valid in the current working language. ++ ++@item @var{funcaddr} ++An address of a function or procedure derived from its name. In C, ++C@t{++}, Objective-C, Fortran, minimal, and assembly, this is ++simply the function's name @var{function} (and actually a special case ++of a valid expression). In Pascal and Modula-2, this is ++@code{&@var{function}}. In Ada, this is @code{@var{function}'Address} ++(although the Pascal form also works). ++ ++This form specifies the address of the function's first instruction, ++before the stack frame and arguments have been set up. ++ ++@item '@var{filename}':@var{funcaddr} ++Like @var{funcaddr} above, but also specifies the name of the source ++file explicitly. This is useful if the name of the function does not ++specify the function unambiguously, e.g., if there are several ++functions with identical names in different source files. ++@end table ++ ++@node Edit ++@section Editing Source Files ++@cindex editing source files ++ ++@kindex edit ++@kindex e @r{(@code{edit})} ++To edit the lines in a source file, use the @code{edit} command. ++The editing program of your choice ++is invoked with the current line set to ++the active line in the program. ++Alternatively, there are several ways to specify what part of the file you ++want to print if you want to see other parts of the program: ++ ++@table @code ++@item edit @var{location} ++Edit the source file specified by @code{location}. Editing starts at ++that @var{location}, e.g., at the specified source line of the ++specified file. @xref{Specify Location}, for all the possible forms ++of the @var{location} argument; here are the forms of the @code{edit} ++command most commonly used: ++ ++@table @code ++@item edit @var{number} ++Edit the current source file with @var{number} as the active line number. ++ ++@item edit @var{function} ++Edit the file containing @var{function} at the beginning of its definition. ++@end table ++ ++@end table ++ ++@subsection Choosing your Editor ++You can customize @value{GDBN} to use any editor you want ++@footnote{ ++The only restriction is that your editor (say @code{ex}), recognizes the ++following command-line syntax: ++@smallexample ++ex +@var{number} file ++@end smallexample ++The optional numeric value +@var{number} specifies the number of the line in ++the file where to start editing.}. ++By default, it is @file{@value{EDITOR}}, but you can change this ++by setting the environment variable @code{EDITOR} before using ++@value{GDBN}. For example, to configure @value{GDBN} to use the ++@code{vi} editor, you could use these commands with the @code{sh} shell: ++@smallexample ++EDITOR=/usr/bin/vi ++export EDITOR ++gdb @dots{} ++@end smallexample ++or in the @code{csh} shell, ++@smallexample ++setenv EDITOR /usr/bin/vi ++gdb @dots{} ++@end smallexample ++ ++@node Search ++@section Searching Source Files ++@cindex searching source files ++ ++There are two commands for searching through the current source file for a ++regular expression. ++ ++@table @code ++@kindex search ++@kindex forward-search ++@kindex fo @r{(@code{forward-search})} ++@item forward-search @var{regexp} ++@itemx search @var{regexp} ++The command @samp{forward-search @var{regexp}} checks each line, ++starting with the one following the last line listed, for a match for ++@var{regexp}. It lists the line that is found. You can use the ++synonym @samp{search @var{regexp}} or abbreviate the command name as ++@code{fo}. ++ ++@kindex reverse-search ++@item reverse-search @var{regexp} ++The command @samp{reverse-search @var{regexp}} checks each line, starting ++with the one before the last line listed and going backward, for a match ++for @var{regexp}. It lists the line that is found. You can abbreviate ++this command as @code{rev}. ++@end table ++ ++@node Source Path ++@section Specifying Source Directories ++ ++@cindex source path ++@cindex directories for source files ++Executable programs sometimes do not record the directories of the source ++files from which they were compiled, just the names. Even when they do, ++the directories could be moved between the compilation and your debugging ++session. @value{GDBN} has a list of directories to search for source files; ++this is called the @dfn{source path}. Each time @value{GDBN} wants a source file, ++it tries all the directories in the list, in the order they are present ++in the list, until it finds a file with the desired name. ++ ++For example, suppose an executable references the file ++@file{/usr/src/foo-1.0/lib/foo.c}, does not record a compilation ++directory, and the @dfn{source path} is @file{/mnt/cross}. ++@value{GDBN} would look for the source file in the following ++locations: ++ ++@enumerate ++ ++@item @file{/usr/src/foo-1.0/lib/foo.c} ++@item @file{/mnt/cross/usr/src/foo-1.0/lib/foo.c} ++@item @file{/mnt/cross/foo.c} ++ ++@end enumerate ++ ++If the source file is not present at any of the above locations then ++an error is printed. @value{GDBN} does not look up the parts of the ++source file name, such as @file{/mnt/cross/src/foo-1.0/lib/foo.c}. ++Likewise, the subdirectories of the source path are not searched: if ++the source path is @file{/mnt/cross}, and the binary refers to ++@file{foo.c}, @value{GDBN} would not find it under ++@file{/mnt/cross/usr/src/foo-1.0/lib}. ++ ++Plain file names, relative file names with leading directories, file ++names containing dots, etc.@: are all treated as described above, ++except that non-absolute file names are not looked up literally. If ++the @dfn{source path} is @file{/mnt/cross}, the source file is ++recorded as @file{../lib/foo.c}, and no compilation directory is ++recorded, then @value{GDBN} will search in the following locations: ++ ++@enumerate ++ ++@item @file{/mnt/cross/../lib/foo.c} ++@item @file{/mnt/cross/foo.c} ++ ++@end enumerate ++ ++@kindex cdir ++@kindex cwd ++@vindex $cdir@r{, convenience variable} ++@vindex $cwd@r{, convenience variable} ++@cindex compilation directory ++@cindex current directory ++@cindex working directory ++@cindex directory, current ++@cindex directory, compilation ++The @dfn{source path} will always include two special entries ++@samp{$cdir} and @samp{$cwd}, these refer to the compilation directory ++(if one is recorded) and the current working directory respectively. ++ ++@samp{$cdir} causes @value{GDBN} to search within the compilation ++directory, if one is recorded in the debug information. If no ++compilation directory is recorded in the debug information then ++@samp{$cdir} is ignored. ++ ++@samp{$cwd} is not the same as @samp{.}---the former tracks the ++current working directory as it changes during your @value{GDBN} ++session, while the latter is immediately expanded to the current ++directory at the time you add an entry to the source path. ++ ++If a compilation directory is recorded in the debug information, and ++@value{GDBN} has not found the source file after the first search ++using @dfn{source path}, then @value{GDBN} will combine the ++compilation directory and the filename, and then search for the source ++file again using the @dfn{source path}. ++ ++For example, if the executable records the source file as ++@file{/usr/src/foo-1.0/lib/foo.c}, the compilation directory is ++recorded as @file{/project/build}, and the @dfn{source path} is ++@file{/mnt/cross:$cdir:$cwd} while the current working directory of ++the @value{GDBN} session is @file{/home/user}, then @value{GDBN} will ++search for the source file in the following locations: ++ ++@enumerate ++ ++@item @file{/usr/src/foo-1.0/lib/foo.c} ++@item @file{/mnt/cross/usr/src/foo-1.0/lib/foo.c} ++@item @file{/project/build/usr/src/foo-1.0/lib/foo.c} ++@item @file{/home/user/usr/src/foo-1.0/lib/foo.c} ++@item @file{/mnt/cross/project/build/usr/src/foo-1.0/lib/foo.c} ++@item @file{/project/build/project/build/usr/src/foo-1.0/lib/foo.c} ++@item @file{/home/user/project/build/usr/src/foo-1.0/lib/foo.c} ++@item @file{/mnt/cross/foo.c} ++@item @file{/project/build/foo.c} ++@item @file{/home/user/foo.c} ++ ++@end enumerate ++ ++If the file name in the previous example had been recorded in the ++executable as a relative path rather than an absolute path, then the ++first look up would not have occurred, but all of the remaining steps ++would be similar. ++ ++When searching for source files on MS-DOS and MS-Windows, where ++absolute paths start with a drive letter (e.g. ++@file{C:/project/foo.c}), @value{GDBN} will remove the drive letter ++from the file name before appending it to a search directory from ++@dfn{source path}; for instance if the executable references the ++source file @file{C:/project/foo.c} and @dfn{source path} is set to ++@file{D:/mnt/cross}, then @value{GDBN} will search in the following ++locations for the source file: ++ ++@enumerate ++ ++@item @file{C:/project/foo.c} ++@item @file{D:/mnt/cross/project/foo.c} ++@item @file{D:/mnt/cross/foo.c} ++ ++@end enumerate ++ ++Note that the executable search path is @emph{not} used to locate the ++source files. ++ ++Whenever you reset or rearrange the source path, @value{GDBN} clears out ++any information it has cached about where source files are found and where ++each line is in the file. ++ ++@kindex directory ++@kindex dir ++When you start @value{GDBN}, its source path includes only @samp{$cdir} ++and @samp{$cwd}, in that order. ++To add other directories, use the @code{directory} command. ++ ++The search path is used to find both program source files and @value{GDBN} ++script files (read using the @samp{-command} option and @samp{source} command). ++ ++In addition to the source path, @value{GDBN} provides a set of commands ++that manage a list of source path substitution rules. A @dfn{substitution ++rule} specifies how to rewrite source directories stored in the program's ++debug information in case the sources were moved to a different ++directory between compilation and debugging. A rule is made of ++two strings, the first specifying what needs to be rewritten in ++the path, and the second specifying how it should be rewritten. ++In @ref{set substitute-path}, we name these two parts @var{from} and ++@var{to} respectively. @value{GDBN} does a simple string replacement ++of @var{from} with @var{to} at the start of the directory part of the ++source file name, and uses that result instead of the original file ++name to look up the sources. ++ ++Using the previous example, suppose the @file{foo-1.0} tree has been ++moved from @file{/usr/src} to @file{/mnt/cross}, then you can tell ++@value{GDBN} to replace @file{/usr/src} in all source path names with ++@file{/mnt/cross}. The first lookup will then be ++@file{/mnt/cross/foo-1.0/lib/foo.c} in place of the original location ++of @file{/usr/src/foo-1.0/lib/foo.c}. To define a source path ++substitution rule, use the @code{set substitute-path} command ++(@pxref{set substitute-path}). ++ ++To avoid unexpected substitution results, a rule is applied only if the ++@var{from} part of the directory name ends at a directory separator. ++For instance, a rule substituting @file{/usr/source} into ++@file{/mnt/cross} will be applied to @file{/usr/source/foo-1.0} but ++not to @file{/usr/sourceware/foo-2.0}. And because the substitution ++is applied only at the beginning of the directory name, this rule will ++not be applied to @file{/root/usr/source/baz.c} either. ++ ++In many cases, you can achieve the same result using the @code{directory} ++command. However, @code{set substitute-path} can be more efficient in ++the case where the sources are organized in a complex tree with multiple ++subdirectories. With the @code{directory} command, you need to add each ++subdirectory of your project. If you moved the entire tree while ++preserving its internal organization, then @code{set substitute-path} ++allows you to direct the debugger to all the sources with one single ++command. ++ ++@code{set substitute-path} is also more than just a shortcut command. ++The source path is only used if the file at the original location no ++longer exists. On the other hand, @code{set substitute-path} modifies ++the debugger behavior to look at the rewritten location instead. So, if ++for any reason a source file that is not relevant to your executable is ++located at the original location, a substitution rule is the only ++method available to point @value{GDBN} at the new location. ++ ++@cindex @samp{--with-relocated-sources} ++@cindex default source path substitution ++You can configure a default source path substitution rule by ++configuring @value{GDBN} with the ++@samp{--with-relocated-sources=@var{dir}} option. The @var{dir} ++should be the name of a directory under @value{GDBN}'s configured ++prefix (set with @samp{--prefix} or @samp{--exec-prefix}), and ++directory names in debug information under @var{dir} will be adjusted ++automatically if the installed @value{GDBN} is moved to a new ++location. This is useful if @value{GDBN}, libraries or executables ++with debug information and corresponding source code are being moved ++together. ++ ++@table @code ++@item directory @var{dirname} @dots{} ++@item dir @var{dirname} @dots{} ++Add directory @var{dirname} to the front of the source path. Several ++directory names may be given to this command, separated by @samp{:} ++(@samp{;} on MS-DOS and MS-Windows, where @samp{:} usually appears as ++part of absolute file names) or ++whitespace. You may specify a directory that is already in the source ++path; this moves it forward, so @value{GDBN} searches it sooner. ++ ++The special strings @samp{$cdir} (to refer to the compilation ++directory, if one is recorded), and @samp{$cwd} (to refer to the ++current working directory) can also be included in the list of ++directories @var{dirname}. Though these will already be in the source ++path they will be moved forward in the list so @value{GDBN} searches ++them sooner. ++ ++@item directory ++Reset the source path to its default value (@samp{$cdir:$cwd} on Unix systems). This requires confirmation. ++ ++@c RET-repeat for @code{directory} is explicitly disabled, but since ++@c repeating it would be a no-op we do not say that. (thanks to RMS) ++ ++@item set directories @var{path-list} ++@kindex set directories ++Set the source path to @var{path-list}. ++@samp{$cdir:$cwd} are added if missing. ++ ++@item show directories ++@kindex show directories ++Print the source path: show which directories it contains. ++ ++@anchor{set substitute-path} ++@item set substitute-path @var{from} @var{to} ++@kindex set substitute-path ++Define a source path substitution rule, and add it at the end of the ++current list of existing substitution rules. If a rule with the same ++@var{from} was already defined, then the old rule is also deleted. ++ ++For example, if the file @file{/foo/bar/baz.c} was moved to ++@file{/mnt/cross/baz.c}, then the command ++ ++@smallexample ++(@value{GDBP}) set substitute-path /foo/bar /mnt/cross ++@end smallexample ++ ++@noindent ++will tell @value{GDBN} to replace @samp{/foo/bar} with ++@samp{/mnt/cross}, which will allow @value{GDBN} to find the file ++@file{baz.c} even though it was moved. ++ ++In the case when more than one substitution rule have been defined, ++the rules are evaluated one by one in the order where they have been ++defined. The first one matching, if any, is selected to perform ++the substitution. ++ ++For instance, if we had entered the following commands: ++ ++@smallexample ++(@value{GDBP}) set substitute-path /usr/src/include /mnt/include ++(@value{GDBP}) set substitute-path /usr/src /mnt/src ++@end smallexample ++ ++@noindent ++@value{GDBN} would then rewrite @file{/usr/src/include/defs.h} into ++@file{/mnt/include/defs.h} by using the first rule. However, it would ++use the second rule to rewrite @file{/usr/src/lib/foo.c} into ++@file{/mnt/src/lib/foo.c}. ++ ++ ++@item unset substitute-path [path] ++@kindex unset substitute-path ++If a path is specified, search the current list of substitution rules ++for a rule that would rewrite that path. Delete that rule if found. ++A warning is emitted by the debugger if no rule could be found. ++ ++If no path is specified, then all substitution rules are deleted. ++ ++@item show substitute-path [path] ++@kindex show substitute-path ++If a path is specified, then print the source path substitution rule ++which would rewrite that path, if any. ++ ++If no path is specified, then print all existing source path substitution ++rules. ++ ++@end table ++ ++If your source path is cluttered with directories that are no longer of ++interest, @value{GDBN} may sometimes cause confusion by finding the wrong ++versions of source. You can correct the situation as follows: ++ ++@enumerate ++@item ++Use @code{directory} with no argument to reset the source path to its default value. ++ ++@item ++Use @code{directory} with suitable arguments to reinstall the ++directories you want in the source path. You can add all the ++directories in one command. ++@end enumerate ++ ++@node Machine Code ++@section Source and Machine Code ++@cindex source line and its code address ++ ++You can use the command @code{info line} to map source lines to program ++addresses (and vice versa), and the command @code{disassemble} to display ++a range of addresses as machine instructions. You can use the command ++@code{set disassemble-next-line} to set whether to disassemble next ++source line when execution stops. When run under @sc{gnu} Emacs ++mode, the @code{info line} command causes the arrow to point to the ++line specified. Also, @code{info line} prints addresses in symbolic form as ++well as hex. ++ ++@table @code ++@kindex info line ++@item info line ++@itemx info line @var{location} ++Print the starting and ending addresses of the compiled code for ++source line @var{location}. You can specify source lines in any of ++the ways documented in @ref{Specify Location}. With no @var{location} ++information about the current source line is printed. ++@end table ++ ++For example, we can use @code{info line} to discover the location of ++the object code for the first line of function ++@code{m4_changequote}: ++ ++@smallexample ++(@value{GDBP}) info line m4_changequote ++Line 895 of "builtin.c" starts at pc 0x634c and \ ++ ends at 0x6350 . ++@end smallexample ++ ++@noindent ++@cindex code address and its source line ++We can also inquire (using @code{*@var{addr}} as the form for ++@var{location}) what source line covers a particular address: ++@smallexample ++(@value{GDBP}) info line *0x63ff ++Line 926 of "builtin.c" starts at pc 0x63e4 and \ ++ ends at 0x6404 . ++@end smallexample ++ ++@cindex @code{$_} and @code{info line} ++@cindex @code{x} command, default address ++@kindex x@r{(examine), and} info line ++After @code{info line}, the default address for the @code{x} command ++is changed to the starting address of the line, so that @samp{x/i} is ++sufficient to begin examining the machine code (@pxref{Memory, ++,Examining Memory}). Also, this address is saved as the value of the ++convenience variable @code{$_} (@pxref{Convenience Vars, ,Convenience ++Variables}). ++ ++@cindex info line, repeated calls ++After @code{info line}, using @code{info line} again without ++specifying a location will display information about the next source ++line. ++ ++@table @code ++@kindex disassemble ++@cindex assembly instructions ++@cindex instructions, assembly ++@cindex machine instructions ++@cindex listing machine instructions ++@item disassemble ++@itemx disassemble /m ++@itemx disassemble /s ++@itemx disassemble /r ++This specialized command dumps a range of memory as machine ++instructions. It can also print mixed source+disassembly by specifying ++the @code{/m} or @code{/s} modifier and print the raw instructions in hex ++as well as in symbolic form by specifying the @code{/r} modifier. ++The default memory range is the function surrounding the ++program counter of the selected frame. A single argument to this ++command is a program counter value; @value{GDBN} dumps the function ++surrounding this value. When two arguments are given, they should ++be separated by a comma, possibly surrounded by whitespace. The ++arguments specify a range of addresses to dump, in one of two forms: ++ ++@table @code ++@item @var{start},@var{end} ++the addresses from @var{start} (inclusive) to @var{end} (exclusive) ++@item @var{start},+@var{length} ++the addresses from @var{start} (inclusive) to ++@code{@var{start}+@var{length}} (exclusive). ++@end table ++ ++@noindent ++When 2 arguments are specified, the name of the function is also ++printed (since there could be several functions in the given range). ++ ++The argument(s) can be any expression yielding a numeric value, such as ++@samp{0x32c4}, @samp{&main+10} or @samp{$pc - 8}. ++ ++If the range of memory being disassembled contains current program counter, ++the instruction at that location is shown with a @code{=>} marker. ++@end table ++ ++The following example shows the disassembly of a range of addresses of ++HP PA-RISC 2.0 code: ++ ++@smallexample ++(@value{GDBP}) disas 0x32c4, 0x32e4 ++Dump of assembler code from 0x32c4 to 0x32e4: ++ 0x32c4 : addil 0,dp ++ 0x32c8 : ldw 0x22c(sr0,r1),r26 ++ 0x32cc : ldil 0x3000,r31 ++ 0x32d0 : ble 0x3f8(sr4,r31) ++ 0x32d4 : ldo 0(r31),rp ++ 0x32d8 : addil -0x800,dp ++ 0x32dc : ldo 0x588(r1),r26 ++ 0x32e0 : ldil 0x3000,r31 ++End of assembler dump. ++@end smallexample ++ ++Here is an example showing mixed source+assembly for Intel x86 ++with @code{/m} or @code{/s}, when the program is stopped just after ++function prologue in a non-optimized function with no inline code. ++ ++@smallexample ++(@value{GDBP}) disas /m main ++Dump of assembler code for function main: ++5 @{ ++ 0x08048330 <+0>: push %ebp ++ 0x08048331 <+1>: mov %esp,%ebp ++ 0x08048333 <+3>: sub $0x8,%esp ++ 0x08048336 <+6>: and $0xfffffff0,%esp ++ 0x08048339 <+9>: sub $0x10,%esp ++ ++6 printf ("Hello.\n"); ++=> 0x0804833c <+12>: movl $0x8048440,(%esp) ++ 0x08048343 <+19>: call 0x8048284 ++ ++7 return 0; ++8 @} ++ 0x08048348 <+24>: mov $0x0,%eax ++ 0x0804834d <+29>: leave ++ 0x0804834e <+30>: ret ++ ++End of assembler dump. ++@end smallexample ++ ++The @code{/m} option is deprecated as its output is not useful when ++there is either inlined code or re-ordered code. ++The @code{/s} option is the preferred choice. ++Here is an example for AMD x86-64 showing the difference between ++@code{/m} output and @code{/s} output. ++This example has one inline function defined in a header file, ++and the code is compiled with @samp{-O2} optimization. ++Note how the @code{/m} output is missing the disassembly of ++several instructions that are present in the @code{/s} output. ++ ++@file{foo.h}: ++ ++@smallexample ++int ++foo (int a) ++@{ ++ if (a < 0) ++ return a * 2; ++ if (a == 0) ++ return 1; ++ return a + 10; ++@} ++@end smallexample ++ ++@file{foo.c}: ++ ++@smallexample ++#include "foo.h" ++volatile int x, y; ++int ++main () ++@{ ++ x = foo (y); ++ return 0; ++@} ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) disas /m main ++Dump of assembler code for function main: ++5 @{ ++ ++6 x = foo (y); ++ 0x0000000000400400 <+0>: mov 0x200c2e(%rip),%eax # 0x601034 ++ 0x0000000000400417 <+23>: mov %eax,0x200c13(%rip) # 0x601030 ++ ++7 return 0; ++8 @} ++ 0x000000000040041d <+29>: xor %eax,%eax ++ 0x000000000040041f <+31>: retq ++ 0x0000000000400420 <+32>: add %eax,%eax ++ 0x0000000000400422 <+34>: jmp 0x400417 ++ ++End of assembler dump. ++(@value{GDBP}) disas /s main ++Dump of assembler code for function main: ++foo.c: ++5 @{ ++6 x = foo (y); ++ 0x0000000000400400 <+0>: mov 0x200c2e(%rip),%eax # 0x601034 ++ ++foo.h: ++4 if (a < 0) ++ 0x0000000000400406 <+6>: test %eax,%eax ++ 0x0000000000400408 <+8>: js 0x400420 ++ ++6 if (a == 0) ++7 return 1; ++8 return a + 10; ++ 0x000000000040040a <+10>: lea 0xa(%rax),%edx ++ 0x000000000040040d <+13>: test %eax,%eax ++ 0x000000000040040f <+15>: mov $0x1,%eax ++ 0x0000000000400414 <+20>: cmovne %edx,%eax ++ ++foo.c: ++6 x = foo (y); ++ 0x0000000000400417 <+23>: mov %eax,0x200c13(%rip) # 0x601030 ++ ++7 return 0; ++8 @} ++ 0x000000000040041d <+29>: xor %eax,%eax ++ 0x000000000040041f <+31>: retq ++ ++foo.h: ++5 return a * 2; ++ 0x0000000000400420 <+32>: add %eax,%eax ++ 0x0000000000400422 <+34>: jmp 0x400417 ++End of assembler dump. ++@end smallexample ++ ++Here is another example showing raw instructions in hex for AMD x86-64, ++ ++@smallexample ++(gdb) disas /r 0x400281,+10 ++Dump of assembler code from 0x400281 to 0x40028b: ++ 0x0000000000400281: 38 36 cmp %dh,(%rsi) ++ 0x0000000000400283: 2d 36 34 2e 73 sub $0x732e3436,%eax ++ 0x0000000000400288: 6f outsl %ds:(%rsi),(%dx) ++ 0x0000000000400289: 2e 32 00 xor %cs:(%rax),%al ++End of assembler dump. ++@end smallexample ++ ++Addresses cannot be specified as a location (@pxref{Specify Location}). ++So, for example, if you want to disassemble function @code{bar} ++in file @file{foo.c}, you must type @samp{disassemble 'foo.c'::bar} ++and not @samp{disassemble foo.c:bar}. ++ ++Some architectures have more than one commonly-used set of instruction ++mnemonics or other syntax. ++ ++For programs that were dynamically linked and use shared libraries, ++instructions that call functions or branch to locations in the shared ++libraries might show a seemingly bogus location---it's actually a ++location of the relocation table. On some architectures, @value{GDBN} ++might be able to resolve these to actual function names. ++ ++@table @code ++@kindex set disassembler-options ++@cindex disassembler options ++@item set disassembler-options @var{option1}[,@var{option2}@dots{}] ++This command controls the passing of target specific information to ++the disassembler. For a list of valid options, please refer to the ++@code{-M}/@code{--disassembler-options} section of the @samp{objdump} ++manual and/or the output of @kbd{objdump --help} ++(@pxref{objdump,,objdump,binutils,The GNU Binary Utilities}). ++The default value is the empty string. ++ ++If it is necessary to specify more than one disassembler option, then ++multiple options can be placed together into a comma separated list. ++Currently this command is only supported on targets ARM, MIPS, PowerPC ++and S/390. ++ ++@kindex show disassembler-options ++@item show disassembler-options ++Show the current setting of the disassembler options. ++@end table ++ ++@table @code ++@kindex set disassembly-flavor ++@cindex Intel disassembly flavor ++@cindex AT&T disassembly flavor ++@item set disassembly-flavor @var{instruction-set} ++Select the instruction set to use when disassembling the ++program via the @code{disassemble} or @code{x/i} commands. ++ ++Currently this command is only defined for the Intel x86 family. You ++can set @var{instruction-set} to either @code{intel} or @code{att}. ++The default is @code{att}, the AT&T flavor used by default by Unix ++assemblers for x86-based targets. ++ ++@kindex show disassembly-flavor ++@item show disassembly-flavor ++Show the current setting of the disassembly flavor. ++@end table ++ ++@table @code ++@kindex set disassemble-next-line ++@kindex show disassemble-next-line ++@item set disassemble-next-line ++@itemx show disassemble-next-line ++Control whether or not @value{GDBN} will disassemble the next source ++line or instruction when execution stops. If ON, @value{GDBN} will ++display disassembly of the next source line when execution of the ++program being debugged stops. This is @emph{in addition} to ++displaying the source line itself, which @value{GDBN} always does if ++possible. If the next source line cannot be displayed for some reason ++(e.g., if @value{GDBN} cannot find the source file, or there's no line ++info in the debug info), @value{GDBN} will display disassembly of the ++next @emph{instruction} instead of showing the next source line. If ++AUTO, @value{GDBN} will display disassembly of next instruction only ++if the source line cannot be displayed. This setting causes ++@value{GDBN} to display some feedback when you step through a function ++with no line info or whose source file is unavailable. The default is ++OFF, which means never display the disassembly of the next line or ++instruction. ++@end table ++ ++ ++@node Data ++@chapter Examining Data ++ ++@cindex printing data ++@cindex examining data ++@kindex print ++@kindex inspect ++The usual way to examine data in your program is with the @code{print} ++command (abbreviated @code{p}), or its synonym @code{inspect}. It ++evaluates and prints the value of an expression of the language your ++program is written in (@pxref{Languages, ,Using @value{GDBN} with ++Different Languages}). It may also print the expression using a ++Python-based pretty-printer (@pxref{Pretty Printing}). ++ ++@table @code ++@item print [[@var{options}] --] @var{expr} ++@itemx print [[@var{options}] --] /@var{f} @var{expr} ++@var{expr} is an expression (in the source language). By default the ++value of @var{expr} is printed in a format appropriate to its data type; ++you can choose a different format by specifying @samp{/@var{f}}, where ++@var{f} is a letter specifying the format; see @ref{Output Formats,,Output ++Formats}. ++ ++@anchor{print options} ++The @code{print} command supports a number of options that allow ++overriding relevant global print settings as set by @code{set print} ++subcommands: ++ ++@table @code ++@item -address [@code{on}|@code{off}] ++Set printing of addresses. ++Related setting: @ref{set print address}. ++ ++@item -array [@code{on}|@code{off}] ++Pretty formatting of arrays. ++Related setting: @ref{set print array}. ++ ++@item -array-indexes [@code{on}|@code{off}] ++Set printing of array indexes. ++Related setting: @ref{set print array-indexes}. ++ ++@item -elements @var{number-of-elements}|@code{unlimited} ++Set limit on string chars or array elements to print. The value ++@code{unlimited} causes there to be no limit. Related setting: ++@ref{set print elements}. ++ ++@item -max-depth @var{depth}|@code{unlimited} ++Set the threshold after which nested structures are replaced with ++ellipsis. Related setting: @ref{set print max-depth}. ++ ++@item -null-stop [@code{on}|@code{off}] ++Set printing of char arrays to stop at first null char. Related ++setting: @ref{set print null-stop}. ++ ++@item -object [@code{on}|@code{off}] ++Set printing C@t{++} virtual function tables. Related setting: ++@ref{set print object}. ++ ++@item -pretty [@code{on}|@code{off}] ++Set pretty formatting of structures. Related setting: @ref{set print ++pretty}. ++ ++@item -raw-values [@code{on}|@code{off}] ++Set whether to print values in raw form, bypassing any ++pretty-printers for that value. Related setting: @ref{set print ++raw-values}. ++ ++@item -repeats @var{number-of-repeats}|@code{unlimited} ++Set threshold for repeated print elements. @code{unlimited} causes ++all elements to be individually printed. Related setting: @ref{set ++print repeats}. ++ ++@item -static-members [@code{on}|@code{off}] ++Set printing C@t{++} static members. Related setting: @ref{set print ++static-members}. ++ ++@item -symbol [@code{on}|@code{off}] ++Set printing of symbol names when printing pointers. Related setting: ++@ref{set print symbol}. ++ ++@item -union [@code{on}|@code{off}] ++Set printing of unions interior to structures. Related setting: ++@ref{set print union}. ++ ++@item -vtbl [@code{on}|@code{off}] ++Set printing of C++ virtual function tables. Related setting: ++@ref{set print vtbl}. ++@end table ++ ++Because the @code{print} command accepts arbitrary expressions which ++may look like options (including abbreviations), if you specify any ++command option, then you must use a double dash (@code{--}) to mark ++the end of option processing. ++ ++For example, this prints the value of the @code{-p} expression: ++ ++@smallexample ++(@value{GDBP}) print -p ++@end smallexample ++ ++While this repeats the last value in the value history (see below) ++with the @code{-pretty} option in effect: ++ ++@smallexample ++(@value{GDBP}) print -p -- ++@end smallexample ++ ++Here is an example including both on option and an expression: ++ ++@smallexample ++@group ++(@value{GDBP}) print -pretty -- *myptr ++$1 = @{ ++ next = 0x0, ++ flags = @{ ++ sweet = 1, ++ sour = 1 ++ @}, ++ meat = 0x54 "Pork" ++@} ++@end group ++@end smallexample ++ ++@item print [@var{options}] ++@itemx print [@var{options}] /@var{f} ++@cindex reprint the last value ++If you omit @var{expr}, @value{GDBN} displays the last value again (from the ++@dfn{value history}; @pxref{Value History, ,Value History}). This allows you to ++conveniently inspect the same value in an alternative format. ++@end table ++ ++A more low-level way of examining data is with the @code{x} command. ++It examines data in memory at a specified address and prints it in a ++specified format. @xref{Memory, ,Examining Memory}. ++ ++If you are interested in information about types, or about how the ++fields of a struct or a class are declared, use the @code{ptype @var{exp}} ++command rather than @code{print}. @xref{Symbols, ,Examining the Symbol ++Table}. ++ ++@cindex exploring hierarchical data structures ++@kindex explore ++Another way of examining values of expressions and type information is ++through the Python extension command @code{explore} (available only if ++the @value{GDBN} build is configured with @code{--with-python}). It ++offers an interactive way to start at the highest level (or, the most ++abstract level) of the data type of an expression (or, the data type ++itself) and explore all the way down to leaf scalar values/fields ++embedded in the higher level data types. ++ ++@table @code ++@item explore @var{arg} ++@var{arg} is either an expression (in the source language), or a type ++visible in the current context of the program being debugged. ++@end table ++ ++The working of the @code{explore} command can be illustrated with an ++example. If a data type @code{struct ComplexStruct} is defined in your ++C program as ++ ++@smallexample ++struct SimpleStruct ++@{ ++ int i; ++ double d; ++@}; ++ ++struct ComplexStruct ++@{ ++ struct SimpleStruct *ss_p; ++ int arr[10]; ++@}; ++@end smallexample ++ ++@noindent ++followed by variable declarations as ++ ++@smallexample ++struct SimpleStruct ss = @{ 10, 1.11 @}; ++struct ComplexStruct cs = @{ &ss, @{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 @} @}; ++@end smallexample ++ ++@noindent ++then, the value of the variable @code{cs} can be explored using the ++@code{explore} command as follows. ++ ++@smallexample ++(gdb) explore cs ++The value of `cs' is a struct/class of type `struct ComplexStruct' with ++the following fields: ++ ++ ss_p = ++ arr = ++ ++Enter the field number of choice: ++@end smallexample ++ ++@noindent ++Since the fields of @code{cs} are not scalar values, you are being ++prompted to chose the field you want to explore. Let's say you choose ++the field @code{ss_p} by entering @code{0}. Then, since this field is a ++pointer, you will be asked if it is pointing to a single value. From ++the declaration of @code{cs} above, it is indeed pointing to a single ++value, hence you enter @code{y}. If you enter @code{n}, then you will ++be asked if it were pointing to an array of values, in which case this ++field will be explored as if it were an array. ++ ++@smallexample ++`cs.ss_p' is a pointer to a value of type `struct SimpleStruct' ++Continue exploring it as a pointer to a single value [y/n]: y ++The value of `*(cs.ss_p)' is a struct/class of type `struct ++SimpleStruct' with the following fields: ++ ++ i = 10 .. (Value of type `int') ++ d = 1.1100000000000001 .. (Value of type `double') ++ ++Press enter to return to parent value: ++@end smallexample ++ ++@noindent ++If the field @code{arr} of @code{cs} was chosen for exploration by ++entering @code{1} earlier, then since it is as array, you will be ++prompted to enter the index of the element in the array that you want ++to explore. ++ ++@smallexample ++`cs.arr' is an array of `int'. ++Enter the index of the element you want to explore in `cs.arr': 5 ++ ++`(cs.arr)[5]' is a scalar value of type `int'. ++ ++(cs.arr)[5] = 4 ++ ++Press enter to return to parent value: ++@end smallexample ++ ++In general, at any stage of exploration, you can go deeper towards the ++leaf values by responding to the prompts appropriately, or hit the ++return key to return to the enclosing data structure (the @i{higher} ++level data structure). ++ ++Similar to exploring values, you can use the @code{explore} command to ++explore types. Instead of specifying a value (which is typically a ++variable name or an expression valid in the current context of the ++program being debugged), you specify a type name. If you consider the ++same example as above, your can explore the type ++@code{struct ComplexStruct} by passing the argument ++@code{struct ComplexStruct} to the @code{explore} command. ++ ++@smallexample ++(gdb) explore struct ComplexStruct ++@end smallexample ++ ++@noindent ++By responding to the prompts appropriately in the subsequent interactive ++session, you can explore the type @code{struct ComplexStruct} in a ++manner similar to how the value @code{cs} was explored in the above ++example. ++ ++The @code{explore} command also has two sub-commands, ++@code{explore value} and @code{explore type}. The former sub-command is ++a way to explicitly specify that value exploration of the argument is ++being invoked, while the latter is a way to explicitly specify that type ++exploration of the argument is being invoked. ++ ++@table @code ++@item explore value @var{expr} ++@cindex explore value ++This sub-command of @code{explore} explores the value of the ++expression @var{expr} (if @var{expr} is an expression valid in the ++current context of the program being debugged). The behavior of this ++command is identical to that of the behavior of the @code{explore} ++command being passed the argument @var{expr}. ++ ++@item explore type @var{arg} ++@cindex explore type ++This sub-command of @code{explore} explores the type of @var{arg} (if ++@var{arg} is a type visible in the current context of program being ++debugged), or the type of the value/expression @var{arg} (if @var{arg} ++is an expression valid in the current context of the program being ++debugged). If @var{arg} is a type, then the behavior of this command is ++identical to that of the @code{explore} command being passed the ++argument @var{arg}. If @var{arg} is an expression, then the behavior of ++this command will be identical to that of the @code{explore} command ++being passed the type of @var{arg} as the argument. ++@end table ++ ++@menu ++* Expressions:: Expressions ++* Ambiguous Expressions:: Ambiguous Expressions ++* Variables:: Program variables ++* Arrays:: Artificial arrays ++* Output Formats:: Output formats ++* Memory:: Examining memory ++* Auto Display:: Automatic display ++* Print Settings:: Print settings ++* Pretty Printing:: Python pretty printing ++* Value History:: Value history ++* Convenience Vars:: Convenience variables ++* Convenience Funs:: Convenience functions ++* Registers:: Registers ++* Floating Point Hardware:: Floating point hardware ++* Vector Unit:: Vector Unit ++* OS Information:: Auxiliary data provided by operating system ++* Memory Region Attributes:: Memory region attributes ++* Dump/Restore Files:: Copy between memory and a file ++* Core File Generation:: Cause a program dump its core ++* Character Sets:: Debugging programs that use a different ++ character set than GDB does ++* Caching Target Data:: Data caching for targets ++* Searching Memory:: Searching memory for a sequence of bytes ++* Value Sizes:: Managing memory allocated for values ++@end menu ++ ++@node Expressions ++@section Expressions ++ ++@cindex expressions ++@code{print} and many other @value{GDBN} commands accept an expression and ++compute its value. Any kind of constant, variable or operator defined ++by the programming language you are using is valid in an expression in ++@value{GDBN}. This includes conditional expressions, function calls, ++casts, and string constants. It also includes preprocessor macros, if ++you compiled your program to include this information; see ++@ref{Compilation}. ++ ++@cindex arrays in expressions ++@value{GDBN} supports array constants in expressions input by ++the user. The syntax is @{@var{element}, @var{element}@dots{}@}. For example, ++you can use the command @code{print @{1, 2, 3@}} to create an array ++of three integers. If you pass an array to a function or assign it ++to a program variable, @value{GDBN} copies the array to memory that ++is @code{malloc}ed in the target program. ++ ++Because C is so widespread, most of the expressions shown in examples in ++this manual are in C. @xref{Languages, , Using @value{GDBN} with Different ++Languages}, for information on how to use expressions in other ++languages. ++ ++In this section, we discuss operators that you can use in @value{GDBN} ++expressions regardless of your programming language. ++ ++@cindex casts, in expressions ++Casts are supported in all languages, not just in C, because it is so ++useful to cast a number into a pointer in order to examine a structure ++at that address in memory. ++@c FIXME: casts supported---Mod2 true? ++ ++@value{GDBN} supports these operators, in addition to those common ++to programming languages: ++ ++@table @code ++@item @@ ++@samp{@@} is a binary operator for treating parts of memory as arrays. ++@xref{Arrays, ,Artificial Arrays}, for more information. ++ ++@item :: ++@samp{::} allows you to specify a variable in terms of the file or ++function where it is defined. @xref{Variables, ,Program Variables}. ++ ++@cindex @{@var{type}@} ++@cindex type casting memory ++@cindex memory, viewing as typed object ++@cindex casts, to view memory ++@item @{@var{type}@} @var{addr} ++Refers to an object of type @var{type} stored at address @var{addr} in ++memory. The address @var{addr} may be any expression whose value is ++an integer or pointer (but parentheses are required around binary ++operators, just as in a cast). This construct is allowed regardless ++of what kind of data is normally supposed to reside at @var{addr}. ++@end table ++ ++@node Ambiguous Expressions ++@section Ambiguous Expressions ++@cindex ambiguous expressions ++ ++Expressions can sometimes contain some ambiguous elements. For instance, ++some programming languages (notably Ada, C@t{++} and Objective-C) permit ++a single function name to be defined several times, for application in ++different contexts. This is called @dfn{overloading}. Another example ++involving Ada is generics. A @dfn{generic package} is similar to C@t{++} ++templates and is typically instantiated several times, resulting in ++the same function name being defined in different contexts. ++ ++In some cases and depending on the language, it is possible to adjust ++the expression to remove the ambiguity. For instance in C@t{++}, you ++can specify the signature of the function you want to break on, as in ++@kbd{break @var{function}(@var{types})}. In Ada, using the fully ++qualified name of your function often makes the expression unambiguous ++as well. ++ ++When an ambiguity that needs to be resolved is detected, the debugger ++has the capability to display a menu of numbered choices for each ++possibility, and then waits for the selection with the prompt @samp{>}. ++The first option is always @samp{[0] cancel}, and typing @kbd{0 @key{RET}} ++aborts the current command. If the command in which the expression was ++used allows more than one choice to be selected, the next option in the ++menu is @samp{[1] all}, and typing @kbd{1 @key{RET}} selects all possible ++choices. ++ ++For example, the following session excerpt shows an attempt to set a ++breakpoint at the overloaded symbol @code{String::after}. ++We choose three particular definitions of that function name: ++ ++@c FIXME! This is likely to change to show arg type lists, at least ++@smallexample ++@group ++(@value{GDBP}) b String::after ++[0] cancel ++[1] all ++[2] file:String.cc; line number:867 ++[3] file:String.cc; line number:860 ++[4] file:String.cc; line number:875 ++[5] file:String.cc; line number:853 ++[6] file:String.cc; line number:846 ++[7] file:String.cc; line number:735 ++> 2 4 6 ++Breakpoint 1 at 0xb26c: file String.cc, line 867. ++Breakpoint 2 at 0xb344: file String.cc, line 875. ++Breakpoint 3 at 0xafcc: file String.cc, line 846. ++Multiple breakpoints were set. ++Use the "delete" command to delete unwanted ++ breakpoints. ++(@value{GDBP}) ++@end group ++@end smallexample ++ ++@table @code ++@kindex set multiple-symbols ++@item set multiple-symbols @var{mode} ++@cindex multiple-symbols menu ++ ++This option allows you to adjust the debugger behavior when an expression ++is ambiguous. ++ ++By default, @var{mode} is set to @code{all}. If the command with which ++the expression is used allows more than one choice, then @value{GDBN} ++automatically selects all possible choices. For instance, inserting ++a breakpoint on a function using an ambiguous name results in a breakpoint ++inserted on each possible match. However, if a unique choice must be made, ++then @value{GDBN} uses the menu to help you disambiguate the expression. ++For instance, printing the address of an overloaded function will result ++in the use of the menu. ++ ++When @var{mode} is set to @code{ask}, the debugger always uses the menu ++when an ambiguity is detected. ++ ++Finally, when @var{mode} is set to @code{cancel}, the debugger reports ++an error due to the ambiguity and the command is aborted. ++ ++@kindex show multiple-symbols ++@item show multiple-symbols ++Show the current value of the @code{multiple-symbols} setting. ++@end table ++ ++@node Variables ++@section Program Variables ++ ++The most common kind of expression to use is the name of a variable ++in your program. ++ ++Variables in expressions are understood in the selected stack frame ++(@pxref{Selection, ,Selecting a Frame}); they must be either: ++ ++@itemize @bullet ++@item ++global (or file-static) ++@end itemize ++ ++@noindent or ++ ++@itemize @bullet ++@item ++visible according to the scope rules of the ++programming language from the point of execution in that frame ++@end itemize ++ ++@noindent This means that in the function ++ ++@smallexample ++foo (a) ++ int a; ++@{ ++ bar (a); ++ @{ ++ int b = test (); ++ bar (b); ++ @} ++@} ++@end smallexample ++ ++@noindent ++you can examine and use the variable @code{a} whenever your program is ++executing within the function @code{foo}, but you can only use or ++examine the variable @code{b} while your program is executing inside ++the block where @code{b} is declared. ++ ++@cindex variable name conflict ++There is an exception: you can refer to a variable or function whose ++scope is a single source file even if the current execution point is not ++in this file. But it is possible to have more than one such variable or ++function with the same name (in different source files). If that ++happens, referring to that name has unpredictable effects. If you wish, ++you can specify a static variable in a particular function or file by ++using the colon-colon (@code{::}) notation: ++ ++@cindex colon-colon, context for variables/functions ++@ifnotinfo ++@c info cannot cope with a :: index entry, but why deprive hard copy readers? ++@cindex @code{::}, context for variables/functions ++@end ifnotinfo ++@smallexample ++@var{file}::@var{variable} ++@var{function}::@var{variable} ++@end smallexample ++ ++@noindent ++Here @var{file} or @var{function} is the name of the context for the ++static @var{variable}. In the case of file names, you can use quotes to ++make sure @value{GDBN} parses the file name as a single word---for example, ++to print a global value of @code{x} defined in @file{f2.c}: ++ ++@smallexample ++(@value{GDBP}) p 'f2.c'::x ++@end smallexample ++ ++The @code{::} notation is normally used for referring to ++static variables, since you typically disambiguate uses of local variables ++in functions by selecting the appropriate frame and using the ++simple name of the variable. However, you may also use this notation ++to refer to local variables in frames enclosing the selected frame: ++ ++@smallexample ++void ++foo (int a) ++@{ ++ if (a < 10) ++ bar (a); ++ else ++ process (a); /* Stop here */ ++@} ++ ++int ++bar (int a) ++@{ ++ foo (a + 5); ++@} ++@end smallexample ++ ++@noindent ++For example, if there is a breakpoint at the commented line, ++here is what you might see ++when the program stops after executing the call @code{bar(0)}: ++ ++@smallexample ++(@value{GDBP}) p a ++$1 = 10 ++(@value{GDBP}) p bar::a ++$2 = 5 ++(@value{GDBP}) up 2 ++#2 0x080483d0 in foo (a=5) at foobar.c:12 ++(@value{GDBP}) p a ++$3 = 5 ++(@value{GDBP}) p bar::a ++$4 = 0 ++@end smallexample ++ ++@cindex C@t{++} scope resolution ++These uses of @samp{::} are very rarely in conflict with the very ++similar use of the same notation in C@t{++}. When they are in ++conflict, the C@t{++} meaning takes precedence; however, this can be ++overridden by quoting the file or function name with single quotes. ++ ++For example, suppose the program is stopped in a method of a class ++that has a field named @code{includefile}, and there is also an ++include file named @file{includefile} that defines a variable, ++@code{some_global}. ++ ++@smallexample ++(@value{GDBP}) p includefile ++$1 = 23 ++(@value{GDBP}) p includefile::some_global ++A syntax error in expression, near `'. ++(@value{GDBP}) p 'includefile'::some_global ++$2 = 27 ++@end smallexample ++ ++@cindex wrong values ++@cindex variable values, wrong ++@cindex function entry/exit, wrong values of variables ++@cindex optimized code, wrong values of variables ++@quotation ++@emph{Warning:} Occasionally, a local variable may appear to have the ++wrong value at certain points in a function---just after entry to a new ++scope, and just before exit. ++@end quotation ++You may see this problem when you are stepping by machine instructions. ++This is because, on most machines, it takes more than one instruction to ++set up a stack frame (including local variable definitions); if you are ++stepping by machine instructions, variables may appear to have the wrong ++values until the stack frame is completely built. On exit, it usually ++also takes more than one machine instruction to destroy a stack frame; ++after you begin stepping through that group of instructions, local ++variable definitions may be gone. ++ ++This may also happen when the compiler does significant optimizations. ++To be sure of always seeing accurate values, turn off all optimization ++when compiling. ++ ++@cindex ``No symbol "foo" in current context'' ++Another possible effect of compiler optimizations is to optimize ++unused variables out of existence, or assign variables to registers (as ++opposed to memory addresses). Depending on the support for such cases ++offered by the debug info format used by the compiler, @value{GDBN} ++might not be able to display values for such local variables. If that ++happens, @value{GDBN} will print a message like this: ++ ++@smallexample ++No symbol "foo" in current context. ++@end smallexample ++ ++To solve such problems, either recompile without optimizations, or use a ++different debug info format, if the compiler supports several such ++formats. @xref{Compilation}, for more information on choosing compiler ++options. @xref{C, ,C and C@t{++}}, for more information about debug ++info formats that are best suited to C@t{++} programs. ++ ++If you ask to print an object whose contents are unknown to ++@value{GDBN}, e.g., because its data type is not completely specified ++by the debug information, @value{GDBN} will say @samp{}. @xref{Symbols, incomplete type}, for more about this. ++ ++@cindex no debug info variables ++If you try to examine or use the value of a (global) variable for ++which @value{GDBN} has no type information, e.g., because the program ++includes no debug information, @value{GDBN} displays an error message. ++@xref{Symbols, unknown type}, for more about unknown types. If you ++cast the variable to its declared type, @value{GDBN} gets the ++variable's value using the cast-to type as the variable's type. For ++example, in a C program: ++ ++@smallexample ++ (@value{GDBP}) p var ++ 'var' has unknown type; cast it to its declared type ++ (@value{GDBP}) p (float) var ++ $1 = 3.14 ++@end smallexample ++ ++If you append @kbd{@@entry} string to a function parameter name you get its ++value at the time the function got called. If the value is not available an ++error message is printed. Entry values are available only with some compilers. ++Entry values are normally also printed at the function parameter list according ++to @ref{set print entry-values}. ++ ++@smallexample ++Breakpoint 1, d (i=30) at gdb.base/entry-value.c:29 ++29 i++; ++(gdb) next ++30 e (i); ++(gdb) print i ++$1 = 31 ++(gdb) print i@@entry ++$2 = 30 ++@end smallexample ++ ++Strings are identified as arrays of @code{char} values without specified ++signedness. Arrays of either @code{signed char} or @code{unsigned char} get ++printed as arrays of 1 byte sized integers. @code{-fsigned-char} or ++@code{-funsigned-char} @value{NGCC} options have no effect as @value{GDBN} ++defines literal string type @code{"char"} as @code{char} without a sign. ++For program code ++ ++@smallexample ++char var0[] = "A"; ++signed char var1[] = "A"; ++@end smallexample ++ ++You get during debugging ++@smallexample ++(gdb) print var0 ++$1 = "A" ++(gdb) print var1 ++$2 = @{65 'A', 0 '\0'@} ++@end smallexample ++ ++@node Arrays ++@section Artificial Arrays ++ ++@cindex artificial array ++@cindex arrays ++@kindex @@@r{, referencing memory as an array} ++It is often useful to print out several successive objects of the ++same type in memory; a section of an array, or an array of ++dynamically determined size for which only a pointer exists in the ++program. ++ ++You can do this by referring to a contiguous span of memory as an ++@dfn{artificial array}, using the binary operator @samp{@@}. The left ++operand of @samp{@@} should be the first element of the desired array ++and be an individual object. The right operand should be the desired length ++of the array. The result is an array value whose elements are all of ++the type of the left argument. The first element is actually the left ++argument; the second element comes from bytes of memory immediately ++following those that hold the first element, and so on. Here is an ++example. If a program says ++ ++@smallexample ++int *array = (int *) malloc (len * sizeof (int)); ++@end smallexample ++ ++@noindent ++you can print the contents of @code{array} with ++ ++@smallexample ++p *array@@len ++@end smallexample ++ ++The left operand of @samp{@@} must reside in memory. Array values made ++with @samp{@@} in this way behave just like other arrays in terms of ++subscripting, and are coerced to pointers when used in expressions. ++Artificial arrays most often appear in expressions via the value history ++(@pxref{Value History, ,Value History}), after printing one out. ++ ++Another way to create an artificial array is to use a cast. ++This re-interprets a value as if it were an array. ++The value need not be in memory: ++@smallexample ++(@value{GDBP}) p/x (short[2])0x12345678 ++$1 = @{0x1234, 0x5678@} ++@end smallexample ++ ++As a convenience, if you leave the array length out (as in ++@samp{(@var{type}[])@var{value}}) @value{GDBN} calculates the size to fill ++the value (as @samp{sizeof(@var{value})/sizeof(@var{type})}: ++@smallexample ++(@value{GDBP}) p/x (short[])0x12345678 ++$2 = @{0x1234, 0x5678@} ++@end smallexample ++ ++Sometimes the artificial array mechanism is not quite enough; in ++moderately complex data structures, the elements of interest may not ++actually be adjacent---for example, if you are interested in the values ++of pointers in an array. One useful work-around in this situation is ++to use a convenience variable (@pxref{Convenience Vars, ,Convenience ++Variables}) as a counter in an expression that prints the first ++interesting value, and then repeat that expression via @key{RET}. For ++instance, suppose you have an array @code{dtab} of pointers to ++structures, and you are interested in the values of a field @code{fv} ++in each structure. Here is an example of what you might type: ++ ++@smallexample ++set $i = 0 ++p dtab[$i++]->fv ++@key{RET} ++@key{RET} ++@dots{} ++@end smallexample ++ ++@node Output Formats ++@section Output Formats ++ ++@cindex formatted output ++@cindex output formats ++By default, @value{GDBN} prints a value according to its data type. Sometimes ++this is not what you want. For example, you might want to print a number ++in hex, or a pointer in decimal. Or you might want to view data in memory ++at a certain address as a character string or as an instruction. To do ++these things, specify an @dfn{output format} when you print a value. ++ ++The simplest use of output formats is to say how to print a value ++already computed. This is done by starting the arguments of the ++@code{print} command with a slash and a format letter. The format ++letters supported are: ++ ++@table @code ++@item x ++Regard the bits of the value as an integer, and print the integer in ++hexadecimal. ++ ++@item d ++Print as integer in signed decimal. ++ ++@item u ++Print as integer in unsigned decimal. ++ ++@item o ++Print as integer in octal. ++ ++@item t ++Print as integer in binary. The letter @samp{t} stands for ``two''. ++@footnote{@samp{b} cannot be used because these format letters are also ++used with the @code{x} command, where @samp{b} stands for ``byte''; ++see @ref{Memory,,Examining Memory}.} ++ ++@item a ++@cindex unknown address, locating ++@cindex locate address ++Print as an address, both absolute in hexadecimal and as an offset from ++the nearest preceding symbol. You can use this format used to discover ++where (in what function) an unknown address is located: ++ ++@smallexample ++(@value{GDBP}) p/a 0x54320 ++$3 = 0x54320 <_initialize_vx+396> ++@end smallexample ++ ++@noindent ++The command @code{info symbol 0x54320} yields similar results. ++@xref{Symbols, info symbol}. ++ ++@item c ++Regard as an integer and print it as a character constant. This ++prints both the numerical value and its character representation. The ++character representation is replaced with the octal escape @samp{\nnn} ++for characters outside the 7-bit @sc{ascii} range. ++ ++Without this format, @value{GDBN} displays @code{char}, ++@w{@code{unsigned char}}, and @w{@code{signed char}} data as character ++constants. Single-byte members of vectors are displayed as integer ++data. ++ ++@item f ++Regard the bits of the value as a floating point number and print ++using typical floating point syntax. ++ ++@item s ++@cindex printing strings ++@cindex printing byte arrays ++Regard as a string, if possible. With this format, pointers to single-byte ++data are displayed as null-terminated strings and arrays of single-byte data ++are displayed as fixed-length strings. Other values are displayed in their ++natural types. ++ ++Without this format, @value{GDBN} displays pointers to and arrays of ++@code{char}, @w{@code{unsigned char}}, and @w{@code{signed char}} as ++strings. Single-byte members of a vector are displayed as an integer ++array. ++ ++@item z ++Like @samp{x} formatting, the value is treated as an integer and ++printed as hexadecimal, but leading zeros are printed to pad the value ++to the size of the integer type. ++ ++@item r ++@cindex raw printing ++Print using the @samp{raw} formatting. By default, @value{GDBN} will ++use a Python-based pretty-printer, if one is available (@pxref{Pretty ++Printing}). This typically results in a higher-level display of the ++value's contents. The @samp{r} format bypasses any Python ++pretty-printer which might exist. ++@end table ++ ++For example, to print the program counter in hex (@pxref{Registers}), type ++ ++@smallexample ++p/x $pc ++@end smallexample ++ ++@noindent ++Note that no space is required before the slash; this is because command ++names in @value{GDBN} cannot contain a slash. ++ ++To reprint the last value in the value history with a different format, ++you can use the @code{print} command with just a format and no ++expression. For example, @samp{p/x} reprints the last value in hex. ++ ++@node Memory ++@section Examining Memory ++ ++You can use the command @code{x} (for ``examine'') to examine memory in ++any of several formats, independently of your program's data types. ++ ++@cindex examining memory ++@table @code ++@kindex x @r{(examine memory)} ++@item x/@var{nfu} @var{addr} ++@itemx x @var{addr} ++@itemx x ++Use the @code{x} command to examine memory. ++@end table ++ ++@var{n}, @var{f}, and @var{u} are all optional parameters that specify how ++much memory to display and how to format it; @var{addr} is an ++expression giving the address where you want to start displaying memory. ++If you use defaults for @var{nfu}, you need not type the slash @samp{/}. ++Several commands set convenient defaults for @var{addr}. ++ ++@table @r ++@item @var{n}, the repeat count ++The repeat count is a decimal integer; the default is 1. It specifies ++how much memory (counting by units @var{u}) to display. If a negative ++number is specified, memory is examined backward from @var{addr}. ++@c This really is **decimal**; unaffected by 'set radix' as of GDB ++@c 4.1.2. ++ ++@item @var{f}, the display format ++The display format is one of the formats used by @code{print} ++(@samp{x}, @samp{d}, @samp{u}, @samp{o}, @samp{t}, @samp{a}, @samp{c}, ++@samp{f}, @samp{s}), and in addition @samp{i} (for machine instructions). ++The default is @samp{x} (hexadecimal) initially. The default changes ++each time you use either @code{x} or @code{print}. ++ ++@item @var{u}, the unit size ++The unit size is any of ++ ++@table @code ++@item b ++Bytes. ++@item h ++Halfwords (two bytes). ++@item w ++Words (four bytes). This is the initial default. ++@item g ++Giant words (eight bytes). ++@end table ++ ++Each time you specify a unit size with @code{x}, that size becomes the ++default unit the next time you use @code{x}. For the @samp{i} format, ++the unit size is ignored and is normally not written. For the @samp{s} format, ++the unit size defaults to @samp{b}, unless it is explicitly given. ++Use @kbd{x /hs} to display 16-bit char strings and @kbd{x /ws} to display ++32-bit strings. The next use of @kbd{x /s} will again display 8-bit strings. ++Note that the results depend on the programming language of the ++current compilation unit. If the language is C, the @samp{s} ++modifier will use the UTF-16 encoding while @samp{w} will use ++UTF-32. The encoding is set by the programming language and cannot ++be altered. ++ ++@item @var{addr}, starting display address ++@var{addr} is the address where you want @value{GDBN} to begin displaying ++memory. The expression need not have a pointer value (though it may); ++it is always interpreted as an integer address of a byte of memory. ++@xref{Expressions, ,Expressions}, for more information on expressions. The default for ++@var{addr} is usually just after the last address examined---but several ++other commands also set the default address: @code{info breakpoints} (to ++the address of the last breakpoint listed), @code{info line} (to the ++starting address of a line), and @code{print} (if you use it to display ++a value from memory). ++@end table ++ ++For example, @samp{x/3uh 0x54320} is a request to display three halfwords ++(@code{h}) of memory, formatted as unsigned decimal integers (@samp{u}), ++starting at address @code{0x54320}. @samp{x/4xw $sp} prints the four ++words (@samp{w}) of memory above the stack pointer (here, @samp{$sp}; ++@pxref{Registers, ,Registers}) in hexadecimal (@samp{x}). ++ ++You can also specify a negative repeat count to examine memory backward ++from the given address. For example, @samp{x/-3uh 0x54320} prints three ++halfwords (@code{h}) at @code{0x54314}, @code{0x54328}, and @code{0x5431c}. ++ ++Since the letters indicating unit sizes are all distinct from the ++letters specifying output formats, you do not have to remember whether ++unit size or format comes first; either order works. The output ++specifications @samp{4xw} and @samp{4wx} mean exactly the same thing. ++(However, the count @var{n} must come first; @samp{wx4} does not work.) ++ ++Even though the unit size @var{u} is ignored for the formats @samp{s} ++and @samp{i}, you might still want to use a count @var{n}; for example, ++@samp{3i} specifies that you want to see three machine instructions, ++including any operands. For convenience, especially when used with ++the @code{display} command, the @samp{i} format also prints branch delay ++slot instructions, if any, beyond the count specified, which immediately ++follow the last instruction that is within the count. The command ++@code{disassemble} gives an alternative way of inspecting machine ++instructions; see @ref{Machine Code,,Source and Machine Code}. ++ ++If a negative repeat count is specified for the formats @samp{s} or @samp{i}, ++the command displays null-terminated strings or instructions before the given ++address as many as the absolute value of the given number. For the @samp{i} ++format, we use line number information in the debug info to accurately locate ++instruction boundaries while disassembling backward. If line info is not ++available, the command stops examining memory with an error message. ++ ++All the defaults for the arguments to @code{x} are designed to make it ++easy to continue scanning memory with minimal specifications each time ++you use @code{x}. For example, after you have inspected three machine ++instructions with @samp{x/3i @var{addr}}, you can inspect the next seven ++with just @samp{x/7}. If you use @key{RET} to repeat the @code{x} command, ++the repeat count @var{n} is used again; the other arguments default as ++for successive uses of @code{x}. ++ ++When examining machine instructions, the instruction at current program ++counter is shown with a @code{=>} marker. For example: ++ ++@smallexample ++(@value{GDBP}) x/5i $pc-6 ++ 0x804837f : mov %esp,%ebp ++ 0x8048381 : push %ecx ++ 0x8048382 : sub $0x4,%esp ++=> 0x8048385 : movl $0x8048460,(%esp) ++ 0x804838c : call 0x80482d4 ++@end smallexample ++ ++@cindex @code{$_}, @code{$__}, and value history ++The addresses and contents printed by the @code{x} command are not saved ++in the value history because there is often too much of them and they ++would get in the way. Instead, @value{GDBN} makes these values available for ++subsequent use in expressions as values of the convenience variables ++@code{$_} and @code{$__}. After an @code{x} command, the last address ++examined is available for use in expressions in the convenience variable ++@code{$_}. The contents of that address, as examined, are available in ++the convenience variable @code{$__}. ++ ++If the @code{x} command has a repeat count, the address and contents saved ++are from the last memory unit printed; this is not the same as the last ++address printed if several units were printed on the last line of output. ++ ++@anchor{addressable memory unit} ++@cindex addressable memory unit ++Most targets have an addressable memory unit size of 8 bits. This means ++that to each memory address are associated 8 bits of data. Some ++targets, however, have other addressable memory unit sizes. ++Within @value{GDBN} and this document, the term ++@dfn{addressable memory unit} (or @dfn{memory unit} for short) is used ++when explicitly referring to a chunk of data of that size. The word ++@dfn{byte} is used to refer to a chunk of data of 8 bits, regardless of ++the addressable memory unit size of the target. For most systems, ++addressable memory unit is a synonym of byte. ++ ++@cindex remote memory comparison ++@cindex target memory comparison ++@cindex verify remote memory image ++@cindex verify target memory image ++When you are debugging a program running on a remote target machine ++(@pxref{Remote Debugging}), you may wish to verify the program's image ++in the remote machine's memory against the executable file you ++downloaded to the target. Or, on any target, you may want to check ++whether the program has corrupted its own read-only sections. The ++@code{compare-sections} command is provided for such situations. ++ ++@table @code ++@kindex compare-sections ++@item compare-sections @r{[}@var{section-name}@r{|}@code{-r}@r{]} ++Compare the data of a loadable section @var{section-name} in the ++executable file of the program being debugged with the same section in ++the target machine's memory, and report any mismatches. With no ++arguments, compares all loadable sections. With an argument of ++@code{-r}, compares all loadable read-only sections. ++ ++Note: for remote targets, this command can be accelerated if the ++target supports computing the CRC checksum of a block of memory ++(@pxref{qCRC packet}). ++@end table ++ ++@node Auto Display ++@section Automatic Display ++@cindex automatic display ++@cindex display of expressions ++ ++If you find that you want to print the value of an expression frequently ++(to see how it changes), you might want to add it to the @dfn{automatic ++display list} so that @value{GDBN} prints its value each time your program stops. ++Each expression added to the list is given a number to identify it; ++to remove an expression from the list, you specify that number. ++The automatic display looks like this: ++ ++@smallexample ++2: foo = 38 ++3: bar[5] = (struct hack *) 0x3804 ++@end smallexample ++ ++@noindent ++This display shows item numbers, expressions and their current values. As with ++displays you request manually using @code{x} or @code{print}, you can ++specify the output format you prefer; in fact, @code{display} decides ++whether to use @code{print} or @code{x} depending your format ++specification---it uses @code{x} if you specify either the @samp{i} ++or @samp{s} format, or a unit size; otherwise it uses @code{print}. ++ ++@table @code ++@kindex display ++@item display @var{expr} ++Add the expression @var{expr} to the list of expressions to display ++each time your program stops. @xref{Expressions, ,Expressions}. ++ ++@code{display} does not repeat if you press @key{RET} again after using it. ++ ++@item display/@var{fmt} @var{expr} ++For @var{fmt} specifying only a display format and not a size or ++count, add the expression @var{expr} to the auto-display list but ++arrange to display it each time in the specified format @var{fmt}. ++@xref{Output Formats,,Output Formats}. ++ ++@item display/@var{fmt} @var{addr} ++For @var{fmt} @samp{i} or @samp{s}, or including a unit-size or a ++number of units, add the expression @var{addr} as a memory address to ++be examined each time your program stops. Examining means in effect ++doing @samp{x/@var{fmt} @var{addr}}. @xref{Memory, ,Examining Memory}. ++@end table ++ ++For example, @samp{display/i $pc} can be helpful, to see the machine ++instruction about to be executed each time execution stops (@samp{$pc} ++is a common name for the program counter; @pxref{Registers, ,Registers}). ++ ++@table @code ++@kindex delete display ++@kindex undisplay ++@item undisplay @var{dnums}@dots{} ++@itemx delete display @var{dnums}@dots{} ++Remove items from the list of expressions to display. Specify the ++numbers of the displays that you want affected with the command ++argument @var{dnums}. It can be a single display number, one of the ++numbers shown in the first field of the @samp{info display} display; ++or it could be a range of display numbers, as in @code{2-4}. ++ ++@code{undisplay} does not repeat if you press @key{RET} after using it. ++(Otherwise you would just get the error @samp{No display number @dots{}}.) ++ ++@kindex disable display ++@item disable display @var{dnums}@dots{} ++Disable the display of item numbers @var{dnums}. A disabled display ++item is not printed automatically, but is not forgotten. It may be ++enabled again later. Specify the numbers of the displays that you ++want affected with the command argument @var{dnums}. It can be a ++single display number, one of the numbers shown in the first field of ++the @samp{info display} display; or it could be a range of display ++numbers, as in @code{2-4}. ++ ++@kindex enable display ++@item enable display @var{dnums}@dots{} ++Enable display of item numbers @var{dnums}. It becomes effective once ++again in auto display of its expression, until you specify otherwise. ++Specify the numbers of the displays that you want affected with the ++command argument @var{dnums}. It can be a single display number, one ++of the numbers shown in the first field of the @samp{info display} ++display; or it could be a range of display numbers, as in @code{2-4}. ++ ++@item display ++Display the current values of the expressions on the list, just as is ++done when your program stops. ++ ++@kindex info display ++@item info display ++Print the list of expressions previously set up to display ++automatically, each one with its item number, but without showing the ++values. This includes disabled expressions, which are marked as such. ++It also includes expressions which would not be displayed right now ++because they refer to automatic variables not currently available. ++@end table ++ ++@cindex display disabled out of scope ++If a display expression refers to local variables, then it does not make ++sense outside the lexical context for which it was set up. Such an ++expression is disabled when execution enters a context where one of its ++variables is not defined. For example, if you give the command ++@code{display last_char} while inside a function with an argument ++@code{last_char}, @value{GDBN} displays this argument while your program ++continues to stop inside that function. When it stops elsewhere---where ++there is no variable @code{last_char}---the display is disabled ++automatically. The next time your program stops where @code{last_char} ++is meaningful, you can enable the display expression once again. ++ ++@node Print Settings ++@section Print Settings ++ ++@cindex format options ++@cindex print settings ++@value{GDBN} provides the following ways to control how arrays, structures, ++and symbols are printed. ++ ++@noindent ++These settings are useful for debugging programs in any language: ++ ++@table @code ++@kindex set print ++@anchor{set print address} ++@item set print address ++@itemx set print address on ++@cindex print/don't print memory addresses ++@value{GDBN} prints memory addresses showing the location of stack ++traces, structure values, pointer values, breakpoints, and so forth, ++even when it also displays the contents of those addresses. The default ++is @code{on}. For example, this is what a stack frame display looks like with ++@code{set print address on}: ++ ++@smallexample ++@group ++(@value{GDBP}) f ++#0 set_quotes (lq=0x34c78 "<<", rq=0x34c88 ">>") ++ at input.c:530 ++530 if (lquote != def_lquote) ++@end group ++@end smallexample ++ ++@item set print address off ++Do not print addresses when displaying their contents. For example, ++this is the same stack frame displayed with @code{set print address off}: ++ ++@smallexample ++@group ++(@value{GDBP}) set print addr off ++(@value{GDBP}) f ++#0 set_quotes (lq="<<", rq=">>") at input.c:530 ++530 if (lquote != def_lquote) ++@end group ++@end smallexample ++ ++You can use @samp{set print address off} to eliminate all machine ++dependent displays from the @value{GDBN} interface. For example, with ++@code{print address off}, you should get the same text for backtraces on ++all machines---whether or not they involve pointer arguments. ++ ++@kindex show print ++@item show print address ++Show whether or not addresses are to be printed. ++@end table ++ ++When @value{GDBN} prints a symbolic address, it normally prints the ++closest earlier symbol plus an offset. If that symbol does not uniquely ++identify the address (for example, it is a name whose scope is a single ++source file), you may need to clarify. One way to do this is with ++@code{info line}, for example @samp{info line *0x4537}. Alternately, ++you can set @value{GDBN} to print the source file and line number when ++it prints a symbolic address: ++ ++@table @code ++@item set print symbol-filename on ++@cindex source file and line of a symbol ++@cindex symbol, source file and line ++Tell @value{GDBN} to print the source file name and line number of a ++symbol in the symbolic form of an address. ++ ++@item set print symbol-filename off ++Do not print source file name and line number of a symbol. This is the ++default. ++ ++@item show print symbol-filename ++Show whether or not @value{GDBN} will print the source file name and ++line number of a symbol in the symbolic form of an address. ++@end table ++ ++Another situation where it is helpful to show symbol filenames and line ++numbers is when disassembling code; @value{GDBN} shows you the line ++number and source file that corresponds to each instruction. ++ ++Also, you may wish to see the symbolic form only if the address being ++printed is reasonably close to the closest earlier symbol: ++ ++@table @code ++@item set print max-symbolic-offset @var{max-offset} ++@itemx set print max-symbolic-offset unlimited ++@cindex maximum value for offset of closest symbol ++Tell @value{GDBN} to only display the symbolic form of an address if the ++offset between the closest earlier symbol and the address is less than ++@var{max-offset}. The default is @code{unlimited}, which tells @value{GDBN} ++to always print the symbolic form of an address if any symbol precedes ++it. Zero is equivalent to @code{unlimited}. ++ ++@item show print max-symbolic-offset ++Ask how large the maximum offset is that @value{GDBN} prints in a ++symbolic address. ++@end table ++ ++@cindex wild pointer, interpreting ++@cindex pointer, finding referent ++If you have a pointer and you are not sure where it points, try ++@samp{set print symbol-filename on}. Then you can determine the name ++and source file location of the variable where it points, using ++@samp{p/a @var{pointer}}. This interprets the address in symbolic form. ++For example, here @value{GDBN} shows that a variable @code{ptt} points ++at another variable @code{t}, defined in @file{hi2.c}: ++ ++@smallexample ++(@value{GDBP}) set print symbol-filename on ++(@value{GDBP}) p/a ptt ++$4 = 0xe008 ++@end smallexample ++ ++@quotation ++@emph{Warning:} For pointers that point to a local variable, @samp{p/a} ++does not show the symbol name and filename of the referent, even with ++the appropriate @code{set print} options turned on. ++@end quotation ++ ++You can also enable @samp{/a}-like formatting all the time using ++@samp{set print symbol on}: ++ ++@anchor{set print symbol} ++@table @code ++@item set print symbol on ++Tell @value{GDBN} to print the symbol corresponding to an address, if ++one exists. ++ ++@item set print symbol off ++Tell @value{GDBN} not to print the symbol corresponding to an ++address. In this mode, @value{GDBN} will still print the symbol ++corresponding to pointers to functions. This is the default. ++ ++@item show print symbol ++Show whether @value{GDBN} will display the symbol corresponding to an ++address. ++@end table ++ ++Other settings control how different kinds of objects are printed: ++ ++@table @code ++@anchor{set print array} ++@item set print array ++@itemx set print array on ++@cindex pretty print arrays ++Pretty print arrays. This format is more convenient to read, ++but uses more space. The default is off. ++ ++@item set print array off ++Return to compressed format for arrays. ++ ++@item show print array ++Show whether compressed or pretty format is selected for displaying ++arrays. ++ ++@cindex print array indexes ++@anchor{set print array-indexes} ++@item set print array-indexes ++@itemx set print array-indexes on ++Print the index of each element when displaying arrays. May be more ++convenient to locate a given element in the array or quickly find the ++index of a given element in that printed array. The default is off. ++ ++@item set print array-indexes off ++Stop printing element indexes when displaying arrays. ++ ++@item show print array-indexes ++Show whether the index of each element is printed when displaying ++arrays. ++ ++@anchor{set print elements} ++@item set print elements @var{number-of-elements} ++@itemx set print elements unlimited ++@cindex number of array elements to print ++@cindex limit on number of printed array elements ++Set a limit on how many elements of an array @value{GDBN} will print. ++If @value{GDBN} is printing a large array, it stops printing after it has ++printed the number of elements set by the @code{set print elements} command. ++This limit also applies to the display of strings. ++When @value{GDBN} starts, this limit is set to 200. ++Setting @var{number-of-elements} to @code{unlimited} or zero means ++that the number of elements to print is unlimited. ++ ++@item show print elements ++Display the number of elements of a large array that @value{GDBN} will print. ++If the number is 0, then the printing is unlimited. ++ ++@anchor{set print frame-arguments} ++@item set print frame-arguments @var{value} ++@kindex set print frame-arguments ++@cindex printing frame argument values ++@cindex print all frame argument values ++@cindex print frame argument values for scalars only ++@cindex do not print frame arguments ++This command allows to control how the values of arguments are printed ++when the debugger prints a frame (@pxref{Frames}). The possible ++values are: ++ ++@table @code ++@item all ++The values of all arguments are printed. ++ ++@item scalars ++Print the value of an argument only if it is a scalar. The value of more ++complex arguments such as arrays, structures, unions, etc, is replaced ++by @code{@dots{}}. This is the default. Here is an example where ++only scalar arguments are shown: ++ ++@smallexample ++#1 0x08048361 in call_me (i=3, s=@dots{}, ss=0xbf8d508c, u=@dots{}, e=green) ++ at frame-args.c:23 ++@end smallexample ++ ++@item none ++None of the argument values are printed. Instead, the value of each argument ++is replaced by @code{@dots{}}. In this case, the example above now becomes: ++ ++@smallexample ++#1 0x08048361 in call_me (i=@dots{}, s=@dots{}, ss=@dots{}, u=@dots{}, e=@dots{}) ++ at frame-args.c:23 ++@end smallexample ++ ++@item presence ++Only the presence of arguments is indicated by @code{@dots{}}. ++The @code{@dots{}} are not printed for function without any arguments. ++None of the argument names and values are printed. ++In this case, the example above now becomes: ++ ++@smallexample ++#1 0x08048361 in call_me (@dots{}) at frame-args.c:23 ++@end smallexample ++ ++@end table ++ ++By default, only scalar arguments are printed. This command can be used ++to configure the debugger to print the value of all arguments, regardless ++of their type. However, it is often advantageous to not print the value ++of more complex parameters. For instance, it reduces the amount of ++information printed in each frame, making the backtrace more readable. ++Also, it improves performance when displaying Ada frames, because ++the computation of large arguments can sometimes be CPU-intensive, ++especially in large applications. Setting @code{print frame-arguments} ++to @code{scalars} (the default), @code{none} or @code{presence} avoids ++this computation, thus speeding up the display of each Ada frame. ++ ++@item show print frame-arguments ++Show how the value of arguments should be displayed when printing a frame. ++ ++@anchor{set print raw-frame-arguments} ++@item set print raw-frame-arguments on ++Print frame arguments in raw, non pretty-printed, form. ++ ++@item set print raw-frame-arguments off ++Print frame arguments in pretty-printed form, if there is a pretty-printer ++for the value (@pxref{Pretty Printing}), ++otherwise print the value in raw form. ++This is the default. ++ ++@item show print raw-frame-arguments ++Show whether to print frame arguments in raw form. ++ ++@anchor{set print entry-values} ++@item set print entry-values @var{value} ++@kindex set print entry-values ++Set printing of frame argument values at function entry. In some cases ++@value{GDBN} can determine the value of function argument which was passed by ++the function caller, even if the value was modified inside the called function ++and therefore is different. With optimized code, the current value could be ++unavailable, but the entry value may still be known. ++ ++The default value is @code{default} (see below for its description). Older ++@value{GDBN} behaved as with the setting @code{no}. Compilers not supporting ++this feature will behave in the @code{default} setting the same way as with the ++@code{no} setting. ++ ++This functionality is currently supported only by DWARF 2 debugging format and ++the compiler has to produce @samp{DW_TAG_call_site} tags. With ++@value{NGCC}, you need to specify @option{-O -g} during compilation, to get ++this information. ++ ++The @var{value} parameter can be one of the following: ++ ++@table @code ++@item no ++Print only actual parameter values, never print values from function entry ++point. ++@smallexample ++#0 equal (val=5) ++#0 different (val=6) ++#0 lost (val=) ++#0 born (val=10) ++#0 invalid (val=) ++@end smallexample ++ ++@item only ++Print only parameter values from function entry point. The actual parameter ++values are never printed. ++@smallexample ++#0 equal (val@@entry=5) ++#0 different (val@@entry=5) ++#0 lost (val@@entry=5) ++#0 born (val@@entry=) ++#0 invalid (val@@entry=) ++@end smallexample ++ ++@item preferred ++Print only parameter values from function entry point. If value from function ++entry point is not known while the actual value is known, print the actual ++value for such parameter. ++@smallexample ++#0 equal (val@@entry=5) ++#0 different (val@@entry=5) ++#0 lost (val@@entry=5) ++#0 born (val=10) ++#0 invalid (val@@entry=) ++@end smallexample ++ ++@item if-needed ++Print actual parameter values. If actual parameter value is not known while ++value from function entry point is known, print the entry point value for such ++parameter. ++@smallexample ++#0 equal (val=5) ++#0 different (val=6) ++#0 lost (val@@entry=5) ++#0 born (val=10) ++#0 invalid (val=) ++@end smallexample ++ ++@item both ++Always print both the actual parameter value and its value from function entry ++point, even if values of one or both are not available due to compiler ++optimizations. ++@smallexample ++#0 equal (val=5, val@@entry=5) ++#0 different (val=6, val@@entry=5) ++#0 lost (val=, val@@entry=5) ++#0 born (val=10, val@@entry=) ++#0 invalid (val=, val@@entry=) ++@end smallexample ++ ++@item compact ++Print the actual parameter value if it is known and also its value from ++function entry point if it is known. If neither is known, print for the actual ++value @code{}. If not in MI mode (@pxref{GDB/MI}) and if both ++values are known and identical, print the shortened ++@code{param=param@@entry=VALUE} notation. ++@smallexample ++#0 equal (val=val@@entry=5) ++#0 different (val=6, val@@entry=5) ++#0 lost (val@@entry=5) ++#0 born (val=10) ++#0 invalid (val=) ++@end smallexample ++ ++@item default ++Always print the actual parameter value. Print also its value from function ++entry point, but only if it is known. If not in MI mode (@pxref{GDB/MI}) and ++if both values are known and identical, print the shortened ++@code{param=param@@entry=VALUE} notation. ++@smallexample ++#0 equal (val=val@@entry=5) ++#0 different (val=6, val@@entry=5) ++#0 lost (val=, val@@entry=5) ++#0 born (val=10) ++#0 invalid (val=) ++@end smallexample ++@end table ++ ++For analysis messages on possible failures of frame argument values at function ++entry resolution see @ref{set debug entry-values}. ++ ++@item show print entry-values ++Show the method being used for printing of frame argument values at function ++entry. ++ ++@anchor{set print frame-info} ++@item set print frame-info @var{value} ++@kindex set print frame-info ++@cindex printing frame information ++@cindex frame information, printing ++This command allows to control the information printed when ++the debugger prints a frame. See @ref{Frames}, @ref{Backtrace}, ++for a general explanation about frames and frame information. ++Note that some other settings (such as @code{set print frame-arguments} ++and @code{set print address}) are also influencing if and how some frame ++information is displayed. In particular, the frame program counter is never ++printed if @code{set print address} is off. ++ ++The possible values for @code{set print frame-info} are: ++@table @code ++@item short-location ++Print the frame level, the program counter (if not at the ++beginning of the location source line), the function, the function ++arguments. ++@item location ++Same as @code{short-location} but also print the source file and source line ++number. ++@item location-and-address ++Same as @code{location} but print the program counter even if located at the ++beginning of the location source line. ++@item source-line ++Print the program counter (if not at the beginning of the location ++source line), the line number and the source line. ++@item source-and-location ++Print what @code{location} and @code{source-line} are printing. ++@item auto ++The information printed for a frame is decided automatically ++by the @value{GDBN} command that prints a frame. ++For example, @code{frame} prints the information printed by ++@code{source-and-location} while @code{stepi} will switch between ++@code{source-line} and @code{source-and-location} depending on the program ++counter. ++The default value is @code{auto}. ++@end table ++ ++@anchor{set print repeats} ++@item set print repeats @var{number-of-repeats} ++@itemx set print repeats unlimited ++@cindex repeated array elements ++Set the threshold for suppressing display of repeated array ++elements. When the number of consecutive identical elements of an ++array exceeds the threshold, @value{GDBN} prints the string ++@code{""}, where @var{n} is the number of ++identical repetitions, instead of displaying the identical elements ++themselves. Setting the threshold to @code{unlimited} or zero will ++cause all elements to be individually printed. The default threshold ++is 10. ++ ++@item show print repeats ++Display the current threshold for printing repeated identical ++elements. ++ ++@anchor{set print max-depth} ++@item set print max-depth @var{depth} ++@item set print max-depth unlimited ++@cindex printing nested structures ++Set the threshold after which nested structures are replaced with ++ellipsis, this can make visualising deeply nested structures easier. ++ ++For example, given this C code ++ ++@smallexample ++typedef struct s1 @{ int a; @} s1; ++typedef struct s2 @{ s1 b; @} s2; ++typedef struct s3 @{ s2 c; @} s3; ++typedef struct s4 @{ s3 d; @} s4; ++ ++s4 var = @{ @{ @{ @{ 3 @} @} @} @}; ++@end smallexample ++ ++The following table shows how different values of @var{depth} will ++effect how @code{var} is printed by @value{GDBN}: ++ ++@multitable @columnfractions .3 .7 ++@headitem @var{depth} setting @tab Result of @samp{p var} ++@item unlimited ++@tab @code{$1 = @{d = @{c = @{b = @{a = 3@}@}@}@}} ++@item @code{0} ++@tab @code{$1 = @{...@}} ++@item @code{1} ++@tab @code{$1 = @{d = @{...@}@}} ++@item @code{2} ++@tab @code{$1 = @{d = @{c = @{...@}@}@}} ++@item @code{3} ++@tab @code{$1 = @{d = @{c = @{b = @{...@}@}@}@}} ++@item @code{4} ++@tab @code{$1 = @{d = @{c = @{b = @{a = 3@}@}@}@}} ++@end multitable ++ ++To see the contents of structures that have been hidden the user can ++either increase the print max-depth, or they can print the elements of ++the structure that are visible, for example ++ ++@smallexample ++(gdb) set print max-depth 2 ++(gdb) p var ++$1 = @{d = @{c = @{...@}@}@} ++(gdb) p var.d ++$2 = @{c = @{b = @{...@}@}@} ++(gdb) p var.d.c ++$3 = @{b = @{a = 3@}@} ++@end smallexample ++ ++The pattern used to replace nested structures varies based on ++language, for most languages @code{@{...@}} is used, but Fortran uses ++@code{(...)}. ++ ++@item show print max-depth ++Display the current threshold after which nested structures are ++replaces with ellipsis. ++ ++@anchor{set print null-stop} ++@item set print null-stop ++@cindex @sc{null} elements in arrays ++Cause @value{GDBN} to stop printing the characters of an array when the first ++@sc{null} is encountered. This is useful when large arrays actually ++contain only short strings. ++The default is off. ++ ++@item show print null-stop ++Show whether @value{GDBN} stops printing an array on the first ++@sc{null} character. ++ ++@anchor{set print pretty} ++@item set print pretty on ++@cindex print structures in indented form ++@cindex indentation in structure display ++Cause @value{GDBN} to print structures in an indented format with one member ++per line, like this: ++ ++@smallexample ++@group ++$1 = @{ ++ next = 0x0, ++ flags = @{ ++ sweet = 1, ++ sour = 1 ++ @}, ++ meat = 0x54 "Pork" ++@} ++@end group ++@end smallexample ++ ++@item set print pretty off ++Cause @value{GDBN} to print structures in a compact format, like this: ++ ++@smallexample ++@group ++$1 = @{next = 0x0, flags = @{sweet = 1, sour = 1@}, \ ++meat = 0x54 "Pork"@} ++@end group ++@end smallexample ++ ++@noindent ++This is the default format. ++ ++@item show print pretty ++Show which format @value{GDBN} is using to print structures. ++ ++@anchor{set print raw-values} ++@item set print raw-values on ++Print values in raw form, without applying the pretty ++printers for the value. ++ ++@item set print raw-values off ++Print values in pretty-printed form, if there is a pretty-printer ++for the value (@pxref{Pretty Printing}), ++otherwise print the value in raw form. ++ ++The default setting is ``off''. ++ ++@item show print raw-values ++Show whether to print values in raw form. ++ ++@item set print sevenbit-strings on ++@cindex eight-bit characters in strings ++@cindex octal escapes in strings ++Print using only seven-bit characters; if this option is set, ++@value{GDBN} displays any eight-bit characters (in strings or ++character values) using the notation @code{\}@var{nnn}. This setting is ++best if you are working in English (@sc{ascii}) and you use the ++high-order bit of characters as a marker or ``meta'' bit. ++ ++@item set print sevenbit-strings off ++Print full eight-bit characters. This allows the use of more ++international character sets, and is the default. ++ ++@item show print sevenbit-strings ++Show whether or not @value{GDBN} is printing only seven-bit characters. ++ ++@anchor{set print union} ++@item set print union on ++@cindex unions in structures, printing ++Tell @value{GDBN} to print unions which are contained in structures ++and other unions. This is the default setting. ++ ++@item set print union off ++Tell @value{GDBN} not to print unions which are contained in ++structures and other unions. @value{GDBN} will print @code{"@{...@}"} ++instead. ++ ++@item show print union ++Ask @value{GDBN} whether or not it will print unions which are contained in ++structures and other unions. ++ ++For example, given the declarations ++ ++@smallexample ++typedef enum @{Tree, Bug@} Species; ++typedef enum @{Big_tree, Acorn, Seedling@} Tree_forms; ++typedef enum @{Caterpillar, Cocoon, Butterfly@} ++ Bug_forms; ++ ++struct thing @{ ++ Species it; ++ union @{ ++ Tree_forms tree; ++ Bug_forms bug; ++ @} form; ++@}; ++ ++struct thing foo = @{Tree, @{Acorn@}@}; ++@end smallexample ++ ++@noindent ++with @code{set print union on} in effect @samp{p foo} would print ++ ++@smallexample ++$1 = @{it = Tree, form = @{tree = Acorn, bug = Cocoon@}@} ++@end smallexample ++ ++@noindent ++and with @code{set print union off} in effect it would print ++ ++@smallexample ++$1 = @{it = Tree, form = @{...@}@} ++@end smallexample ++ ++@noindent ++@code{set print union} affects programs written in C-like languages ++and in Pascal. ++@end table ++ ++@need 1000 ++@noindent ++These settings are of interest when debugging C@t{++} programs: ++ ++@table @code ++@cindex demangling C@t{++} names ++@item set print demangle ++@itemx set print demangle on ++Print C@t{++} names in their source form rather than in the encoded ++(``mangled'') form passed to the assembler and linker for type-safe ++linkage. The default is on. ++ ++@item show print demangle ++Show whether C@t{++} names are printed in mangled or demangled form. ++ ++@item set print asm-demangle ++@itemx set print asm-demangle on ++Print C@t{++} names in their source form rather than their mangled form, even ++in assembler code printouts such as instruction disassemblies. ++The default is off. ++ ++@item show print asm-demangle ++Show whether C@t{++} names in assembly listings are printed in mangled ++or demangled form. ++ ++@cindex C@t{++} symbol decoding style ++@cindex symbol decoding style, C@t{++} ++@kindex set demangle-style ++@item set demangle-style @var{style} ++Choose among several encoding schemes used by different compilers to represent ++C@t{++} names. If you omit @var{style}, you will see a list of possible ++formats. The default value is @var{auto}, which lets @value{GDBN} choose a ++decoding style by inspecting your program. ++ ++@item show demangle-style ++Display the encoding style currently in use for decoding C@t{++} symbols. ++ ++@anchor{set print object} ++@item set print object ++@itemx set print object on ++@cindex derived type of an object, printing ++@cindex display derived types ++When displaying a pointer to an object, identify the @emph{actual} ++(derived) type of the object rather than the @emph{declared} type, using ++the virtual function table. Note that the virtual function table is ++required---this feature can only work for objects that have run-time ++type identification; a single virtual method in the object's declared ++type is sufficient. Note that this setting is also taken into account when ++working with variable objects via MI (@pxref{GDB/MI}). ++ ++@item set print object off ++Display only the declared type of objects, without reference to the ++virtual function table. This is the default setting. ++ ++@item show print object ++Show whether actual, or declared, object types are displayed. ++ ++@anchor{set print static-members} ++@item set print static-members ++@itemx set print static-members on ++@cindex static members of C@t{++} objects ++Print static members when displaying a C@t{++} object. The default is on. ++ ++@item set print static-members off ++Do not print static members when displaying a C@t{++} object. ++ ++@item show print static-members ++Show whether C@t{++} static members are printed or not. ++ ++@item set print pascal_static-members ++@itemx set print pascal_static-members on ++@cindex static members of Pascal objects ++@cindex Pascal objects, static members display ++Print static members when displaying a Pascal object. The default is on. ++ ++@item set print pascal_static-members off ++Do not print static members when displaying a Pascal object. ++ ++@item show print pascal_static-members ++Show whether Pascal static members are printed or not. ++ ++@c These don't work with HP ANSI C++ yet. ++@anchor{set print vtbl} ++@item set print vtbl ++@itemx set print vtbl on ++@cindex pretty print C@t{++} virtual function tables ++@cindex virtual functions (C@t{++}) display ++@cindex VTBL display ++Pretty print C@t{++} virtual function tables. The default is off. ++(The @code{vtbl} commands do not work on programs compiled with the HP ++ANSI C@t{++} compiler (@code{aCC}).) ++ ++@item set print vtbl off ++Do not pretty print C@t{++} virtual function tables. ++ ++@item show print vtbl ++Show whether C@t{++} virtual function tables are pretty printed, or not. ++@end table ++ ++@node Pretty Printing ++@section Pretty Printing ++ ++@value{GDBN} provides a mechanism to allow pretty-printing of values using ++Python code. It greatly simplifies the display of complex objects. This ++mechanism works for both MI and the CLI. ++ ++@menu ++* Pretty-Printer Introduction:: Introduction to pretty-printers ++* Pretty-Printer Example:: An example pretty-printer ++* Pretty-Printer Commands:: Pretty-printer commands ++@end menu ++ ++@node Pretty-Printer Introduction ++@subsection Pretty-Printer Introduction ++ ++When @value{GDBN} prints a value, it first sees if there is a pretty-printer ++registered for the value. If there is then @value{GDBN} invokes the ++pretty-printer to print the value. Otherwise the value is printed normally. ++ ++Pretty-printers are normally named. This makes them easy to manage. ++The @samp{info pretty-printer} command will list all the installed ++pretty-printers with their names. ++If a pretty-printer can handle multiple data types, then its ++@dfn{subprinters} are the printers for the individual data types. ++Each such subprinter has its own name. ++The format of the name is @var{printer-name};@var{subprinter-name}. ++ ++Pretty-printers are installed by @dfn{registering} them with @value{GDBN}. ++Typically they are automatically loaded and registered when the corresponding ++debug information is loaded, thus making them available without having to ++do anything special. ++ ++There are three places where a pretty-printer can be registered. ++ ++@itemize @bullet ++@item ++Pretty-printers registered globally are available when debugging ++all inferiors. ++ ++@item ++Pretty-printers registered with a program space are available only ++when debugging that program. ++@xref{Progspaces In Python}, for more details on program spaces in Python. ++ ++@item ++Pretty-printers registered with an objfile are loaded and unloaded ++with the corresponding objfile (e.g., shared library). ++@xref{Objfiles In Python}, for more details on objfiles in Python. ++@end itemize ++ ++@xref{Selecting Pretty-Printers}, for further information on how ++pretty-printers are selected, ++ ++@xref{Writing a Pretty-Printer}, for implementing pretty printers ++for new types. ++ ++@node Pretty-Printer Example ++@subsection Pretty-Printer Example ++ ++Here is how a C@t{++} @code{std::string} looks without a pretty-printer: ++ ++@smallexample ++(@value{GDBP}) print s ++$1 = @{ ++ static npos = 4294967295, ++ _M_dataplus = @{ ++ > = @{ ++ <__gnu_cxx::new_allocator> = @{ ++ @}, ++ @}, ++ members of std::basic_string, ++ std::allocator >::_Alloc_hider: ++ _M_p = 0x804a014 "abcd" ++ @} ++@} ++@end smallexample ++ ++With a pretty-printer for @code{std::string} only the contents are printed: ++ ++@smallexample ++(@value{GDBP}) print s ++$2 = "abcd" ++@end smallexample ++ ++@node Pretty-Printer Commands ++@subsection Pretty-Printer Commands ++@cindex pretty-printer commands ++ ++@table @code ++@kindex info pretty-printer ++@item info pretty-printer [@var{object-regexp} [@var{name-regexp}]] ++Print the list of installed pretty-printers. ++This includes disabled pretty-printers, which are marked as such. ++ ++@var{object-regexp} is a regular expression matching the objects ++whose pretty-printers to list. ++Objects can be @code{global}, the program space's file ++(@pxref{Progspaces In Python}), ++and the object files within that program space (@pxref{Objfiles In Python}). ++@xref{Selecting Pretty-Printers}, for details on how @value{GDBN} ++looks up a printer from these three objects. ++ ++@var{name-regexp} is a regular expression matching the name of the printers ++to list. ++ ++@kindex disable pretty-printer ++@item disable pretty-printer [@var{object-regexp} [@var{name-regexp}]] ++Disable pretty-printers matching @var{object-regexp} and @var{name-regexp}. ++A disabled pretty-printer is not forgotten, it may be enabled again later. ++ ++@kindex enable pretty-printer ++@item enable pretty-printer [@var{object-regexp} [@var{name-regexp}]] ++Enable pretty-printers matching @var{object-regexp} and @var{name-regexp}. ++@end table ++ ++Example: ++ ++Suppose we have three pretty-printers installed: one from library1.so ++named @code{foo} that prints objects of type @code{foo}, and ++another from library2.so named @code{bar} that prints two types of objects, ++@code{bar1} and @code{bar2}. ++ ++@smallexample ++(gdb) info pretty-printer ++library1.so: ++ foo ++library2.so: ++ bar ++ bar1 ++ bar2 ++(gdb) info pretty-printer library2 ++library2.so: ++ bar ++ bar1 ++ bar2 ++(gdb) disable pretty-printer library1 ++1 printer disabled ++2 of 3 printers enabled ++(gdb) info pretty-printer ++library1.so: ++ foo [disabled] ++library2.so: ++ bar ++ bar1 ++ bar2 ++(gdb) disable pretty-printer library2 bar;bar1 ++1 printer disabled ++1 of 3 printers enabled ++(gdb) info pretty-printer library2 ++library1.so: ++ foo [disabled] ++library2.so: ++ bar ++ bar1 [disabled] ++ bar2 ++(gdb) disable pretty-printer library2 bar ++1 printer disabled ++0 of 3 printers enabled ++(gdb) info pretty-printer library2 ++library1.so: ++ foo [disabled] ++library2.so: ++ bar [disabled] ++ bar1 [disabled] ++ bar2 ++@end smallexample ++ ++Note that for @code{bar} the entire printer can be disabled, ++as can each individual subprinter. ++ ++Printing values and frame arguments is done by default using ++the enabled pretty printers. ++ ++The print option @code{-raw-values} and @value{GDBN} setting ++@code{set print raw-values} (@pxref{set print raw-values}) can be ++used to print values without applying the enabled pretty printers. ++ ++Similarly, the backtrace option @code{-raw-frame-arguments} and ++@value{GDBN} setting @code{set print raw-frame-arguments} ++(@pxref{set print raw-frame-arguments}) can be used to ignore the ++enabled pretty printers when printing frame argument values. ++ ++@node Value History ++@section Value History ++ ++@cindex value history ++@cindex history of values printed by @value{GDBN} ++Values printed by the @code{print} command are saved in the @value{GDBN} ++@dfn{value history}. This allows you to refer to them in other expressions. ++Values are kept until the symbol table is re-read or discarded ++(for example with the @code{file} or @code{symbol-file} commands). ++When the symbol table changes, the value history is discarded, ++since the values may contain pointers back to the types defined in the ++symbol table. ++ ++@cindex @code{$} ++@cindex @code{$$} ++@cindex history number ++The values printed are given @dfn{history numbers} by which you can ++refer to them. These are successive integers starting with one. ++@code{print} shows you the history number assigned to a value by ++printing @samp{$@var{num} = } before the value; here @var{num} is the ++history number. ++ ++To refer to any previous value, use @samp{$} followed by the value's ++history number. The way @code{print} labels its output is designed to ++remind you of this. Just @code{$} refers to the most recent value in ++the history, and @code{$$} refers to the value before that. ++@code{$$@var{n}} refers to the @var{n}th value from the end; @code{$$2} ++is the value just prior to @code{$$}, @code{$$1} is equivalent to ++@code{$$}, and @code{$$0} is equivalent to @code{$}. ++ ++For example, suppose you have just printed a pointer to a structure and ++want to see the contents of the structure. It suffices to type ++ ++@smallexample ++p *$ ++@end smallexample ++ ++If you have a chain of structures where the component @code{next} points ++to the next one, you can print the contents of the next one with this: ++ ++@smallexample ++p *$.next ++@end smallexample ++ ++@noindent ++You can print successive links in the chain by repeating this ++command---which you can do by just typing @key{RET}. ++ ++Note that the history records values, not expressions. If the value of ++@code{x} is 4 and you type these commands: ++ ++@smallexample ++print x ++set x=5 ++@end smallexample ++ ++@noindent ++then the value recorded in the value history by the @code{print} command ++remains 4 even though the value of @code{x} has changed. ++ ++@table @code ++@kindex show values ++@item show values ++Print the last ten values in the value history, with their item numbers. ++This is like @samp{p@ $$9} repeated ten times, except that @code{show ++values} does not change the history. ++ ++@item show values @var{n} ++Print ten history values centered on history item number @var{n}. ++ ++@item show values + ++Print ten history values just after the values last printed. If no more ++values are available, @code{show values +} produces no display. ++@end table ++ ++Pressing @key{RET} to repeat @code{show values @var{n}} has exactly the ++same effect as @samp{show values +}. ++ ++@node Convenience Vars ++@section Convenience Variables ++ ++@cindex convenience variables ++@cindex user-defined variables ++@value{GDBN} provides @dfn{convenience variables} that you can use within ++@value{GDBN} to hold on to a value and refer to it later. These variables ++exist entirely within @value{GDBN}; they are not part of your program, and ++setting a convenience variable has no direct effect on further execution ++of your program. That is why you can use them freely. ++ ++Convenience variables are prefixed with @samp{$}. Any name preceded by ++@samp{$} can be used for a convenience variable, unless it is one of ++the predefined machine-specific register names (@pxref{Registers, ,Registers}). ++(Value history references, in contrast, are @emph{numbers} preceded ++by @samp{$}. @xref{Value History, ,Value History}.) ++ ++You can save a value in a convenience variable with an assignment ++expression, just as you would set a variable in your program. ++For example: ++ ++@smallexample ++set $foo = *object_ptr ++@end smallexample ++ ++@noindent ++would save in @code{$foo} the value contained in the object pointed to by ++@code{object_ptr}. ++ ++Using a convenience variable for the first time creates it, but its ++value is @code{void} until you assign a new value. You can alter the ++value with another assignment at any time. ++ ++Convenience variables have no fixed types. You can assign a convenience ++variable any type of value, including structures and arrays, even if ++that variable already has a value of a different type. The convenience ++variable, when used as an expression, has the type of its current value. ++ ++@table @code ++@kindex show convenience ++@cindex show all user variables and functions ++@item show convenience ++Print a list of convenience variables used so far, and their values, ++as well as a list of the convenience functions. ++Abbreviated @code{show conv}. ++ ++@kindex init-if-undefined ++@cindex convenience variables, initializing ++@item init-if-undefined $@var{variable} = @var{expression} ++Set a convenience variable if it has not already been set. This is useful ++for user-defined commands that keep some state. It is similar, in concept, ++to using local static variables with initializers in C (except that ++convenience variables are global). It can also be used to allow users to ++override default values used in a command script. ++ ++If the variable is already defined then the expression is not evaluated so ++any side-effects do not occur. ++@end table ++ ++One of the ways to use a convenience variable is as a counter to be ++incremented or a pointer to be advanced. For example, to print ++a field from successive elements of an array of structures: ++ ++@smallexample ++set $i = 0 ++print bar[$i++]->contents ++@end smallexample ++ ++@noindent ++Repeat that command by typing @key{RET}. ++ ++Some convenience variables are created automatically by @value{GDBN} and given ++values likely to be useful. ++ ++@table @code ++@vindex $_@r{, convenience variable} ++@item $_ ++The variable @code{$_} is automatically set by the @code{x} command to ++the last address examined (@pxref{Memory, ,Examining Memory}). Other ++commands which provide a default address for @code{x} to examine also ++set @code{$_} to that address; these commands include @code{info line} ++and @code{info breakpoint}. The type of @code{$_} is @code{void *} ++except when set by the @code{x} command, in which case it is a pointer ++to the type of @code{$__}. ++ ++@vindex $__@r{, convenience variable} ++@item $__ ++The variable @code{$__} is automatically set by the @code{x} command ++to the value found in the last address examined. Its type is chosen ++to match the format in which the data was printed. ++ ++@item $_exitcode ++@vindex $_exitcode@r{, convenience variable} ++When the program being debugged terminates normally, @value{GDBN} ++automatically sets this variable to the exit code of the program, and ++resets @code{$_exitsignal} to @code{void}. ++ ++@item $_exitsignal ++@vindex $_exitsignal@r{, convenience variable} ++When the program being debugged dies due to an uncaught signal, ++@value{GDBN} automatically sets this variable to that signal's number, ++and resets @code{$_exitcode} to @code{void}. ++ ++To distinguish between whether the program being debugged has exited ++(i.e., @code{$_exitcode} is not @code{void}) or signalled (i.e., ++@code{$_exitsignal} is not @code{void}), the convenience function ++@code{$_isvoid} can be used (@pxref{Convenience Funs,, Convenience ++Functions}). For example, considering the following source code: ++ ++@smallexample ++#include ++ ++int ++main (int argc, char *argv[]) ++@{ ++ raise (SIGALRM); ++ return 0; ++@} ++@end smallexample ++ ++A valid way of telling whether the program being debugged has exited ++or signalled would be: ++ ++@smallexample ++(@value{GDBP}) define has_exited_or_signalled ++Type commands for definition of ``has_exited_or_signalled''. ++End with a line saying just ``end''. ++>if $_isvoid ($_exitsignal) ++ >echo The program has exited\n ++ >else ++ >echo The program has signalled\n ++ >end ++>end ++(@value{GDBP}) run ++Starting program: ++ ++Program terminated with signal SIGALRM, Alarm clock. ++The program no longer exists. ++(@value{GDBP}) has_exited_or_signalled ++The program has signalled ++@end smallexample ++ ++As can be seen, @value{GDBN} correctly informs that the program being ++debugged has signalled, since it calls @code{raise} and raises a ++@code{SIGALRM} signal. If the program being debugged had not called ++@code{raise}, then @value{GDBN} would report a normal exit: ++ ++@smallexample ++(@value{GDBP}) has_exited_or_signalled ++The program has exited ++@end smallexample ++ ++@item $_exception ++The variable @code{$_exception} is set to the exception object being ++thrown at an exception-related catchpoint. @xref{Set Catchpoints}. ++ ++@item $_ada_exception ++The variable @code{$_ada_exception} is set to the address of the ++exception being caught or thrown at an Ada exception-related ++catchpoint. @xref{Set Catchpoints}. ++ ++@item $_probe_argc ++@itemx $_probe_arg0@dots{}$_probe_arg11 ++Arguments to a static probe. @xref{Static Probe Points}. ++ ++@item $_sdata ++@vindex $_sdata@r{, inspect, convenience variable} ++The variable @code{$_sdata} contains extra collected static tracepoint ++data. @xref{Tracepoint Actions,,Tracepoint Action Lists}. Note that ++@code{$_sdata} could be empty, if not inspecting a trace buffer, or ++if extra static tracepoint data has not been collected. ++ ++@item $_siginfo ++@vindex $_siginfo@r{, convenience variable} ++The variable @code{$_siginfo} contains extra signal information ++(@pxref{extra signal information}). Note that @code{$_siginfo} ++could be empty, if the application has not yet received any signals. ++For example, it will be empty before you execute the @code{run} command. ++ ++@item $_tlb ++@vindex $_tlb@r{, convenience variable} ++The variable @code{$_tlb} is automatically set when debugging ++applications running on MS-Windows in native mode or connected to ++gdbserver that supports the @code{qGetTIBAddr} request. ++@xref{General Query Packets}. ++This variable contains the address of the thread information block. ++ ++@item $_inferior ++The number of the current inferior. @xref{Inferiors Connections and ++Programs, ,Debugging Multiple Inferiors Connections and Programs}. ++ ++@item $_thread ++The thread number of the current thread. @xref{thread numbers}. ++ ++@item $_gthread ++The global number of the current thread. @xref{global thread numbers}. ++ ++@item $_gdb_major ++@itemx $_gdb_minor ++@vindex $_gdb_major@r{, convenience variable} ++@vindex $_gdb_minor@r{, convenience variable} ++The major and minor version numbers of the running @value{GDBN}. ++Development snapshots and pretest versions have their minor version ++incremented by one; thus, @value{GDBN} pretest 9.11.90 will produce ++the value 12 for @code{$_gdb_minor}. These variables allow you to ++write scripts that work with different versions of @value{GDBN} ++without errors caused by features unavailable in some of those ++versions. ++ ++@item $_shell_exitcode ++@itemx $_shell_exitsignal ++@vindex $_shell_exitcode@r{, convenience variable} ++@vindex $_shell_exitsignal@r{, convenience variable} ++@cindex shell command, exit code ++@cindex shell command, exit signal ++@cindex exit status of shell commands ++@value{GDBN} commands such as @code{shell} and @code{|} are launching ++shell commands. When a launched command terminates, @value{GDBN} ++automatically maintains the variables @code{$_shell_exitcode} ++and @code{$_shell_exitsignal} according to the exit status of the last ++launched command. These variables are set and used similarly to ++the variables @code{$_exitcode} and @code{$_exitsignal}. ++ ++@end table ++ ++@node Convenience Funs ++@section Convenience Functions ++ ++@cindex convenience functions ++@value{GDBN} also supplies some @dfn{convenience functions}. These ++have a syntax similar to convenience variables. A convenience ++function can be used in an expression just like an ordinary function; ++however, a convenience function is implemented internally to ++@value{GDBN}. ++ ++These functions do not require @value{GDBN} to be configured with ++@code{Python} support, which means that they are always available. ++ ++@table @code ++ ++@item $_isvoid (@var{expr}) ++@findex $_isvoid@r{, convenience function} ++Return one if the expression @var{expr} is @code{void}. Otherwise it ++returns zero. ++ ++A @code{void} expression is an expression where the type of the result ++is @code{void}. For example, you can examine a convenience variable ++(see @ref{Convenience Vars,, Convenience Variables}) to check whether ++it is @code{void}: ++ ++@smallexample ++(@value{GDBP}) print $_exitcode ++$1 = void ++(@value{GDBP}) print $_isvoid ($_exitcode) ++$2 = 1 ++(@value{GDBP}) run ++Starting program: ./a.out ++[Inferior 1 (process 29572) exited normally] ++(@value{GDBP}) print $_exitcode ++$3 = 0 ++(@value{GDBP}) print $_isvoid ($_exitcode) ++$4 = 0 ++@end smallexample ++ ++In the example above, we used @code{$_isvoid} to check whether ++@code{$_exitcode} is @code{void} before and after the execution of the ++program being debugged. Before the execution there is no exit code to ++be examined, therefore @code{$_exitcode} is @code{void}. After the ++execution the program being debugged returned zero, therefore ++@code{$_exitcode} is zero, which means that it is not @code{void} ++anymore. ++ ++The @code{void} expression can also be a call of a function from the ++program being debugged. For example, given the following function: ++ ++@smallexample ++void ++foo (void) ++@{ ++@} ++@end smallexample ++ ++The result of calling it inside @value{GDBN} is @code{void}: ++ ++@smallexample ++(@value{GDBP}) print foo () ++$1 = void ++(@value{GDBP}) print $_isvoid (foo ()) ++$2 = 1 ++(@value{GDBP}) set $v = foo () ++(@value{GDBP}) print $v ++$3 = void ++(@value{GDBP}) print $_isvoid ($v) ++$4 = 1 ++@end smallexample ++ ++@item $_gdb_setting_str (@var{setting}) ++@findex $_gdb_setting_str@r{, convenience function} ++Return the value of the @value{GDBN} @var{setting} as a string. ++@var{setting} is any setting that can be used in a @code{set} or ++@code{show} command (@pxref{Controlling GDB}). ++ ++@smallexample ++(@value{GDBP}) show print frame-arguments ++Printing of non-scalar frame arguments is "scalars". ++(@value{GDBP}) p $_gdb_setting_str("print frame-arguments") ++$1 = "scalars" ++(@value{GDBP}) p $_gdb_setting_str("height") ++$2 = "30" ++(@value{GDBP}) ++@end smallexample ++ ++@item $_gdb_setting (@var{setting}) ++@findex $_gdb_setting@r{, convenience function} ++Return the value of the @value{GDBN} @var{setting}. ++The type of the returned value depends on the setting. ++ ++The value type for boolean and auto boolean settings is @code{int}. ++The boolean values @code{off} and @code{on} are converted to ++the integer values @code{0} and @code{1}. The value @code{auto} is ++converted to the value @code{-1}. ++ ++The value type for integer settings is either @code{unsigned int} ++or @code{int}, depending on the setting. ++ ++Some integer settings accept an @code{unlimited} value. ++Depending on the setting, the @code{set} command also accepts ++the value @code{0} or the value @code{@minus{}1} as a synonym for ++@code{unlimited}. ++For example, @code{set height unlimited} is equivalent to ++@code{set height 0}. ++ ++Some other settings that accept the @code{unlimited} value ++use the value @code{0} to literally mean zero. ++For example, @code{set history size 0} indicates to not ++record any @value{GDBN} commands in the command history. ++For such settings, @code{@minus{}1} is the synonym ++for @code{unlimited}. ++ ++See the documentation of the corresponding @code{set} command for ++the numerical value equivalent to @code{unlimited}. ++ ++The @code{$_gdb_setting} function converts the unlimited value ++to a @code{0} or a @code{@minus{}1} value according to what the ++@code{set} command uses. ++ ++@smallexample ++@group ++(@value{GDBP}) p $_gdb_setting_str("height") ++$1 = "30" ++(@value{GDBP}) p $_gdb_setting("height") ++$2 = 30 ++(@value{GDBP}) set height unlimited ++(@value{GDBP}) p $_gdb_setting_str("height") ++$3 = "unlimited" ++(@value{GDBP}) p $_gdb_setting("height") ++$4 = 0 ++@end group ++@group ++(@value{GDBP}) p $_gdb_setting_str("history size") ++$5 = "unlimited" ++(@value{GDBP}) p $_gdb_setting("history size") ++$6 = -1 ++(@value{GDBP}) p $_gdb_setting_str("disassemble-next-line") ++$7 = "auto" ++(@value{GDBP}) p $_gdb_setting("disassemble-next-line") ++$8 = -1 ++(@value{GDBP}) ++@end group ++@end smallexample ++ ++Other setting types (enum, filename, optional filename, string, string noescape) ++are returned as string values. ++ ++ ++@item $_gdb_maint_setting_str (@var{setting}) ++@findex $_gdb_maint_setting_str@r{, convenience function} ++Like the @code{$_gdb_setting_str} function, but works with ++@code{maintenance set} variables. ++ ++@item $_gdb_maint_setting (@var{setting}) ++@findex $_gdb_maint_setting@r{, convenience function} ++Like the @code{$_gdb_setting} function, but works with ++@code{maintenance set} variables. ++ ++@end table ++ ++The following functions require @value{GDBN} to be configured with ++@code{Python} support. ++ ++@table @code ++ ++@item $_memeq(@var{buf1}, @var{buf2}, @var{length}) ++@findex $_memeq@r{, convenience function} ++Returns one if the @var{length} bytes at the addresses given by ++@var{buf1} and @var{buf2} are equal. ++Otherwise it returns zero. ++ ++@item $_regex(@var{str}, @var{regex}) ++@findex $_regex@r{, convenience function} ++Returns one if the string @var{str} matches the regular expression ++@var{regex}. Otherwise it returns zero. ++The syntax of the regular expression is that specified by @code{Python}'s ++regular expression support. ++ ++@item $_streq(@var{str1}, @var{str2}) ++@findex $_streq@r{, convenience function} ++Returns one if the strings @var{str1} and @var{str2} are equal. ++Otherwise it returns zero. ++ ++@item $_strlen(@var{str}) ++@findex $_strlen@r{, convenience function} ++Returns the length of string @var{str}. ++ ++@item $_caller_is(@var{name}@r{[}, @var{number_of_frames}@r{]}) ++@findex $_caller_is@r{, convenience function} ++Returns one if the calling function's name is equal to @var{name}. ++Otherwise it returns zero. ++ ++If the optional argument @var{number_of_frames} is provided, ++it is the number of frames up in the stack to look. ++The default is 1. ++ ++Example: ++ ++@smallexample ++(gdb) backtrace ++#0 bottom_func () ++ at testsuite/gdb.python/py-caller-is.c:21 ++#1 0x00000000004005a0 in middle_func () ++ at testsuite/gdb.python/py-caller-is.c:27 ++#2 0x00000000004005ab in top_func () ++ at testsuite/gdb.python/py-caller-is.c:33 ++#3 0x00000000004005b6 in main () ++ at testsuite/gdb.python/py-caller-is.c:39 ++(gdb) print $_caller_is ("middle_func") ++$1 = 1 ++(gdb) print $_caller_is ("top_func", 2) ++$1 = 1 ++@end smallexample ++ ++@item $_caller_matches(@var{regexp}@r{[}, @var{number_of_frames}@r{]}) ++@findex $_caller_matches@r{, convenience function} ++Returns one if the calling function's name matches the regular expression ++@var{regexp}. Otherwise it returns zero. ++ ++If the optional argument @var{number_of_frames} is provided, ++it is the number of frames up in the stack to look. ++The default is 1. ++ ++@item $_any_caller_is(@var{name}@r{[}, @var{number_of_frames}@r{]}) ++@findex $_any_caller_is@r{, convenience function} ++Returns one if any calling function's name is equal to @var{name}. ++Otherwise it returns zero. ++ ++If the optional argument @var{number_of_frames} is provided, ++it is the number of frames up in the stack to look. ++The default is 1. ++ ++This function differs from @code{$_caller_is} in that this function ++checks all stack frames from the immediate caller to the frame specified ++by @var{number_of_frames}, whereas @code{$_caller_is} only checks the ++frame specified by @var{number_of_frames}. ++ ++@item $_any_caller_matches(@var{regexp}@r{[}, @var{number_of_frames}@r{]}) ++@findex $_any_caller_matches@r{, convenience function} ++Returns one if any calling function's name matches the regular expression ++@var{regexp}. Otherwise it returns zero. ++ ++If the optional argument @var{number_of_frames} is provided, ++it is the number of frames up in the stack to look. ++The default is 1. ++ ++This function differs from @code{$_caller_matches} in that this function ++checks all stack frames from the immediate caller to the frame specified ++by @var{number_of_frames}, whereas @code{$_caller_matches} only checks the ++frame specified by @var{number_of_frames}. ++ ++@item $_as_string(@var{value}) ++@findex $_as_string@r{, convenience function} ++Return the string representation of @var{value}. ++ ++This function is useful to obtain the textual label (enumerator) of an ++enumeration value. For example, assuming the variable @var{node} is of ++an enumerated type: ++ ++@smallexample ++(gdb) printf "Visiting node of type %s\n", $_as_string(node) ++Visiting node of type NODE_INTEGER ++@end smallexample ++ ++@item $_cimag(@var{value}) ++@itemx $_creal(@var{value}) ++@findex $_cimag@r{, convenience function} ++@findex $_creal@r{, convenience function} ++Return the imaginary (@code{$_cimag}) or real (@code{$_creal}) part of ++the complex number @var{value}. ++ ++The type of the imaginary or real part depends on the type of the ++complex number, e.g., using @code{$_cimag} on a @code{float complex} ++will return an imaginary part of type @code{float}. ++ ++@end table ++ ++@value{GDBN} provides the ability to list and get help on ++convenience functions. ++ ++@table @code ++@item help function ++@kindex help function ++@cindex show all convenience functions ++Print a list of all convenience functions. ++@end table ++ ++@node Registers ++@section Registers ++ ++@cindex registers ++You can refer to machine register contents, in expressions, as variables ++with names starting with @samp{$}. The names of registers are different ++for each machine; use @code{info registers} to see the names used on ++your machine. ++ ++@table @code ++@kindex info registers ++@item info registers ++Print the names and values of all registers except floating-point ++and vector registers (in the selected stack frame). ++ ++@kindex info all-registers ++@cindex floating point registers ++@item info all-registers ++Print the names and values of all registers, including floating-point ++and vector registers (in the selected stack frame). ++ ++@anchor{info_registers_reggroup} ++@item info registers @var{reggroup} @dots{} ++Print the name and value of the registers in each of the specified ++@var{reggroup}s. The @var{reggroup} can be any of those returned by ++@code{maint print reggroups} (@pxref{Maintenance Commands}). ++ ++@item info registers @var{regname} @dots{} ++Print the @dfn{relativized} value of each specified register @var{regname}. ++As discussed in detail below, register values are normally relative to ++the selected stack frame. The @var{regname} may be any register name valid on ++the machine you are using, with or without the initial @samp{$}. ++@end table ++ ++@anchor{standard registers} ++@cindex stack pointer register ++@cindex program counter register ++@cindex process status register ++@cindex frame pointer register ++@cindex standard registers ++@value{GDBN} has four ``standard'' register names that are available (in ++expressions) on most machines---whenever they do not conflict with an ++architecture's canonical mnemonics for registers. The register names ++@code{$pc} and @code{$sp} are used for the program counter register and ++the stack pointer. @code{$fp} is used for a register that contains a ++pointer to the current stack frame, and @code{$ps} is used for a ++register that contains the processor status. For example, ++you could print the program counter in hex with ++ ++@smallexample ++p/x $pc ++@end smallexample ++ ++@noindent ++or print the instruction to be executed next with ++ ++@smallexample ++x/i $pc ++@end smallexample ++ ++@noindent ++or add four to the stack pointer@footnote{This is a way of removing ++one word from the stack, on machines where stacks grow downward in ++memory (most machines, nowadays). This assumes that the innermost ++stack frame is selected; setting @code{$sp} is not allowed when other ++stack frames are selected. To pop entire frames off the stack, ++regardless of machine architecture, use @code{return}; ++see @ref{Returning, ,Returning from a Function}.} with ++ ++@smallexample ++set $sp += 4 ++@end smallexample ++ ++Whenever possible, these four standard register names are available on ++your machine even though the machine has different canonical mnemonics, ++so long as there is no conflict. The @code{info registers} command ++shows the canonical names. For example, on the SPARC, @code{info ++registers} displays the processor status register as @code{$psr} but you ++can also refer to it as @code{$ps}; and on x86-based machines @code{$ps} ++is an alias for the @sc{eflags} register. ++ ++@value{GDBN} always considers the contents of an ordinary register as an ++integer when the register is examined in this way. Some machines have ++special registers which can hold nothing but floating point; these ++registers are considered to have floating point values. There is no way ++to refer to the contents of an ordinary register as floating point value ++(although you can @emph{print} it as a floating point value with ++@samp{print/f $@var{regname}}). ++ ++Some registers have distinct ``raw'' and ``virtual'' data formats. This ++means that the data format in which the register contents are saved by ++the operating system is not the same one that your program normally ++sees. For example, the registers of the 68881 floating point ++coprocessor are always saved in ``extended'' (raw) format, but all C ++programs expect to work with ``double'' (virtual) format. In such ++cases, @value{GDBN} normally works with the virtual format only (the format ++that makes sense for your program), but the @code{info registers} command ++prints the data in both formats. ++ ++@cindex SSE registers (x86) ++@cindex MMX registers (x86) ++Some machines have special registers whose contents can be interpreted ++in several different ways. For example, modern x86-based machines ++have SSE and MMX registers that can hold several values packed ++together in several different formats. @value{GDBN} refers to such ++registers in @code{struct} notation: ++ ++@smallexample ++(@value{GDBP}) print $xmm1 ++$1 = @{ ++ v4_float = @{0, 3.43859137e-038, 1.54142831e-044, 1.821688e-044@}, ++ v2_double = @{9.92129282474342e-303, 2.7585945287983262e-313@}, ++ v16_int8 = "\000\000\000\000\3706;\001\v\000\000\000\r\000\000", ++ v8_int16 = @{0, 0, 14072, 315, 11, 0, 13, 0@}, ++ v4_int32 = @{0, 20657912, 11, 13@}, ++ v2_int64 = @{88725056443645952, 55834574859@}, ++ uint128 = 0x0000000d0000000b013b36f800000000 ++@} ++@end smallexample ++ ++@noindent ++To set values of such registers, you need to tell @value{GDBN} which ++view of the register you wish to change, as if you were assigning ++value to a @code{struct} member: ++ ++@smallexample ++ (@value{GDBP}) set $xmm1.uint128 = 0x000000000000000000000000FFFFFFFF ++@end smallexample ++ ++Normally, register values are relative to the selected stack frame ++(@pxref{Selection, ,Selecting a Frame}). This means that you get the ++value that the register would contain if all stack frames farther in ++were exited and their saved registers restored. In order to see the ++true contents of hardware registers, you must select the innermost ++frame (with @samp{frame 0}). ++ ++@cindex caller-saved registers ++@cindex call-clobbered registers ++@cindex volatile registers ++@cindex values ++Usually ABIs reserve some registers as not needed to be saved by the ++callee (a.k.a.: ``caller-saved'', ``call-clobbered'' or ``volatile'' ++registers). It may therefore not be possible for @value{GDBN} to know ++the value a register had before the call (in other words, in the outer ++frame), if the register value has since been changed by the callee. ++@value{GDBN} tries to deduce where the inner frame saved ++(``callee-saved'') registers, from the debug info, unwind info, or the ++machine code generated by your compiler. If some register is not ++saved, and @value{GDBN} knows the register is ``caller-saved'' (via ++its own knowledge of the ABI, or because the debug/unwind info ++explicitly says the register's value is undefined), @value{GDBN} ++displays @w{@samp{}} as the register's value. With targets ++that @value{GDBN} has no knowledge of the register saving convention, ++if a register was not saved by the callee, then its value and location ++in the outer frame are assumed to be the same of the inner frame. ++This is usually harmless, because if the register is call-clobbered, ++the caller either does not care what is in the register after the ++call, or has code to restore the value that it does care about. Note, ++however, that if you change such a register in the outer frame, you ++may also be affecting the inner frame. Also, the more ``outer'' the ++frame is you're looking at, the more likely a call-clobbered ++register's value is to be wrong, in the sense that it doesn't actually ++represent the value the register had just before the call. ++ ++@node Floating Point Hardware ++@section Floating Point Hardware ++@cindex floating point ++ ++Depending on the configuration, @value{GDBN} may be able to give ++you more information about the status of the floating point hardware. ++ ++@table @code ++@kindex info float ++@item info float ++Display hardware-dependent information about the floating ++point unit. The exact contents and layout vary depending on the ++floating point chip. Currently, @samp{info float} is supported on ++the ARM and x86 machines. ++@end table ++ ++@node Vector Unit ++@section Vector Unit ++@cindex vector unit ++ ++Depending on the configuration, @value{GDBN} may be able to give you ++more information about the status of the vector unit. ++ ++@table @code ++@kindex info vector ++@item info vector ++Display information about the vector unit. The exact contents and ++layout vary depending on the hardware. ++@end table ++ ++@node OS Information ++@section Operating System Auxiliary Information ++@cindex OS information ++ ++@value{GDBN} provides interfaces to useful OS facilities that can help ++you debug your program. ++ ++@cindex auxiliary vector ++@cindex vector, auxiliary ++Some operating systems supply an @dfn{auxiliary vector} to programs at ++startup. This is akin to the arguments and environment that you ++specify for a program, but contains a system-dependent variety of ++binary values that tell system libraries important details about the ++hardware, operating system, and process. Each value's purpose is ++identified by an integer tag; the meanings are well-known but system-specific. ++Depending on the configuration and operating system facilities, ++@value{GDBN} may be able to show you this information. For remote ++targets, this functionality may further depend on the remote stub's ++support of the @samp{qXfer:auxv:read} packet, see ++@ref{qXfer auxiliary vector read}. ++ ++@table @code ++@kindex info auxv ++@item info auxv ++Display the auxiliary vector of the inferior, which can be either a ++live process or a core dump file. @value{GDBN} prints each tag value ++numerically, and also shows names and text descriptions for recognized ++tags. Some values in the vector are numbers, some bit masks, and some ++pointers to strings or other data. @value{GDBN} displays each value in the ++most appropriate form for a recognized tag, and in hexadecimal for ++an unrecognized tag. ++@end table ++ ++On some targets, @value{GDBN} can access operating system-specific ++information and show it to you. The types of information available ++will differ depending on the type of operating system running on the ++target. The mechanism used to fetch the data is described in ++@ref{Operating System Information}. For remote targets, this ++functionality depends on the remote stub's support of the ++@samp{qXfer:osdata:read} packet, see @ref{qXfer osdata read}. ++ ++@table @code ++@kindex info os ++@item info os @var{infotype} ++ ++Display OS information of the requested type. ++ ++On @sc{gnu}/Linux, the following values of @var{infotype} are valid: ++ ++@anchor{linux info os infotypes} ++@table @code ++@kindex info os cpus ++@item cpus ++Display the list of all CPUs/cores. For each CPU/core, @value{GDBN} prints ++the available fields from /proc/cpuinfo. For each supported architecture ++different fields are available. Two common entries are processor which gives ++CPU number and bogomips; a system constant that is calculated during ++kernel initialization. ++ ++@kindex info os files ++@item files ++Display the list of open file descriptors on the target. For each ++file descriptor, @value{GDBN} prints the identifier of the process ++owning the descriptor, the command of the owning process, the value ++of the descriptor, and the target of the descriptor. ++ ++@kindex info os modules ++@item modules ++Display the list of all loaded kernel modules on the target. For each ++module, @value{GDBN} prints the module name, the size of the module in ++bytes, the number of times the module is used, the dependencies of the ++module, the status of the module, and the address of the loaded module ++in memory. ++ ++@kindex info os msg ++@item msg ++Display the list of all System V message queues on the target. For each ++message queue, @value{GDBN} prints the message queue key, the message ++queue identifier, the access permissions, the current number of bytes ++on the queue, the current number of messages on the queue, the processes ++that last sent and received a message on the queue, the user and group ++of the owner and creator of the message queue, the times at which a ++message was last sent and received on the queue, and the time at which ++the message queue was last changed. ++ ++@kindex info os processes ++@item processes ++Display the list of processes on the target. For each process, ++@value{GDBN} prints the process identifier, the name of the user, the ++command corresponding to the process, and the list of processor cores ++that the process is currently running on. (To understand what these ++properties mean, for this and the following info types, please consult ++the general @sc{gnu}/Linux documentation.) ++ ++@kindex info os procgroups ++@item procgroups ++Display the list of process groups on the target. For each process, ++@value{GDBN} prints the identifier of the process group that it belongs ++to, the command corresponding to the process group leader, the process ++identifier, and the command line of the process. The list is sorted ++first by the process group identifier, then by the process identifier, ++so that processes belonging to the same process group are grouped together ++and the process group leader is listed first. ++ ++@kindex info os semaphores ++@item semaphores ++Display the list of all System V semaphore sets on the target. For each ++semaphore set, @value{GDBN} prints the semaphore set key, the semaphore ++set identifier, the access permissions, the number of semaphores in the ++set, the user and group of the owner and creator of the semaphore set, ++and the times at which the semaphore set was operated upon and changed. ++ ++@kindex info os shm ++@item shm ++Display the list of all System V shared-memory regions on the target. ++For each shared-memory region, @value{GDBN} prints the region key, ++the shared-memory identifier, the access permissions, the size of the ++region, the process that created the region, the process that last ++attached to or detached from the region, the current number of live ++attaches to the region, and the times at which the region was last ++attached to, detach from, and changed. ++ ++@kindex info os sockets ++@item sockets ++Display the list of Internet-domain sockets on the target. For each ++socket, @value{GDBN} prints the address and port of the local and ++remote endpoints, the current state of the connection, the creator of ++the socket, the IP address family of the socket, and the type of the ++connection. ++ ++@kindex info os threads ++@item threads ++Display the list of threads running on the target. For each thread, ++@value{GDBN} prints the identifier of the process that the thread ++belongs to, the command of the process, the thread identifier, and the ++processor core that it is currently running on. The main thread of a ++process is not listed. ++@end table ++ ++@item info os ++If @var{infotype} is omitted, then list the possible values for ++@var{infotype} and the kind of OS information available for each ++@var{infotype}. If the target does not return a list of possible ++types, this command will report an error. ++@end table ++ ++@node Memory Region Attributes ++@section Memory Region Attributes ++@cindex memory region attributes ++ ++@dfn{Memory region attributes} allow you to describe special handling ++required by regions of your target's memory. @value{GDBN} uses ++attributes to determine whether to allow certain types of memory ++accesses; whether to use specific width accesses; and whether to cache ++target memory. By default the description of memory regions is ++fetched from the target (if the current target supports this), but the ++user can override the fetched regions. ++ ++Defined memory regions can be individually enabled and disabled. When a ++memory region is disabled, @value{GDBN} uses the default attributes when ++accessing memory in that region. Similarly, if no memory regions have ++been defined, @value{GDBN} uses the default attributes when accessing ++all memory. ++ ++When a memory region is defined, it is given a number to identify it; ++to enable, disable, or remove a memory region, you specify that number. ++ ++@table @code ++@kindex mem ++@item mem @var{lower} @var{upper} @var{attributes}@dots{} ++Define a memory region bounded by @var{lower} and @var{upper} with ++attributes @var{attributes}@dots{}, and add it to the list of regions ++monitored by @value{GDBN}. Note that @var{upper} == 0 is a special ++case: it is treated as the target's maximum memory address. ++(0xffff on 16 bit targets, 0xffffffff on 32 bit targets, etc.) ++ ++@item mem auto ++Discard any user changes to the memory regions and use target-supplied ++regions, if available, or no regions if the target does not support. ++ ++@kindex delete mem ++@item delete mem @var{nums}@dots{} ++Remove memory regions @var{nums}@dots{} from the list of regions ++monitored by @value{GDBN}. ++ ++@kindex disable mem ++@item disable mem @var{nums}@dots{} ++Disable monitoring of memory regions @var{nums}@dots{}. ++A disabled memory region is not forgotten. ++It may be enabled again later. ++ ++@kindex enable mem ++@item enable mem @var{nums}@dots{} ++Enable monitoring of memory regions @var{nums}@dots{}. ++ ++@kindex info mem ++@item info mem ++Print a table of all defined memory regions, with the following columns ++for each region: ++ ++@table @emph ++@item Memory Region Number ++@item Enabled or Disabled. ++Enabled memory regions are marked with @samp{y}. ++Disabled memory regions are marked with @samp{n}. ++ ++@item Lo Address ++The address defining the inclusive lower bound of the memory region. ++ ++@item Hi Address ++The address defining the exclusive upper bound of the memory region. ++ ++@item Attributes ++The list of attributes set for this memory region. ++@end table ++@end table ++ ++ ++@subsection Attributes ++ ++@subsubsection Memory Access Mode ++The access mode attributes set whether @value{GDBN} may make read or ++write accesses to a memory region. ++ ++While these attributes prevent @value{GDBN} from performing invalid ++memory accesses, they do nothing to prevent the target system, I/O DMA, ++etc.@: from accessing memory. ++ ++@table @code ++@item ro ++Memory is read only. ++@item wo ++Memory is write only. ++@item rw ++Memory is read/write. This is the default. ++@end table ++ ++@subsubsection Memory Access Size ++The access size attribute tells @value{GDBN} to use specific sized ++accesses in the memory region. Often memory mapped device registers ++require specific sized accesses. If no access size attribute is ++specified, @value{GDBN} may use accesses of any size. ++ ++@table @code ++@item 8 ++Use 8 bit memory accesses. ++@item 16 ++Use 16 bit memory accesses. ++@item 32 ++Use 32 bit memory accesses. ++@item 64 ++Use 64 bit memory accesses. ++@end table ++ ++@c @subsubsection Hardware/Software Breakpoints ++@c The hardware/software breakpoint attributes set whether @value{GDBN} ++@c will use hardware or software breakpoints for the internal breakpoints ++@c used by the step, next, finish, until, etc. commands. ++@c ++@c @table @code ++@c @item hwbreak ++@c Always use hardware breakpoints ++@c @item swbreak (default) ++@c @end table ++ ++@subsubsection Data Cache ++The data cache attributes set whether @value{GDBN} will cache target ++memory. While this generally improves performance by reducing debug ++protocol overhead, it can lead to incorrect results because @value{GDBN} ++does not know about volatile variables or memory mapped device ++registers. ++ ++@table @code ++@item cache ++Enable @value{GDBN} to cache target memory. ++@item nocache ++Disable @value{GDBN} from caching target memory. This is the default. ++@end table ++ ++@subsection Memory Access Checking ++@value{GDBN} can be instructed to refuse accesses to memory that is ++not explicitly described. This can be useful if accessing such ++regions has undesired effects for a specific target, or to provide ++better error checking. The following commands control this behaviour. ++ ++@table @code ++@kindex set mem inaccessible-by-default ++@item set mem inaccessible-by-default [on|off] ++If @code{on} is specified, make @value{GDBN} treat memory not ++explicitly described by the memory ranges as non-existent and refuse accesses ++to such memory. The checks are only performed if there's at least one ++memory range defined. If @code{off} is specified, make @value{GDBN} ++treat the memory not explicitly described by the memory ranges as RAM. ++The default value is @code{on}. ++@kindex show mem inaccessible-by-default ++@item show mem inaccessible-by-default ++Show the current handling of accesses to unknown memory. ++@end table ++ ++ ++@c @subsubsection Memory Write Verification ++@c The memory write verification attributes set whether @value{GDBN} ++@c will re-reads data after each write to verify the write was successful. ++@c ++@c @table @code ++@c @item verify ++@c @item noverify (default) ++@c @end table ++ ++@node Dump/Restore Files ++@section Copy Between Memory and a File ++@cindex dump/restore files ++@cindex append data to a file ++@cindex dump data to a file ++@cindex restore data from a file ++ ++You can use the commands @code{dump}, @code{append}, and ++@code{restore} to copy data between target memory and a file. The ++@code{dump} and @code{append} commands write data to a file, and the ++@code{restore} command reads data from a file back into the inferior's ++memory. Files may be in binary, Motorola S-record, Intel hex, ++Tektronix Hex, or Verilog Hex format; however, @value{GDBN} can only ++append to binary files, and cannot read from Verilog Hex files. ++ ++@table @code ++ ++@kindex dump ++@item dump @r{[}@var{format}@r{]} memory @var{filename} @var{start_addr} @var{end_addr} ++@itemx dump @r{[}@var{format}@r{]} value @var{filename} @var{expr} ++Dump the contents of memory from @var{start_addr} to @var{end_addr}, ++or the value of @var{expr}, to @var{filename} in the given format. ++ ++The @var{format} parameter may be any one of: ++@table @code ++@item binary ++Raw binary form. ++@item ihex ++Intel hex format. ++@item srec ++Motorola S-record format. ++@item tekhex ++Tektronix Hex format. ++@item verilog ++Verilog Hex format. ++@end table ++ ++@value{GDBN} uses the same definitions of these formats as the ++@sc{gnu} binary utilities, like @samp{objdump} and @samp{objcopy}. If ++@var{format} is omitted, @value{GDBN} dumps the data in raw binary ++form. ++ ++@kindex append ++@item append @r{[}binary@r{]} memory @var{filename} @var{start_addr} @var{end_addr} ++@itemx append @r{[}binary@r{]} value @var{filename} @var{expr} ++Append the contents of memory from @var{start_addr} to @var{end_addr}, ++or the value of @var{expr}, to the file @var{filename}, in raw binary form. ++(@value{GDBN} can only append data to files in raw binary form.) ++ ++@kindex restore ++@item restore @var{filename} @r{[}binary@r{]} @var{bias} @var{start} @var{end} ++Restore the contents of file @var{filename} into memory. The ++@code{restore} command can automatically recognize any known @sc{bfd} ++file format, except for raw binary. To restore a raw binary file you ++must specify the optional keyword @code{binary} after the filename. ++ ++If @var{bias} is non-zero, its value will be added to the addresses ++contained in the file. Binary files always start at address zero, so ++they will be restored at address @var{bias}. Other bfd files have ++a built-in location; they will be restored at offset @var{bias} ++from that location. ++ ++If @var{start} and/or @var{end} are non-zero, then only data between ++file offset @var{start} and file offset @var{end} will be restored. ++These offsets are relative to the addresses in the file, before ++the @var{bias} argument is applied. ++ ++@end table ++ ++@node Core File Generation ++@section How to Produce a Core File from Your Program ++@cindex dump core from inferior ++ ++A @dfn{core file} or @dfn{core dump} is a file that records the memory ++image of a running process and its process status (register values ++etc.). Its primary use is post-mortem debugging of a program that ++crashed while it ran outside a debugger. A program that crashes ++automatically produces a core file, unless this feature is disabled by ++the user. @xref{Files}, for information on invoking @value{GDBN} in ++the post-mortem debugging mode. ++ ++Occasionally, you may wish to produce a core file of the program you ++are debugging in order to preserve a snapshot of its state. ++@value{GDBN} has a special command for that. ++ ++@table @code ++@kindex gcore ++@kindex generate-core-file ++@item generate-core-file [@var{file}] ++@itemx gcore [@var{file}] ++Produce a core dump of the inferior process. The optional argument ++@var{file} specifies the file name where to put the core dump. If not ++specified, the file name defaults to @file{core.@var{pid}}, where ++@var{pid} is the inferior process ID. ++ ++Note that this command is implemented only for some systems (as of ++this writing, @sc{gnu}/Linux, FreeBSD, Solaris, and S390). ++ ++On @sc{gnu}/Linux, this command can take into account the value of the ++file @file{/proc/@var{pid}/coredump_filter} when generating the core ++dump (@pxref{set use-coredump-filter}), and by default honors the ++@code{VM_DONTDUMP} flag for mappings where it is present in the file ++@file{/proc/@var{pid}/smaps} (@pxref{set dump-excluded-mappings}). ++ ++@kindex set use-coredump-filter ++@anchor{set use-coredump-filter} ++@item set use-coredump-filter on ++@itemx set use-coredump-filter off ++Enable or disable the use of the file ++@file{/proc/@var{pid}/coredump_filter} when generating core dump ++files. This file is used by the Linux kernel to decide what types of ++memory mappings will be dumped or ignored when generating a core dump ++file. @var{pid} is the process ID of a currently running process. ++ ++To make use of this feature, you have to write in the ++@file{/proc/@var{pid}/coredump_filter} file a value, in hexadecimal, ++which is a bit mask representing the memory mapping types. If a bit ++is set in the bit mask, then the memory mappings of the corresponding ++types will be dumped; otherwise, they will be ignored. This ++configuration is inherited by child processes. For more information ++about the bits that can be set in the ++@file{/proc/@var{pid}/coredump_filter} file, please refer to the ++manpage of @code{core(5)}. ++ ++By default, this option is @code{on}. If this option is turned ++@code{off}, @value{GDBN} does not read the @file{coredump_filter} file ++and instead uses the same default value as the Linux kernel in order ++to decide which pages will be dumped in the core dump file. This ++value is currently @code{0x33}, which means that bits @code{0} ++(anonymous private mappings), @code{1} (anonymous shared mappings), ++@code{4} (ELF headers) and @code{5} (private huge pages) are active. ++This will cause these memory mappings to be dumped automatically. ++ ++@kindex set dump-excluded-mappings ++@anchor{set dump-excluded-mappings} ++@item set dump-excluded-mappings on ++@itemx set dump-excluded-mappings off ++If @code{on} is specified, @value{GDBN} will dump memory mappings ++marked with the @code{VM_DONTDUMP} flag. This flag is represented in ++the file @file{/proc/@var{pid}/smaps} with the acronym @code{dd}. ++ ++The default value is @code{off}. ++@end table ++ ++@node Character Sets ++@section Character Sets ++@cindex character sets ++@cindex charset ++@cindex translating between character sets ++@cindex host character set ++@cindex target character set ++ ++If the program you are debugging uses a different character set to ++represent characters and strings than the one @value{GDBN} uses itself, ++@value{GDBN} can automatically translate between the character sets for ++you. The character set @value{GDBN} uses we call the @dfn{host ++character set}; the one the inferior program uses we call the ++@dfn{target character set}. ++ ++For example, if you are running @value{GDBN} on a @sc{gnu}/Linux system, which ++uses the ISO Latin 1 character set, but you are using @value{GDBN}'s ++remote protocol (@pxref{Remote Debugging}) to debug a program ++running on an IBM mainframe, which uses the @sc{ebcdic} character set, ++then the host character set is Latin-1, and the target character set is ++@sc{ebcdic}. If you give @value{GDBN} the command @code{set ++target-charset EBCDIC-US}, then @value{GDBN} translates between ++@sc{ebcdic} and Latin 1 as you print character or string values, or use ++character and string literals in expressions. ++ ++@value{GDBN} has no way to automatically recognize which character set ++the inferior program uses; you must tell it, using the @code{set ++target-charset} command, described below. ++ ++Here are the commands for controlling @value{GDBN}'s character set ++support: ++ ++@table @code ++@item set target-charset @var{charset} ++@kindex set target-charset ++Set the current target character set to @var{charset}. To display the ++list of supported target character sets, type ++@kbd{@w{set target-charset @key{TAB}@key{TAB}}}. ++ ++@item set host-charset @var{charset} ++@kindex set host-charset ++Set the current host character set to @var{charset}. ++ ++By default, @value{GDBN} uses a host character set appropriate to the ++system it is running on; you can override that default using the ++@code{set host-charset} command. On some systems, @value{GDBN} cannot ++automatically determine the appropriate host character set. In this ++case, @value{GDBN} uses @samp{UTF-8}. ++ ++@value{GDBN} can only use certain character sets as its host character ++set. If you type @kbd{@w{set host-charset @key{TAB}@key{TAB}}}, ++@value{GDBN} will list the host character sets it supports. ++ ++@item set charset @var{charset} ++@kindex set charset ++Set the current host and target character sets to @var{charset}. As ++above, if you type @kbd{@w{set charset @key{TAB}@key{TAB}}}, ++@value{GDBN} will list the names of the character sets that can be used ++for both host and target. ++ ++@item show charset ++@kindex show charset ++Show the names of the current host and target character sets. ++ ++@item show host-charset ++@kindex show host-charset ++Show the name of the current host character set. ++ ++@item show target-charset ++@kindex show target-charset ++Show the name of the current target character set. ++ ++@item set target-wide-charset @var{charset} ++@kindex set target-wide-charset ++Set the current target's wide character set to @var{charset}. This is ++the character set used by the target's @code{wchar_t} type. To ++display the list of supported wide character sets, type ++@kbd{@w{set target-wide-charset @key{TAB}@key{TAB}}}. ++ ++@item show target-wide-charset ++@kindex show target-wide-charset ++Show the name of the current target's wide character set. ++@end table ++ ++Here is an example of @value{GDBN}'s character set support in action. ++Assume that the following source code has been placed in the file ++@file{charset-test.c}: ++ ++@smallexample ++#include ++ ++char ascii_hello[] ++ = @{72, 101, 108, 108, 111, 44, 32, 119, ++ 111, 114, 108, 100, 33, 10, 0@}; ++char ibm1047_hello[] ++ = @{200, 133, 147, 147, 150, 107, 64, 166, ++ 150, 153, 147, 132, 90, 37, 0@}; ++ ++main () ++@{ ++ printf ("Hello, world!\n"); ++@} ++@end smallexample ++ ++In this program, @code{ascii_hello} and @code{ibm1047_hello} are arrays ++containing the string @samp{Hello, world!} followed by a newline, ++encoded in the @sc{ascii} and @sc{ibm1047} character sets. ++ ++We compile the program, and invoke the debugger on it: ++ ++@smallexample ++$ gcc -g charset-test.c -o charset-test ++$ gdb -nw charset-test ++GNU gdb 2001-12-19-cvs ++Copyright 2001 Free Software Foundation, Inc. ++@dots{} ++(@value{GDBP}) ++@end smallexample ++ ++We can use the @code{show charset} command to see what character sets ++@value{GDBN} is currently using to interpret and display characters and ++strings: ++ ++@smallexample ++(@value{GDBP}) show charset ++The current host and target character set is `ISO-8859-1'. ++(@value{GDBP}) ++@end smallexample ++ ++For the sake of printing this manual, let's use @sc{ascii} as our ++initial character set: ++@smallexample ++(@value{GDBP}) set charset ASCII ++(@value{GDBP}) show charset ++The current host and target character set is `ASCII'. ++(@value{GDBP}) ++@end smallexample ++ ++Let's assume that @sc{ascii} is indeed the correct character set for our ++host system --- in other words, let's assume that if @value{GDBN} prints ++characters using the @sc{ascii} character set, our terminal will display ++them properly. Since our current target character set is also ++@sc{ascii}, the contents of @code{ascii_hello} print legibly: ++ ++@smallexample ++(@value{GDBP}) print ascii_hello ++$1 = 0x401698 "Hello, world!\n" ++(@value{GDBP}) print ascii_hello[0] ++$2 = 72 'H' ++(@value{GDBP}) ++@end smallexample ++ ++@value{GDBN} uses the target character set for character and string ++literals you use in expressions: ++ ++@smallexample ++(@value{GDBP}) print '+' ++$3 = 43 '+' ++(@value{GDBP}) ++@end smallexample ++ ++The @sc{ascii} character set uses the number 43 to encode the @samp{+} ++character. ++ ++@value{GDBN} relies on the user to tell it which character set the ++target program uses. If we print @code{ibm1047_hello} while our target ++character set is still @sc{ascii}, we get jibberish: ++ ++@smallexample ++(@value{GDBP}) print ibm1047_hello ++$4 = 0x4016a8 "\310\205\223\223\226k@@\246\226\231\223\204Z%" ++(@value{GDBP}) print ibm1047_hello[0] ++$5 = 200 '\310' ++(@value{GDBP}) ++@end smallexample ++ ++If we invoke the @code{set target-charset} followed by @key{TAB}@key{TAB}, ++@value{GDBN} tells us the character sets it supports: ++ ++@smallexample ++(@value{GDBP}) set target-charset ++ASCII EBCDIC-US IBM1047 ISO-8859-1 ++(@value{GDBP}) set target-charset ++@end smallexample ++ ++We can select @sc{ibm1047} as our target character set, and examine the ++program's strings again. Now the @sc{ascii} string is wrong, but ++@value{GDBN} translates the contents of @code{ibm1047_hello} from the ++target character set, @sc{ibm1047}, to the host character set, ++@sc{ascii}, and they display correctly: ++ ++@smallexample ++(@value{GDBP}) set target-charset IBM1047 ++(@value{GDBP}) show charset ++The current host character set is `ASCII'. ++The current target character set is `IBM1047'. ++(@value{GDBP}) print ascii_hello ++$6 = 0x401698 "\110\145%%?\054\040\167?\162%\144\041\012" ++(@value{GDBP}) print ascii_hello[0] ++$7 = 72 '\110' ++(@value{GDBP}) print ibm1047_hello ++$8 = 0x4016a8 "Hello, world!\n" ++(@value{GDBP}) print ibm1047_hello[0] ++$9 = 200 'H' ++(@value{GDBP}) ++@end smallexample ++ ++As above, @value{GDBN} uses the target character set for character and ++string literals you use in expressions: ++ ++@smallexample ++(@value{GDBP}) print '+' ++$10 = 78 '+' ++(@value{GDBP}) ++@end smallexample ++ ++The @sc{ibm1047} character set uses the number 78 to encode the @samp{+} ++character. ++ ++@node Caching Target Data ++@section Caching Data of Targets ++@cindex caching data of targets ++ ++@value{GDBN} caches data exchanged between the debugger and a target. ++Each cache is associated with the address space of the inferior. ++@xref{Inferiors Connections and Programs}, about inferior and address space. ++Such caching generally improves performance in remote debugging ++(@pxref{Remote Debugging}), because it reduces the overhead of the ++remote protocol by bundling memory reads and writes into large chunks. ++Unfortunately, simply caching everything would lead to incorrect results, ++since @value{GDBN} does not necessarily know anything about volatile ++values, memory-mapped I/O addresses, etc. Furthermore, in non-stop mode ++(@pxref{Non-Stop Mode}) memory can be changed @emph{while} a gdb command ++is executing. ++Therefore, by default, @value{GDBN} only caches data ++known to be on the stack@footnote{In non-stop mode, it is moderately ++rare for a running thread to modify the stack of a stopped thread ++in a way that would interfere with a backtrace, and caching of ++stack reads provides a significant speed up of remote backtraces.} or ++in the code segment. ++Other regions of memory can be explicitly marked as ++cacheable; @pxref{Memory Region Attributes}. ++ ++@table @code ++@kindex set remotecache ++@item set remotecache on ++@itemx set remotecache off ++This option no longer does anything; it exists for compatibility ++with old scripts. ++ ++@kindex show remotecache ++@item show remotecache ++Show the current state of the obsolete remotecache flag. ++ ++@kindex set stack-cache ++@item set stack-cache on ++@itemx set stack-cache off ++Enable or disable caching of stack accesses. When @code{on}, use ++caching. By default, this option is @code{on}. ++ ++@kindex show stack-cache ++@item show stack-cache ++Show the current state of data caching for memory accesses. ++ ++@kindex set code-cache ++@item set code-cache on ++@itemx set code-cache off ++Enable or disable caching of code segment accesses. When @code{on}, ++use caching. By default, this option is @code{on}. This improves ++performance of disassembly in remote debugging. ++ ++@kindex show code-cache ++@item show code-cache ++Show the current state of target memory cache for code segment ++accesses. ++ ++@kindex info dcache ++@item info dcache @r{[}line@r{]} ++Print the information about the performance of data cache of the ++current inferior's address space. The information displayed ++includes the dcache width and depth, and for each cache line, its ++number, address, and how many times it was referenced. This ++command is useful for debugging the data cache operation. ++ ++If a line number is specified, the contents of that line will be ++printed in hex. ++ ++@item set dcache size @var{size} ++@cindex dcache size ++@kindex set dcache size ++Set maximum number of entries in dcache (dcache depth above). ++ ++@item set dcache line-size @var{line-size} ++@cindex dcache line-size ++@kindex set dcache line-size ++Set number of bytes each dcache entry caches (dcache width above). ++Must be a power of 2. ++ ++@item show dcache size ++@kindex show dcache size ++Show maximum number of dcache entries. @xref{Caching Target Data, info dcache}. ++ ++@item show dcache line-size ++@kindex show dcache line-size ++Show default size of dcache lines. ++ ++@end table ++ ++@node Searching Memory ++@section Search Memory ++@cindex searching memory ++ ++Memory can be searched for a particular sequence of bytes with the ++@code{find} command. ++ ++@table @code ++@kindex find ++@item find @r{[}/@var{sn}@r{]} @var{start_addr}, +@var{len}, @var{val1} @r{[}, @var{val2}, @dots{}@r{]} ++@itemx find @r{[}/@var{sn}@r{]} @var{start_addr}, @var{end_addr}, @var{val1} @r{[}, @var{val2}, @dots{}@r{]} ++Search memory for the sequence of bytes specified by @var{val1}, @var{val2}, ++etc. The search begins at address @var{start_addr} and continues for either ++@var{len} bytes or through to @var{end_addr} inclusive. ++@end table ++ ++@var{s} and @var{n} are optional parameters. ++They may be specified in either order, apart or together. ++ ++@table @r ++@item @var{s}, search query size ++The size of each search query value. ++ ++@table @code ++@item b ++bytes ++@item h ++halfwords (two bytes) ++@item w ++words (four bytes) ++@item g ++giant words (eight bytes) ++@end table ++ ++All values are interpreted in the current language. ++This means, for example, that if the current source language is C/C@t{++} ++then searching for the string ``hello'' includes the trailing '\0'. ++The null terminator can be removed from searching by using casts, ++e.g.: @samp{@{char[5]@}"hello"}. ++ ++If the value size is not specified, it is taken from the ++value's type in the current language. ++This is useful when one wants to specify the search ++pattern as a mixture of types. ++Note that this means, for example, that in the case of C-like languages ++a search for an untyped 0x42 will search for @samp{(int) 0x42} ++which is typically four bytes. ++ ++@item @var{n}, maximum number of finds ++The maximum number of matches to print. The default is to print all finds. ++@end table ++ ++You can use strings as search values. Quote them with double-quotes ++ (@code{"}). ++The string value is copied into the search pattern byte by byte, ++regardless of the endianness of the target and the size specification. ++ ++The address of each match found is printed as well as a count of the ++number of matches found. ++ ++The address of the last value found is stored in convenience variable ++@samp{$_}. ++A count of the number of matches is stored in @samp{$numfound}. ++ ++For example, if stopped at the @code{printf} in this function: ++ ++@smallexample ++void ++hello () ++@{ ++ static char hello[] = "hello-hello"; ++ static struct @{ char c; short s; int i; @} ++ __attribute__ ((packed)) mixed ++ = @{ 'c', 0x1234, 0x87654321 @}; ++ printf ("%s\n", hello); ++@} ++@end smallexample ++ ++@noindent ++you get during debugging: ++ ++@smallexample ++(gdb) find &hello[0], +sizeof(hello), "hello" ++0x804956d ++1 pattern found ++(gdb) find &hello[0], +sizeof(hello), 'h', 'e', 'l', 'l', 'o' ++0x8049567 ++0x804956d ++2 patterns found. ++(gdb) find &hello[0], +sizeof(hello), @{char[5]@}"hello" ++0x8049567 ++0x804956d ++2 patterns found. ++(gdb) find /b1 &hello[0], +sizeof(hello), 'h', 0x65, 'l' ++0x8049567 ++1 pattern found ++(gdb) find &mixed, +sizeof(mixed), (char) 'c', (short) 0x1234, (int) 0x87654321 ++0x8049560 ++1 pattern found ++(gdb) print $numfound ++$1 = 1 ++(gdb) print $_ ++$2 = (void *) 0x8049560 ++@end smallexample ++ ++@node Value Sizes ++@section Value Sizes ++ ++Whenever @value{GDBN} prints a value memory will be allocated within ++@value{GDBN} to hold the contents of the value. It is possible in ++some languages with dynamic typing systems, that an invalid program ++may indicate a value that is incorrectly large, this in turn may cause ++@value{GDBN} to try and allocate an overly large amount of memory. ++ ++@table @code ++@kindex set max-value-size ++@item set max-value-size @var{bytes} ++@itemx set max-value-size unlimited ++Set the maximum size of memory that @value{GDBN} will allocate for the ++contents of a value to @var{bytes}, trying to display a value that ++requires more memory than that will result in an error. ++ ++Setting this variable does not effect values that have already been ++allocated within @value{GDBN}, only future allocations. ++ ++There's a minimum size that @code{max-value-size} can be set to in ++order that @value{GDBN} can still operate correctly, this minimum is ++currently 16 bytes. ++ ++The limit applies to the results of some subexpressions as well as to ++complete expressions. For example, an expression denoting a simple ++integer component, such as @code{x.y.z}, may fail if the size of ++@var{x.y} is dynamic and exceeds @var{bytes}. On the other hand, ++@value{GDBN} is sometimes clever; the expression @code{A[i]}, where ++@var{A} is an array variable with non-constant size, will generally ++succeed regardless of the bounds on @var{A}, as long as the component ++size is less than @var{bytes}. ++ ++The default value of @code{max-value-size} is currently 64k. ++ ++@kindex show max-value-size ++@item show max-value-size ++Show the maximum size of memory, in bytes, that @value{GDBN} will ++allocate for the contents of a value. ++@end table ++ ++@node Optimized Code ++@chapter Debugging Optimized Code ++@cindex optimized code, debugging ++@cindex debugging optimized code ++ ++Almost all compilers support optimization. With optimization ++disabled, the compiler generates assembly code that corresponds ++directly to your source code, in a simplistic way. As the compiler ++applies more powerful optimizations, the generated assembly code ++diverges from your original source code. With help from debugging ++information generated by the compiler, @value{GDBN} can map from ++the running program back to constructs from your original source. ++ ++@value{GDBN} is more accurate with optimization disabled. If you ++can recompile without optimization, it is easier to follow the ++progress of your program during debugging. But, there are many cases ++where you may need to debug an optimized version. ++ ++When you debug a program compiled with @samp{-g -O}, remember that the ++optimizer has rearranged your code; the debugger shows you what is ++really there. Do not be too surprised when the execution path does not ++exactly match your source file! An extreme example: if you define a ++variable, but never use it, @value{GDBN} never sees that ++variable---because the compiler optimizes it out of existence. ++ ++Some things do not work as well with @samp{-g -O} as with just ++@samp{-g}, particularly on machines with instruction scheduling. If in ++doubt, recompile with @samp{-g} alone, and if this fixes the problem, ++please report it to us as a bug (including a test case!). ++@xref{Variables}, for more information about debugging optimized code. ++ ++@menu ++* Inline Functions:: How @value{GDBN} presents inlining ++* Tail Call Frames:: @value{GDBN} analysis of jumps to functions ++@end menu ++ ++@node Inline Functions ++@section Inline Functions ++@cindex inline functions, debugging ++ ++@dfn{Inlining} is an optimization that inserts a copy of the function ++body directly at each call site, instead of jumping to a shared ++routine. @value{GDBN} displays inlined functions just like ++non-inlined functions. They appear in backtraces. You can view their ++arguments and local variables, step into them with @code{step}, skip ++them with @code{next}, and escape from them with @code{finish}. ++You can check whether a function was inlined by using the ++@code{info frame} command. ++ ++For @value{GDBN} to support inlined functions, the compiler must ++record information about inlining in the debug information --- ++@value{NGCC} using the @sc{dwarf 2} format does this, and several ++other compilers do also. @value{GDBN} only supports inlined functions ++when using @sc{dwarf 2}. Versions of @value{NGCC} before 4.1 ++do not emit two required attributes (@samp{DW_AT_call_file} and ++@samp{DW_AT_call_line}); @value{GDBN} does not display inlined ++function calls with earlier versions of @value{NGCC}. It instead ++displays the arguments and local variables of inlined functions as ++local variables in the caller. ++ ++The body of an inlined function is directly included at its call site; ++unlike a non-inlined function, there are no instructions devoted to ++the call. @value{GDBN} still pretends that the call site and the ++start of the inlined function are different instructions. Stepping to ++the call site shows the call site, and then stepping again shows ++the first line of the inlined function, even though no additional ++instructions are executed. ++ ++This makes source-level debugging much clearer; you can see both the ++context of the call and then the effect of the call. Only stepping by ++a single instruction using @code{stepi} or @code{nexti} does not do ++this; single instruction steps always show the inlined body. ++ ++There are some ways that @value{GDBN} does not pretend that inlined ++function calls are the same as normal calls: ++ ++@itemize @bullet ++@item ++Setting breakpoints at the call site of an inlined function may not ++work, because the call site does not contain any code. @value{GDBN} ++may incorrectly move the breakpoint to the next line of the enclosing ++function, after the call. This limitation will be removed in a future ++version of @value{GDBN}; until then, set a breakpoint on an earlier line ++or inside the inlined function instead. ++ ++@item ++@value{GDBN} cannot locate the return value of inlined calls after ++using the @code{finish} command. This is a limitation of compiler-generated ++debugging information; after @code{finish}, you can step to the next line ++and print a variable where your program stored the return value. ++ ++@end itemize ++ ++@node Tail Call Frames ++@section Tail Call Frames ++@cindex tail call frames, debugging ++ ++Function @code{B} can call function @code{C} in its very last statement. In ++unoptimized compilation the call of @code{C} is immediately followed by return ++instruction at the end of @code{B} code. Optimizing compiler may replace the ++call and return in function @code{B} into one jump to function @code{C} ++instead. Such use of a jump instruction is called @dfn{tail call}. ++ ++During execution of function @code{C}, there will be no indication in the ++function call stack frames that it was tail-called from @code{B}. If function ++@code{A} regularly calls function @code{B} which tail-calls function @code{C}, ++then @value{GDBN} will see @code{A} as the caller of @code{C}. However, in ++some cases @value{GDBN} can determine that @code{C} was tail-called from ++@code{B}, and it will then create fictitious call frame for that, with the ++return address set up as if @code{B} called @code{C} normally. ++ ++This functionality is currently supported only by DWARF 2 debugging format and ++the compiler has to produce @samp{DW_TAG_call_site} tags. With ++@value{NGCC}, you need to specify @option{-O -g} during compilation, to get ++this information. ++ ++@kbd{info frame} command (@pxref{Frame Info}) will indicate the tail call frame ++kind by text @code{tail call frame} such as in this sample @value{GDBN} output: ++ ++@smallexample ++(gdb) x/i $pc - 2 ++ 0x40066b : jmp 0x400640 ++(gdb) info frame ++Stack level 1, frame at 0x7fffffffda30: ++ rip = 0x40066d in b (amd64-entry-value.cc:59); saved rip 0x4004c5 ++ tail call frame, caller of frame at 0x7fffffffda30 ++ source language c++. ++ Arglist at unknown address. ++ Locals at unknown address, Previous frame's sp is 0x7fffffffda30 ++@end smallexample ++ ++The detection of all the possible code path executions can find them ambiguous. ++There is no execution history stored (possible @ref{Reverse Execution} is never ++used for this purpose) and the last known caller could have reached the known ++callee by multiple different jump sequences. In such case @value{GDBN} still ++tries to show at least all the unambiguous top tail callers and all the ++unambiguous bottom tail calees, if any. ++ ++@table @code ++@anchor{set debug entry-values} ++@item set debug entry-values ++@kindex set debug entry-values ++When set to on, enables printing of analysis messages for both frame argument ++values at function entry and tail calls. It will show all the possible valid ++tail calls code paths it has considered. It will also print the intersection ++of them with the final unambiguous (possibly partial or even empty) code path ++result. ++ ++@item show debug entry-values ++@kindex show debug entry-values ++Show the current state of analysis messages printing for both frame argument ++values at function entry and tail calls. ++@end table ++ ++The analysis messages for tail calls can for example show why the virtual tail ++call frame for function @code{c} has not been recognized (due to the indirect ++reference by variable @code{x}): ++ ++@smallexample ++static void __attribute__((noinline, noclone)) c (void); ++void (*x) (void) = c; ++static void __attribute__((noinline, noclone)) a (void) @{ x++; @} ++static void __attribute__((noinline, noclone)) c (void) @{ a (); @} ++int main (void) @{ x (); return 0; @} ++ ++Breakpoint 1, DW_OP_entry_value resolving cannot find ++DW_TAG_call_site 0x40039a in main ++a () at t.c:3 ++3 static void __attribute__((noinline, noclone)) a (void) @{ x++; @} ++(gdb) bt ++#0 a () at t.c:3 ++#1 0x000000000040039a in main () at t.c:5 ++@end smallexample ++ ++Another possibility is an ambiguous virtual tail call frames resolution: ++ ++@smallexample ++int i; ++static void __attribute__((noinline, noclone)) f (void) @{ i++; @} ++static void __attribute__((noinline, noclone)) e (void) @{ f (); @} ++static void __attribute__((noinline, noclone)) d (void) @{ f (); @} ++static void __attribute__((noinline, noclone)) c (void) @{ d (); @} ++static void __attribute__((noinline, noclone)) b (void) ++@{ if (i) c (); else e (); @} ++static void __attribute__((noinline, noclone)) a (void) @{ b (); @} ++int main (void) @{ a (); return 0; @} ++ ++tailcall: initial: 0x4004d2(a) 0x4004ce(b) 0x4004b2(c) 0x4004a2(d) ++tailcall: compare: 0x4004d2(a) 0x4004cc(b) 0x400492(e) ++tailcall: reduced: 0x4004d2(a) | ++(gdb) bt ++#0 f () at t.c:2 ++#1 0x00000000004004d2 in a () at t.c:8 ++#2 0x0000000000400395 in main () at t.c:9 ++@end smallexample ++ ++@set CALLSEQ1A @code{main@value{ARROW}a@value{ARROW}b@value{ARROW}c@value{ARROW}d@value{ARROW}f} ++@set CALLSEQ2A @code{main@value{ARROW}a@value{ARROW}b@value{ARROW}e@value{ARROW}f} ++ ++@c Convert CALLSEQ#A to CALLSEQ#B depending on HAVE_MAKEINFO_CLICK. ++@ifset HAVE_MAKEINFO_CLICK ++@set ARROW @click{} ++@set CALLSEQ1B @clicksequence{@value{CALLSEQ1A}} ++@set CALLSEQ2B @clicksequence{@value{CALLSEQ2A}} ++@end ifset ++@ifclear HAVE_MAKEINFO_CLICK ++@set ARROW -> ++@set CALLSEQ1B @value{CALLSEQ1A} ++@set CALLSEQ2B @value{CALLSEQ2A} ++@end ifclear ++ ++Frames #0 and #2 are real, #1 is a virtual tail call frame. ++The code can have possible execution paths @value{CALLSEQ1B} or ++@value{CALLSEQ2B}, @value{GDBN} cannot find which one from the inferior state. ++ ++@code{initial:} state shows some random possible calling sequence @value{GDBN} ++has found. It then finds another possible calling sequence - that one is ++prefixed by @code{compare:}. The non-ambiguous intersection of these two is ++printed as the @code{reduced:} calling sequence. That one could have many ++further @code{compare:} and @code{reduced:} statements as long as there remain ++any non-ambiguous sequence entries. ++ ++For the frame of function @code{b} in both cases there are different possible ++@code{$pc} values (@code{0x4004cc} or @code{0x4004ce}), therefore this frame is ++also ambiguous. The only non-ambiguous frame is the one for function @code{a}, ++therefore this one is displayed to the user while the ambiguous frames are ++omitted. ++ ++There can be also reasons why printing of frame argument values at function ++entry may fail: ++ ++@smallexample ++int v; ++static void __attribute__((noinline, noclone)) c (int i) @{ v++; @} ++static void __attribute__((noinline, noclone)) a (int i); ++static void __attribute__((noinline, noclone)) b (int i) @{ a (i); @} ++static void __attribute__((noinline, noclone)) a (int i) ++@{ if (i) b (i - 1); else c (0); @} ++int main (void) @{ a (5); return 0; @} ++ ++(gdb) bt ++#0 c (i=i@@entry=0) at t.c:2 ++#1 0x0000000000400428 in a (DW_OP_entry_value resolving has found ++function "a" at 0x400420 can call itself via tail calls ++i=) at t.c:6 ++#2 0x000000000040036e in main () at t.c:7 ++@end smallexample ++ ++@value{GDBN} cannot find out from the inferior state if and how many times did ++function @code{a} call itself (via function @code{b}) as these calls would be ++tail calls. Such tail calls would modify the @code{i} variable, therefore ++@value{GDBN} cannot be sure the value it knows would be right - @value{GDBN} ++prints @code{} instead. ++ ++@node Macros ++@chapter C Preprocessor Macros ++ ++Some languages, such as C and C@t{++}, provide a way to define and invoke ++``preprocessor macros'' which expand into strings of tokens. ++@value{GDBN} can evaluate expressions containing macro invocations, show ++the result of macro expansion, and show a macro's definition, including ++where it was defined. ++ ++You may need to compile your program specially to provide @value{GDBN} ++with information about preprocessor macros. Most compilers do not ++include macros in their debugging information, even when you compile ++with the @option{-g} flag. @xref{Compilation}. ++ ++A program may define a macro at one point, remove that definition later, ++and then provide a different definition after that. Thus, at different ++points in the program, a macro may have different definitions, or have ++no definition at all. If there is a current stack frame, @value{GDBN} ++uses the macros in scope at that frame's source code line. Otherwise, ++@value{GDBN} uses the macros in scope at the current listing location; ++see @ref{List}. ++ ++Whenever @value{GDBN} evaluates an expression, it always expands any ++macro invocations present in the expression. @value{GDBN} also provides ++the following commands for working with macros explicitly. ++ ++@table @code ++ ++@kindex macro expand ++@cindex macro expansion, showing the results of preprocessor ++@cindex preprocessor macro expansion, showing the results of ++@cindex expanding preprocessor macros ++@item macro expand @var{expression} ++@itemx macro exp @var{expression} ++Show the results of expanding all preprocessor macro invocations in ++@var{expression}. Since @value{GDBN} simply expands macros, but does ++not parse the result, @var{expression} need not be a valid expression; ++it can be any string of tokens. ++ ++@kindex macro exp1 ++@item macro expand-once @var{expression} ++@itemx macro exp1 @var{expression} ++@cindex expand macro once ++@i{(This command is not yet implemented.)} Show the results of ++expanding those preprocessor macro invocations that appear explicitly in ++@var{expression}. Macro invocations appearing in that expansion are ++left unchanged. This command allows you to see the effect of a ++particular macro more clearly, without being confused by further ++expansions. Since @value{GDBN} simply expands macros, but does not ++parse the result, @var{expression} need not be a valid expression; it ++can be any string of tokens. ++ ++@kindex info macro ++@cindex macro definition, showing ++@cindex definition of a macro, showing ++@cindex macros, from debug info ++@item info macro [-a|-all] [--] @var{macro} ++Show the current definition or all definitions of the named @var{macro}, ++and describe the source location or compiler command-line where that ++definition was established. The optional double dash is to signify the end of ++argument processing and the beginning of @var{macro} for non C-like macros where ++the macro may begin with a hyphen. ++ ++@kindex info macros ++@item info macros @var{location} ++Show all macro definitions that are in effect at the location specified ++by @var{location}, and describe the source location or compiler ++command-line where those definitions were established. ++ ++@kindex macro define ++@cindex user-defined macros ++@cindex defining macros interactively ++@cindex macros, user-defined ++@item macro define @var{macro} @var{replacement-list} ++@itemx macro define @var{macro}(@var{arglist}) @var{replacement-list} ++Introduce a definition for a preprocessor macro named @var{macro}, ++invocations of which are replaced by the tokens given in ++@var{replacement-list}. The first form of this command defines an ++``object-like'' macro, which takes no arguments; the second form ++defines a ``function-like'' macro, which takes the arguments given in ++@var{arglist}. ++ ++A definition introduced by this command is in scope in every ++expression evaluated in @value{GDBN}, until it is removed with the ++@code{macro undef} command, described below. The definition overrides ++all definitions for @var{macro} present in the program being debugged, ++as well as any previous user-supplied definition. ++ ++@kindex macro undef ++@item macro undef @var{macro} ++Remove any user-supplied definition for the macro named @var{macro}. ++This command only affects definitions provided with the @code{macro ++define} command, described above; it cannot remove definitions present ++in the program being debugged. ++ ++@kindex macro list ++@item macro list ++List all the macros defined using the @code{macro define} command. ++@end table ++ ++@cindex macros, example of debugging with ++Here is a transcript showing the above commands in action. First, we ++show our source files: ++ ++@smallexample ++$ cat sample.c ++#include ++#include "sample.h" ++ ++#define M 42 ++#define ADD(x) (M + x) ++ ++main () ++@{ ++#define N 28 ++ printf ("Hello, world!\n"); ++#undef N ++ printf ("We're so creative.\n"); ++#define N 1729 ++ printf ("Goodbye, world!\n"); ++@} ++$ cat sample.h ++#define Q < ++$ ++@end smallexample ++ ++Now, we compile the program using the @sc{gnu} C compiler, ++@value{NGCC}. We pass the @option{-gdwarf-2}@footnote{This is the ++minimum. Recent versions of @value{NGCC} support @option{-gdwarf-3} ++and @option{-gdwarf-4}; we recommend always choosing the most recent ++version of DWARF.} @emph{and} @option{-g3} flags to ensure the compiler ++includes information about preprocessor macros in the debugging ++information. ++ ++@smallexample ++$ gcc -gdwarf-2 -g3 sample.c -o sample ++$ ++@end smallexample ++ ++Now, we start @value{GDBN} on our sample program: ++ ++@smallexample ++$ gdb -nw sample ++GNU gdb 2002-05-06-cvs ++Copyright 2002 Free Software Foundation, Inc. ++GDB is free software, @dots{} ++(@value{GDBP}) ++@end smallexample ++ ++We can expand macros and examine their definitions, even when the ++program is not running. @value{GDBN} uses the current listing position ++to decide which macro definitions are in scope: ++ ++@smallexample ++(@value{GDBP}) list main ++3 ++4 #define M 42 ++5 #define ADD(x) (M + x) ++6 ++7 main () ++8 @{ ++9 #define N 28 ++10 printf ("Hello, world!\n"); ++11 #undef N ++12 printf ("We're so creative.\n"); ++(@value{GDBP}) info macro ADD ++Defined at /home/jimb/gdb/macros/play/sample.c:5 ++#define ADD(x) (M + x) ++(@value{GDBP}) info macro Q ++Defined at /home/jimb/gdb/macros/play/sample.h:1 ++ included at /home/jimb/gdb/macros/play/sample.c:2 ++#define Q < ++(@value{GDBP}) macro expand ADD(1) ++expands to: (42 + 1) ++(@value{GDBP}) macro expand-once ADD(1) ++expands to: once (M + 1) ++(@value{GDBP}) ++@end smallexample ++ ++In the example above, note that @code{macro expand-once} expands only ++the macro invocation explicit in the original text --- the invocation of ++@code{ADD} --- but does not expand the invocation of the macro @code{M}, ++which was introduced by @code{ADD}. ++ ++Once the program is running, @value{GDBN} uses the macro definitions in ++force at the source line of the current stack frame: ++ ++@smallexample ++(@value{GDBP}) break main ++Breakpoint 1 at 0x8048370: file sample.c, line 10. ++(@value{GDBP}) run ++Starting program: /home/jimb/gdb/macros/play/sample ++ ++Breakpoint 1, main () at sample.c:10 ++10 printf ("Hello, world!\n"); ++(@value{GDBP}) ++@end smallexample ++ ++At line 10, the definition of the macro @code{N} at line 9 is in force: ++ ++@smallexample ++(@value{GDBP}) info macro N ++Defined at /home/jimb/gdb/macros/play/sample.c:9 ++#define N 28 ++(@value{GDBP}) macro expand N Q M ++expands to: 28 < 42 ++(@value{GDBP}) print N Q M ++$1 = 1 ++(@value{GDBP}) ++@end smallexample ++ ++As we step over directives that remove @code{N}'s definition, and then ++give it a new definition, @value{GDBN} finds the definition (or lack ++thereof) in force at each point: ++ ++@smallexample ++(@value{GDBP}) next ++Hello, world! ++12 printf ("We're so creative.\n"); ++(@value{GDBP}) info macro N ++The symbol `N' has no definition as a C/C++ preprocessor macro ++at /home/jimb/gdb/macros/play/sample.c:12 ++(@value{GDBP}) next ++We're so creative. ++14 printf ("Goodbye, world!\n"); ++(@value{GDBP}) info macro N ++Defined at /home/jimb/gdb/macros/play/sample.c:13 ++#define N 1729 ++(@value{GDBP}) macro expand N Q M ++expands to: 1729 < 42 ++(@value{GDBP}) print N Q M ++$2 = 0 ++(@value{GDBP}) ++@end smallexample ++ ++In addition to source files, macros can be defined on the compilation command ++line using the @option{-D@var{name}=@var{value}} syntax. For macros defined in ++such a way, @value{GDBN} displays the location of their definition as line zero ++of the source file submitted to the compiler. ++ ++@smallexample ++(@value{GDBP}) info macro __STDC__ ++Defined at /home/jimb/gdb/macros/play/sample.c:0 ++-D__STDC__=1 ++(@value{GDBP}) ++@end smallexample ++ ++ ++@node Tracepoints ++@chapter Tracepoints ++@c This chapter is based on the documentation written by Michael ++@c Snyder, David Taylor, Jim Blandy, and Elena Zannoni. ++ ++@cindex tracepoints ++In some applications, it is not feasible for the debugger to interrupt ++the program's execution long enough for the developer to learn ++anything helpful about its behavior. If the program's correctness ++depends on its real-time behavior, delays introduced by a debugger ++might cause the program to change its behavior drastically, or perhaps ++fail, even when the code itself is correct. It is useful to be able ++to observe the program's behavior without interrupting it. ++ ++Using @value{GDBN}'s @code{trace} and @code{collect} commands, you can ++specify locations in the program, called @dfn{tracepoints}, and ++arbitrary expressions to evaluate when those tracepoints are reached. ++Later, using the @code{tfind} command, you can examine the values ++those expressions had when the program hit the tracepoints. The ++expressions may also denote objects in memory---structures or arrays, ++for example---whose values @value{GDBN} should record; while visiting ++a particular tracepoint, you may inspect those objects as if they were ++in memory at that moment. However, because @value{GDBN} records these ++values without interacting with you, it can do so quickly and ++unobtrusively, hopefully not disturbing the program's behavior. ++ ++The tracepoint facility is currently available only for remote ++targets. @xref{Targets}. In addition, your remote target must know ++how to collect trace data. This functionality is implemented in the ++remote stub; however, none of the stubs distributed with @value{GDBN} ++support tracepoints as of this writing. The format of the remote ++packets used to implement tracepoints are described in @ref{Tracepoint ++Packets}. ++ ++It is also possible to get trace data from a file, in a manner reminiscent ++of corefiles; you specify the filename, and use @code{tfind} to search ++through the file. @xref{Trace Files}, for more details. ++ ++This chapter describes the tracepoint commands and features. ++ ++@menu ++* Set Tracepoints:: ++* Analyze Collected Data:: ++* Tracepoint Variables:: ++* Trace Files:: ++@end menu ++ ++@node Set Tracepoints ++@section Commands to Set Tracepoints ++ ++Before running such a @dfn{trace experiment}, an arbitrary number of ++tracepoints can be set. A tracepoint is actually a special type of ++breakpoint (@pxref{Set Breaks}), so you can manipulate it using ++standard breakpoint commands. For instance, as with breakpoints, ++tracepoint numbers are successive integers starting from one, and many ++of the commands associated with tracepoints take the tracepoint number ++as their argument, to identify which tracepoint to work on. ++ ++For each tracepoint, you can specify, in advance, some arbitrary set ++of data that you want the target to collect in the trace buffer when ++it hits that tracepoint. The collected data can include registers, ++local variables, or global data. Later, you can use @value{GDBN} ++commands to examine the values these data had at the time the ++tracepoint was hit. ++ ++Tracepoints do not support every breakpoint feature. Ignore counts on ++tracepoints have no effect, and tracepoints cannot run @value{GDBN} ++commands when they are hit. Tracepoints may not be thread-specific ++either. ++ ++@cindex fast tracepoints ++Some targets may support @dfn{fast tracepoints}, which are inserted in ++a different way (such as with a jump instead of a trap), that is ++faster but possibly restricted in where they may be installed. ++ ++@cindex static tracepoints ++@cindex markers, static tracepoints ++@cindex probing markers, static tracepoints ++Regular and fast tracepoints are dynamic tracing facilities, meaning ++that they can be used to insert tracepoints at (almost) any location ++in the target. Some targets may also support controlling @dfn{static ++tracepoints} from @value{GDBN}. With static tracing, a set of ++instrumentation points, also known as @dfn{markers}, are embedded in ++the target program, and can be activated or deactivated by name or ++address. These are usually placed at locations which facilitate ++investigating what the target is actually doing. @value{GDBN}'s ++support for static tracing includes being able to list instrumentation ++points, and attach them with @value{GDBN} defined high level ++tracepoints that expose the whole range of convenience of ++@value{GDBN}'s tracepoints support. Namely, support for collecting ++registers values and values of global or local (to the instrumentation ++point) variables; tracepoint conditions and trace state variables. ++The act of installing a @value{GDBN} static tracepoint on an ++instrumentation point, or marker, is referred to as @dfn{probing} a ++static tracepoint marker. ++ ++@code{gdbserver} supports tracepoints on some target systems. ++@xref{Server,,Tracepoints support in @code{gdbserver}}. ++ ++This section describes commands to set tracepoints and associated ++conditions and actions. ++ ++@menu ++* Create and Delete Tracepoints:: ++* Enable and Disable Tracepoints:: ++* Tracepoint Passcounts:: ++* Tracepoint Conditions:: ++* Trace State Variables:: ++* Tracepoint Actions:: ++* Listing Tracepoints:: ++* Listing Static Tracepoint Markers:: ++* Starting and Stopping Trace Experiments:: ++* Tracepoint Restrictions:: ++@end menu ++ ++@node Create and Delete Tracepoints ++@subsection Create and Delete Tracepoints ++ ++@table @code ++@cindex set tracepoint ++@kindex trace ++@item trace @var{location} ++The @code{trace} command is very similar to the @code{break} command. ++Its argument @var{location} can be any valid location. ++@xref{Specify Location}. The @code{trace} command defines a tracepoint, ++which is a point in the target program where the debugger will briefly stop, ++collect some data, and then allow the program to continue. Setting a tracepoint ++or changing its actions takes effect immediately if the remote stub ++supports the @samp{InstallInTrace} feature (@pxref{install tracepoint ++in tracing}). ++If remote stub doesn't support the @samp{InstallInTrace} feature, all ++these changes don't take effect until the next @code{tstart} ++command, and once a trace experiment is running, further changes will ++not have any effect until the next trace experiment starts. In addition, ++@value{GDBN} supports @dfn{pending tracepoints}---tracepoints whose ++address is not yet resolved. (This is similar to pending breakpoints.) ++Pending tracepoints are not downloaded to the target and not installed ++until they are resolved. The resolution of pending tracepoints requires ++@value{GDBN} support---when debugging with the remote target, and ++@value{GDBN} disconnects from the remote stub (@pxref{disconnected ++tracing}), pending tracepoints can not be resolved (and downloaded to ++the remote stub) while @value{GDBN} is disconnected. ++ ++Here are some examples of using the @code{trace} command: ++ ++@smallexample ++(@value{GDBP}) @b{trace foo.c:121} // a source file and line number ++ ++(@value{GDBP}) @b{trace +2} // 2 lines forward ++ ++(@value{GDBP}) @b{trace my_function} // first source line of function ++ ++(@value{GDBP}) @b{trace *my_function} // EXACT start address of function ++ ++(@value{GDBP}) @b{trace *0x2117c4} // an address ++@end smallexample ++ ++@noindent ++You can abbreviate @code{trace} as @code{tr}. ++ ++@item trace @var{location} if @var{cond} ++Set a tracepoint with condition @var{cond}; evaluate the expression ++@var{cond} each time the tracepoint is reached, and collect data only ++if the value is nonzero---that is, if @var{cond} evaluates as true. ++@xref{Tracepoint Conditions, ,Tracepoint Conditions}, for more ++information on tracepoint conditions. ++ ++@item ftrace @var{location} [ if @var{cond} ] ++@cindex set fast tracepoint ++@cindex fast tracepoints, setting ++@kindex ftrace ++The @code{ftrace} command sets a fast tracepoint. For targets that ++support them, fast tracepoints will use a more efficient but possibly ++less general technique to trigger data collection, such as a jump ++instruction instead of a trap, or some sort of hardware support. It ++may not be possible to create a fast tracepoint at the desired ++location, in which case the command will exit with an explanatory ++message. ++ ++@value{GDBN} handles arguments to @code{ftrace} exactly as for ++@code{trace}. ++ ++On 32-bit x86-architecture systems, fast tracepoints normally need to ++be placed at an instruction that is 5 bytes or longer, but can be ++placed at 4-byte instructions if the low 64K of memory of the target ++program is available to install trampolines. Some Unix-type systems, ++such as @sc{gnu}/Linux, exclude low addresses from the program's ++address space; but for instance with the Linux kernel it is possible ++to let @value{GDBN} use this area by doing a @command{sysctl} command ++to set the @code{mmap_min_addr} kernel parameter, as in ++ ++@example ++sudo sysctl -w vm.mmap_min_addr=32768 ++@end example ++ ++@noindent ++which sets the low address to 32K, which leaves plenty of room for ++trampolines. The minimum address should be set to a page boundary. ++ ++@item strace @var{location} [ if @var{cond} ] ++@cindex set static tracepoint ++@cindex static tracepoints, setting ++@cindex probe static tracepoint marker ++@kindex strace ++The @code{strace} command sets a static tracepoint. For targets that ++support it, setting a static tracepoint probes a static ++instrumentation point, or marker, found at @var{location}. It may not ++be possible to set a static tracepoint at the desired location, in ++which case the command will exit with an explanatory message. ++ ++@value{GDBN} handles arguments to @code{strace} exactly as for ++@code{trace}, with the addition that the user can also specify ++@code{-m @var{marker}} as @var{location}. This probes the marker ++identified by the @var{marker} string identifier. This identifier ++depends on the static tracepoint backend library your program is ++using. You can find all the marker identifiers in the @samp{ID} field ++of the @code{info static-tracepoint-markers} command output. ++@xref{Listing Static Tracepoint Markers,,Listing Static Tracepoint ++Markers}. For example, in the following small program using the UST ++tracing engine: ++ ++@smallexample ++main () ++@{ ++ trace_mark(ust, bar33, "str %s", "FOOBAZ"); ++@} ++@end smallexample ++ ++@noindent ++the marker id is composed of joining the first two arguments to the ++@code{trace_mark} call with a slash, which translates to: ++ ++@smallexample ++(@value{GDBP}) info static-tracepoint-markers ++Cnt Enb ID Address What ++1 n ust/bar33 0x0000000000400ddc in main at stexample.c:22 ++ Data: "str %s" ++[etc...] ++@end smallexample ++ ++@noindent ++so you may probe the marker above with: ++ ++@smallexample ++(@value{GDBP}) strace -m ust/bar33 ++@end smallexample ++ ++Static tracepoints accept an extra collect action --- @code{collect ++$_sdata}. This collects arbitrary user data passed in the probe point ++call to the tracing library. In the UST example above, you'll see ++that the third argument to @code{trace_mark} is a printf-like format ++string. The user data is then the result of running that formatting ++string against the following arguments. Note that @code{info ++static-tracepoint-markers} command output lists that format string in ++the @samp{Data:} field. ++ ++You can inspect this data when analyzing the trace buffer, by printing ++the $_sdata variable like any other variable available to ++@value{GDBN}. @xref{Tracepoint Actions,,Tracepoint Action Lists}. ++ ++@vindex $tpnum ++@cindex last tracepoint number ++@cindex recent tracepoint number ++@cindex tracepoint number ++The convenience variable @code{$tpnum} records the tracepoint number ++of the most recently set tracepoint. ++ ++@kindex delete tracepoint ++@cindex tracepoint deletion ++@item delete tracepoint @r{[}@var{num}@r{]} ++Permanently delete one or more tracepoints. With no argument, the ++default is to delete all tracepoints. Note that the regular ++@code{delete} command can remove tracepoints also. ++ ++Examples: ++ ++@smallexample ++(@value{GDBP}) @b{delete trace 1 2 3} // remove three tracepoints ++ ++(@value{GDBP}) @b{delete trace} // remove all tracepoints ++@end smallexample ++ ++@noindent ++You can abbreviate this command as @code{del tr}. ++@end table ++ ++@node Enable and Disable Tracepoints ++@subsection Enable and Disable Tracepoints ++ ++These commands are deprecated; they are equivalent to plain @code{disable} and @code{enable}. ++ ++@table @code ++@kindex disable tracepoint ++@item disable tracepoint @r{[}@var{num}@r{]} ++Disable tracepoint @var{num}, or all tracepoints if no argument ++@var{num} is given. A disabled tracepoint will have no effect during ++a trace experiment, but it is not forgotten. You can re-enable ++a disabled tracepoint using the @code{enable tracepoint} command. ++If the command is issued during a trace experiment and the debug target ++has support for disabling tracepoints during a trace experiment, then the ++change will be effective immediately. Otherwise, it will be applied to the ++next trace experiment. ++ ++@kindex enable tracepoint ++@item enable tracepoint @r{[}@var{num}@r{]} ++Enable tracepoint @var{num}, or all tracepoints. If this command is ++issued during a trace experiment and the debug target supports enabling ++tracepoints during a trace experiment, then the enabled tracepoints will ++become effective immediately. Otherwise, they will become effective the ++next time a trace experiment is run. ++@end table ++ ++@node Tracepoint Passcounts ++@subsection Tracepoint Passcounts ++ ++@table @code ++@kindex passcount ++@cindex tracepoint pass count ++@item passcount @r{[}@var{n} @r{[}@var{num}@r{]]} ++Set the @dfn{passcount} of a tracepoint. The passcount is a way to ++automatically stop a trace experiment. If a tracepoint's passcount is ++@var{n}, then the trace experiment will be automatically stopped on ++the @var{n}'th time that tracepoint is hit. If the tracepoint number ++@var{num} is not specified, the @code{passcount} command sets the ++passcount of the most recently defined tracepoint. If no passcount is ++given, the trace experiment will run until stopped explicitly by the ++user. ++ ++Examples: ++ ++@smallexample ++(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of ++@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// tracepoint 2} ++ ++(@value{GDBP}) @b{passcount 12} // Stop on the 12th execution of the ++@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// most recently defined tracepoint.} ++(@value{GDBP}) @b{trace foo} ++(@value{GDBP}) @b{pass 3} ++(@value{GDBP}) @b{trace bar} ++(@value{GDBP}) @b{pass 2} ++(@value{GDBP}) @b{trace baz} ++(@value{GDBP}) @b{pass 1} // Stop tracing when foo has been ++@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// executed 3 times OR when bar has} ++@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// been executed 2 times} ++@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// OR when baz has been executed 1 time.} ++@end smallexample ++@end table ++ ++@node Tracepoint Conditions ++@subsection Tracepoint Conditions ++@cindex conditional tracepoints ++@cindex tracepoint conditions ++ ++The simplest sort of tracepoint collects data every time your program ++reaches a specified place. You can also specify a @dfn{condition} for ++a tracepoint. A condition is just a Boolean expression in your ++programming language (@pxref{Expressions, ,Expressions}). A ++tracepoint with a condition evaluates the expression each time your ++program reaches it, and data collection happens only if the condition ++is true. ++ ++Tracepoint conditions can be specified when a tracepoint is set, by ++using @samp{if} in the arguments to the @code{trace} command. ++@xref{Create and Delete Tracepoints, ,Setting Tracepoints}. They can ++also be set or changed at any time with the @code{condition} command, ++just as with breakpoints. ++ ++Unlike breakpoint conditions, @value{GDBN} does not actually evaluate ++the conditional expression itself. Instead, @value{GDBN} encodes the ++expression into an agent expression (@pxref{Agent Expressions}) ++suitable for execution on the target, independently of @value{GDBN}. ++Global variables become raw memory locations, locals become stack ++accesses, and so forth. ++ ++For instance, suppose you have a function that is usually called ++frequently, but should not be called after an error has occurred. You ++could use the following tracepoint command to collect data about calls ++of that function that happen while the error code is propagating ++through the program; an unconditional tracepoint could end up ++collecting thousands of useless trace frames that you would have to ++search through. ++ ++@smallexample ++(@value{GDBP}) @kbd{trace normal_operation if errcode > 0} ++@end smallexample ++ ++@node Trace State Variables ++@subsection Trace State Variables ++@cindex trace state variables ++ ++A @dfn{trace state variable} is a special type of variable that is ++created and managed by target-side code. The syntax is the same as ++that for GDB's convenience variables (a string prefixed with ``$''), ++but they are stored on the target. They must be created explicitly, ++using a @code{tvariable} command. They are always 64-bit signed ++integers. ++ ++Trace state variables are remembered by @value{GDBN}, and downloaded ++to the target along with tracepoint information when the trace ++experiment starts. There are no intrinsic limits on the number of ++trace state variables, beyond memory limitations of the target. ++ ++@cindex convenience variables, and trace state variables ++Although trace state variables are managed by the target, you can use ++them in print commands and expressions as if they were convenience ++variables; @value{GDBN} will get the current value from the target ++while the trace experiment is running. Trace state variables share ++the same namespace as other ``$'' variables, which means that you ++cannot have trace state variables with names like @code{$23} or ++@code{$pc}, nor can you have a trace state variable and a convenience ++variable with the same name. ++ ++@table @code ++ ++@item tvariable $@var{name} [ = @var{expression} ] ++@kindex tvariable ++The @code{tvariable} command creates a new trace state variable named ++@code{$@var{name}}, and optionally gives it an initial value of ++@var{expression}. The @var{expression} is evaluated when this command is ++entered; the result will be converted to an integer if possible, ++otherwise @value{GDBN} will report an error. A subsequent ++@code{tvariable} command specifying the same name does not create a ++variable, but instead assigns the supplied initial value to the ++existing variable of that name, overwriting any previous initial ++value. The default initial value is 0. ++ ++@item info tvariables ++@kindex info tvariables ++List all the trace state variables along with their initial values. ++Their current values may also be displayed, if the trace experiment is ++currently running. ++ ++@item delete tvariable @r{[} $@var{name} @dots{} @r{]} ++@kindex delete tvariable ++Delete the given trace state variables, or all of them if no arguments ++are specified. ++ ++@end table ++ ++@node Tracepoint Actions ++@subsection Tracepoint Action Lists ++ ++@table @code ++@kindex actions ++@cindex tracepoint actions ++@item actions @r{[}@var{num}@r{]} ++This command will prompt for a list of actions to be taken when the ++tracepoint is hit. If the tracepoint number @var{num} is not ++specified, this command sets the actions for the one that was most ++recently defined (so that you can define a tracepoint and then say ++@code{actions} without bothering about its number). You specify the ++actions themselves on the following lines, one action at a time, and ++terminate the actions list with a line containing just @code{end}. So ++far, the only defined actions are @code{collect}, @code{teval}, and ++@code{while-stepping}. ++ ++@code{actions} is actually equivalent to @code{commands} (@pxref{Break ++Commands, ,Breakpoint Command Lists}), except that only the defined ++actions are allowed; any other @value{GDBN} command is rejected. ++ ++@cindex remove actions from a tracepoint ++To remove all actions from a tracepoint, type @samp{actions @var{num}} ++and follow it immediately with @samp{end}. ++ ++@smallexample ++(@value{GDBP}) @b{collect @var{data}} // collect some data ++ ++(@value{GDBP}) @b{while-stepping 5} // single-step 5 times, collect data ++ ++(@value{GDBP}) @b{end} // signals the end of actions. ++@end smallexample ++ ++In the following example, the action list begins with @code{collect} ++commands indicating the things to be collected when the tracepoint is ++hit. Then, in order to single-step and collect additional data ++following the tracepoint, a @code{while-stepping} command is used, ++followed by the list of things to be collected after each step in a ++sequence of single steps. The @code{while-stepping} command is ++terminated by its own separate @code{end} command. Lastly, the action ++list is terminated by an @code{end} command. ++ ++@smallexample ++(@value{GDBP}) @b{trace foo} ++(@value{GDBP}) @b{actions} ++Enter actions for tracepoint 1, one per line: ++> collect bar,baz ++> collect $regs ++> while-stepping 12 ++ > collect $pc, arr[i] ++ > end ++end ++@end smallexample ++ ++@kindex collect @r{(tracepoints)} ++@item collect@r{[}/@var{mods}@r{]} @var{expr1}, @var{expr2}, @dots{} ++Collect values of the given expressions when the tracepoint is hit. ++This command accepts a comma-separated list of any valid expressions. ++In addition to global, static, or local variables, the following ++special arguments are supported: ++ ++@table @code ++@item $regs ++Collect all registers. ++ ++@item $args ++Collect all function arguments. ++ ++@item $locals ++Collect all local variables. ++ ++@item $_ret ++Collect the return address. This is helpful if you want to see more ++of a backtrace. ++ ++@emph{Note:} The return address location can not always be reliably ++determined up front, and the wrong address / registers may end up ++collected instead. On some architectures the reliability is higher ++for tracepoints at function entry, while on others it's the opposite. ++When this happens, backtracing will stop because the return address is ++found unavailable (unless another collect rule happened to match it). ++ ++@item $_probe_argc ++Collects the number of arguments from the static probe at which the ++tracepoint is located. ++@xref{Static Probe Points}. ++ ++@item $_probe_arg@var{n} ++@var{n} is an integer between 0 and 11. Collects the @var{n}th argument ++from the static probe at which the tracepoint is located. ++@xref{Static Probe Points}. ++ ++@item $_sdata ++@vindex $_sdata@r{, collect} ++Collect static tracepoint marker specific data. Only available for ++static tracepoints. @xref{Tracepoint Actions,,Tracepoint Action ++Lists}. On the UST static tracepoints library backend, an ++instrumentation point resembles a @code{printf} function call. The ++tracing library is able to collect user specified data formatted to a ++character string using the format provided by the programmer that ++instrumented the program. Other backends have similar mechanisms. ++Here's an example of a UST marker call: ++ ++@smallexample ++ const char master_name[] = "$your_name"; ++ trace_mark(channel1, marker1, "hello %s", master_name) ++@end smallexample ++ ++In this case, collecting @code{$_sdata} collects the string ++@samp{hello $yourname}. When analyzing the trace buffer, you can ++inspect @samp{$_sdata} like any other variable available to ++@value{GDBN}. ++@end table ++ ++You can give several consecutive @code{collect} commands, each one ++with a single argument, or one @code{collect} command with several ++arguments separated by commas; the effect is the same. ++ ++The optional @var{mods} changes the usual handling of the arguments. ++@code{s} requests that pointers to chars be handled as strings, in ++particular collecting the contents of the memory being pointed at, up ++to the first zero. The upper bound is by default the value of the ++@code{print elements} variable; if @code{s} is followed by a decimal ++number, that is the upper bound instead. So for instance ++@samp{collect/s25 mystr} collects as many as 25 characters at ++@samp{mystr}. ++ ++The command @code{info scope} (@pxref{Symbols, info scope}) is ++particularly useful for figuring out what data to collect. ++ ++@kindex teval @r{(tracepoints)} ++@item teval @var{expr1}, @var{expr2}, @dots{} ++Evaluate the given expressions when the tracepoint is hit. This ++command accepts a comma-separated list of expressions. The results ++are discarded, so this is mainly useful for assigning values to trace ++state variables (@pxref{Trace State Variables}) without adding those ++values to the trace buffer, as would be the case if the @code{collect} ++action were used. ++ ++@kindex while-stepping @r{(tracepoints)} ++@item while-stepping @var{n} ++Perform @var{n} single-step instruction traces after the tracepoint, ++collecting new data after each step. The @code{while-stepping} ++command is followed by the list of what to collect while stepping ++(followed by its own @code{end} command): ++ ++@smallexample ++> while-stepping 12 ++ > collect $regs, myglobal ++ > end ++> ++@end smallexample ++ ++@noindent ++Note that @code{$pc} is not automatically collected by ++@code{while-stepping}; you need to explicitly collect that register if ++you need it. You may abbreviate @code{while-stepping} as @code{ws} or ++@code{stepping}. ++ ++@item set default-collect @var{expr1}, @var{expr2}, @dots{} ++@kindex set default-collect ++@cindex default collection action ++This variable is a list of expressions to collect at each tracepoint ++hit. It is effectively an additional @code{collect} action prepended ++to every tracepoint action list. The expressions are parsed ++individually for each tracepoint, so for instance a variable named ++@code{xyz} may be interpreted as a global for one tracepoint, and a ++local for another, as appropriate to the tracepoint's location. ++ ++@item show default-collect ++@kindex show default-collect ++Show the list of expressions that are collected by default at each ++tracepoint hit. ++ ++@end table ++ ++@node Listing Tracepoints ++@subsection Listing Tracepoints ++ ++@table @code ++@kindex info tracepoints @r{[}@var{n}@dots{}@r{]} ++@kindex info tp @r{[}@var{n}@dots{}@r{]} ++@cindex information about tracepoints ++@item info tracepoints @r{[}@var{num}@dots{}@r{]} ++Display information about the tracepoint @var{num}. If you don't ++specify a tracepoint number, displays information about all the ++tracepoints defined so far. The format is similar to that used for ++@code{info breakpoints}; in fact, @code{info tracepoints} is the same ++command, simply restricting itself to tracepoints. ++ ++A tracepoint's listing may include additional information specific to ++tracing: ++ ++@itemize @bullet ++@item ++its passcount as given by the @code{passcount @var{n}} command ++ ++@item ++the state about installed on target of each location ++@end itemize ++ ++@smallexample ++(@value{GDBP}) @b{info trace} ++Num Type Disp Enb Address What ++1 tracepoint keep y 0x0804ab57 in foo() at main.cxx:7 ++ while-stepping 20 ++ collect globfoo, $regs ++ end ++ collect globfoo2 ++ end ++ pass count 1200 ++2 tracepoint keep y ++ collect $eip ++2.1 y 0x0804859c in func4 at change-loc.h:35 ++ installed on target ++2.2 y 0xb7ffc480 in func4 at change-loc.h:35 ++ installed on target ++2.3 y set_tracepoint ++3 tracepoint keep y 0x080485b1 in foo at change-loc.c:29 ++ not installed on target ++(@value{GDBP}) ++@end smallexample ++ ++@noindent ++This command can be abbreviated @code{info tp}. ++@end table ++ ++@node Listing Static Tracepoint Markers ++@subsection Listing Static Tracepoint Markers ++ ++@table @code ++@kindex info static-tracepoint-markers ++@cindex information about static tracepoint markers ++@item info static-tracepoint-markers ++Display information about all static tracepoint markers defined in the ++program. ++ ++For each marker, the following columns are printed: ++ ++@table @emph ++@item Count ++An incrementing counter, output to help readability. This is not a ++stable identifier. ++@item ID ++The marker ID, as reported by the target. ++@item Enabled or Disabled ++Probed markers are tagged with @samp{y}. @samp{n} identifies marks ++that are not enabled. ++@item Address ++Where the marker is in your program, as a memory address. ++@item What ++Where the marker is in the source for your program, as a file and line ++number. If the debug information included in the program does not ++allow @value{GDBN} to locate the source of the marker, this column ++will be left blank. ++@end table ++ ++@noindent ++In addition, the following information may be printed for each marker: ++ ++@table @emph ++@item Data ++User data passed to the tracing library by the marker call. In the ++UST backend, this is the format string passed as argument to the ++marker call. ++@item Static tracepoints probing the marker ++The list of static tracepoints attached to the marker. ++@end table ++ ++@smallexample ++(@value{GDBP}) info static-tracepoint-markers ++Cnt ID Enb Address What ++1 ust/bar2 y 0x0000000000400e1a in main at stexample.c:25 ++ Data: number1 %d number2 %d ++ Probed by static tracepoints: #2 ++2 ust/bar33 n 0x0000000000400c87 in main at stexample.c:24 ++ Data: str %s ++(@value{GDBP}) ++@end smallexample ++@end table ++ ++@node Starting and Stopping Trace Experiments ++@subsection Starting and Stopping Trace Experiments ++ ++@table @code ++@kindex tstart [ @var{notes} ] ++@cindex start a new trace experiment ++@cindex collected data discarded ++@item tstart ++This command starts the trace experiment, and begins collecting data. ++It has the side effect of discarding all the data collected in the ++trace buffer during the previous trace experiment. If any arguments ++are supplied, they are taken as a note and stored with the trace ++experiment's state. The notes may be arbitrary text, and are ++especially useful with disconnected tracing in a multi-user context; ++the notes can explain what the trace is doing, supply user contact ++information, and so forth. ++ ++@kindex tstop [ @var{notes} ] ++@cindex stop a running trace experiment ++@item tstop ++This command stops the trace experiment. If any arguments are ++supplied, they are recorded with the experiment as a note. This is ++useful if you are stopping a trace started by someone else, for ++instance if the trace is interfering with the system's behavior and ++needs to be stopped quickly. ++ ++@strong{Note}: a trace experiment and data collection may stop ++automatically if any tracepoint's passcount is reached ++(@pxref{Tracepoint Passcounts}), or if the trace buffer becomes full. ++ ++@kindex tstatus ++@cindex status of trace data collection ++@cindex trace experiment, status of ++@item tstatus ++This command displays the status of the current trace data ++collection. ++@end table ++ ++Here is an example of the commands we described so far: ++ ++@smallexample ++(@value{GDBP}) @b{trace gdb_c_test} ++(@value{GDBP}) @b{actions} ++Enter actions for tracepoint #1, one per line. ++> collect $regs,$locals,$args ++> while-stepping 11 ++ > collect $regs ++ > end ++> end ++(@value{GDBP}) @b{tstart} ++ [time passes @dots{}] ++(@value{GDBP}) @b{tstop} ++@end smallexample ++ ++@anchor{disconnected tracing} ++@cindex disconnected tracing ++You can choose to continue running the trace experiment even if ++@value{GDBN} disconnects from the target, voluntarily or ++involuntarily. For commands such as @code{detach}, the debugger will ++ask what you want to do with the trace. But for unexpected ++terminations (@value{GDBN} crash, network outage), it would be ++unfortunate to lose hard-won trace data, so the variable ++@code{disconnected-tracing} lets you decide whether the trace should ++continue running without @value{GDBN}. ++ ++@table @code ++@item set disconnected-tracing on ++@itemx set disconnected-tracing off ++@kindex set disconnected-tracing ++Choose whether a tracing run should continue to run if @value{GDBN} ++has disconnected from the target. Note that @code{detach} or ++@code{quit} will ask you directly what to do about a running trace no ++matter what this variable's setting, so the variable is mainly useful ++for handling unexpected situations, such as loss of the network. ++ ++@item show disconnected-tracing ++@kindex show disconnected-tracing ++Show the current choice for disconnected tracing. ++ ++@end table ++ ++When you reconnect to the target, the trace experiment may or may not ++still be running; it might have filled the trace buffer in the ++meantime, or stopped for one of the other reasons. If it is running, ++it will continue after reconnection. ++ ++Upon reconnection, the target will upload information about the ++tracepoints in effect. @value{GDBN} will then compare that ++information to the set of tracepoints currently defined, and attempt ++to match them up, allowing for the possibility that the numbers may ++have changed due to creation and deletion in the meantime. If one of ++the target's tracepoints does not match any in @value{GDBN}, the ++debugger will create a new tracepoint, so that you have a number with ++which to specify that tracepoint. This matching-up process is ++necessarily heuristic, and it may result in useless tracepoints being ++created; you may simply delete them if they are of no use. ++ ++@cindex circular trace buffer ++If your target agent supports a @dfn{circular trace buffer}, then you ++can run a trace experiment indefinitely without filling the trace ++buffer; when space runs out, the agent deletes already-collected trace ++frames, oldest first, until there is enough room to continue ++collecting. This is especially useful if your tracepoints are being ++hit too often, and your trace gets terminated prematurely because the ++buffer is full. To ask for a circular trace buffer, simply set ++@samp{circular-trace-buffer} to on. You can set this at any time, ++including during tracing; if the agent can do it, it will change ++buffer handling on the fly, otherwise it will not take effect until ++the next run. ++ ++@table @code ++@item set circular-trace-buffer on ++@itemx set circular-trace-buffer off ++@kindex set circular-trace-buffer ++Choose whether a tracing run should use a linear or circular buffer ++for trace data. A linear buffer will not lose any trace data, but may ++fill up prematurely, while a circular buffer will discard old trace ++data, but it will have always room for the latest tracepoint hits. ++ ++@item show circular-trace-buffer ++@kindex show circular-trace-buffer ++Show the current choice for the trace buffer. Note that this may not ++match the agent's current buffer handling, nor is it guaranteed to ++match the setting that might have been in effect during a past run, ++for instance if you are looking at frames from a trace file. ++ ++@end table ++ ++@table @code ++@item set trace-buffer-size @var{n} ++@itemx set trace-buffer-size unlimited ++@kindex set trace-buffer-size ++Request that the target use a trace buffer of @var{n} bytes. Not all ++targets will honor the request; they may have a compiled-in size for ++the trace buffer, or some other limitation. Set to a value of ++@code{unlimited} or @code{-1} to let the target use whatever size it ++likes. This is also the default. ++ ++@item show trace-buffer-size ++@kindex show trace-buffer-size ++Show the current requested size for the trace buffer. Note that this ++will only match the actual size if the target supports size-setting, ++and was able to handle the requested size. For instance, if the ++target can only change buffer size between runs, this variable will ++not reflect the change until the next run starts. Use @code{tstatus} ++to get a report of the actual buffer size. ++@end table ++ ++@table @code ++@item set trace-user @var{text} ++@kindex set trace-user ++ ++@item show trace-user ++@kindex show trace-user ++ ++@item set trace-notes @var{text} ++@kindex set trace-notes ++Set the trace run's notes. ++ ++@item show trace-notes ++@kindex show trace-notes ++Show the trace run's notes. ++ ++@item set trace-stop-notes @var{text} ++@kindex set trace-stop-notes ++Set the trace run's stop notes. The handling of the note is as for ++@code{tstop} arguments; the set command is convenient way to fix a ++stop note that is mistaken or incomplete. ++ ++@item show trace-stop-notes ++@kindex show trace-stop-notes ++Show the trace run's stop notes. ++ ++@end table ++ ++@node Tracepoint Restrictions ++@subsection Tracepoint Restrictions ++ ++@cindex tracepoint restrictions ++There are a number of restrictions on the use of tracepoints. As ++described above, tracepoint data gathering occurs on the target ++without interaction from @value{GDBN}. Thus the full capabilities of ++the debugger are not available during data gathering, and then at data ++examination time, you will be limited by only having what was ++collected. The following items describe some common problems, but it ++is not exhaustive, and you may run into additional difficulties not ++mentioned here. ++ ++@itemize @bullet ++ ++@item ++Tracepoint expressions are intended to gather objects (lvalues). Thus ++the full flexibility of GDB's expression evaluator is not available. ++You cannot call functions, cast objects to aggregate types, access ++convenience variables or modify values (except by assignment to trace ++state variables). Some language features may implicitly call ++functions (for instance Objective-C fields with accessors), and therefore ++cannot be collected either. ++ ++@item ++Collection of local variables, either individually or in bulk with ++@code{$locals} or @code{$args}, during @code{while-stepping} may ++behave erratically. The stepping action may enter a new scope (for ++instance by stepping into a function), or the location of the variable ++may change (for instance it is loaded into a register). The ++tracepoint data recorded uses the location information for the ++variables that is correct for the tracepoint location. When the ++tracepoint is created, it is not possible, in general, to determine ++where the steps of a @code{while-stepping} sequence will advance the ++program---particularly if a conditional branch is stepped. ++ ++@item ++Collection of an incompletely-initialized or partially-destroyed object ++may result in something that @value{GDBN} cannot display, or displays ++in a misleading way. ++ ++@item ++When @value{GDBN} displays a pointer to character it automatically ++dereferences the pointer to also display characters of the string ++being pointed to. However, collecting the pointer during tracing does ++not automatically collect the string. You need to explicitly ++dereference the pointer and provide size information if you want to ++collect not only the pointer, but the memory pointed to. For example, ++@code{*ptr@@50} can be used to collect the 50 element array pointed to ++by @code{ptr}. ++ ++@item ++It is not possible to collect a complete stack backtrace at a ++tracepoint. Instead, you may collect the registers and a few hundred ++bytes from the stack pointer with something like @code{*(unsigned char *)$esp@@300} ++(adjust to use the name of the actual stack pointer register on your ++target architecture, and the amount of stack you wish to capture). ++Then the @code{backtrace} command will show a partial backtrace when ++using a trace frame. The number of stack frames that can be examined ++depends on the sizes of the frames in the collected stack. Note that ++if you ask for a block so large that it goes past the bottom of the ++stack, the target agent may report an error trying to read from an ++invalid address. ++ ++@item ++If you do not collect registers at a tracepoint, @value{GDBN} can ++infer that the value of @code{$pc} must be the same as the address of ++the tracepoint and use that when you are looking at a trace frame ++for that tracepoint. However, this cannot work if the tracepoint has ++multiple locations (for instance if it was set in a function that was ++inlined), or if it has a @code{while-stepping} loop. In those cases ++@value{GDBN} will warn you that it can't infer @code{$pc}, and default ++it to zero. ++ ++@end itemize ++ ++@node Analyze Collected Data ++@section Using the Collected Data ++ ++After the tracepoint experiment ends, you use @value{GDBN} commands ++for examining the trace data. The basic idea is that each tracepoint ++collects a trace @dfn{snapshot} every time it is hit and another ++snapshot every time it single-steps. All these snapshots are ++consecutively numbered from zero and go into a buffer, and you can ++examine them later. The way you examine them is to @dfn{focus} on a ++specific trace snapshot. When the remote stub is focused on a trace ++snapshot, it will respond to all @value{GDBN} requests for memory and ++registers by reading from the buffer which belongs to that snapshot, ++rather than from @emph{real} memory or registers of the program being ++debugged. This means that @strong{all} @value{GDBN} commands ++(@code{print}, @code{info registers}, @code{backtrace}, etc.) will ++behave as if we were currently debugging the program state as it was ++when the tracepoint occurred. Any requests for data that are not in ++the buffer will fail. ++ ++@menu ++* tfind:: How to select a trace snapshot ++* tdump:: How to display all data for a snapshot ++* save tracepoints:: How to save tracepoints for a future run ++@end menu ++ ++@node tfind ++@subsection @code{tfind @var{n}} ++ ++@kindex tfind ++@cindex select trace snapshot ++@cindex find trace snapshot ++The basic command for selecting a trace snapshot from the buffer is ++@code{tfind @var{n}}, which finds trace snapshot number @var{n}, ++counting from zero. If no argument @var{n} is given, the next ++snapshot is selected. ++ ++Here are the various forms of using the @code{tfind} command. ++ ++@table @code ++@item tfind start ++Find the first snapshot in the buffer. This is a synonym for ++@code{tfind 0} (since 0 is the number of the first snapshot). ++ ++@item tfind none ++Stop debugging trace snapshots, resume @emph{live} debugging. ++ ++@item tfind end ++Same as @samp{tfind none}. ++ ++@item tfind ++No argument means find the next trace snapshot or find the first ++one if no trace snapshot is selected. ++ ++@item tfind - ++Find the previous trace snapshot before the current one. This permits ++retracing earlier steps. ++ ++@item tfind tracepoint @var{num} ++Find the next snapshot associated with tracepoint @var{num}. Search ++proceeds forward from the last examined trace snapshot. If no ++argument @var{num} is given, it means find the next snapshot collected ++for the same tracepoint as the current snapshot. ++ ++@item tfind pc @var{addr} ++Find the next snapshot associated with the value @var{addr} of the ++program counter. Search proceeds forward from the last examined trace ++snapshot. If no argument @var{addr} is given, it means find the next ++snapshot with the same value of PC as the current snapshot. ++ ++@item tfind outside @var{addr1}, @var{addr2} ++Find the next snapshot whose PC is outside the given range of ++addresses (exclusive). ++ ++@item tfind range @var{addr1}, @var{addr2} ++Find the next snapshot whose PC is between @var{addr1} and ++@var{addr2} (inclusive). ++ ++@item tfind line @r{[}@var{file}:@r{]}@var{n} ++Find the next snapshot associated with the source line @var{n}. If ++the optional argument @var{file} is given, refer to line @var{n} in ++that source file. Search proceeds forward from the last examined ++trace snapshot. If no argument @var{n} is given, it means find the ++next line other than the one currently being examined; thus saying ++@code{tfind line} repeatedly can appear to have the same effect as ++stepping from line to line in a @emph{live} debugging session. ++@end table ++ ++The default arguments for the @code{tfind} commands are specifically ++designed to make it easy to scan through the trace buffer. For ++instance, @code{tfind} with no argument selects the next trace ++snapshot, and @code{tfind -} with no argument selects the previous ++trace snapshot. So, by giving one @code{tfind} command, and then ++simply hitting @key{RET} repeatedly you can examine all the trace ++snapshots in order. Or, by saying @code{tfind -} and then hitting ++@key{RET} repeatedly you can examine the snapshots in reverse order. ++The @code{tfind line} command with no argument selects the snapshot ++for the next source line executed. The @code{tfind pc} command with ++no argument selects the next snapshot with the same program counter ++(PC) as the current frame. The @code{tfind tracepoint} command with ++no argument selects the next trace snapshot collected by the same ++tracepoint as the current one. ++ ++In addition to letting you scan through the trace buffer manually, ++these commands make it easy to construct @value{GDBN} scripts that ++scan through the trace buffer and print out whatever collected data ++you are interested in. Thus, if we want to examine the PC, FP, and SP ++registers from each trace frame in the buffer, we can say this: ++ ++@smallexample ++(@value{GDBP}) @b{tfind start} ++(@value{GDBP}) @b{while ($trace_frame != -1)} ++> printf "Frame %d, PC = %08X, SP = %08X, FP = %08X\n", \ ++ $trace_frame, $pc, $sp, $fp ++> tfind ++> end ++ ++Frame 0, PC = 0020DC64, SP = 0030BF3C, FP = 0030BF44 ++Frame 1, PC = 0020DC6C, SP = 0030BF38, FP = 0030BF44 ++Frame 2, PC = 0020DC70, SP = 0030BF34, FP = 0030BF44 ++Frame 3, PC = 0020DC74, SP = 0030BF30, FP = 0030BF44 ++Frame 4, PC = 0020DC78, SP = 0030BF2C, FP = 0030BF44 ++Frame 5, PC = 0020DC7C, SP = 0030BF28, FP = 0030BF44 ++Frame 6, PC = 0020DC80, SP = 0030BF24, FP = 0030BF44 ++Frame 7, PC = 0020DC84, SP = 0030BF20, FP = 0030BF44 ++Frame 8, PC = 0020DC88, SP = 0030BF1C, FP = 0030BF44 ++Frame 9, PC = 0020DC8E, SP = 0030BF18, FP = 0030BF44 ++Frame 10, PC = 00203F6C, SP = 0030BE3C, FP = 0030BF14 ++@end smallexample ++ ++Or, if we want to examine the variable @code{X} at each source line in ++the buffer: ++ ++@smallexample ++(@value{GDBP}) @b{tfind start} ++(@value{GDBP}) @b{while ($trace_frame != -1)} ++> printf "Frame %d, X == %d\n", $trace_frame, X ++> tfind line ++> end ++ ++Frame 0, X = 1 ++Frame 7, X = 2 ++Frame 13, X = 255 ++@end smallexample ++ ++@node tdump ++@subsection @code{tdump} ++@kindex tdump ++@cindex dump all data collected at tracepoint ++@cindex tracepoint data, display ++ ++This command takes no arguments. It prints all the data collected at ++the current trace snapshot. ++ ++@smallexample ++(@value{GDBP}) @b{trace 444} ++(@value{GDBP}) @b{actions} ++Enter actions for tracepoint #2, one per line: ++> collect $regs, $locals, $args, gdb_long_test ++> end ++ ++(@value{GDBP}) @b{tstart} ++ ++(@value{GDBP}) @b{tfind line 444} ++#0 gdb_test (p1=0x11, p2=0x22, p3=0x33, p4=0x44, p5=0x55, p6=0x66) ++at gdb_test.c:444 ++444 printp( "%s: arguments = 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", ) ++ ++(@value{GDBP}) @b{tdump} ++Data collected at tracepoint 2, trace frame 1: ++d0 0xc4aa0085 -995491707 ++d1 0x18 24 ++d2 0x80 128 ++d3 0x33 51 ++d4 0x71aea3d 119204413 ++d5 0x22 34 ++d6 0xe0 224 ++d7 0x380035 3670069 ++a0 0x19e24a 1696330 ++a1 0x3000668 50333288 ++a2 0x100 256 ++a3 0x322000 3284992 ++a4 0x3000698 50333336 ++a5 0x1ad3cc 1758156 ++fp 0x30bf3c 0x30bf3c ++sp 0x30bf34 0x30bf34 ++ps 0x0 0 ++pc 0x20b2c8 0x20b2c8 ++fpcontrol 0x0 0 ++fpstatus 0x0 0 ++fpiaddr 0x0 0 ++p = 0x20e5b4 "gdb-test" ++p1 = (void *) 0x11 ++p2 = (void *) 0x22 ++p3 = (void *) 0x33 ++p4 = (void *) 0x44 ++p5 = (void *) 0x55 ++p6 = (void *) 0x66 ++gdb_long_test = 17 '\021' ++ ++(@value{GDBP}) ++@end smallexample ++ ++@code{tdump} works by scanning the tracepoint's current collection ++actions and printing the value of each expression listed. So ++@code{tdump} can fail, if after a run, you change the tracepoint's ++actions to mention variables that were not collected during the run. ++ ++Also, for tracepoints with @code{while-stepping} loops, @code{tdump} ++uses the collected value of @code{$pc} to distinguish between trace ++frames that were collected at the tracepoint hit, and frames that were ++collected while stepping. This allows it to correctly choose whether ++to display the basic list of collections, or the collections from the ++body of the while-stepping loop. However, if @code{$pc} was not collected, ++then @code{tdump} will always attempt to dump using the basic collection ++list, and may fail if a while-stepping frame does not include all the ++same data that is collected at the tracepoint hit. ++@c This is getting pretty arcane, example would be good. ++ ++@node save tracepoints ++@subsection @code{save tracepoints @var{filename}} ++@kindex save tracepoints ++@kindex save-tracepoints ++@cindex save tracepoints for future sessions ++ ++This command saves all current tracepoint definitions together with ++their actions and passcounts, into a file @file{@var{filename}} ++suitable for use in a later debugging session. To read the saved ++tracepoint definitions, use the @code{source} command (@pxref{Command ++Files}). The @w{@code{save-tracepoints}} command is a deprecated ++alias for @w{@code{save tracepoints}} ++ ++@node Tracepoint Variables ++@section Convenience Variables for Tracepoints ++@cindex tracepoint variables ++@cindex convenience variables for tracepoints ++ ++@table @code ++@vindex $trace_frame ++@item (int) $trace_frame ++The current trace snapshot (a.k.a.@: @dfn{frame}) number, or -1 if no ++snapshot is selected. ++ ++@vindex $tracepoint ++@item (int) $tracepoint ++The tracepoint for the current trace snapshot. ++ ++@vindex $trace_line ++@item (int) $trace_line ++The line number for the current trace snapshot. ++ ++@vindex $trace_file ++@item (char []) $trace_file ++The source file for the current trace snapshot. ++ ++@vindex $trace_func ++@item (char []) $trace_func ++The name of the function containing @code{$tracepoint}. ++@end table ++ ++Note: @code{$trace_file} is not suitable for use in @code{printf}, ++use @code{output} instead. ++ ++Here's a simple example of using these convenience variables for ++stepping through all the trace snapshots and printing some of their ++data. Note that these are not the same as trace state variables, ++which are managed by the target. ++ ++@smallexample ++(@value{GDBP}) @b{tfind start} ++ ++(@value{GDBP}) @b{while $trace_frame != -1} ++> output $trace_file ++> printf ", line %d (tracepoint #%d)\n", $trace_line, $tracepoint ++> tfind ++> end ++@end smallexample ++ ++@node Trace Files ++@section Using Trace Files ++@cindex trace files ++ ++In some situations, the target running a trace experiment may no ++longer be available; perhaps it crashed, or the hardware was needed ++for a different activity. To handle these cases, you can arrange to ++dump the trace data into a file, and later use that file as a source ++of trace data, via the @code{target tfile} command. ++ ++@table @code ++ ++@kindex tsave ++@item tsave [ -r ] @var{filename} ++@itemx tsave [-ctf] @var{dirname} ++Save the trace data to @var{filename}. By default, this command ++assumes that @var{filename} refers to the host filesystem, so if ++necessary @value{GDBN} will copy raw trace data up from the target and ++then save it. If the target supports it, you can also supply the ++optional argument @code{-r} (``remote'') to direct the target to save ++the data directly into @var{filename} in its own filesystem, which may be ++more efficient if the trace buffer is very large. (Note, however, that ++@code{target tfile} can only read from files accessible to the host.) ++By default, this command will save trace frame in tfile format. ++You can supply the optional argument @code{-ctf} to save data in CTF ++format. The @dfn{Common Trace Format} (CTF) is proposed as a trace format ++that can be shared by multiple debugging and tracing tools. Please go to ++@indicateurl{http://www.efficios.com/ctf} to get more information. ++ ++@kindex target tfile ++@kindex tfile ++@kindex target ctf ++@kindex ctf ++@item target tfile @var{filename} ++@itemx target ctf @var{dirname} ++Use the file named @var{filename} or directory named @var{dirname} as ++a source of trace data. Commands that examine data work as they do with ++a live target, but it is not possible to run any new trace experiments. ++@code{tstatus} will report the state of the trace run at the moment ++the data was saved, as well as the current trace frame you are examining. ++Both @var{filename} and @var{dirname} must be on a filesystem accessible to ++the host. ++ ++@smallexample ++(@value{GDBP}) target ctf ctf.ctf ++(@value{GDBP}) tfind ++Found trace frame 0, tracepoint 2 ++39 ++a; /* set tracepoint 1 here */ ++(@value{GDBP}) tdump ++Data collected at tracepoint 2, trace frame 0: ++i = 0 ++a = 0 ++b = 1 '\001' ++c = @{"123", "456", "789", "123", "456", "789"@} ++d = @{@{@{a = 1, b = 2@}, @{a = 3, b = 4@}@}, @{@{a = 5, b = 6@}, @{a = 7, b = 8@}@}@} ++(@value{GDBP}) p b ++$1 = 1 ++@end smallexample ++ ++@end table ++ ++@node Overlays ++@chapter Debugging Programs That Use Overlays ++@cindex overlays ++ ++If your program is too large to fit completely in your target system's ++memory, you can sometimes use @dfn{overlays} to work around this ++problem. @value{GDBN} provides some support for debugging programs that ++use overlays. ++ ++@menu ++* How Overlays Work:: A general explanation of overlays. ++* Overlay Commands:: Managing overlays in @value{GDBN}. ++* Automatic Overlay Debugging:: @value{GDBN} can find out which overlays are ++ mapped by asking the inferior. ++* Overlay Sample Program:: A sample program using overlays. ++@end menu ++ ++@node How Overlays Work ++@section How Overlays Work ++@cindex mapped overlays ++@cindex unmapped overlays ++@cindex load address, overlay's ++@cindex mapped address ++@cindex overlay area ++ ++Suppose you have a computer whose instruction address space is only 64 ++kilobytes long, but which has much more memory which can be accessed by ++other means: special instructions, segment registers, or memory ++management hardware, for example. Suppose further that you want to ++adapt a program which is larger than 64 kilobytes to run on this system. ++ ++One solution is to identify modules of your program which are relatively ++independent, and need not call each other directly; call these modules ++@dfn{overlays}. Separate the overlays from the main program, and place ++their machine code in the larger memory. Place your main program in ++instruction memory, but leave at least enough space there to hold the ++largest overlay as well. ++ ++Now, to call a function located in an overlay, you must first copy that ++overlay's machine code from the large memory into the space set aside ++for it in the instruction memory, and then jump to its entry point ++there. ++ ++@c NB: In the below the mapped area's size is greater or equal to the ++@c size of all overlays. This is intentional to remind the developer ++@c that overlays don't necessarily need to be the same size. ++ ++@smallexample ++@group ++ Data Instruction Larger ++Address Space Address Space Address Space +++-----------+ +-----------+ +-----------+ ++| | | | | | +++-----------+ +-----------+ +-----------+<-- overlay 1 ++| program | | main | .----| overlay 1 | load address ++| variables | | program | | +-----------+ ++| and heap | | | | | | +++-----------+ | | | +-----------+<-- overlay 2 ++| | +-----------+ | | | load address +++-----------+ | | | .-| overlay 2 | ++ | | | | | | ++ mapped --->+-----------+ | | +-----------+ ++ address | | | | | | ++ | overlay | <-' | | | ++ | area | <---' +-----------+<-- overlay 3 ++ | | <---. | | load address ++ +-----------+ `--| overlay 3 | ++ | | | | ++ +-----------+ | | ++ +-----------+ ++ | | ++ +-----------+ ++ ++ @anchor{A code overlay}A code overlay ++@end group ++@end smallexample ++ ++The diagram (@pxref{A code overlay}) shows a system with separate data ++and instruction address spaces. To map an overlay, the program copies ++its code from the larger address space to the instruction address space. ++Since the overlays shown here all use the same mapped address, only one ++may be mapped at a time. For a system with a single address space for ++data and instructions, the diagram would be similar, except that the ++program variables and heap would share an address space with the main ++program and the overlay area. ++ ++An overlay loaded into instruction memory and ready for use is called a ++@dfn{mapped} overlay; its @dfn{mapped address} is its address in the ++instruction memory. An overlay not present (or only partially present) ++in instruction memory is called @dfn{unmapped}; its @dfn{load address} ++is its address in the larger memory. The mapped address is also called ++the @dfn{virtual memory address}, or @dfn{VMA}; the load address is also ++called the @dfn{load memory address}, or @dfn{LMA}. ++ ++Unfortunately, overlays are not a completely transparent way to adapt a ++program to limited instruction memory. They introduce a new set of ++global constraints you must keep in mind as you design your program: ++ ++@itemize @bullet ++ ++@item ++Before calling or returning to a function in an overlay, your program ++must make sure that overlay is actually mapped. Otherwise, the call or ++return will transfer control to the right address, but in the wrong ++overlay, and your program will probably crash. ++ ++@item ++If the process of mapping an overlay is expensive on your system, you ++will need to choose your overlays carefully to minimize their effect on ++your program's performance. ++ ++@item ++The executable file you load onto your system must contain each ++overlay's instructions, appearing at the overlay's load address, not its ++mapped address. However, each overlay's instructions must be relocated ++and its symbols defined as if the overlay were at its mapped address. ++You can use GNU linker scripts to specify different load and relocation ++addresses for pieces of your program; see @ref{Overlay Description,,, ++ld.info, Using ld: the GNU linker}. ++ ++@item ++The procedure for loading executable files onto your system must be able ++to load their contents into the larger address space as well as the ++instruction and data spaces. ++ ++@end itemize ++ ++The overlay system described above is rather simple, and could be ++improved in many ways: ++ ++@itemize @bullet ++ ++@item ++If your system has suitable bank switch registers or memory management ++hardware, you could use those facilities to make an overlay's load area ++contents simply appear at their mapped address in instruction space. ++This would probably be faster than copying the overlay to its mapped ++area in the usual way. ++ ++@item ++If your overlays are small enough, you could set aside more than one ++overlay area, and have more than one overlay mapped at a time. ++ ++@item ++You can use overlays to manage data, as well as instructions. In ++general, data overlays are even less transparent to your design than ++code overlays: whereas code overlays only require care when you call or ++return to functions, data overlays require care every time you access ++the data. Also, if you change the contents of a data overlay, you ++must copy its contents back out to its load address before you can copy a ++different data overlay into the same mapped area. ++ ++@end itemize ++ ++ ++@node Overlay Commands ++@section Overlay Commands ++ ++To use @value{GDBN}'s overlay support, each overlay in your program must ++correspond to a separate section of the executable file. The section's ++virtual memory address and load memory address must be the overlay's ++mapped and load addresses. Identifying overlays with sections allows ++@value{GDBN} to determine the appropriate address of a function or ++variable, depending on whether the overlay is mapped or not. ++ ++@value{GDBN}'s overlay commands all start with the word @code{overlay}; ++you can abbreviate this as @code{ov} or @code{ovly}. The commands are: ++ ++@table @code ++@item overlay off ++@kindex overlay ++Disable @value{GDBN}'s overlay support. When overlay support is ++disabled, @value{GDBN} assumes that all functions and variables are ++always present at their mapped addresses. By default, @value{GDBN}'s ++overlay support is disabled. ++ ++@item overlay manual ++@cindex manual overlay debugging ++Enable @dfn{manual} overlay debugging. In this mode, @value{GDBN} ++relies on you to tell it which overlays are mapped, and which are not, ++using the @code{overlay map-overlay} and @code{overlay unmap-overlay} ++commands described below. ++ ++@item overlay map-overlay @var{overlay} ++@itemx overlay map @var{overlay} ++@cindex map an overlay ++Tell @value{GDBN} that @var{overlay} is now mapped; @var{overlay} must ++be the name of the object file section containing the overlay. When an ++overlay is mapped, @value{GDBN} assumes it can find the overlay's ++functions and variables at their mapped addresses. @value{GDBN} assumes ++that any other overlays whose mapped ranges overlap that of ++@var{overlay} are now unmapped. ++ ++@item overlay unmap-overlay @var{overlay} ++@itemx overlay unmap @var{overlay} ++@cindex unmap an overlay ++Tell @value{GDBN} that @var{overlay} is no longer mapped; @var{overlay} ++must be the name of the object file section containing the overlay. ++When an overlay is unmapped, @value{GDBN} assumes it can find the ++overlay's functions and variables at their load addresses. ++ ++@item overlay auto ++Enable @dfn{automatic} overlay debugging. In this mode, @value{GDBN} ++consults a data structure the overlay manager maintains in the inferior ++to see which overlays are mapped. For details, see @ref{Automatic ++Overlay Debugging}. ++ ++@item overlay load-target ++@itemx overlay load ++@cindex reloading the overlay table ++Re-read the overlay table from the inferior. Normally, @value{GDBN} ++re-reads the table @value{GDBN} automatically each time the inferior ++stops, so this command should only be necessary if you have changed the ++overlay mapping yourself using @value{GDBN}. This command is only ++useful when using automatic overlay debugging. ++ ++@item overlay list-overlays ++@itemx overlay list ++@cindex listing mapped overlays ++Display a list of the overlays currently mapped, along with their mapped ++addresses, load addresses, and sizes. ++ ++@end table ++ ++Normally, when @value{GDBN} prints a code address, it includes the name ++of the function the address falls in: ++ ++@smallexample ++(@value{GDBP}) print main ++$3 = @{int ()@} 0x11a0
++@end smallexample ++@noindent ++When overlay debugging is enabled, @value{GDBN} recognizes code in ++unmapped overlays, and prints the names of unmapped functions with ++asterisks around them. For example, if @code{foo} is a function in an ++unmapped overlay, @value{GDBN} prints it this way: ++ ++@smallexample ++(@value{GDBP}) overlay list ++No sections are mapped. ++(@value{GDBP}) print foo ++$5 = @{int (int)@} 0x100000 <*foo*> ++@end smallexample ++@noindent ++When @code{foo}'s overlay is mapped, @value{GDBN} prints the function's ++name normally: ++ ++@smallexample ++(@value{GDBP}) overlay list ++Section .ov.foo.text, loaded at 0x100000 - 0x100034, ++ mapped at 0x1016 - 0x104a ++(@value{GDBP}) print foo ++$6 = @{int (int)@} 0x1016 ++@end smallexample ++ ++When overlay debugging is enabled, @value{GDBN} can find the correct ++address for functions and variables in an overlay, whether or not the ++overlay is mapped. This allows most @value{GDBN} commands, like ++@code{break} and @code{disassemble}, to work normally, even on unmapped ++code. However, @value{GDBN}'s breakpoint support has some limitations: ++ ++@itemize @bullet ++@item ++@cindex breakpoints in overlays ++@cindex overlays, setting breakpoints in ++You can set breakpoints in functions in unmapped overlays, as long as ++@value{GDBN} can write to the overlay at its load address. ++@item ++@value{GDBN} can not set hardware or simulator-based breakpoints in ++unmapped overlays. However, if you set a breakpoint at the end of your ++overlay manager (and tell @value{GDBN} which overlays are now mapped, if ++you are using manual overlay management), @value{GDBN} will re-set its ++breakpoints properly. ++@end itemize ++ ++ ++@node Automatic Overlay Debugging ++@section Automatic Overlay Debugging ++@cindex automatic overlay debugging ++ ++@value{GDBN} can automatically track which overlays are mapped and which ++are not, given some simple co-operation from the overlay manager in the ++inferior. If you enable automatic overlay debugging with the ++@code{overlay auto} command (@pxref{Overlay Commands}), @value{GDBN} ++looks in the inferior's memory for certain variables describing the ++current state of the overlays. ++ ++Here are the variables your overlay manager must define to support ++@value{GDBN}'s automatic overlay debugging: ++ ++@table @asis ++ ++@item @code{_ovly_table}: ++This variable must be an array of the following structures: ++ ++@smallexample ++struct ++@{ ++ /* The overlay's mapped address. */ ++ unsigned long vma; ++ ++ /* The size of the overlay, in bytes. */ ++ unsigned long size; ++ ++ /* The overlay's load address. */ ++ unsigned long lma; ++ ++ /* Non-zero if the overlay is currently mapped; ++ zero otherwise. */ ++ unsigned long mapped; ++@} ++@end smallexample ++ ++@item @code{_novlys}: ++This variable must be a four-byte signed integer, holding the total ++number of elements in @code{_ovly_table}. ++ ++@end table ++ ++To decide whether a particular overlay is mapped or not, @value{GDBN} ++looks for an entry in @w{@code{_ovly_table}} whose @code{vma} and ++@code{lma} members equal the VMA and LMA of the overlay's section in the ++executable file. When @value{GDBN} finds a matching entry, it consults ++the entry's @code{mapped} member to determine whether the overlay is ++currently mapped. ++ ++In addition, your overlay manager may define a function called ++@code{_ovly_debug_event}. If this function is defined, @value{GDBN} ++will silently set a breakpoint there. If the overlay manager then ++calls this function whenever it has changed the overlay table, this ++will enable @value{GDBN} to accurately keep track of which overlays ++are in program memory, and update any breakpoints that may be set ++in overlays. This will allow breakpoints to work even if the ++overlays are kept in ROM or other non-writable memory while they ++are not being executed. ++ ++@node Overlay Sample Program ++@section Overlay Sample Program ++@cindex overlay example program ++ ++When linking a program which uses overlays, you must place the overlays ++at their load addresses, while relocating them to run at their mapped ++addresses. To do this, you must write a linker script (@pxref{Overlay ++Description,,, ld.info, Using ld: the GNU linker}). Unfortunately, ++since linker scripts are specific to a particular host system, target ++architecture, and target memory layout, this manual cannot provide ++portable sample code demonstrating @value{GDBN}'s overlay support. ++ ++However, the @value{GDBN} source distribution does contain an overlaid ++program, with linker scripts for a few systems, as part of its test ++suite. The program consists of the following files from ++@file{gdb/testsuite/gdb.base}: ++ ++@table @file ++@item overlays.c ++The main program file. ++@item ovlymgr.c ++A simple overlay manager, used by @file{overlays.c}. ++@item foo.c ++@itemx bar.c ++@itemx baz.c ++@itemx grbx.c ++Overlay modules, loaded and used by @file{overlays.c}. ++@item d10v.ld ++@itemx m32r.ld ++Linker scripts for linking the test program on the @code{d10v-elf} ++and @code{m32r-elf} targets. ++@end table ++ ++You can build the test program using the @code{d10v-elf} GCC ++cross-compiler like this: ++ ++@smallexample ++$ d10v-elf-gcc -g -c overlays.c ++$ d10v-elf-gcc -g -c ovlymgr.c ++$ d10v-elf-gcc -g -c foo.c ++$ d10v-elf-gcc -g -c bar.c ++$ d10v-elf-gcc -g -c baz.c ++$ d10v-elf-gcc -g -c grbx.c ++$ d10v-elf-gcc -g overlays.o ovlymgr.o foo.o bar.o \ ++ baz.o grbx.o -Wl,-Td10v.ld -o overlays ++@end smallexample ++ ++The build process is identical for any other architecture, except that ++you must substitute the appropriate compiler and linker script for the ++target system for @code{d10v-elf-gcc} and @code{d10v.ld}. ++ ++ ++@node Languages ++@chapter Using @value{GDBN} with Different Languages ++@cindex languages ++ ++Although programming languages generally have common aspects, they are ++rarely expressed in the same manner. For instance, in ANSI C, ++dereferencing a pointer @code{p} is accomplished by @code{*p}, but in ++Modula-2, it is accomplished by @code{p^}. Values can also be ++represented (and displayed) differently. Hex numbers in C appear as ++@samp{0x1ae}, while in Modula-2 they appear as @samp{1AEH}. ++ ++@cindex working language ++Language-specific information is built into @value{GDBN} for some languages, ++allowing you to express operations like the above in your program's ++native language, and allowing @value{GDBN} to output values in a manner ++consistent with the syntax of your program's native language. The ++language you use to build expressions is called the @dfn{working ++language}. ++ ++@menu ++* Setting:: Switching between source languages ++* Show:: Displaying the language ++* Checks:: Type and range checks ++* Supported Languages:: Supported languages ++* Unsupported Languages:: Unsupported languages ++@end menu ++ ++@node Setting ++@section Switching Between Source Languages ++ ++There are two ways to control the working language---either have @value{GDBN} ++set it automatically, or select it manually yourself. You can use the ++@code{set language} command for either purpose. On startup, @value{GDBN} ++defaults to setting the language automatically. The working language is ++used to determine how expressions you type are interpreted, how values ++are printed, etc. ++ ++In addition to the working language, every source file that ++@value{GDBN} knows about has its own working language. For some object ++file formats, the compiler might indicate which language a particular ++source file is in. However, most of the time @value{GDBN} infers the ++language from the name of the file. The language of a source file ++controls whether C@t{++} names are demangled---this way @code{backtrace} can ++show each frame appropriately for its own language. There is no way to ++set the language of a source file from within @value{GDBN}, but you can ++set the language associated with a filename extension. @xref{Show, , ++Displaying the Language}. ++ ++This is most commonly a problem when you use a program, such ++as @code{cfront} or @code{f2c}, that generates C but is written in ++another language. In that case, make the ++program use @code{#line} directives in its C output; that way ++@value{GDBN} will know the correct language of the source code of the original ++program, and will display that source code, not the generated C code. ++ ++@menu ++* Filenames:: Filename extensions and languages. ++* Manually:: Setting the working language manually ++* Automatically:: Having @value{GDBN} infer the source language ++@end menu ++ ++@node Filenames ++@subsection List of Filename Extensions and Languages ++ ++If a source file name ends in one of the following extensions, then ++@value{GDBN} infers that its language is the one indicated. ++ ++@table @file ++@item .ada ++@itemx .ads ++@itemx .adb ++@itemx .a ++Ada source file. ++ ++@item .c ++C source file ++ ++@item .C ++@itemx .cc ++@itemx .cp ++@itemx .cpp ++@itemx .cxx ++@itemx .c++ ++C@t{++} source file ++ ++@item .d ++D source file ++ ++@item .m ++Objective-C source file ++ ++@item .f ++@itemx .F ++Fortran source file ++ ++@item .mod ++Modula-2 source file ++ ++@item .s ++@itemx .S ++Assembler source file. This actually behaves almost like C, but ++@value{GDBN} does not skip over function prologues when stepping. ++@end table ++ ++In addition, you may set the language associated with a filename ++extension. @xref{Show, , Displaying the Language}. ++ ++@node Manually ++@subsection Setting the Working Language ++ ++If you allow @value{GDBN} to set the language automatically, ++expressions are interpreted the same way in your debugging session and ++your program. ++ ++@kindex set language ++If you wish, you may set the language manually. To do this, issue the ++command @samp{set language @var{lang}}, where @var{lang} is the name of ++a language, such as ++@code{c} or @code{modula-2}. ++For a list of the supported languages, type @samp{set language}. ++ ++Setting the language manually prevents @value{GDBN} from updating the working ++language automatically. This can lead to confusion if you try ++to debug a program when the working language is not the same as the ++source language, when an expression is acceptable to both ++languages---but means different things. For instance, if the current ++source file were written in C, and @value{GDBN} was parsing Modula-2, a ++command such as: ++ ++@smallexample ++print a = b + c ++@end smallexample ++ ++@noindent ++might not have the effect you intended. In C, this means to add ++@code{b} and @code{c} and place the result in @code{a}. The result ++printed would be the value of @code{a}. In Modula-2, this means to compare ++@code{a} to the result of @code{b+c}, yielding a @code{BOOLEAN} value. ++ ++@node Automatically ++@subsection Having @value{GDBN} Infer the Source Language ++ ++To have @value{GDBN} set the working language automatically, use ++@samp{set language local} or @samp{set language auto}. @value{GDBN} ++then infers the working language. That is, when your program stops in a ++frame (usually by encountering a breakpoint), @value{GDBN} sets the ++working language to the language recorded for the function in that ++frame. If the language for a frame is unknown (that is, if the function ++or block corresponding to the frame was defined in a source file that ++does not have a recognized extension), the current working language is ++not changed, and @value{GDBN} issues a warning. ++ ++This may not seem necessary for most programs, which are written ++entirely in one source language. However, program modules and libraries ++written in one source language can be used by a main program written in ++a different source language. Using @samp{set language auto} in this ++case frees you from having to set the working language manually. ++ ++@node Show ++@section Displaying the Language ++ ++The following commands help you find out which language is the ++working language, and also what language source files were written in. ++ ++@table @code ++@item show language ++@anchor{show language} ++@kindex show language ++Display the current working language. This is the ++language you can use with commands such as @code{print} to ++build and compute expressions that may involve variables in your program. ++ ++@item info frame ++@kindex info frame@r{, show the source language} ++Display the source language for this frame. This language becomes the ++working language if you use an identifier from this frame. ++@xref{Frame Info, ,Information about a Frame}, to identify the other ++information listed here. ++ ++@item info source ++@kindex info source@r{, show the source language} ++Display the source language of this source file. ++@xref{Symbols, ,Examining the Symbol Table}, to identify the other ++information listed here. ++@end table ++ ++In unusual circumstances, you may have source files with extensions ++not in the standard list. You can then set the extension associated ++with a language explicitly: ++ ++@table @code ++@item set extension-language @var{ext} @var{language} ++@kindex set extension-language ++Tell @value{GDBN} that source files with extension @var{ext} are to be ++assumed as written in the source language @var{language}. ++ ++@item info extensions ++@kindex info extensions ++List all the filename extensions and the associated languages. ++@end table ++ ++@node Checks ++@section Type and Range Checking ++ ++Some languages are designed to guard you against making seemingly common ++errors through a series of compile- and run-time checks. These include ++checking the type of arguments to functions and operators and making ++sure mathematical overflows are caught at run time. Checks such as ++these help to ensure a program's correctness once it has been compiled ++by eliminating type mismatches and providing active checks for range ++errors when your program is running. ++ ++By default @value{GDBN} checks for these errors according to the ++rules of the current source language. Although @value{GDBN} does not check ++the statements in your program, it can check expressions entered directly ++into @value{GDBN} for evaluation via the @code{print} command, for example. ++ ++@menu ++* Type Checking:: An overview of type checking ++* Range Checking:: An overview of range checking ++@end menu ++ ++@cindex type checking ++@cindex checks, type ++@node Type Checking ++@subsection An Overview of Type Checking ++ ++Some languages, such as C and C@t{++}, are strongly typed, meaning that the ++arguments to operators and functions have to be of the correct type, ++otherwise an error occurs. These checks prevent type mismatch ++errors from ever causing any run-time problems. For example, ++ ++@smallexample ++int klass::my_method(char *b) @{ return b ? 1 : 2; @} ++ ++(@value{GDBP}) print obj.my_method (0) ++$1 = 2 ++@exdent but ++(@value{GDBP}) print obj.my_method (0x1234) ++Cannot resolve method klass::my_method to any overloaded instance ++@end smallexample ++ ++The second example fails because in C@t{++} the integer constant ++@samp{0x1234} is not type-compatible with the pointer parameter type. ++ ++For the expressions you use in @value{GDBN} commands, you can tell ++@value{GDBN} to not enforce strict type checking or ++to treat any mismatches as errors and abandon the expression; ++When type checking is disabled, @value{GDBN} successfully evaluates ++expressions like the second example above. ++ ++Even if type checking is off, there may be other reasons ++related to type that prevent @value{GDBN} from evaluating an expression. ++For instance, @value{GDBN} does not know how to add an @code{int} and ++a @code{struct foo}. These particular type errors have nothing to do ++with the language in use and usually arise from expressions which make ++little sense to evaluate anyway. ++ ++@value{GDBN} provides some additional commands for controlling type checking: ++ ++@kindex set check type ++@kindex show check type ++@table @code ++@item set check type on ++@itemx set check type off ++Set strict type checking on or off. If any type mismatches occur in ++evaluating an expression while type checking is on, @value{GDBN} prints a ++message and aborts evaluation of the expression. ++ ++@item show check type ++Show the current setting of type checking and whether @value{GDBN} ++is enforcing strict type checking rules. ++@end table ++ ++@cindex range checking ++@cindex checks, range ++@node Range Checking ++@subsection An Overview of Range Checking ++ ++In some languages (such as Modula-2), it is an error to exceed the ++bounds of a type; this is enforced with run-time checks. Such range ++checking is meant to ensure program correctness by making sure ++computations do not overflow, or indices on an array element access do ++not exceed the bounds of the array. ++ ++For expressions you use in @value{GDBN} commands, you can tell ++@value{GDBN} to treat range errors in one of three ways: ignore them, ++always treat them as errors and abandon the expression, or issue ++warnings but evaluate the expression anyway. ++ ++A range error can result from numerical overflow, from exceeding an ++array index bound, or when you type a constant that is not a member ++of any type. Some languages, however, do not treat overflows as an ++error. In many implementations of C, mathematical overflow causes the ++result to ``wrap around'' to lower values---for example, if @var{m} is ++the largest integer value, and @var{s} is the smallest, then ++ ++@smallexample ++@var{m} + 1 @result{} @var{s} ++@end smallexample ++ ++This, too, is specific to individual languages, and in some cases ++specific to individual compilers or machines. @xref{Supported Languages, , ++Supported Languages}, for further details on specific languages. ++ ++@value{GDBN} provides some additional commands for controlling the range checker: ++ ++@kindex set check range ++@kindex show check range ++@table @code ++@item set check range auto ++Set range checking on or off based on the current working language. ++@xref{Supported Languages, ,Supported Languages}, for the default settings for ++each language. ++ ++@item set check range on ++@itemx set check range off ++Set range checking on or off, overriding the default setting for the ++current working language. A warning is issued if the setting does not ++match the language default. If a range error occurs and range checking is on, ++then a message is printed and evaluation of the expression is aborted. ++ ++@item set check range warn ++Output messages when the @value{GDBN} range checker detects a range error, ++but attempt to evaluate the expression anyway. Evaluating the ++expression may still be impossible for other reasons, such as accessing ++memory that the process does not own (a typical example from many Unix ++systems). ++ ++@item show range ++Show the current setting of the range checker, and whether or not it is ++being set automatically by @value{GDBN}. ++@end table ++ ++@node Supported Languages ++@section Supported Languages ++ ++@value{GDBN} supports C, C@t{++}, D, Go, Objective-C, Fortran, ++OpenCL C, Pascal, Rust, assembly, Modula-2, and Ada. ++@c This is false ... ++Some @value{GDBN} features may be used in expressions regardless of the ++language you use: the @value{GDBN} @code{@@} and @code{::} operators, ++and the @samp{@{type@}addr} construct (@pxref{Expressions, ++,Expressions}) can be used with the constructs of any supported ++language. ++ ++The following sections detail to what degree each source language is ++supported by @value{GDBN}. These sections are not meant to be language ++tutorials or references, but serve only as a reference guide to what the ++@value{GDBN} expression parser accepts, and what input and output ++formats should look like for different languages. There are many good ++books written on each of these languages; please look to these for a ++language reference or tutorial. ++ ++@menu ++* C:: C and C@t{++} ++* D:: D ++* Go:: Go ++* Objective-C:: Objective-C ++* OpenCL C:: OpenCL C ++* Fortran:: Fortran ++* Pascal:: Pascal ++* Rust:: Rust ++* Modula-2:: Modula-2 ++* Ada:: Ada ++@end menu ++ ++@node C ++@subsection C and C@t{++} ++ ++@cindex C and C@t{++} ++@cindex expressions in C or C@t{++} ++ ++Since C and C@t{++} are so closely related, many features of @value{GDBN} apply ++to both languages. Whenever this is the case, we discuss those languages ++together. ++ ++@cindex C@t{++} ++@cindex @code{g++}, @sc{gnu} C@t{++} compiler ++@cindex @sc{gnu} C@t{++} ++The C@t{++} debugging facilities are jointly implemented by the C@t{++} ++compiler and @value{GDBN}. Therefore, to debug your C@t{++} code ++effectively, you must compile your C@t{++} programs with a supported ++C@t{++} compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C@t{++} ++compiler (@code{aCC}). ++ ++@menu ++* C Operators:: C and C@t{++} operators ++* C Constants:: C and C@t{++} constants ++* C Plus Plus Expressions:: C@t{++} expressions ++* C Defaults:: Default settings for C and C@t{++} ++* C Checks:: C and C@t{++} type and range checks ++* Debugging C:: @value{GDBN} and C ++* Debugging C Plus Plus:: @value{GDBN} features for C@t{++} ++* Decimal Floating Point:: Numbers in Decimal Floating Point format ++@end menu ++ ++@node C Operators ++@subsubsection C and C@t{++} Operators ++ ++@cindex C and C@t{++} operators ++ ++Operators must be defined on values of specific types. For instance, ++@code{+} is defined on numbers, but not on structures. Operators are ++often defined on groups of types. ++ ++For the purposes of C and C@t{++}, the following definitions hold: ++ ++@itemize @bullet ++ ++@item ++@emph{Integral types} include @code{int} with any of its storage-class ++specifiers; @code{char}; @code{enum}; and, for C@t{++}, @code{bool}. ++ ++@item ++@emph{Floating-point types} include @code{float}, @code{double}, and ++@code{long double} (if supported by the target platform). ++ ++@item ++@emph{Pointer types} include all types defined as @code{(@var{type} *)}. ++ ++@item ++@emph{Scalar types} include all of the above. ++ ++@end itemize ++ ++@noindent ++The following operators are supported. They are listed here ++in order of increasing precedence: ++ ++@table @code ++@item , ++The comma or sequencing operator. Expressions in a comma-separated list ++are evaluated from left to right, with the result of the entire ++expression being the last expression evaluated. ++ ++@item = ++Assignment. The value of an assignment expression is the value ++assigned. Defined on scalar types. ++ ++@item @var{op}= ++Used in an expression of the form @w{@code{@var{a} @var{op}= @var{b}}}, ++and translated to @w{@code{@var{a} = @var{a op b}}}. ++@w{@code{@var{op}=}} and @code{=} have the same precedence. The operator ++@var{op} is any one of the operators @code{|}, @code{^}, @code{&}, ++@code{<<}, @code{>>}, @code{+}, @code{-}, @code{*}, @code{/}, @code{%}. ++ ++@item ?: ++The ternary operator. @code{@var{a} ? @var{b} : @var{c}} can be thought ++of as: if @var{a} then @var{b} else @var{c}. The argument @var{a} ++should be of an integral type. ++ ++@item || ++Logical @sc{or}. Defined on integral types. ++ ++@item && ++Logical @sc{and}. Defined on integral types. ++ ++@item | ++Bitwise @sc{or}. Defined on integral types. ++ ++@item ^ ++Bitwise exclusive-@sc{or}. Defined on integral types. ++ ++@item & ++Bitwise @sc{and}. Defined on integral types. ++ ++@item ==@r{, }!= ++Equality and inequality. Defined on scalar types. The value of these ++expressions is 0 for false and non-zero for true. ++ ++@item <@r{, }>@r{, }<=@r{, }>= ++Less than, greater than, less than or equal, greater than or equal. ++Defined on scalar types. The value of these expressions is 0 for false ++and non-zero for true. ++ ++@item <<@r{, }>> ++left shift, and right shift. Defined on integral types. ++ ++@item @@ ++The @value{GDBN} ``artificial array'' operator (@pxref{Expressions, ,Expressions}). ++ ++@item +@r{, }- ++Addition and subtraction. Defined on integral types, floating-point types and ++pointer types. ++ ++@item *@r{, }/@r{, }% ++Multiplication, division, and modulus. Multiplication and division are ++defined on integral and floating-point types. Modulus is defined on ++integral types. ++ ++@item ++@r{, }-- ++Increment and decrement. When appearing before a variable, the ++operation is performed before the variable is used in an expression; ++when appearing after it, the variable's value is used before the ++operation takes place. ++ ++@item * ++Pointer dereferencing. Defined on pointer types. Same precedence as ++@code{++}. ++ ++@item & ++Address operator. Defined on variables. Same precedence as @code{++}. ++ ++For debugging C@t{++}, @value{GDBN} implements a use of @samp{&} beyond what is ++allowed in the C@t{++} language itself: you can use @samp{&(&@var{ref})} ++to examine the address ++where a C@t{++} reference variable (declared with @samp{&@var{ref}}) is ++stored. ++ ++@item - ++Negative. Defined on integral and floating-point types. Same ++precedence as @code{++}. ++ ++@item ! ++Logical negation. Defined on integral types. Same precedence as ++@code{++}. ++ ++@item ~ ++Bitwise complement operator. Defined on integral types. Same precedence as ++@code{++}. ++ ++ ++@item .@r{, }-> ++Structure member, and pointer-to-structure member. For convenience, ++@value{GDBN} regards the two as equivalent, choosing whether to dereference a ++pointer based on the stored type information. ++Defined on @code{struct} and @code{union} data. ++ ++@item .*@r{, }->* ++Dereferences of pointers to members. ++ ++@item [] ++Array indexing. @code{@var{a}[@var{i}]} is defined as ++@code{*(@var{a}+@var{i})}. Same precedence as @code{->}. ++ ++@item () ++Function parameter list. Same precedence as @code{->}. ++ ++@item :: ++C@t{++} scope resolution operator. Defined on @code{struct}, @code{union}, ++and @code{class} types. ++ ++@item :: ++Doubled colons also represent the @value{GDBN} scope operator ++(@pxref{Expressions, ,Expressions}). Same precedence as @code{::}, ++above. ++@end table ++ ++If an operator is redefined in the user code, @value{GDBN} usually ++attempts to invoke the redefined version instead of using the operator's ++predefined meaning. ++ ++@node C Constants ++@subsubsection C and C@t{++} Constants ++ ++@cindex C and C@t{++} constants ++ ++@value{GDBN} allows you to express the constants of C and C@t{++} in the ++following ways: ++ ++@itemize @bullet ++@item ++Integer constants are a sequence of digits. Octal constants are ++specified by a leading @samp{0} (i.e.@: zero), and hexadecimal constants ++by a leading @samp{0x} or @samp{0X}. Constants may also end with a letter ++@samp{l}, specifying that the constant should be treated as a ++@code{long} value. ++ ++@item ++Floating point constants are a sequence of digits, followed by a decimal ++point, followed by a sequence of digits, and optionally followed by an ++exponent. An exponent is of the form: ++@samp{@w{e@r{[[}+@r{]|}-@r{]}@var{nnn}}}, where @var{nnn} is another ++sequence of digits. The @samp{+} is optional for positive exponents. ++A floating-point constant may also end with a letter @samp{f} or ++@samp{F}, specifying that the constant should be treated as being of ++the @code{float} (as opposed to the default @code{double}) type; or with ++a letter @samp{l} or @samp{L}, which specifies a @code{long double} ++constant. ++ ++@item ++Enumerated constants consist of enumerated identifiers, or their ++integral equivalents. ++ ++@item ++Character constants are a single character surrounded by single quotes ++(@code{'}), or a number---the ordinal value of the corresponding character ++(usually its @sc{ascii} value). Within quotes, the single character may ++be represented by a letter or by @dfn{escape sequences}, which are of ++the form @samp{\@var{nnn}}, where @var{nnn} is the octal representation ++of the character's ordinal value; or of the form @samp{\@var{x}}, where ++@samp{@var{x}} is a predefined special character---for example, ++@samp{\n} for newline. ++ ++Wide character constants can be written by prefixing a character ++constant with @samp{L}, as in C. For example, @samp{L'x'} is the wide ++form of @samp{x}. The target wide character set is used when ++computing the value of this constant (@pxref{Character Sets}). ++ ++@item ++String constants are a sequence of character constants surrounded by ++double quotes (@code{"}). Any valid character constant (as described ++above) may appear. Double quotes within the string must be preceded by ++a backslash, so for instance @samp{"a\"b'c"} is a string of five ++characters. ++ ++Wide string constants can be written by prefixing a string constant ++with @samp{L}, as in C. The target wide character set is used when ++computing the value of this constant (@pxref{Character Sets}). ++ ++@item ++Pointer constants are an integral value. You can also write pointers ++to constants using the C operator @samp{&}. ++ ++@item ++Array constants are comma-separated lists surrounded by braces @samp{@{} ++and @samp{@}}; for example, @samp{@{1,2,3@}} is a three-element array of ++integers, @samp{@{@{1,2@}, @{3,4@}, @{5,6@}@}} is a three-by-two array, ++and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers. ++@end itemize ++ ++@node C Plus Plus Expressions ++@subsubsection C@t{++} Expressions ++ ++@cindex expressions in C@t{++} ++@value{GDBN} expression handling can interpret most C@t{++} expressions. ++ ++@cindex debugging C@t{++} programs ++@cindex C@t{++} compilers ++@cindex debug formats and C@t{++} ++@cindex @value{NGCC} and C@t{++} ++@quotation ++@emph{Warning:} @value{GDBN} can only debug C@t{++} code if you use ++the proper compiler and the proper debug format. Currently, ++@value{GDBN} works best when debugging C@t{++} code that is compiled ++with the most recent version of @value{NGCC} possible. The DWARF ++debugging format is preferred; @value{NGCC} defaults to this on most ++popular platforms. Other compilers and/or debug formats are likely to ++work badly or not at all when using @value{GDBN} to debug C@t{++} ++code. @xref{Compilation}. ++@end quotation ++ ++@enumerate ++ ++@cindex member functions ++@item ++Member function calls are allowed; you can use expressions like ++ ++@smallexample ++count = aml->GetOriginal(x, y) ++@end smallexample ++ ++@vindex this@r{, inside C@t{++} member functions} ++@cindex namespace in C@t{++} ++@item ++While a member function is active (in the selected stack frame), your ++expressions have the same namespace available as the member function; ++that is, @value{GDBN} allows implicit references to the class instance ++pointer @code{this} following the same rules as C@t{++}. @code{using} ++declarations in the current scope are also respected by @value{GDBN}. ++ ++@cindex call overloaded functions ++@cindex overloaded functions, calling ++@cindex type conversions in C@t{++} ++@item ++You can call overloaded functions; @value{GDBN} resolves the function ++call to the right definition, with some restrictions. @value{GDBN} does not ++perform overload resolution involving user-defined type conversions, ++calls to constructors, or instantiations of templates that do not exist ++in the program. It also cannot handle ellipsis argument lists or ++default arguments. ++ ++It does perform integral conversions and promotions, floating-point ++promotions, arithmetic conversions, pointer conversions, conversions of ++class objects to base classes, and standard conversions such as those of ++functions or arrays to pointers; it requires an exact match on the ++number of function arguments. ++ ++Overload resolution is always performed, unless you have specified ++@code{set overload-resolution off}. @xref{Debugging C Plus Plus, ++,@value{GDBN} Features for C@t{++}}. ++ ++You must specify @code{set overload-resolution off} in order to use an ++explicit function signature to call an overloaded function, as in ++@smallexample ++p 'foo(char,int)'('x', 13) ++@end smallexample ++ ++The @value{GDBN} command-completion facility can simplify this; ++see @ref{Completion, ,Command Completion}. ++ ++@cindex reference declarations ++@item ++@value{GDBN} understands variables declared as C@t{++} lvalue or rvalue ++references; you can use them in expressions just as you do in C@t{++} ++source---they are automatically dereferenced. ++ ++In the parameter list shown when @value{GDBN} displays a frame, the values of ++reference variables are not displayed (unlike other variables); this ++avoids clutter, since references are often used for large structures. ++The @emph{address} of a reference variable is always shown, unless ++you have specified @samp{set print address off}. ++ ++@item ++@value{GDBN} supports the C@t{++} name resolution operator @code{::}---your ++expressions can use it just as expressions in your program do. Since ++one scope may be defined in another, you can use @code{::} repeatedly if ++necessary, for example in an expression like ++@samp{@var{scope1}::@var{scope2}::@var{name}}. @value{GDBN} also allows ++resolving name scope by reference to source files, in both C and C@t{++} ++debugging (@pxref{Variables, ,Program Variables}). ++ ++@item ++@value{GDBN} performs argument-dependent lookup, following the C@t{++} ++specification. ++@end enumerate ++ ++@node C Defaults ++@subsubsection C and C@t{++} Defaults ++ ++@cindex C and C@t{++} defaults ++ ++If you allow @value{GDBN} to set range checking automatically, it ++defaults to @code{off} whenever the working language changes to ++C or C@t{++}. This happens regardless of whether you or @value{GDBN} ++selects the working language. ++ ++If you allow @value{GDBN} to set the language automatically, it ++recognizes source files whose names end with @file{.c}, @file{.C}, or ++@file{.cc}, etc, and when @value{GDBN} enters code compiled from one of ++these files, it sets the working language to C or C@t{++}. ++@xref{Automatically, ,Having @value{GDBN} Infer the Source Language}, ++for further details. ++ ++@node C Checks ++@subsubsection C and C@t{++} Type and Range Checks ++ ++@cindex C and C@t{++} checks ++ ++By default, when @value{GDBN} parses C or C@t{++} expressions, strict type ++checking is used. However, if you turn type checking off, @value{GDBN} ++will allow certain non-standard conversions, such as promoting integer ++constants to pointers. ++ ++Range checking, if turned on, is done on mathematical operations. Array ++indices are not checked, since they are often used to index a pointer ++that is not itself an array. ++ ++@node Debugging C ++@subsubsection @value{GDBN} and C ++ ++The @code{set print union} and @code{show print union} commands apply to ++the @code{union} type. When set to @samp{on}, any @code{union} that is ++inside a @code{struct} or @code{class} is also printed. Otherwise, it ++appears as @samp{@{...@}}. ++ ++The @code{@@} operator aids in the debugging of dynamic arrays, formed ++with pointers and a memory allocation function. @xref{Expressions, ++,Expressions}. ++ ++@node Debugging C Plus Plus ++@subsubsection @value{GDBN} Features for C@t{++} ++ ++@cindex commands for C@t{++} ++ ++Some @value{GDBN} commands are particularly useful with C@t{++}, and some are ++designed specifically for use with C@t{++}. Here is a summary: ++ ++@table @code ++@cindex break in overloaded functions ++@item @r{breakpoint menus} ++When you want a breakpoint in a function whose name is overloaded, ++@value{GDBN} has the capability to display a menu of possible breakpoint ++locations to help you specify which function definition you want. ++@xref{Ambiguous Expressions,,Ambiguous Expressions}. ++ ++@cindex overloading in C@t{++} ++@item rbreak @var{regex} ++Setting breakpoints using regular expressions is helpful for setting ++breakpoints on overloaded functions that are not members of any special ++classes. ++@xref{Set Breaks, ,Setting Breakpoints}. ++ ++@cindex C@t{++} exception handling ++@item catch throw ++@itemx catch rethrow ++@itemx catch catch ++Debug C@t{++} exception handling using these commands. @xref{Set ++Catchpoints, , Setting Catchpoints}. ++ ++@cindex inheritance ++@item ptype @var{typename} ++Print inheritance relationships as well as other information for type ++@var{typename}. ++@xref{Symbols, ,Examining the Symbol Table}. ++ ++@item info vtbl @var{expression}. ++The @code{info vtbl} command can be used to display the virtual ++method tables of the object computed by @var{expression}. This shows ++one entry per virtual table; there may be multiple virtual tables when ++multiple inheritance is in use. ++ ++@cindex C@t{++} demangling ++@item demangle @var{name} ++Demangle @var{name}. ++@xref{Symbols}, for a more complete description of the @code{demangle} command. ++ ++@cindex C@t{++} symbol display ++@item set print demangle ++@itemx show print demangle ++@itemx set print asm-demangle ++@itemx show print asm-demangle ++Control whether C@t{++} symbols display in their source form, both when ++displaying code as C@t{++} source and when displaying disassemblies. ++@xref{Print Settings, ,Print Settings}. ++ ++@item set print object ++@itemx show print object ++Choose whether to print derived (actual) or declared types of objects. ++@xref{Print Settings, ,Print Settings}. ++ ++@item set print vtbl ++@itemx show print vtbl ++Control the format for printing virtual function tables. ++@xref{Print Settings, ,Print Settings}. ++(The @code{vtbl} commands do not work on programs compiled with the HP ++ANSI C@t{++} compiler (@code{aCC}).) ++ ++@kindex set overload-resolution ++@cindex overloaded functions, overload resolution ++@item set overload-resolution on ++Enable overload resolution for C@t{++} expression evaluation. The default ++is on. For overloaded functions, @value{GDBN} evaluates the arguments ++and searches for a function whose signature matches the argument types, ++using the standard C@t{++} conversion rules (see @ref{C Plus Plus ++Expressions, ,C@t{++} Expressions}, for details). ++If it cannot find a match, it emits a message. ++ ++@item set overload-resolution off ++Disable overload resolution for C@t{++} expression evaluation. For ++overloaded functions that are not class member functions, @value{GDBN} ++chooses the first function of the specified name that it finds in the ++symbol table, whether or not its arguments are of the correct type. For ++overloaded functions that are class member functions, @value{GDBN} ++searches for a function whose signature @emph{exactly} matches the ++argument types. ++ ++@kindex show overload-resolution ++@item show overload-resolution ++Show the current setting of overload resolution. ++ ++@item @r{Overloaded symbol names} ++You can specify a particular definition of an overloaded symbol, using ++the same notation that is used to declare such symbols in C@t{++}: type ++@code{@var{symbol}(@var{types})} rather than just @var{symbol}. You can ++also use the @value{GDBN} command-line word completion facilities to list the ++available choices, or to finish the type list for you. ++@xref{Completion,, Command Completion}, for details on how to do this. ++ ++@item @r{Breakpoints in functions with ABI tags} ++ ++The GNU C@t{++} compiler introduced the notion of ABI ``tags'', which ++correspond to changes in the ABI of a type, function, or variable that ++would not otherwise be reflected in a mangled name. See ++@url{https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/} ++for more detail. ++ ++The ABI tags are visible in C@t{++} demangled names. For example, a ++function that returns a std::string: ++ ++@smallexample ++std::string function(int); ++@end smallexample ++ ++@noindent ++when compiled for the C++11 ABI is marked with the @code{cxx11} ABI ++tag, and @value{GDBN} displays the symbol like this: ++ ++@smallexample ++function[abi:cxx11](int) ++@end smallexample ++ ++You can set a breakpoint on such functions simply as if they had no ++tag. For example: ++ ++@smallexample ++(gdb) b function(int) ++Breakpoint 2 at 0x40060d: file main.cc, line 10. ++(gdb) info breakpoints ++Num Type Disp Enb Address What ++1 breakpoint keep y 0x0040060d in function[abi:cxx11](int) ++ at main.cc:10 ++@end smallexample ++ ++On the rare occasion you need to disambiguate between different ABI ++tags, you can do so by simply including the ABI tag in the function ++name, like: ++ ++@smallexample ++(@value{GDBP}) b ambiguous[abi:other_tag](int) ++@end smallexample ++@end table ++ ++@node Decimal Floating Point ++@subsubsection Decimal Floating Point format ++@cindex decimal floating point format ++ ++@value{GDBN} can examine, set and perform computations with numbers in ++decimal floating point format, which in the C language correspond to the ++@code{_Decimal32}, @code{_Decimal64} and @code{_Decimal128} types as ++specified by the extension to support decimal floating-point arithmetic. ++ ++There are two encodings in use, depending on the architecture: BID (Binary ++Integer Decimal) for x86 and x86-64, and DPD (Densely Packed Decimal) for ++PowerPC and S/390. @value{GDBN} will use the appropriate encoding for the ++configured target. ++ ++Because of a limitation in @file{libdecnumber}, the library used by @value{GDBN} ++to manipulate decimal floating point numbers, it is not possible to convert ++(using a cast, for example) integers wider than 32-bit to decimal float. ++ ++In addition, in order to imitate @value{GDBN}'s behaviour with binary floating ++point computations, error checking in decimal float operations ignores ++underflow, overflow and divide by zero exceptions. ++ ++In the PowerPC architecture, @value{GDBN} provides a set of pseudo-registers ++to inspect @code{_Decimal128} values stored in floating point registers. ++See @ref{PowerPC,,PowerPC} for more details. ++ ++@node D ++@subsection D ++ ++@cindex D ++@value{GDBN} can be used to debug programs written in D and compiled with ++GDC, LDC or DMD compilers. Currently @value{GDBN} supports only one D ++specific feature --- dynamic arrays. ++ ++@node Go ++@subsection Go ++ ++@cindex Go (programming language) ++@value{GDBN} can be used to debug programs written in Go and compiled with ++@file{gccgo} or @file{6g} compilers. ++ ++Here is a summary of the Go-specific features and restrictions: ++ ++@table @code ++@cindex current Go package ++@item The current Go package ++The name of the current package does not need to be specified when ++specifying global variables and functions. ++ ++For example, given the program: ++ ++@example ++package main ++var myglob = "Shall we?" ++func main () @{ ++ // ... ++@} ++@end example ++ ++When stopped inside @code{main} either of these work: ++ ++@example ++(gdb) p myglob ++(gdb) p main.myglob ++@end example ++ ++@cindex builtin Go types ++@item Builtin Go types ++The @code{string} type is recognized by @value{GDBN} and is printed ++as a string. ++ ++@cindex builtin Go functions ++@item Builtin Go functions ++The @value{GDBN} expression parser recognizes the @code{unsafe.Sizeof} ++function and handles it internally. ++ ++@cindex restrictions on Go expressions ++@item Restrictions on Go expressions ++All Go operators are supported except @code{&^}. ++The Go @code{_} ``blank identifier'' is not supported. ++Automatic dereferencing of pointers is not supported. ++@end table ++ ++@node Objective-C ++@subsection Objective-C ++ ++@cindex Objective-C ++This section provides information about some commands and command ++options that are useful for debugging Objective-C code. See also ++@ref{Symbols, info classes}, and @ref{Symbols, info selectors}, for a ++few more commands specific to Objective-C support. ++ ++@menu ++* Method Names in Commands:: ++* The Print Command with Objective-C:: ++@end menu ++ ++@node Method Names in Commands ++@subsubsection Method Names in Commands ++ ++The following commands have been extended to accept Objective-C method ++names as line specifications: ++ ++@kindex clear@r{, and Objective-C} ++@kindex break@r{, and Objective-C} ++@kindex info line@r{, and Objective-C} ++@kindex jump@r{, and Objective-C} ++@kindex list@r{, and Objective-C} ++@itemize ++@item @code{clear} ++@item @code{break} ++@item @code{info line} ++@item @code{jump} ++@item @code{list} ++@end itemize ++ ++A fully qualified Objective-C method name is specified as ++ ++@smallexample ++-[@var{Class} @var{methodName}] ++@end smallexample ++ ++where the minus sign is used to indicate an instance method and a ++plus sign (not shown) is used to indicate a class method. The class ++name @var{Class} and method name @var{methodName} are enclosed in ++brackets, similar to the way messages are specified in Objective-C ++source code. For example, to set a breakpoint at the @code{create} ++instance method of class @code{Fruit} in the program currently being ++debugged, enter: ++ ++@smallexample ++break -[Fruit create] ++@end smallexample ++ ++To list ten program lines around the @code{initialize} class method, ++enter: ++ ++@smallexample ++list +[NSText initialize] ++@end smallexample ++ ++In the current version of @value{GDBN}, the plus or minus sign is ++required. In future versions of @value{GDBN}, the plus or minus ++sign will be optional, but you can use it to narrow the search. It ++is also possible to specify just a method name: ++ ++@smallexample ++break create ++@end smallexample ++ ++You must specify the complete method name, including any colons. If ++your program's source files contain more than one @code{create} method, ++you'll be presented with a numbered list of classes that implement that ++method. Indicate your choice by number, or type @samp{0} to exit if ++none apply. ++ ++As another example, to clear a breakpoint established at the ++@code{makeKeyAndOrderFront:} method of the @code{NSWindow} class, enter: ++ ++@smallexample ++clear -[NSWindow makeKeyAndOrderFront:] ++@end smallexample ++ ++@node The Print Command with Objective-C ++@subsubsection The Print Command With Objective-C ++@cindex Objective-C, print objects ++@kindex print-object ++@kindex po @r{(@code{print-object})} ++ ++The print command has also been extended to accept methods. For example: ++ ++@smallexample ++print -[@var{object} hash] ++@end smallexample ++ ++@cindex print an Objective-C object description ++@cindex @code{_NSPrintForDebugger}, and printing Objective-C objects ++@noindent ++will tell @value{GDBN} to send the @code{hash} message to @var{object} ++and print the result. Also, an additional command has been added, ++@code{print-object} or @code{po} for short, which is meant to print ++the description of an object. However, this command may only work ++with certain Objective-C libraries that have a particular hook ++function, @code{_NSPrintForDebugger}, defined. ++ ++@node OpenCL C ++@subsection OpenCL C ++ ++@cindex OpenCL C ++This section provides information about @value{GDBN}s OpenCL C support. ++ ++@menu ++* OpenCL C Datatypes:: ++* OpenCL C Expressions:: ++* OpenCL C Operators:: ++@end menu ++ ++@node OpenCL C Datatypes ++@subsubsection OpenCL C Datatypes ++ ++@cindex OpenCL C Datatypes ++@value{GDBN} supports the builtin scalar and vector datatypes specified ++by OpenCL 1.1. In addition the half- and double-precision floating point ++data types of the @code{cl_khr_fp16} and @code{cl_khr_fp64} OpenCL ++extensions are also known to @value{GDBN}. ++ ++@node OpenCL C Expressions ++@subsubsection OpenCL C Expressions ++ ++@cindex OpenCL C Expressions ++@value{GDBN} supports accesses to vector components including the access as ++lvalue where possible. Since OpenCL C is based on C99 most C expressions ++supported by @value{GDBN} can be used as well. ++ ++@node OpenCL C Operators ++@subsubsection OpenCL C Operators ++ ++@cindex OpenCL C Operators ++@value{GDBN} supports the operators specified by OpenCL 1.1 for scalar and ++vector data types. ++ ++@node Fortran ++@subsection Fortran ++@cindex Fortran-specific support in @value{GDBN} ++ ++@value{GDBN} can be used to debug programs written in Fortran, but it ++currently supports only the features of Fortran 77 language. ++ ++@cindex trailing underscore, in Fortran symbols ++Some Fortran compilers (@sc{gnu} Fortran 77 and Fortran 95 compilers ++among them) append an underscore to the names of variables and ++functions. When you debug programs compiled by those compilers, you ++will need to refer to variables and functions with a trailing ++underscore. ++ ++@menu ++* Fortran Operators:: Fortran operators and expressions ++* Fortran Defaults:: Default settings for Fortran ++* Special Fortran Commands:: Special @value{GDBN} commands for Fortran ++@end menu ++ ++@node Fortran Operators ++@subsubsection Fortran Operators and Expressions ++ ++@cindex Fortran operators and expressions ++ ++Operators must be defined on values of specific types. For instance, ++@code{+} is defined on numbers, but not on characters or other non- ++arithmetic types. Operators are often defined on groups of types. ++ ++@table @code ++@item ** ++The exponentiation operator. It raises the first operand to the power ++of the second one. ++ ++@item : ++The range operator. Normally used in the form of array(low:high) to ++represent a section of array. ++ ++@item % ++The access component operator. Normally used to access elements in derived ++types. Also suitable for unions. As unions aren't part of regular Fortran, ++this can only happen when accessing a register that uses a gdbarch-defined ++union type. ++@item :: ++The scope operator. Normally used to access variables in modules or ++to set breakpoints on subroutines nested in modules or in other ++subroutines (internal subroutines). ++@end table ++ ++@node Fortran Defaults ++@subsubsection Fortran Defaults ++ ++@cindex Fortran Defaults ++ ++Fortran symbols are usually case-insensitive, so @value{GDBN} by ++default uses case-insensitive matches for Fortran symbols. You can ++change that with the @samp{set case-insensitive} command, see ++@ref{Symbols}, for the details. ++ ++@node Special Fortran Commands ++@subsubsection Special Fortran Commands ++ ++@cindex Special Fortran commands ++ ++@value{GDBN} has some commands to support Fortran-specific features, ++such as displaying common blocks. ++ ++@table @code ++@cindex @code{COMMON} blocks, Fortran ++@kindex info common ++@item info common @r{[}@var{common-name}@r{]} ++This command prints the values contained in the Fortran @code{COMMON} ++block whose name is @var{common-name}. With no argument, the names of ++all @code{COMMON} blocks visible at the current program location are ++printed. ++@end table ++ ++@node Pascal ++@subsection Pascal ++ ++@cindex Pascal support in @value{GDBN}, limitations ++Debugging Pascal programs which use sets, subranges, file variables, or ++nested functions does not currently work. @value{GDBN} does not support ++entering expressions, printing values, or similar features using Pascal ++syntax. ++ ++The Pascal-specific command @code{set print pascal_static-members} ++controls whether static members of Pascal objects are displayed. ++@xref{Print Settings, pascal_static-members}. ++ ++@node Rust ++@subsection Rust ++ ++@value{GDBN} supports the @url{https://www.rust-lang.org/, Rust ++Programming Language}. Type- and value-printing, and expression ++parsing, are reasonably complete. However, there are a few ++peculiarities and holes to be aware of. ++ ++@itemize @bullet ++@item ++Linespecs (@pxref{Specify Location}) are never relative to the current ++crate. Instead, they act as if there were a global namespace of ++crates, somewhat similar to the way @code{extern crate} behaves. ++ ++That is, if @value{GDBN} is stopped at a breakpoint in a function in ++crate @samp{A}, module @samp{B}, then @code{break B::f} will attempt ++to set a breakpoint in a function named @samp{f} in a crate named ++@samp{B}. ++ ++As a consequence of this approach, linespecs also cannot refer to ++items using @samp{self::} or @samp{super::}. ++ ++@item ++Because @value{GDBN} implements Rust name-lookup semantics in ++expressions, it will sometimes prepend the current crate to a name. ++For example, if @value{GDBN} is stopped at a breakpoint in the crate ++@samp{K}, then @code{print ::x::y} will try to find the symbol ++@samp{K::x::y}. ++ ++However, since it is useful to be able to refer to other crates when ++debugging, @value{GDBN} provides the @code{extern} extension to ++circumvent this. To use the extension, just put @code{extern} before ++a path expression to refer to the otherwise unavailable ``global'' ++scope. ++ ++In the above example, if you wanted to refer to the symbol @samp{y} in ++the crate @samp{x}, you would use @code{print extern x::y}. ++ ++@item ++The Rust expression evaluator does not support ``statement-like'' ++expressions such as @code{if} or @code{match}, or lambda expressions. ++ ++@item ++Tuple expressions are not implemented. ++ ++@item ++The Rust expression evaluator does not currently implement the ++@code{Drop} trait. Objects that may be created by the evaluator will ++never be destroyed. ++ ++@item ++@value{GDBN} does not implement type inference for generics. In order ++to call generic functions or otherwise refer to generic items, you ++will have to specify the type parameters manually. ++ ++@item ++@value{GDBN} currently uses the C@t{++} demangler for Rust. In most ++cases this does not cause any problems. However, in an expression ++context, completing a generic function name will give syntactically ++invalid results. This happens because Rust requires the @samp{::} ++operator between the function name and its generic arguments. For ++example, @value{GDBN} might provide a completion like ++@code{crate::f}, where the parser would require ++@code{crate::f::}. ++ ++@item ++As of this writing, the Rust compiler (version 1.8) has a few holes in ++the debugging information it generates. These holes prevent certain ++features from being implemented by @value{GDBN}: ++@itemize @bullet ++ ++@item ++Method calls cannot be made via traits. ++ ++@item ++Operator overloading is not implemented. ++ ++@item ++When debugging in a monomorphized function, you cannot use the generic ++type names. ++ ++@item ++The type @code{Self} is not available. ++ ++@item ++@code{use} statements are not available, so some names may not be ++available in the crate. ++@end itemize ++@end itemize ++ ++@node Modula-2 ++@subsection Modula-2 ++ ++@cindex Modula-2, @value{GDBN} support ++ ++The extensions made to @value{GDBN} to support Modula-2 only support ++output from the @sc{gnu} Modula-2 compiler (which is currently being ++developed). Other Modula-2 compilers are not currently supported, and ++attempting to debug executables produced by them is most likely ++to give an error as @value{GDBN} reads in the executable's symbol ++table. ++ ++@cindex expressions in Modula-2 ++@menu ++* M2 Operators:: Built-in operators ++* Built-In Func/Proc:: Built-in functions and procedures ++* M2 Constants:: Modula-2 constants ++* M2 Types:: Modula-2 types ++* M2 Defaults:: Default settings for Modula-2 ++* Deviations:: Deviations from standard Modula-2 ++* M2 Checks:: Modula-2 type and range checks ++* M2 Scope:: The scope operators @code{::} and @code{.} ++* GDB/M2:: @value{GDBN} and Modula-2 ++@end menu ++ ++@node M2 Operators ++@subsubsection Operators ++@cindex Modula-2 operators ++ ++Operators must be defined on values of specific types. For instance, ++@code{+} is defined on numbers, but not on structures. Operators are ++often defined on groups of types. For the purposes of Modula-2, the ++following definitions hold: ++ ++@itemize @bullet ++ ++@item ++@emph{Integral types} consist of @code{INTEGER}, @code{CARDINAL}, and ++their subranges. ++ ++@item ++@emph{Character types} consist of @code{CHAR} and its subranges. ++ ++@item ++@emph{Floating-point types} consist of @code{REAL}. ++ ++@item ++@emph{Pointer types} consist of anything declared as @code{POINTER TO ++@var{type}}. ++ ++@item ++@emph{Scalar types} consist of all of the above. ++ ++@item ++@emph{Set types} consist of @code{SET} and @code{BITSET} types. ++ ++@item ++@emph{Boolean types} consist of @code{BOOLEAN}. ++@end itemize ++ ++@noindent ++The following operators are supported, and appear in order of ++increasing precedence: ++ ++@table @code ++@item , ++Function argument or array index separator. ++ ++@item := ++Assignment. The value of @var{var} @code{:=} @var{value} is ++@var{value}. ++ ++@item <@r{, }> ++Less than, greater than on integral, floating-point, or enumerated ++types. ++ ++@item <=@r{, }>= ++Less than or equal to, greater than or equal to ++on integral, floating-point and enumerated types, or set inclusion on ++set types. Same precedence as @code{<}. ++ ++@item =@r{, }<>@r{, }# ++Equality and two ways of expressing inequality, valid on scalar types. ++Same precedence as @code{<}. In @value{GDBN} scripts, only @code{<>} is ++available for inequality, since @code{#} conflicts with the script ++comment character. ++ ++@item IN ++Set membership. Defined on set types and the types of their members. ++Same precedence as @code{<}. ++ ++@item OR ++Boolean disjunction. Defined on boolean types. ++ ++@item AND@r{, }& ++Boolean conjunction. Defined on boolean types. ++ ++@item @@ ++The @value{GDBN} ``artificial array'' operator (@pxref{Expressions, ,Expressions}). ++ ++@item +@r{, }- ++Addition and subtraction on integral and floating-point types, or union ++and difference on set types. ++ ++@item * ++Multiplication on integral and floating-point types, or set intersection ++on set types. ++ ++@item / ++Division on floating-point types, or symmetric set difference on set ++types. Same precedence as @code{*}. ++ ++@item DIV@r{, }MOD ++Integer division and remainder. Defined on integral types. Same ++precedence as @code{*}. ++ ++@item - ++Negative. Defined on @code{INTEGER} and @code{REAL} data. ++ ++@item ^ ++Pointer dereferencing. Defined on pointer types. ++ ++@item NOT ++Boolean negation. Defined on boolean types. Same precedence as ++@code{^}. ++ ++@item . ++@code{RECORD} field selector. Defined on @code{RECORD} data. Same ++precedence as @code{^}. ++ ++@item [] ++Array indexing. Defined on @code{ARRAY} data. Same precedence as @code{^}. ++ ++@item () ++Procedure argument list. Defined on @code{PROCEDURE} objects. Same precedence ++as @code{^}. ++ ++@item ::@r{, }. ++@value{GDBN} and Modula-2 scope operators. ++@end table ++ ++@quotation ++@emph{Warning:} Set expressions and their operations are not yet supported, so @value{GDBN} ++treats the use of the operator @code{IN}, or the use of operators ++@code{+}, @code{-}, @code{*}, @code{/}, @code{=}, , @code{<>}, @code{#}, ++@code{<=}, and @code{>=} on sets as an error. ++@end quotation ++ ++ ++@node Built-In Func/Proc ++@subsubsection Built-in Functions and Procedures ++@cindex Modula-2 built-ins ++ ++Modula-2 also makes available several built-in procedures and functions. ++In describing these, the following metavariables are used: ++ ++@table @var ++ ++@item a ++represents an @code{ARRAY} variable. ++ ++@item c ++represents a @code{CHAR} constant or variable. ++ ++@item i ++represents a variable or constant of integral type. ++ ++@item m ++represents an identifier that belongs to a set. Generally used in the ++same function with the metavariable @var{s}. The type of @var{s} should ++be @code{SET OF @var{mtype}} (where @var{mtype} is the type of @var{m}). ++ ++@item n ++represents a variable or constant of integral or floating-point type. ++ ++@item r ++represents a variable or constant of floating-point type. ++ ++@item t ++represents a type. ++ ++@item v ++represents a variable. ++ ++@item x ++represents a variable or constant of one of many types. See the ++explanation of the function for details. ++@end table ++ ++All Modula-2 built-in procedures also return a result, described below. ++ ++@table @code ++@item ABS(@var{n}) ++Returns the absolute value of @var{n}. ++ ++@item CAP(@var{c}) ++If @var{c} is a lower case letter, it returns its upper case ++equivalent, otherwise it returns its argument. ++ ++@item CHR(@var{i}) ++Returns the character whose ordinal value is @var{i}. ++ ++@item DEC(@var{v}) ++Decrements the value in the variable @var{v} by one. Returns the new value. ++ ++@item DEC(@var{v},@var{i}) ++Decrements the value in the variable @var{v} by @var{i}. Returns the ++new value. ++ ++@item EXCL(@var{m},@var{s}) ++Removes the element @var{m} from the set @var{s}. Returns the new ++set. ++ ++@item FLOAT(@var{i}) ++Returns the floating point equivalent of the integer @var{i}. ++ ++@item HIGH(@var{a}) ++Returns the index of the last member of @var{a}. ++ ++@item INC(@var{v}) ++Increments the value in the variable @var{v} by one. Returns the new value. ++ ++@item INC(@var{v},@var{i}) ++Increments the value in the variable @var{v} by @var{i}. Returns the ++new value. ++ ++@item INCL(@var{m},@var{s}) ++Adds the element @var{m} to the set @var{s} if it is not already ++there. Returns the new set. ++ ++@item MAX(@var{t}) ++Returns the maximum value of the type @var{t}. ++ ++@item MIN(@var{t}) ++Returns the minimum value of the type @var{t}. ++ ++@item ODD(@var{i}) ++Returns boolean TRUE if @var{i} is an odd number. ++ ++@item ORD(@var{x}) ++Returns the ordinal value of its argument. For example, the ordinal ++value of a character is its @sc{ascii} value (on machines supporting ++the @sc{ascii} character set). The argument @var{x} must be of an ++ordered type, which include integral, character and enumerated types. ++ ++@item SIZE(@var{x}) ++Returns the size of its argument. The argument @var{x} can be a ++variable or a type. ++ ++@item TRUNC(@var{r}) ++Returns the integral part of @var{r}. ++ ++@item TSIZE(@var{x}) ++Returns the size of its argument. The argument @var{x} can be a ++variable or a type. ++ ++@item VAL(@var{t},@var{i}) ++Returns the member of the type @var{t} whose ordinal value is @var{i}. ++@end table ++ ++@quotation ++@emph{Warning:} Sets and their operations are not yet supported, so ++@value{GDBN} treats the use of procedures @code{INCL} and @code{EXCL} as ++an error. ++@end quotation ++ ++@cindex Modula-2 constants ++@node M2 Constants ++@subsubsection Constants ++ ++@value{GDBN} allows you to express the constants of Modula-2 in the following ++ways: ++ ++@itemize @bullet ++ ++@item ++Integer constants are simply a sequence of digits. When used in an ++expression, a constant is interpreted to be type-compatible with the ++rest of the expression. Hexadecimal integers are specified by a ++trailing @samp{H}, and octal integers by a trailing @samp{B}. ++ ++@item ++Floating point constants appear as a sequence of digits, followed by a ++decimal point and another sequence of digits. An optional exponent can ++then be specified, in the form @samp{E@r{[}+@r{|}-@r{]}@var{nnn}}, where ++@samp{@r{[}+@r{|}-@r{]}@var{nnn}} is the desired exponent. All of the ++digits of the floating point constant must be valid decimal (base 10) ++digits. ++ ++@item ++Character constants consist of a single character enclosed by a pair of ++like quotes, either single (@code{'}) or double (@code{"}). They may ++also be expressed by their ordinal value (their @sc{ascii} value, usually) ++followed by a @samp{C}. ++ ++@item ++String constants consist of a sequence of characters enclosed by a ++pair of like quotes, either single (@code{'}) or double (@code{"}). ++Escape sequences in the style of C are also allowed. @xref{C ++Constants, ,C and C@t{++} Constants}, for a brief explanation of escape ++sequences. ++ ++@item ++Enumerated constants consist of an enumerated identifier. ++ ++@item ++Boolean constants consist of the identifiers @code{TRUE} and ++@code{FALSE}. ++ ++@item ++Pointer constants consist of integral values only. ++ ++@item ++Set constants are not yet supported. ++@end itemize ++ ++@node M2 Types ++@subsubsection Modula-2 Types ++@cindex Modula-2 types ++ ++Currently @value{GDBN} can print the following data types in Modula-2 ++syntax: array types, record types, set types, pointer types, procedure ++types, enumerated types, subrange types and base types. You can also ++print the contents of variables declared using these type. ++This section gives a number of simple source code examples together with ++sample @value{GDBN} sessions. ++ ++The first example contains the following section of code: ++ ++@smallexample ++VAR ++ s: SET OF CHAR ; ++ r: [20..40] ; ++@end smallexample ++ ++@noindent ++and you can request @value{GDBN} to interrogate the type and value of ++@code{r} and @code{s}. ++ ++@smallexample ++(@value{GDBP}) print s ++@{'A'..'C', 'Z'@} ++(@value{GDBP}) ptype s ++SET OF CHAR ++(@value{GDBP}) print r ++21 ++(@value{GDBP}) ptype r ++[20..40] ++@end smallexample ++ ++@noindent ++Likewise if your source code declares @code{s} as: ++ ++@smallexample ++VAR ++ s: SET ['A'..'Z'] ; ++@end smallexample ++ ++@noindent ++then you may query the type of @code{s} by: ++ ++@smallexample ++(@value{GDBP}) ptype s ++type = SET ['A'..'Z'] ++@end smallexample ++ ++@noindent ++Note that at present you cannot interactively manipulate set ++expressions using the debugger. ++ ++The following example shows how you might declare an array in Modula-2 ++and how you can interact with @value{GDBN} to print its type and contents: ++ ++@smallexample ++VAR ++ s: ARRAY [-10..10] OF CHAR ; ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) ptype s ++ARRAY [-10..10] OF CHAR ++@end smallexample ++ ++Note that the array handling is not yet complete and although the type ++is printed correctly, expression handling still assumes that all ++arrays have a lower bound of zero and not @code{-10} as in the example ++above. ++ ++Here are some more type related Modula-2 examples: ++ ++@smallexample ++TYPE ++ colour = (blue, red, yellow, green) ; ++ t = [blue..yellow] ; ++VAR ++ s: t ; ++BEGIN ++ s := blue ; ++@end smallexample ++ ++@noindent ++The @value{GDBN} interaction shows how you can query the data type ++and value of a variable. ++ ++@smallexample ++(@value{GDBP}) print s ++$1 = blue ++(@value{GDBP}) ptype t ++type = [blue..yellow] ++@end smallexample ++ ++@noindent ++In this example a Modula-2 array is declared and its contents ++displayed. Observe that the contents are written in the same way as ++their @code{C} counterparts. ++ ++@smallexample ++VAR ++ s: ARRAY [1..5] OF CARDINAL ; ++BEGIN ++ s[1] := 1 ; ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) print s ++$1 = @{1, 0, 0, 0, 0@} ++(@value{GDBP}) ptype s ++type = ARRAY [1..5] OF CARDINAL ++@end smallexample ++ ++The Modula-2 language interface to @value{GDBN} also understands ++pointer types as shown in this example: ++ ++@smallexample ++VAR ++ s: POINTER TO ARRAY [1..5] OF CARDINAL ; ++BEGIN ++ NEW(s) ; ++ s^[1] := 1 ; ++@end smallexample ++ ++@noindent ++and you can request that @value{GDBN} describes the type of @code{s}. ++ ++@smallexample ++(@value{GDBP}) ptype s ++type = POINTER TO ARRAY [1..5] OF CARDINAL ++@end smallexample ++ ++@value{GDBN} handles compound types as we can see in this example. ++Here we combine array types, record types, pointer types and subrange ++types: ++ ++@smallexample ++TYPE ++ foo = RECORD ++ f1: CARDINAL ; ++ f2: CHAR ; ++ f3: myarray ; ++ END ; ++ ++ myarray = ARRAY myrange OF CARDINAL ; ++ myrange = [-2..2] ; ++VAR ++ s: POINTER TO ARRAY myrange OF foo ; ++@end smallexample ++ ++@noindent ++and you can ask @value{GDBN} to describe the type of @code{s} as shown ++below. ++ ++@smallexample ++(@value{GDBP}) ptype s ++type = POINTER TO ARRAY [-2..2] OF foo = RECORD ++ f1 : CARDINAL; ++ f2 : CHAR; ++ f3 : ARRAY [-2..2] OF CARDINAL; ++END ++@end smallexample ++ ++@node M2 Defaults ++@subsubsection Modula-2 Defaults ++@cindex Modula-2 defaults ++ ++If type and range checking are set automatically by @value{GDBN}, they ++both default to @code{on} whenever the working language changes to ++Modula-2. This happens regardless of whether you or @value{GDBN} ++selected the working language. ++ ++If you allow @value{GDBN} to set the language automatically, then entering ++code compiled from a file whose name ends with @file{.mod} sets the ++working language to Modula-2. @xref{Automatically, ,Having @value{GDBN} ++Infer the Source Language}, for further details. ++ ++@node Deviations ++@subsubsection Deviations from Standard Modula-2 ++@cindex Modula-2, deviations from ++ ++A few changes have been made to make Modula-2 programs easier to debug. ++This is done primarily via loosening its type strictness: ++ ++@itemize @bullet ++@item ++Unlike in standard Modula-2, pointer constants can be formed by ++integers. This allows you to modify pointer variables during ++debugging. (In standard Modula-2, the actual address contained in a ++pointer variable is hidden from you; it can only be modified ++through direct assignment to another pointer variable or expression that ++returned a pointer.) ++ ++@item ++C escape sequences can be used in strings and characters to represent ++non-printable characters. @value{GDBN} prints out strings with these ++escape sequences embedded. Single non-printable characters are ++printed using the @samp{CHR(@var{nnn})} format. ++ ++@item ++The assignment operator (@code{:=}) returns the value of its right-hand ++argument. ++ ++@item ++All built-in procedures both modify @emph{and} return their argument. ++@end itemize ++ ++@node M2 Checks ++@subsubsection Modula-2 Type and Range Checks ++@cindex Modula-2 checks ++ ++@quotation ++@emph{Warning:} in this release, @value{GDBN} does not yet perform type or ++range checking. ++@end quotation ++@c FIXME remove warning when type/range checks added ++ ++@value{GDBN} considers two Modula-2 variables type equivalent if: ++ ++@itemize @bullet ++@item ++They are of types that have been declared equivalent via a @code{TYPE ++@var{t1} = @var{t2}} statement ++ ++@item ++They have been declared on the same line. (Note: This is true of the ++@sc{gnu} Modula-2 compiler, but it may not be true of other compilers.) ++@end itemize ++ ++As long as type checking is enabled, any attempt to combine variables ++whose types are not equivalent is an error. ++ ++Range checking is done on all mathematical operations, assignment, array ++index bounds, and all built-in functions and procedures. ++ ++@node M2 Scope ++@subsubsection The Scope Operators @code{::} and @code{.} ++@cindex scope ++@cindex @code{.}, Modula-2 scope operator ++@cindex colon, doubled as scope operator ++@ifinfo ++@vindex colon-colon@r{, in Modula-2} ++@c Info cannot handle :: but TeX can. ++@end ifinfo ++@ifnotinfo ++@vindex ::@r{, in Modula-2} ++@end ifnotinfo ++ ++There are a few subtle differences between the Modula-2 scope operator ++(@code{.}) and the @value{GDBN} scope operator (@code{::}). The two have ++similar syntax: ++ ++@smallexample ++ ++@var{module} . @var{id} ++@var{scope} :: @var{id} ++@end smallexample ++ ++@noindent ++where @var{scope} is the name of a module or a procedure, ++@var{module} the name of a module, and @var{id} is any declared ++identifier within your program, except another module. ++ ++Using the @code{::} operator makes @value{GDBN} search the scope ++specified by @var{scope} for the identifier @var{id}. If it is not ++found in the specified scope, then @value{GDBN} searches all scopes ++enclosing the one specified by @var{scope}. ++ ++Using the @code{.} operator makes @value{GDBN} search the current scope for ++the identifier specified by @var{id} that was imported from the ++definition module specified by @var{module}. With this operator, it is ++an error if the identifier @var{id} was not imported from definition ++module @var{module}, or if @var{id} is not an identifier in ++@var{module}. ++ ++@node GDB/M2 ++@subsubsection @value{GDBN} and Modula-2 ++ ++Some @value{GDBN} commands have little use when debugging Modula-2 programs. ++Five subcommands of @code{set print} and @code{show print} apply ++specifically to C and C@t{++}: @samp{vtbl}, @samp{demangle}, ++@samp{asm-demangle}, @samp{object}, and @samp{union}. The first four ++apply to C@t{++}, and the last to the C @code{union} type, which has no direct ++analogue in Modula-2. ++ ++The @code{@@} operator (@pxref{Expressions, ,Expressions}), while available ++with any language, is not useful with Modula-2. Its ++intent is to aid the debugging of @dfn{dynamic arrays}, which cannot be ++created in Modula-2 as they can in C or C@t{++}. However, because an ++address can be specified by an integral constant, the construct ++@samp{@{@var{type}@}@var{adrexp}} is still useful. ++ ++@cindex @code{#} in Modula-2 ++In @value{GDBN} scripts, the Modula-2 inequality operator @code{#} is ++interpreted as the beginning of a comment. Use @code{<>} instead. ++ ++@node Ada ++@subsection Ada ++@cindex Ada ++ ++The extensions made to @value{GDBN} for Ada only support ++output from the @sc{gnu} Ada (GNAT) compiler. ++Other Ada compilers are not currently supported, and ++attempting to debug executables produced by them is most likely ++to be difficult. ++ ++ ++@cindex expressions in Ada ++@menu ++* Ada Mode Intro:: General remarks on the Ada syntax ++ and semantics supported by Ada mode ++ in @value{GDBN}. ++* Omissions from Ada:: Restrictions on the Ada expression syntax. ++* Additions to Ada:: Extensions of the Ada expression syntax. ++* Overloading support for Ada:: Support for expressions involving overloaded ++ subprograms. ++* Stopping Before Main Program:: Debugging the program during elaboration. ++* Ada Exceptions:: Ada Exceptions ++* Ada Tasks:: Listing and setting breakpoints in tasks. ++* Ada Tasks and Core Files:: Tasking Support when Debugging Core Files ++* Ravenscar Profile:: Tasking Support when using the Ravenscar ++ Profile ++* Ada Settings:: New settable GDB parameters for Ada. ++* Ada Glitches:: Known peculiarities of Ada mode. ++@end menu ++ ++@node Ada Mode Intro ++@subsubsection Introduction ++@cindex Ada mode, general ++ ++The Ada mode of @value{GDBN} supports a fairly large subset of Ada expression ++syntax, with some extensions. ++The philosophy behind the design of this subset is ++ ++@itemize @bullet ++@item ++That @value{GDBN} should provide basic literals and access to operations for ++arithmetic, dereferencing, field selection, indexing, and subprogram calls, ++leaving more sophisticated computations to subprograms written into the ++program (which therefore may be called from @value{GDBN}). ++ ++@item ++That type safety and strict adherence to Ada language restrictions ++are not particularly important to the @value{GDBN} user. ++ ++@item ++That brevity is important to the @value{GDBN} user. ++@end itemize ++ ++Thus, for brevity, the debugger acts as if all names declared in ++user-written packages are directly visible, even if they are not visible ++according to Ada rules, thus making it unnecessary to fully qualify most ++names with their packages, regardless of context. Where this causes ++ambiguity, @value{GDBN} asks the user's intent. ++ ++The debugger will start in Ada mode if it detects an Ada main program. ++As for other languages, it will enter Ada mode when stopped in a program that ++was translated from an Ada source file. ++ ++While in Ada mode, you may use `@t{--}' for comments. This is useful ++mostly for documenting command files. The standard @value{GDBN} comment ++(@samp{#}) still works at the beginning of a line in Ada mode, but not in the ++middle (to allow based literals). ++ ++@node Omissions from Ada ++@subsubsection Omissions from Ada ++@cindex Ada, omissions from ++ ++Here are the notable omissions from the subset: ++ ++@itemize @bullet ++@item ++Only a subset of the attributes are supported: ++ ++@itemize @minus ++@item ++@t{'First}, @t{'Last}, and @t{'Length} ++ on array objects (not on types and subtypes). ++ ++@item ++@t{'Min} and @t{'Max}. ++ ++@item ++@t{'Pos} and @t{'Val}. ++ ++@item ++@t{'Tag}. ++ ++@item ++@t{'Range} on array objects (not subtypes), but only as the right ++operand of the membership (@code{in}) operator. ++ ++@item ++@t{'Access}, @t{'Unchecked_Access}, and ++@t{'Unrestricted_Access} (a GNAT extension). ++ ++@item ++@t{'Address}. ++@end itemize ++ ++@item ++The names in ++@code{Characters.Latin_1} are not available and ++concatenation is not implemented. Thus, escape characters in strings are ++not currently available. ++ ++@item ++Equality tests (@samp{=} and @samp{/=}) on arrays test for bitwise ++equality of representations. They will generally work correctly ++for strings and arrays whose elements have integer or enumeration types. ++They may not work correctly for arrays whose element ++types have user-defined equality, for arrays of real values ++(in particular, IEEE-conformant floating point, because of negative ++zeroes and NaNs), and for arrays whose elements contain unused bits with ++indeterminate values. ++ ++@item ++The other component-by-component array operations (@code{and}, @code{or}, ++@code{xor}, @code{not}, and relational tests other than equality) ++are not implemented. ++ ++@item ++@cindex array aggregates (Ada) ++@cindex record aggregates (Ada) ++@cindex aggregates (Ada) ++There is limited support for array and record aggregates. They are ++permitted only on the right sides of assignments, as in these examples: ++ ++@smallexample ++(@value{GDBP}) set An_Array := (1, 2, 3, 4, 5, 6) ++(@value{GDBP}) set An_Array := (1, others => 0) ++(@value{GDBP}) set An_Array := (0|4 => 1, 1..3 => 2, 5 => 6) ++(@value{GDBP}) set A_2D_Array := ((1, 2, 3), (4, 5, 6), (7, 8, 9)) ++(@value{GDBP}) set A_Record := (1, "Peter", True); ++(@value{GDBP}) set A_Record := (Name => "Peter", Id => 1, Alive => True) ++@end smallexample ++ ++Changing a ++discriminant's value by assigning an aggregate has an ++undefined effect if that discriminant is used within the record. ++However, you can first modify discriminants by directly assigning to ++them (which normally would not be allowed in Ada), and then performing an ++aggregate assignment. For example, given a variable @code{A_Rec} ++declared to have a type such as: ++ ++@smallexample ++type Rec (Len : Small_Integer := 0) is record ++ Id : Integer; ++ Vals : IntArray (1 .. Len); ++end record; ++@end smallexample ++ ++you can assign a value with a different size of @code{Vals} with two ++assignments: ++ ++@smallexample ++(@value{GDBP}) set A_Rec.Len := 4 ++(@value{GDBP}) set A_Rec := (Id => 42, Vals => (1, 2, 3, 4)) ++@end smallexample ++ ++As this example also illustrates, @value{GDBN} is very loose about the usual ++rules concerning aggregates. You may leave out some of the ++components of an array or record aggregate (such as the @code{Len} ++component in the assignment to @code{A_Rec} above); they will retain their ++original values upon assignment. You may freely use dynamic values as ++indices in component associations. You may even use overlapping or ++redundant component associations, although which component values are ++assigned in such cases is not defined. ++ ++@item ++Calls to dispatching subprograms are not implemented. ++ ++@item ++The overloading algorithm is much more limited (i.e., less selective) ++than that of real Ada. It makes only limited use of the context in ++which a subexpression appears to resolve its meaning, and it is much ++looser in its rules for allowing type matches. As a result, some ++function calls will be ambiguous, and the user will be asked to choose ++the proper resolution. ++ ++@item ++The @code{new} operator is not implemented. ++ ++@item ++Entry calls are not implemented. ++ ++@item ++Aside from printing, arithmetic operations on the native VAX floating-point ++formats are not supported. ++ ++@item ++It is not possible to slice a packed array. ++ ++@item ++The names @code{True} and @code{False}, when not part of a qualified name, ++are interpreted as if implicitly prefixed by @code{Standard}, regardless of ++context. ++Should your program ++redefine these names in a package or procedure (at best a dubious practice), ++you will have to use fully qualified names to access their new definitions. ++@end itemize ++ ++@node Additions to Ada ++@subsubsection Additions to Ada ++@cindex Ada, deviations from ++ ++As it does for other languages, @value{GDBN} makes certain generic ++extensions to Ada (@pxref{Expressions}): ++ ++@itemize @bullet ++@item ++If the expression @var{E} is a variable residing in memory (typically ++a local variable or array element) and @var{N} is a positive integer, ++then @code{@var{E}@@@var{N}} displays the values of @var{E} and the ++@var{N}-1 adjacent variables following it in memory as an array. In ++Ada, this operator is generally not necessary, since its prime use is ++in displaying parts of an array, and slicing will usually do this in ++Ada. However, there are occasional uses when debugging programs in ++which certain debugging information has been optimized away. ++ ++@item ++@code{@var{B}::@var{var}} means ``the variable named @var{var} that ++appears in function or file @var{B}.'' When @var{B} is a file name, ++you must typically surround it in single quotes. ++ ++@item ++The expression @code{@{@var{type}@} @var{addr}} means ``the variable of type ++@var{type} that appears at address @var{addr}.'' ++ ++@item ++A name starting with @samp{$} is a convenience variable ++(@pxref{Convenience Vars}) or a machine register (@pxref{Registers}). ++@end itemize ++ ++In addition, @value{GDBN} provides a few other shortcuts and outright ++additions specific to Ada: ++ ++@itemize @bullet ++@item ++The assignment statement is allowed as an expression, returning ++its right-hand operand as its value. Thus, you may enter ++ ++@smallexample ++(@value{GDBP}) set x := y + 3 ++(@value{GDBP}) print A(tmp := y + 1) ++@end smallexample ++ ++@item ++The semicolon is allowed as an ``operator,'' returning as its value ++the value of its right-hand operand. ++This allows, for example, ++complex conditional breaks: ++ ++@smallexample ++(@value{GDBP}) break f ++(@value{GDBP}) condition 1 (report(i); k += 1; A(k) > 100) ++@end smallexample ++ ++@item ++Rather than use catenation and symbolic character names to introduce special ++characters into strings, one may instead use a special bracket notation, ++which is also used to print strings. A sequence of characters of the form ++@samp{["@var{XX}"]} within a string or character literal denotes the ++(single) character whose numeric encoding is @var{XX} in hexadecimal. The ++sequence of characters @samp{["""]} also denotes a single quotation mark ++in strings. For example, ++@smallexample ++ "One line.["0a"]Next line.["0a"]" ++@end smallexample ++@noindent ++contains an ASCII newline character (@code{Ada.Characters.Latin_1.LF}) ++after each period. ++ ++@item ++The subtype used as a prefix for the attributes @t{'Pos}, @t{'Min}, and ++@t{'Max} is optional (and is ignored in any case). For example, it is valid ++to write ++ ++@smallexample ++(@value{GDBP}) print 'max(x, y) ++@end smallexample ++ ++@item ++When printing arrays, @value{GDBN} uses positional notation when the ++array has a lower bound of 1, and uses a modified named notation otherwise. ++For example, a one-dimensional array of three integers with a lower bound ++of 3 might print as ++ ++@smallexample ++(3 => 10, 17, 1) ++@end smallexample ++ ++@noindent ++That is, in contrast to valid Ada, only the first component has a @code{=>} ++clause. ++ ++@item ++You may abbreviate attributes in expressions with any unique, ++multi-character subsequence of ++their names (an exact match gets preference). ++For example, you may use @t{a'len}, @t{a'gth}, or @t{a'lh} ++in place of @t{a'length}. ++ ++@item ++@cindex quoting Ada internal identifiers ++Since Ada is case-insensitive, the debugger normally maps identifiers you type ++to lower case. The GNAT compiler uses upper-case characters for ++some of its internal identifiers, which are normally of no interest to users. ++For the rare occasions when you actually have to look at them, ++enclose them in angle brackets to avoid the lower-case mapping. ++For example, ++@smallexample ++(@value{GDBP}) print [0] ++@end smallexample ++ ++@item ++Printing an object of class-wide type or dereferencing an ++access-to-class-wide value will display all the components of the object's ++specific type (as indicated by its run-time tag). Likewise, component ++selection on such a value will operate on the specific type of the ++object. ++ ++@end itemize ++ ++@node Overloading support for Ada ++@subsubsection Overloading support for Ada ++@cindex overloading, Ada ++ ++The debugger supports limited overloading. Given a subprogram call in which ++the function symbol has multiple definitions, it will use the number of ++actual parameters and some information about their types to attempt to narrow ++the set of definitions. It also makes very limited use of context, preferring ++procedures to functions in the context of the @code{call} command, and ++functions to procedures elsewhere. ++ ++If, after narrowing, the set of matching definitions still contains more than ++one definition, @value{GDBN} will display a menu to query which one it should ++use, for instance: ++ ++@smallexample ++(@value{GDBP}) print f(1) ++Multiple matches for f ++[0] cancel ++[1] foo.f (integer) return boolean at foo.adb:23 ++[2] foo.f (foo.new_integer) return boolean at foo.adb:28 ++> ++@end smallexample ++ ++In this case, just select one menu entry either to cancel expression evaluation ++(type @kbd{0} and press @key{RET}) or to continue evaluation with a specific ++instance (type the corresponding number and press @key{RET}). ++ ++Here are a couple of commands to customize @value{GDBN}'s behavior in this ++case: ++ ++@table @code ++ ++@kindex set ada print-signatures ++@item set ada print-signatures ++Control whether parameter types and return types are displayed in overloads ++selection menus. It is @code{on} by default. ++@xref{Overloading support for Ada}. ++ ++@kindex show ada print-signatures ++@item show ada print-signatures ++Show the current setting for displaying parameter types and return types in ++overloads selection menu. ++@xref{Overloading support for Ada}. ++ ++@end table ++ ++@node Stopping Before Main Program ++@subsubsection Stopping at the Very Beginning ++ ++@cindex breakpointing Ada elaboration code ++It is sometimes necessary to debug the program during elaboration, and ++before reaching the main procedure. ++As defined in the Ada Reference ++Manual, the elaboration code is invoked from a procedure called ++@code{adainit}. To run your program up to the beginning of ++elaboration, simply use the following two commands: ++@code{tbreak adainit} and @code{run}. ++ ++@node Ada Exceptions ++@subsubsection Ada Exceptions ++ ++A command is provided to list all Ada exceptions: ++ ++@table @code ++@kindex info exceptions ++@item info exceptions ++@itemx info exceptions @var{regexp} ++The @code{info exceptions} command allows you to list all Ada exceptions ++defined within the program being debugged, as well as their addresses. ++With a regular expression, @var{regexp}, as argument, only those exceptions ++whose names match @var{regexp} are listed. ++@end table ++ ++Below is a small example, showing how the command can be used, first ++without argument, and next with a regular expression passed as an ++argument. ++ ++@smallexample ++(@value{GDBP}) info exceptions ++All defined Ada exceptions: ++constraint_error: 0x613da0 ++program_error: 0x613d20 ++storage_error: 0x613ce0 ++tasking_error: 0x613ca0 ++const.aint_global_e: 0x613b00 ++(@value{GDBP}) info exceptions const.aint ++All Ada exceptions matching regular expression "const.aint": ++constraint_error: 0x613da0 ++const.aint_global_e: 0x613b00 ++@end smallexample ++ ++It is also possible to ask @value{GDBN} to stop your program's execution ++when an exception is raised. For more details, see @ref{Set Catchpoints}. ++ ++@node Ada Tasks ++@subsubsection Extensions for Ada Tasks ++@cindex Ada, tasking ++ ++Support for Ada tasks is analogous to that for threads (@pxref{Threads}). ++@value{GDBN} provides the following task-related commands: ++ ++@table @code ++@kindex info tasks ++@item info tasks ++This command shows a list of current Ada tasks, as in the following example: ++ ++ ++@smallexample ++@iftex ++@leftskip=0.5cm ++@end iftex ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 8088000 0 15 Child Activation Wait main_task ++ 2 80a4000 1 15 Accept Statement b ++ 3 809a800 1 15 Child Activation Wait a ++* 4 80ae800 3 15 Runnable c ++ ++@end smallexample ++ ++@noindent ++In this listing, the asterisk before the last task indicates it to be the ++task currently being inspected. ++ ++@table @asis ++@item ID ++Represents @value{GDBN}'s internal task number. ++ ++@item TID ++The Ada task ID. ++ ++@item P-ID ++The parent's task ID (@value{GDBN}'s internal task number). ++ ++@item Pri ++The base priority of the task. ++ ++@item State ++Current state of the task. ++ ++@table @code ++@item Unactivated ++The task has been created but has not been activated. It cannot be ++executing. ++ ++@item Runnable ++The task is not blocked for any reason known to Ada. (It may be waiting ++for a mutex, though.) It is conceptually "executing" in normal mode. ++ ++@item Terminated ++The task is terminated, in the sense of ARM 9.3 (5). Any dependents ++that were waiting on terminate alternatives have been awakened and have ++terminated themselves. ++ ++@item Child Activation Wait ++The task is waiting for created tasks to complete activation. ++ ++@item Accept Statement ++The task is waiting on an accept or selective wait statement. ++ ++@item Waiting on entry call ++The task is waiting on an entry call. ++ ++@item Async Select Wait ++The task is waiting to start the abortable part of an asynchronous ++select statement. ++ ++@item Delay Sleep ++The task is waiting on a select statement with only a delay ++alternative open. ++ ++@item Child Termination Wait ++The task is sleeping having completed a master within itself, and is ++waiting for the tasks dependent on that master to become terminated or ++waiting on a terminate Phase. ++ ++@item Wait Child in Term Alt ++The task is sleeping waiting for tasks on terminate alternatives to ++finish terminating. ++ ++@item Accepting RV with @var{taskno} ++The task is accepting a rendez-vous with the task @var{taskno}. ++@end table ++ ++@item Name ++Name of the task in the program. ++ ++@end table ++ ++@kindex info task @var{taskno} ++@item info task @var{taskno} ++This command shows detailed informations on the specified task, as in ++the following example: ++@smallexample ++@iftex ++@leftskip=0.5cm ++@end iftex ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 8077880 0 15 Child Activation Wait main_task ++* 2 807c468 1 15 Runnable task_1 ++(@value{GDBP}) info task 2 ++Ada Task: 0x807c468 ++Name: "task_1" ++Thread: 0 ++LWP: 0x1fac ++Parent: 1 ("main_task") ++Base Priority: 15 ++State: Runnable ++@end smallexample ++ ++@item task ++@kindex task@r{ (Ada)} ++@cindex current Ada task ID ++This command prints the ID and name of the current task. ++ ++@smallexample ++@iftex ++@leftskip=0.5cm ++@end iftex ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 8077870 0 15 Child Activation Wait main_task ++* 2 807c458 1 15 Runnable some_task ++(@value{GDBP}) task ++[Current task is 2 "some_task"] ++@end smallexample ++ ++@item task @var{taskno} ++@cindex Ada task switching ++This command is like the @code{thread @var{thread-id}} ++command (@pxref{Threads}). It switches the context of debugging ++from the current task to the given task. ++ ++@smallexample ++@iftex ++@leftskip=0.5cm ++@end iftex ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 8077870 0 15 Child Activation Wait main_task ++* 2 807c458 1 15 Runnable some_task ++(@value{GDBP}) task 1 ++[Switching to task 1 "main_task"] ++#0 0x8067726 in pthread_cond_wait () ++(@value{GDBP}) bt ++#0 0x8067726 in pthread_cond_wait () ++#1 0x8056714 in system.os_interface.pthread_cond_wait () ++#2 0x805cb63 in system.task_primitives.operations.sleep () ++#3 0x806153e in system.tasking.stages.activate_tasks () ++#4 0x804aacc in un () at un.adb:5 ++@end smallexample ++ ++@item break @var{location} task @var{taskno} ++@itemx break @var{location} task @var{taskno} if @dots{} ++@cindex breakpoints and tasks, in Ada ++@cindex task breakpoints, in Ada ++@kindex break @dots{} task @var{taskno}@r{ (Ada)} ++These commands are like the @code{break @dots{} thread @dots{}} ++command (@pxref{Thread Stops}). The ++@var{location} argument specifies source lines, as described ++in @ref{Specify Location}. ++ ++Use the qualifier @samp{task @var{taskno}} with a breakpoint command ++to specify that you only want @value{GDBN} to stop the program when a ++particular Ada task reaches this breakpoint. The @var{taskno} is one of the ++numeric task identifiers assigned by @value{GDBN}, shown in the first ++column of the @samp{info tasks} display. ++ ++If you do not specify @samp{task @var{taskno}} when you set a ++breakpoint, the breakpoint applies to @emph{all} tasks of your ++program. ++ ++You can use the @code{task} qualifier on conditional breakpoints as ++well; in this case, place @samp{task @var{taskno}} before the ++breakpoint condition (before the @code{if}). ++ ++For example, ++ ++@smallexample ++@iftex ++@leftskip=0.5cm ++@end iftex ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 140022020 0 15 Child Activation Wait main_task ++ 2 140045060 1 15 Accept/Select Wait t2 ++ 3 140044840 1 15 Runnable t1 ++* 4 140056040 1 15 Runnable t3 ++(@value{GDBP}) b 15 task 2 ++Breakpoint 5 at 0x120044cb0: file test_task_debug.adb, line 15. ++(@value{GDBP}) cont ++Continuing. ++task # 1 running ++task # 2 running ++ ++Breakpoint 5, test_task_debug () at test_task_debug.adb:15 ++15 flush; ++(@value{GDBP}) info tasks ++ ID TID P-ID Pri State Name ++ 1 140022020 0 15 Child Activation Wait main_task ++* 2 140045060 1 15 Runnable t2 ++ 3 140044840 1 15 Runnable t1 ++ 4 140056040 1 15 Delay Sleep t3 ++@end smallexample ++@end table ++ ++@node Ada Tasks and Core Files ++@subsubsection Tasking Support when Debugging Core Files ++@cindex Ada tasking and core file debugging ++ ++When inspecting a core file, as opposed to debugging a live program, ++tasking support may be limited or even unavailable, depending on ++the platform being used. ++For instance, on x86-linux, the list of tasks is available, but task ++switching is not supported. ++ ++On certain platforms, the debugger needs to perform some ++memory writes in order to provide Ada tasking support. When inspecting ++a core file, this means that the core file must be opened with read-write ++privileges, using the command @samp{"set write on"} (@pxref{Patching}). ++Under these circumstances, you should make a backup copy of the core ++file before inspecting it with @value{GDBN}. ++ ++@node Ravenscar Profile ++@subsubsection Tasking Support when using the Ravenscar Profile ++@cindex Ravenscar Profile ++ ++The @dfn{Ravenscar Profile} is a subset of the Ada tasking features, ++specifically designed for systems with safety-critical real-time ++requirements. ++ ++@table @code ++@kindex set ravenscar task-switching on ++@cindex task switching with program using Ravenscar Profile ++@item set ravenscar task-switching on ++Allows task switching when debugging a program that uses the Ravenscar ++Profile. This is the default. ++ ++@kindex set ravenscar task-switching off ++@item set ravenscar task-switching off ++Turn off task switching when debugging a program that uses the Ravenscar ++Profile. This is mostly intended to disable the code that adds support ++for the Ravenscar Profile, in case a bug in either @value{GDBN} or in ++the Ravenscar runtime is preventing @value{GDBN} from working properly. ++To be effective, this command should be run before the program is started. ++ ++@kindex show ravenscar task-switching ++@item show ravenscar task-switching ++Show whether it is possible to switch from task to task in a program ++using the Ravenscar Profile. ++ ++@end table ++ ++@cindex Ravenscar thread ++When Ravenscar task-switching is enabled, Ravenscar tasks are ++announced by @value{GDBN} as if they were threads: ++ ++@smallexample ++(gdb) continue ++[New Ravenscar Thread 0x2b8f0] ++@end smallexample ++ ++Both Ravenscar tasks and the underlying CPU threads will show up in ++the output of @code{info threads}: ++ ++@smallexample ++(gdb) info threads ++ Id Target Id Frame ++ 1 Thread 1 (CPU#0 [running]) simple () at simple.adb:10 ++ 2 Thread 2 (CPU#1 [running]) 0x0000000000003d34 in __gnat_initialize_cpu_devices () ++ 3 Thread 3 (CPU#2 [running]) 0x0000000000003d28 in __gnat_initialize_cpu_devices () ++ 4 Thread 4 (CPU#3 [halted ]) 0x000000000000c6ec in system.task_primitives.operations.idle () ++* 5 Ravenscar Thread 0x2b8f0 simple () at simple.adb:10 ++ 6 Ravenscar Thread 0x2f150 0x000000000000c6ec in system.task_primitives.operations.idle () ++@end smallexample ++ ++One known limitation of the Ravenscar support in @value{GDBN} is that ++it isn't currently possible to single-step through the runtime ++initialization sequence. If you need to debug this code, you should ++use @code{set ravenscar task-switching off}. ++ ++@node Ada Settings ++@subsubsection Ada Settings ++@cindex Ada settings ++ ++@table @code ++@kindex set varsize-limit ++@item set varsize-limit @var{size} ++Prevent @value{GDBN} from attempting to evaluate objects whose size ++is above the given limit (@var{size}) when those sizes are computed ++from run-time quantities. This is typically the case when the object ++has a variable size, such as an array whose bounds are not known at ++compile time for example. Setting @var{size} to @code{unlimited} ++removes the size limitation. By default, the limit is about 65KB. ++ ++The purpose of having such a limit is to prevent @value{GDBN} from ++trying to grab enormous chunks of virtual memory when asked to evaluate ++a quantity whose bounds have been corrupted or have not yet been fully ++initialized. The limit applies to the results of some subexpressions ++as well as to complete expressions. For example, an expression denoting ++a simple integer component, such as @code{x.y.z}, may fail if the size of ++@code{x.y} is variable and exceeds @code{size}. On the other hand, ++@value{GDBN} is sometimes clever; the expression @code{A(i)}, where ++@code{A} is an array variable with non-constant size, will generally ++succeed regardless of the bounds on @code{A}, as long as the component ++size is less than @var{size}. ++ ++@kindex show varsize-limit ++@item show varsize-limit ++Show the limit on types whose size is determined by run-time quantities. ++@end table ++ ++@node Ada Glitches ++@subsubsection Known Peculiarities of Ada Mode ++@cindex Ada, problems ++ ++Besides the omissions listed previously (@pxref{Omissions from Ada}), ++we know of several problems with and limitations of Ada mode in ++@value{GDBN}, ++some of which will be fixed with planned future releases of the debugger ++and the GNU Ada compiler. ++ ++@itemize @bullet ++@item ++Static constants that the compiler chooses not to materialize as objects in ++storage are invisible to the debugger. ++ ++@item ++Named parameter associations in function argument lists are ignored (the ++argument lists are treated as positional). ++ ++@item ++Many useful library packages are currently invisible to the debugger. ++ ++@item ++Fixed-point arithmetic, conversions, input, and output is carried out using ++floating-point arithmetic, and may give results that only approximate those on ++the host machine. ++ ++@item ++The GNAT compiler never generates the prefix @code{Standard} for any of ++the standard symbols defined by the Ada language. @value{GDBN} knows about ++this: it will strip the prefix from names when you use it, and will never ++look for a name you have so qualified among local symbols, nor match against ++symbols in other packages or subprograms. If you have ++defined entities anywhere in your program other than parameters and ++local variables whose simple names match names in @code{Standard}, ++GNAT's lack of qualification here can cause confusion. When this happens, ++you can usually resolve the confusion ++by qualifying the problematic names with package ++@code{Standard} explicitly. ++@end itemize ++ ++Older versions of the compiler sometimes generate erroneous debugging ++information, resulting in the debugger incorrectly printing the value ++of affected entities. In some cases, the debugger is able to work ++around an issue automatically. In other cases, the debugger is able ++to work around the issue, but the work-around has to be specifically ++enabled. ++ ++@kindex set ada trust-PAD-over-XVS ++@kindex show ada trust-PAD-over-XVS ++@table @code ++ ++@item set ada trust-PAD-over-XVS on ++Configure GDB to strictly follow the GNAT encoding when computing the ++value of Ada entities, particularly when @code{PAD} and @code{PAD___XVS} ++types are involved (see @code{ada/exp_dbug.ads} in the GCC sources for ++a complete description of the encoding used by the GNAT compiler). ++This is the default. ++ ++@item set ada trust-PAD-over-XVS off ++This is related to the encoding using by the GNAT compiler. If @value{GDBN} ++sometimes prints the wrong value for certain entities, changing @code{ada ++trust-PAD-over-XVS} to @code{off} activates a work-around which may fix ++the issue. It is always safe to set @code{ada trust-PAD-over-XVS} to ++@code{off}, but this incurs a slight performance penalty, so it is ++recommended to leave this setting to @code{on} unless necessary. ++ ++@end table ++ ++@cindex GNAT descriptive types ++@cindex GNAT encoding ++Internally, the debugger also relies on the compiler following a number ++of conventions known as the @samp{GNAT Encoding}, all documented in ++@file{gcc/ada/exp_dbug.ads} in the GCC sources. This encoding describes ++how the debugging information should be generated for certain types. ++In particular, this convention makes use of @dfn{descriptive types}, ++which are artificial types generated purely to help the debugger. ++ ++These encodings were defined at a time when the debugging information ++format used was not powerful enough to describe some of the more complex ++types available in Ada. Since DWARF allows us to express nearly all ++Ada features, the long-term goal is to slowly replace these descriptive ++types by their pure DWARF equivalent. To facilitate that transition, ++a new maintenance option is available to force the debugger to ignore ++those descriptive types. It allows the user to quickly evaluate how ++well @value{GDBN} works without them. ++ ++@table @code ++ ++@kindex maint ada set ignore-descriptive-types ++@item maintenance ada set ignore-descriptive-types [on|off] ++Control whether the debugger should ignore descriptive types. ++The default is not to ignore descriptives types (@code{off}). ++ ++@kindex maint ada show ignore-descriptive-types ++@item maintenance ada show ignore-descriptive-types ++Show if descriptive types are ignored by @value{GDBN}. ++ ++@end table ++ ++@node Unsupported Languages ++@section Unsupported Languages ++ ++@cindex unsupported languages ++@cindex minimal language ++In addition to the other fully-supported programming languages, ++@value{GDBN} also provides a pseudo-language, called @code{minimal}. ++It does not represent a real programming language, but provides a set ++of capabilities close to what the C or assembly languages provide. ++This should allow most simple operations to be performed while debugging ++an application that uses a language currently not supported by @value{GDBN}. ++ ++If the language is set to @code{auto}, @value{GDBN} will automatically ++select this language if the current frame corresponds to an unsupported ++language. ++ ++@node Symbols ++@chapter Examining the Symbol Table ++ ++The commands described in this chapter allow you to inquire about the ++symbols (names of variables, functions and types) defined in your ++program. This information is inherent in the text of your program and ++does not change as your program executes. @value{GDBN} finds it in your ++program's symbol table, in the file indicated when you started @value{GDBN} ++(@pxref{File Options, ,Choosing Files}), or by one of the ++file-management commands (@pxref{Files, ,Commands to Specify Files}). ++ ++@cindex symbol names ++@cindex names of symbols ++@cindex quoting names ++@anchor{quoting names} ++Occasionally, you may need to refer to symbols that contain unusual ++characters, which @value{GDBN} ordinarily treats as word delimiters. The ++most frequent case is in referring to static variables in other ++source files (@pxref{Variables,,Program Variables}). File names ++are recorded in object files as debugging symbols, but @value{GDBN} would ++ordinarily parse a typical file name, like @file{foo.c}, as the three words ++@samp{foo} @samp{.} @samp{c}. To allow @value{GDBN} to recognize ++@samp{foo.c} as a single symbol, enclose it in single quotes; for example, ++ ++@smallexample ++p 'foo.c'::x ++@end smallexample ++ ++@noindent ++looks up the value of @code{x} in the scope of the file @file{foo.c}. ++ ++@table @code ++@cindex case-insensitive symbol names ++@cindex case sensitivity in symbol names ++@kindex set case-sensitive ++@item set case-sensitive on ++@itemx set case-sensitive off ++@itemx set case-sensitive auto ++Normally, when @value{GDBN} looks up symbols, it matches their names ++with case sensitivity determined by the current source language. ++Occasionally, you may wish to control that. The command @code{set ++case-sensitive} lets you do that by specifying @code{on} for ++case-sensitive matches or @code{off} for case-insensitive ones. If ++you specify @code{auto}, case sensitivity is reset to the default ++suitable for the source language. The default is case-sensitive ++matches for all languages except for Fortran, for which the default is ++case-insensitive matches. ++ ++@kindex show case-sensitive ++@item show case-sensitive ++This command shows the current setting of case sensitivity for symbols ++lookups. ++ ++@kindex set print type methods ++@item set print type methods ++@itemx set print type methods on ++@itemx set print type methods off ++Normally, when @value{GDBN} prints a class, it displays any methods ++declared in that class. You can control this behavior either by ++passing the appropriate flag to @code{ptype}, or using @command{set ++print type methods}. Specifying @code{on} will cause @value{GDBN} to ++display the methods; this is the default. Specifying @code{off} will ++cause @value{GDBN} to omit the methods. ++ ++@kindex show print type methods ++@item show print type methods ++This command shows the current setting of method display when printing ++classes. ++ ++@kindex set print type nested-type-limit ++@item set print type nested-type-limit @var{limit} ++@itemx set print type nested-type-limit unlimited ++Set the limit of displayed nested types that the type printer will ++show. A @var{limit} of @code{unlimited} or @code{-1} will show all ++nested definitions. By default, the type printer will not show any nested ++types defined in classes. ++ ++@kindex show print type nested-type-limit ++@item show print type nested-type-limit ++This command shows the current display limit of nested types when ++printing classes. ++ ++@kindex set print type typedefs ++@item set print type typedefs ++@itemx set print type typedefs on ++@itemx set print type typedefs off ++ ++Normally, when @value{GDBN} prints a class, it displays any typedefs ++defined in that class. You can control this behavior either by ++passing the appropriate flag to @code{ptype}, or using @command{set ++print type typedefs}. Specifying @code{on} will cause @value{GDBN} to ++display the typedef definitions; this is the default. Specifying ++@code{off} will cause @value{GDBN} to omit the typedef definitions. ++Note that this controls whether the typedef definition itself is ++printed, not whether typedef names are substituted when printing other ++types. ++ ++@kindex show print type typedefs ++@item show print type typedefs ++This command shows the current setting of typedef display when ++printing classes. ++ ++@kindex info address ++@cindex address of a symbol ++@item info address @var{symbol} ++Describe where the data for @var{symbol} is stored. For a register ++variable, this says which register it is kept in. For a non-register ++local variable, this prints the stack-frame offset at which the variable ++is always stored. ++ ++Note the contrast with @samp{print &@var{symbol}}, which does not work ++at all for a register variable, and for a stack local variable prints ++the exact address of the current instantiation of the variable. ++ ++@kindex info symbol ++@cindex symbol from address ++@cindex closest symbol and offset for an address ++@item info symbol @var{addr} ++Print the name of a symbol which is stored at the address @var{addr}. ++If no symbol is stored exactly at @var{addr}, @value{GDBN} prints the ++nearest symbol and an offset from it: ++ ++@smallexample ++(@value{GDBP}) info symbol 0x54320 ++_initialize_vx + 396 in section .text ++@end smallexample ++ ++@noindent ++This is the opposite of the @code{info address} command. You can use ++it to find out the name of a variable or a function given its address. ++ ++For dynamically linked executables, the name of executable or shared ++library containing the symbol is also printed: ++ ++@smallexample ++(@value{GDBP}) info symbol 0x400225 ++_start + 5 in section .text of /tmp/a.out ++(@value{GDBP}) info symbol 0x2aaaac2811cf ++__read_nocancel + 6 in section .text of /usr/lib64/libc.so.6 ++@end smallexample ++ ++@kindex demangle ++@cindex demangle ++@item demangle @r{[}-l @var{language}@r{]} @r{[}@var{--}@r{]} @var{name} ++Demangle @var{name}. ++If @var{language} is provided it is the name of the language to demangle ++@var{name} in. Otherwise @var{name} is demangled in the current language. ++ ++The @samp{--} option specifies the end of options, ++and is useful when @var{name} begins with a dash. ++ ++The parameter @code{demangle-style} specifies how to interpret the kind ++of mangling used. @xref{Print Settings}. ++ ++@kindex whatis ++@item whatis[/@var{flags}] [@var{arg}] ++Print the data type of @var{arg}, which can be either an expression ++or a name of a data type. With no argument, print the data type of ++@code{$}, the last value in the value history. ++ ++If @var{arg} is an expression (@pxref{Expressions, ,Expressions}), it ++is not actually evaluated, and any side-effecting operations (such as ++assignments or function calls) inside it do not take place. ++ ++If @var{arg} is a variable or an expression, @code{whatis} prints its ++literal type as it is used in the source code. If the type was ++defined using a @code{typedef}, @code{whatis} will @emph{not} print ++the data type underlying the @code{typedef}. If the type of the ++variable or the expression is a compound data type, such as ++@code{struct} or @code{class}, @code{whatis} never prints their ++fields or methods. It just prints the @code{struct}/@code{class} ++name (a.k.a.@: its @dfn{tag}). If you want to see the members of ++such a compound data type, use @code{ptype}. ++ ++If @var{arg} is a type name that was defined using @code{typedef}, ++@code{whatis} @dfn{unrolls} only one level of that @code{typedef}. ++Unrolling means that @code{whatis} will show the underlying type used ++in the @code{typedef} declaration of @var{arg}. However, if that ++underlying type is also a @code{typedef}, @code{whatis} will not ++unroll it. ++ ++For C code, the type names may also have the form @samp{class ++@var{class-name}}, @samp{struct @var{struct-tag}}, @samp{union ++@var{union-tag}} or @samp{enum @var{enum-tag}}. ++ ++@var{flags} can be used to modify how the type is displayed. ++Available flags are: ++ ++@table @code ++@item r ++Display in ``raw'' form. Normally, @value{GDBN} substitutes template ++parameters and typedefs defined in a class when printing the class' ++members. The @code{/r} flag disables this. ++ ++@item m ++Do not print methods defined in the class. ++ ++@item M ++Print methods defined in the class. This is the default, but the flag ++exists in case you change the default with @command{set print type methods}. ++ ++@item t ++Do not print typedefs defined in the class. Note that this controls ++whether the typedef definition itself is printed, not whether typedef ++names are substituted when printing other types. ++ ++@item T ++Print typedefs defined in the class. This is the default, but the flag ++exists in case you change the default with @command{set print type typedefs}. ++ ++@item o ++Print the offsets and sizes of fields in a struct, similar to what the ++@command{pahole} tool does. This option implies the @code{/tm} flags. ++ ++For example, given the following declarations: ++ ++@smallexample ++struct tuv ++@{ ++ int a1; ++ char *a2; ++ int a3; ++@}; ++ ++struct xyz ++@{ ++ int f1; ++ char f2; ++ void *f3; ++ struct tuv f4; ++@}; ++ ++union qwe ++@{ ++ struct tuv fff1; ++ struct xyz fff2; ++@}; ++ ++struct tyu ++@{ ++ int a1 : 1; ++ int a2 : 3; ++ int a3 : 23; ++ char a4 : 2; ++ int64_t a5; ++ int a6 : 5; ++ int64_t a7 : 3; ++@}; ++@end smallexample ++ ++Issuing a @kbd{ptype /o struct tuv} command would print: ++ ++@smallexample ++(@value{GDBP}) ptype /o struct tuv ++/* offset | size */ type = struct tuv @{ ++/* 0 | 4 */ int a1; ++/* XXX 4-byte hole */ ++/* 8 | 8 */ char *a2; ++/* 16 | 4 */ int a3; ++ ++ /* total size (bytes): 24 */ ++ @} ++@end smallexample ++ ++Notice the format of the first column of comments. There, you can ++find two parts separated by the @samp{|} character: the @emph{offset}, ++which indicates where the field is located inside the struct, in ++bytes, and the @emph{size} of the field. Another interesting line is ++the marker of a @emph{hole} in the struct, indicating that it may be ++possible to pack the struct and make it use less space by reorganizing ++its fields. ++ ++It is also possible to print offsets inside an union: ++ ++@smallexample ++(@value{GDBP}) ptype /o union qwe ++/* offset | size */ type = union qwe @{ ++/* 24 */ struct tuv @{ ++/* 0 | 4 */ int a1; ++/* XXX 4-byte hole */ ++/* 8 | 8 */ char *a2; ++/* 16 | 4 */ int a3; ++ ++ /* total size (bytes): 24 */ ++ @} fff1; ++/* 40 */ struct xyz @{ ++/* 0 | 4 */ int f1; ++/* 4 | 1 */ char f2; ++/* XXX 3-byte hole */ ++/* 8 | 8 */ void *f3; ++/* 16 | 24 */ struct tuv @{ ++/* 16 | 4 */ int a1; ++/* XXX 4-byte hole */ ++/* 24 | 8 */ char *a2; ++/* 32 | 4 */ int a3; ++ ++ /* total size (bytes): 24 */ ++ @} f4; ++ ++ /* total size (bytes): 40 */ ++ @} fff2; ++ ++ /* total size (bytes): 40 */ ++ @} ++@end smallexample ++ ++In this case, since @code{struct tuv} and @code{struct xyz} occupy the ++same space (because we are dealing with an union), the offset is not ++printed for them. However, you can still examine the offset of each ++of these structures' fields. ++ ++Another useful scenario is printing the offsets of a struct containing ++bitfields: ++ ++@smallexample ++(@value{GDBP}) ptype /o struct tyu ++/* offset | size */ type = struct tyu @{ ++/* 0:31 | 4 */ int a1 : 1; ++/* 0:28 | 4 */ int a2 : 3; ++/* 0: 5 | 4 */ int a3 : 23; ++/* 3: 3 | 1 */ signed char a4 : 2; ++/* XXX 3-bit hole */ ++/* XXX 4-byte hole */ ++/* 8 | 8 */ int64_t a5; ++/* 16: 0 | 4 */ int a6 : 5; ++/* 16: 5 | 8 */ int64_t a7 : 3; ++"/* XXX 7-byte padding */ ++ ++ /* total size (bytes): 24 */ ++ @} ++@end smallexample ++ ++Note how the offset information is now extended to also include the ++first bit of the bitfield. ++@end table ++ ++@kindex ptype ++@item ptype[/@var{flags}] [@var{arg}] ++@code{ptype} accepts the same arguments as @code{whatis}, but prints a ++detailed description of the type, instead of just the name of the type. ++@xref{Expressions, ,Expressions}. ++ ++Contrary to @code{whatis}, @code{ptype} always unrolls any ++@code{typedef}s in its argument declaration, whether the argument is ++a variable, expression, or a data type. This means that @code{ptype} ++of a variable or an expression will not print literally its type as ++present in the source code---use @code{whatis} for that. @code{typedef}s at ++the pointer or reference targets are also unrolled. Only @code{typedef}s of ++fields, methods and inner @code{class typedef}s of @code{struct}s, ++@code{class}es and @code{union}s are not unrolled even with @code{ptype}. ++ ++For example, for this variable declaration: ++ ++@smallexample ++typedef double real_t; ++struct complex @{ real_t real; double imag; @}; ++typedef struct complex complex_t; ++complex_t var; ++real_t *real_pointer_var; ++@end smallexample ++ ++@noindent ++the two commands give this output: ++ ++@smallexample ++@group ++(@value{GDBP}) whatis var ++type = complex_t ++(@value{GDBP}) ptype var ++type = struct complex @{ ++ real_t real; ++ double imag; ++@} ++(@value{GDBP}) whatis complex_t ++type = struct complex ++(@value{GDBP}) whatis struct complex ++type = struct complex ++(@value{GDBP}) ptype struct complex ++type = struct complex @{ ++ real_t real; ++ double imag; ++@} ++(@value{GDBP}) whatis real_pointer_var ++type = real_t * ++(@value{GDBP}) ptype real_pointer_var ++type = double * ++@end group ++@end smallexample ++ ++@noindent ++As with @code{whatis}, using @code{ptype} without an argument refers to ++the type of @code{$}, the last value in the value history. ++ ++@cindex incomplete type ++Sometimes, programs use opaque data types or incomplete specifications ++of complex data structure. If the debug information included in the ++program does not allow @value{GDBN} to display a full declaration of ++the data type, it will say @samp{}. For example, ++given these declarations: ++ ++@smallexample ++ struct foo; ++ struct foo *fooptr; ++@end smallexample ++ ++@noindent ++but no definition for @code{struct foo} itself, @value{GDBN} will say: ++ ++@smallexample ++ (@value{GDBP}) ptype foo ++ $1 = ++@end smallexample ++ ++@noindent ++``Incomplete type'' is C terminology for data types that are not ++completely specified. ++ ++@cindex unknown type ++Othertimes, information about a variable's type is completely absent ++from the debug information included in the program. This most often ++happens when the program or library where the variable is defined ++includes no debug information at all. @value{GDBN} knows the variable ++exists from inspecting the linker/loader symbol table (e.g., the ELF ++dynamic symbol table), but such symbols do not contain type ++information. Inspecting the type of a (global) variable for which ++@value{GDBN} has no type information shows: ++ ++@smallexample ++ (@value{GDBP}) ptype var ++ type = ++@end smallexample ++ ++@xref{Variables, no debug info variables}, for how to print the values ++of such variables. ++ ++@kindex info types ++@item info types [-q] [@var{regexp}] ++Print a brief description of all types whose names match the regular ++expression @var{regexp} (or all types in your program, if you supply ++no argument). Each complete typename is matched as though it were a ++complete line; thus, @samp{i type value} gives information on all ++types in your program whose names include the string @code{value}, but ++@samp{i type ^value$} gives information only on types whose complete ++name is @code{value}. ++ ++In programs using different languages, @value{GDBN} chooses the syntax ++to print the type description according to the ++@samp{set language} value: using @samp{set language auto} ++(see @ref{Automatically, ,Set Language Automatically}) means to use the ++language of the type, other values mean to use ++the manually specified language (see @ref{Manually, ,Set Language Manually}). ++ ++This command differs from @code{ptype} in two ways: first, like ++@code{whatis}, it does not print a detailed description; second, it ++lists all source files and line numbers where a type is defined. ++ ++The output from @samp{into types} is proceeded with a header line ++describing what types are being listed. The optional flag @samp{-q}, ++which stands for @samp{quiet}, disables printing this header ++information. ++ ++@kindex info type-printers ++@item info type-printers ++Versions of @value{GDBN} that ship with Python scripting enabled may ++have ``type printers'' available. When using @command{ptype} or ++@command{whatis}, these printers are consulted when the name of a type ++is needed. @xref{Type Printing API}, for more information on writing ++type printers. ++ ++@code{info type-printers} displays all the available type printers. ++ ++@kindex enable type-printer ++@kindex disable type-printer ++@item enable type-printer @var{name}@dots{} ++@item disable type-printer @var{name}@dots{} ++These commands can be used to enable or disable type printers. ++ ++@kindex info scope ++@cindex local variables ++@item info scope @var{location} ++List all the variables local to a particular scope. This command ++accepts a @var{location} argument---a function name, a source line, or ++an address preceded by a @samp{*}, and prints all the variables local ++to the scope defined by that location. (@xref{Specify Location}, for ++details about supported forms of @var{location}.) For example: ++ ++@smallexample ++(@value{GDBP}) @b{info scope command_line_handler} ++Scope for command_line_handler: ++Symbol rl is an argument at stack/frame offset 8, length 4. ++Symbol linebuffer is in static storage at address 0x150a18, length 4. ++Symbol linelength is in static storage at address 0x150a1c, length 4. ++Symbol p is a local variable in register $esi, length 4. ++Symbol p1 is a local variable in register $ebx, length 4. ++Symbol nline is a local variable in register $edx, length 4. ++Symbol repeat is a local variable at frame offset -8, length 4. ++@end smallexample ++ ++@noindent ++This command is especially useful for determining what data to collect ++during a @dfn{trace experiment}, see @ref{Tracepoint Actions, ++collect}. ++ ++@kindex info source ++@item info source ++Show information about the current source file---that is, the source file for ++the function containing the current point of execution: ++@itemize @bullet ++@item ++the name of the source file, and the directory containing it, ++@item ++the directory it was compiled in, ++@item ++its length, in lines, ++@item ++which programming language it is written in, ++@item ++if the debug information provides it, the program that compiled the file ++(which may include, e.g., the compiler version and command line arguments), ++@item ++whether the executable includes debugging information for that file, and ++if so, what format the information is in (e.g., STABS, Dwarf 2, etc.), and ++@item ++whether the debugging information includes information about ++preprocessor macros. ++@end itemize ++ ++ ++@kindex info sources ++@item info sources ++Print the names of all source files in your program for which there is ++debugging information, organized into two lists: files whose symbols ++have already been read, and files whose symbols will be read when needed. ++ ++@item info sources [-dirname | -basename] [--] [@var{regexp}] ++Like @samp{info sources}, but only print the names of the files ++matching the provided @var{regexp}. ++By default, the @var{regexp} is used to match anywhere in the filename. ++If @code{-dirname}, only files having a dirname matching @var{regexp} are shown. ++If @code{-basename}, only files having a basename matching @var{regexp} ++are shown. ++The matching is case-sensitive, except on operating systems that ++have case-insensitive filesystem (e.g., MS-Windows). ++ ++@kindex info functions ++@item info functions [-q] [-n] ++Print the names and data types of all defined functions. ++Similarly to @samp{info types}, this command groups its output by source ++files and annotates each function definition with its source line ++number. ++ ++In programs using different languages, @value{GDBN} chooses the syntax ++to print the function name and type according to the ++@samp{set language} value: using @samp{set language auto} ++(see @ref{Automatically, ,Set Language Automatically}) means to use the ++language of the function, other values mean to use ++the manually specified language (see @ref{Manually, ,Set Language Manually}). ++ ++The @samp{-n} flag excludes @dfn{non-debugging symbols} from the ++results. A non-debugging symbol is a symbol that comes from the ++executable's symbol table, not from the debug information (for ++example, DWARF) associated with the executable. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no functions ++have been printed. ++ ++@item info functions [-q] [-n] [-t @var{type_regexp}] [@var{regexp}] ++Like @samp{info functions}, but only print the names and data types ++of the functions selected with the provided regexp(s). ++ ++If @var{regexp} is provided, print only the functions whose names ++match the regular expression @var{regexp}. ++Thus, @samp{info fun step} finds all functions whose ++names include @code{step}; @samp{info fun ^step} finds those whose names ++start with @code{step}. If a function name contains characters that ++conflict with the regular expression language (e.g.@: ++@samp{operator*()}), they may be quoted with a backslash. ++ ++If @var{type_regexp} is provided, print only the functions whose ++types, as printed by the @code{whatis} command, match ++the regular expression @var{type_regexp}. ++If @var{type_regexp} contains space(s), it should be enclosed in ++quote characters. If needed, use backslash to escape the meaning ++of special characters or quotes. ++Thus, @samp{info fun -t '^int ('} finds the functions that return ++an integer; @samp{info fun -t '(.*int.*'} finds the functions that ++have an argument type containing int; @samp{info fun -t '^int (' ^step} ++finds the functions whose names start with @code{step} and that return ++int. ++ ++If both @var{regexp} and @var{type_regexp} are provided, a function ++is printed only if its name matches @var{regexp} and its type matches ++@var{type_regexp}. ++ ++ ++@kindex info variables ++@item info variables [-q] [-n] ++Print the names and data types of all variables that are defined ++outside of functions (i.e.@: excluding local variables). ++The printed variables are grouped by source files and annotated with ++their respective source line numbers. ++ ++In programs using different languages, @value{GDBN} chooses the syntax ++to print the variable name and type according to the ++@samp{set language} value: using @samp{set language auto} ++(see @ref{Automatically, ,Set Language Automatically}) means to use the ++language of the variable, other values mean to use ++the manually specified language (see @ref{Manually, ,Set Language Manually}). ++ ++The @samp{-n} flag excludes non-debugging symbols from the results. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no variables ++have been printed. ++ ++@item info variables [-q] [-n] [-t @var{type_regexp}] [@var{regexp}] ++Like @kbd{info variables}, but only print the variables selected ++with the provided regexp(s). ++ ++If @var{regexp} is provided, print only the variables whose names ++match the regular expression @var{regexp}. ++ ++If @var{type_regexp} is provided, print only the variables whose ++types, as printed by the @code{whatis} command, match ++the regular expression @var{type_regexp}. ++If @var{type_regexp} contains space(s), it should be enclosed in ++quote characters. If needed, use backslash to escape the meaning ++of special characters or quotes. ++ ++If both @var{regexp} and @var{type_regexp} are provided, an argument ++is printed only if its name matches @var{regexp} and its type matches ++@var{type_regexp}. ++ ++@kindex info modules ++@cindex modules ++@item info modules @r{[}-q@r{]} @r{[}@var{regexp}@r{]} ++List all Fortran modules in the program, or all modules matching the ++optional regular expression @var{regexp}. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no modules ++have been printed. ++ ++@kindex info module ++@cindex Fortran modules, information about ++@cindex functions and variables by Fortran module ++@cindex module functions and variables ++@item info module functions @r{[}-q@r{]} @r{[}-m @var{module-regexp}@r{]} @r{[}-t @var{type-regexp}@r{]} @r{[}@var{regexp}@r{]} ++@itemx info module variables @r{[}-q@r{]} @r{[}-m @var{module-regexp}@r{]} @r{[}-t @var{type-regexp}@r{]} @r{[}@var{regexp}@r{]} ++List all functions or variables within all Fortran modules. The set ++of functions or variables listed can be limited by providing some or ++all of the optional regular expressions. If @var{module-regexp} is ++provided, then only Fortran modules matching @var{module-regexp} will ++be searched. Only functions or variables whose type matches the ++optional regular expression @var{type-regexp} will be listed. And ++only functions or variables whose name matches the optional regular ++expression @var{regexp} will be listed. ++ ++The optional flag @samp{-q}, which stands for @samp{quiet}, disables ++printing header information and messages explaining why no functions ++or variables have been printed. ++ ++@kindex info classes ++@cindex Objective-C, classes and selectors ++@item info classes ++@itemx info classes @var{regexp} ++Display all Objective-C classes in your program, or ++(with the @var{regexp} argument) all those matching a particular regular ++expression. ++ ++@kindex info selectors ++@item info selectors ++@itemx info selectors @var{regexp} ++Display all Objective-C selectors in your program, or ++(with the @var{regexp} argument) all those matching a particular regular ++expression. ++ ++@ignore ++This was never implemented. ++@kindex info methods ++@item info methods ++@itemx info methods @var{regexp} ++The @code{info methods} command permits the user to examine all defined ++methods within C@t{++} program, or (with the @var{regexp} argument) a ++specific set of methods found in the various C@t{++} classes. Many ++C@t{++} classes provide a large number of methods. Thus, the output ++from the @code{ptype} command can be overwhelming and hard to use. The ++@code{info-methods} command filters the methods, printing only those ++which match the regular-expression @var{regexp}. ++@end ignore ++ ++@cindex opaque data types ++@kindex set opaque-type-resolution ++@item set opaque-type-resolution on ++Tell @value{GDBN} to resolve opaque types. An opaque type is a type ++declared as a pointer to a @code{struct}, @code{class}, or ++@code{union}---for example, @code{struct MyType *}---that is used in one ++source file although the full declaration of @code{struct MyType} is in ++another source file. The default is on. ++ ++A change in the setting of this subcommand will not take effect until ++the next time symbols for a file are loaded. ++ ++@item set opaque-type-resolution off ++Tell @value{GDBN} not to resolve opaque types. In this case, the type ++is printed as follows: ++@smallexample ++@{@} ++@end smallexample ++ ++@kindex show opaque-type-resolution ++@item show opaque-type-resolution ++Show whether opaque types are resolved or not. ++ ++@kindex set print symbol-loading ++@cindex print messages when symbols are loaded ++@item set print symbol-loading ++@itemx set print symbol-loading full ++@itemx set print symbol-loading brief ++@itemx set print symbol-loading off ++The @code{set print symbol-loading} command allows you to control the ++printing of messages when @value{GDBN} loads symbol information. ++By default a message is printed for the executable and one for each ++shared library, and normally this is what you want. However, when ++debugging apps with large numbers of shared libraries these messages ++can be annoying. ++When set to @code{brief} a message is printed for each executable, ++and when @value{GDBN} loads a collection of shared libraries at once ++it will only print one message regardless of the number of shared ++libraries. When set to @code{off} no messages are printed. ++ ++@kindex show print symbol-loading ++@item show print symbol-loading ++Show whether messages will be printed when a @value{GDBN} command ++entered from the keyboard causes symbol information to be loaded. ++ ++@kindex maint print symbols ++@cindex symbol dump ++@kindex maint print psymbols ++@cindex partial symbol dump ++@kindex maint print msymbols ++@cindex minimal symbol dump ++@item maint print symbols @r{[}-pc @var{address}@r{]} @r{[}@var{filename}@r{]} ++@itemx maint print symbols @r{[}-objfile @var{objfile}@r{]} @r{[}-source @var{source}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]} ++@itemx maint print psymbols @r{[}-objfile @var{objfile}@r{]} @r{[}-pc @var{address}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]} ++@itemx maint print psymbols @r{[}-objfile @var{objfile}@r{]} @r{[}-source @var{source}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]} ++@itemx maint print msymbols @r{[}-objfile @var{objfile}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]} ++Write a dump of debugging symbol data into the file @var{filename} or ++the terminal if @var{filename} is unspecified. ++If @code{-objfile @var{objfile}} is specified, only dump symbols for ++that objfile. ++If @code{-pc @var{address}} is specified, only dump symbols for the file ++with code at that address. Note that @var{address} may be a symbol like ++@code{main}. ++If @code{-source @var{source}} is specified, only dump symbols for that ++source file. ++ ++These commands are used to debug the @value{GDBN} symbol-reading code. ++These commands do not modify internal @value{GDBN} state, therefore ++@samp{maint print symbols} will only print symbols for already expanded symbol ++tables. ++You can use the command @code{info sources} to find out which files these are. ++If you use @samp{maint print psymbols} instead, the dump shows information ++about symbols that @value{GDBN} only knows partially---that is, symbols ++defined in files that @value{GDBN} has skimmed, but not yet read completely. ++Finally, @samp{maint print msymbols} just dumps ``minimal symbols'', e.g., ++``ELF symbols''. ++ ++@xref{Files, ,Commands to Specify Files}, for a discussion of how ++@value{GDBN} reads symbols (in the description of @code{symbol-file}). ++ ++@kindex maint info symtabs ++@kindex maint info psymtabs ++@cindex listing @value{GDBN}'s internal symbol tables ++@cindex symbol tables, listing @value{GDBN}'s internal ++@cindex full symbol tables, listing @value{GDBN}'s internal ++@cindex partial symbol tables, listing @value{GDBN}'s internal ++@item maint info symtabs @r{[} @var{regexp} @r{]} ++@itemx maint info psymtabs @r{[} @var{regexp} @r{]} ++ ++List the @code{struct symtab} or @code{struct partial_symtab} ++structures whose names match @var{regexp}. If @var{regexp} is not ++given, list them all. The output includes expressions which you can ++copy into a @value{GDBN} debugging this one to examine a particular ++structure in more detail. For example: ++ ++@smallexample ++(@value{GDBP}) maint info psymtabs dwarf2read ++@{ objfile /home/gnu/build/gdb/gdb ++ ((struct objfile *) 0x82e69d0) ++ @{ psymtab /home/gnu/src/gdb/dwarf2read.c ++ ((struct partial_symtab *) 0x8474b10) ++ readin no ++ fullname (null) ++ text addresses 0x814d3c8 -- 0x8158074 ++ globals (* (struct partial_symbol **) 0x8507a08 @@ 9) ++ statics (* (struct partial_symbol **) 0x40e95b78 @@ 2882) ++ dependencies (none) ++ @} ++@} ++(@value{GDBP}) maint info symtabs ++(@value{GDBP}) ++@end smallexample ++@noindent ++We see that there is one partial symbol table whose filename contains ++the string @samp{dwarf2read}, belonging to the @samp{gdb} executable; ++and we see that @value{GDBN} has not read in any symtabs yet at all. ++If we set a breakpoint on a function, that will cause @value{GDBN} to ++read the symtab for the compilation unit containing that function: ++ ++@smallexample ++(@value{GDBP}) break dwarf2_psymtab_to_symtab ++Breakpoint 1 at 0x814e5da: file /home/gnu/src/gdb/dwarf2read.c, ++line 1574. ++(@value{GDBP}) maint info symtabs ++@{ objfile /home/gnu/build/gdb/gdb ++ ((struct objfile *) 0x82e69d0) ++ @{ symtab /home/gnu/src/gdb/dwarf2read.c ++ ((struct symtab *) 0x86c1f38) ++ dirname (null) ++ fullname (null) ++ blockvector ((struct blockvector *) 0x86c1bd0) (primary) ++ linetable ((struct linetable *) 0x8370fa0) ++ debugformat DWARF 2 ++ @} ++@} ++(@value{GDBP}) ++@end smallexample ++ ++@kindex maint info line-table ++@cindex listing @value{GDBN}'s internal line tables ++@cindex line tables, listing @value{GDBN}'s internal ++@item maint info line-table @r{[} @var{regexp} @r{]} ++ ++List the @code{struct linetable} from all @code{struct symtab} ++instances whose name matches @var{regexp}. If @var{regexp} is not ++given, list the @code{struct linetable} from all @code{struct symtab}. ++ ++@kindex maint set symbol-cache-size ++@cindex symbol cache size ++@item maint set symbol-cache-size @var{size} ++Set the size of the symbol cache to @var{size}. ++The default size is intended to be good enough for debugging ++most applications. This option exists to allow for experimenting ++with different sizes. ++ ++@kindex maint show symbol-cache-size ++@item maint show symbol-cache-size ++Show the size of the symbol cache. ++ ++@kindex maint print symbol-cache ++@cindex symbol cache, printing its contents ++@item maint print symbol-cache ++Print the contents of the symbol cache. ++This is useful when debugging symbol cache issues. ++ ++@kindex maint print symbol-cache-statistics ++@cindex symbol cache, printing usage statistics ++@item maint print symbol-cache-statistics ++Print symbol cache usage statistics. ++This helps determine how well the cache is being utilized. ++ ++@kindex maint flush-symbol-cache ++@cindex symbol cache, flushing ++@item maint flush-symbol-cache ++Flush the contents of the symbol cache, all entries are removed. ++This command is useful when debugging the symbol cache. ++It is also useful when collecting performance data. ++ ++@end table ++ ++@node Altering ++@chapter Altering Execution ++ ++Once you think you have found an error in your program, you might want to ++find out for certain whether correcting the apparent error would lead to ++correct results in the rest of the run. You can find the answer by ++experiment, using the @value{GDBN} features for altering execution of the ++program. ++ ++For example, you can store new values into variables or memory ++locations, give your program a signal, restart it at a different ++address, or even return prematurely from a function. ++ ++@menu ++* Assignment:: Assignment to variables ++* Jumping:: Continuing at a different address ++* Signaling:: Giving your program a signal ++* Returning:: Returning from a function ++* Calling:: Calling your program's functions ++* Patching:: Patching your program ++* Compiling and Injecting Code:: Compiling and injecting code in @value{GDBN} ++@end menu ++ ++@node Assignment ++@section Assignment to Variables ++ ++@cindex assignment ++@cindex setting variables ++To alter the value of a variable, evaluate an assignment expression. ++@xref{Expressions, ,Expressions}. For example, ++ ++@smallexample ++print x=4 ++@end smallexample ++ ++@noindent ++stores the value 4 into the variable @code{x}, and then prints the ++value of the assignment expression (which is 4). ++@xref{Languages, ,Using @value{GDBN} with Different Languages}, for more ++information on operators in supported languages. ++ ++@kindex set variable ++@cindex variables, setting ++If you are not interested in seeing the value of the assignment, use the ++@code{set} command instead of the @code{print} command. @code{set} is ++really the same as @code{print} except that the expression's value is ++not printed and is not put in the value history (@pxref{Value History, ++,Value History}). The expression is evaluated only for its effects. ++ ++If the beginning of the argument string of the @code{set} command ++appears identical to a @code{set} subcommand, use the @code{set ++variable} command instead of just @code{set}. This command is identical ++to @code{set} except for its lack of subcommands. For example, if your ++program has a variable @code{width}, you get an error if you try to set ++a new value with just @samp{set width=13}, because @value{GDBN} has the ++command @code{set width}: ++ ++@smallexample ++(@value{GDBP}) whatis width ++type = double ++(@value{GDBP}) p width ++$4 = 13 ++(@value{GDBP}) set width=47 ++Invalid syntax in expression. ++@end smallexample ++ ++@noindent ++The invalid expression, of course, is @samp{=47}. In ++order to actually set the program's variable @code{width}, use ++ ++@smallexample ++(@value{GDBP}) set var width=47 ++@end smallexample ++ ++Because the @code{set} command has many subcommands that can conflict ++with the names of program variables, it is a good idea to use the ++@code{set variable} command instead of just @code{set}. For example, if ++your program has a variable @code{g}, you run into problems if you try ++to set a new value with just @samp{set g=4}, because @value{GDBN} has ++the command @code{set gnutarget}, abbreviated @code{set g}: ++ ++@smallexample ++@group ++(@value{GDBP}) whatis g ++type = double ++(@value{GDBP}) p g ++$1 = 1 ++(@value{GDBP}) set g=4 ++(@value{GDBP}) p g ++$2 = 1 ++(@value{GDBP}) r ++The program being debugged has been started already. ++Start it from the beginning? (y or n) y ++Starting program: /home/smith/cc_progs/a.out ++"/home/smith/cc_progs/a.out": can't open to read symbols: ++ Invalid bfd target. ++(@value{GDBP}) show g ++The current BFD target is "=4". ++@end group ++@end smallexample ++ ++@noindent ++The program variable @code{g} did not change, and you silently set the ++@code{gnutarget} to an invalid value. In order to set the variable ++@code{g}, use ++ ++@smallexample ++(@value{GDBP}) set var g=4 ++@end smallexample ++ ++@value{GDBN} allows more implicit conversions in assignments than C; you can ++freely store an integer value into a pointer variable or vice versa, ++and you can convert any structure to any other structure that is the ++same length or shorter. ++@comment FIXME: how do structs align/pad in these conversions? ++@comment /doc@cygnus.com 18dec1990 ++ ++To store values into arbitrary places in memory, use the @samp{@{@dots{}@}} ++construct to generate a value of specified type at a specified address ++(@pxref{Expressions, ,Expressions}). For example, @code{@{int@}0x83040} refers ++to memory location @code{0x83040} as an integer (which implies a certain size ++and representation in memory), and ++ ++@smallexample ++set @{int@}0x83040 = 4 ++@end smallexample ++ ++@noindent ++stores the value 4 into that memory location. ++ ++@node Jumping ++@section Continuing at a Different Address ++ ++Ordinarily, when you continue your program, you do so at the place where ++it stopped, with the @code{continue} command. You can instead continue at ++an address of your own choosing, with the following commands: ++ ++@table @code ++@kindex jump ++@kindex j @r{(@code{jump})} ++@item jump @var{location} ++@itemx j @var{location} ++Resume execution at @var{location}. Execution stops again immediately ++if there is a breakpoint there. @xref{Specify Location}, for a description ++of the different forms of @var{location}. It is common ++practice to use the @code{tbreak} command in conjunction with ++@code{jump}. @xref{Set Breaks, ,Setting Breakpoints}. ++ ++The @code{jump} command does not change the current stack frame, or ++the stack pointer, or the contents of any memory location or any ++register other than the program counter. If @var{location} is in ++a different function from the one currently executing, the results may ++be bizarre if the two functions expect different patterns of arguments or ++of local variables. For this reason, the @code{jump} command requests ++confirmation if the specified line is not in the function currently ++executing. However, even bizarre results are predictable if you are ++well acquainted with the machine-language code of your program. ++@end table ++ ++On many systems, you can get much the same effect as the @code{jump} ++command by storing a new value into the register @code{$pc}. The ++difference is that this does not start your program running; it only ++changes the address of where it @emph{will} run when you continue. For ++example, ++ ++@smallexample ++set $pc = 0x485 ++@end smallexample ++ ++@noindent ++makes the next @code{continue} command or stepping command execute at ++address @code{0x485}, rather than at the address where your program stopped. ++@xref{Continuing and Stepping, ,Continuing and Stepping}. ++ ++The most common occasion to use the @code{jump} command is to back ++up---perhaps with more breakpoints set---over a portion of a program ++that has already executed, in order to examine its execution in more ++detail. ++ ++@c @group ++@node Signaling ++@section Giving your Program a Signal ++@cindex deliver a signal to a program ++ ++@table @code ++@kindex signal ++@item signal @var{signal} ++Resume execution where your program is stopped, but immediately give it the ++signal @var{signal}. The @var{signal} can be the name or the number of a ++signal. For example, on many systems @code{signal 2} and @code{signal ++SIGINT} are both ways of sending an interrupt signal. ++ ++Alternatively, if @var{signal} is zero, continue execution without ++giving a signal. This is useful when your program stopped on account of ++a signal and would ordinarily see the signal when resumed with the ++@code{continue} command; @samp{signal 0} causes it to resume without a ++signal. ++ ++@emph{Note:} When resuming a multi-threaded program, @var{signal} is ++delivered to the currently selected thread, not the thread that last ++reported a stop. This includes the situation where a thread was ++stopped due to a signal. So if you want to continue execution ++suppressing the signal that stopped a thread, you should select that ++same thread before issuing the @samp{signal 0} command. If you issue ++the @samp{signal 0} command with another thread as the selected one, ++@value{GDBN} detects that and asks for confirmation. ++ ++Invoking the @code{signal} command is not the same as invoking the ++@code{kill} utility from the shell. Sending a signal with @code{kill} ++causes @value{GDBN} to decide what to do with the signal depending on ++the signal handling tables (@pxref{Signals}). The @code{signal} command ++passes the signal directly to your program. ++ ++@code{signal} does not repeat when you press @key{RET} a second time ++after executing the command. ++ ++@kindex queue-signal ++@item queue-signal @var{signal} ++Queue @var{signal} to be delivered immediately to the current thread ++when execution of the thread resumes. The @var{signal} can be the name or ++the number of a signal. For example, on many systems @code{signal 2} and ++@code{signal SIGINT} are both ways of sending an interrupt signal. ++The handling of the signal must be set to pass the signal to the program, ++otherwise @value{GDBN} will report an error. ++You can control the handling of signals from @value{GDBN} with the ++@code{handle} command (@pxref{Signals}). ++ ++Alternatively, if @var{signal} is zero, any currently queued signal ++for the current thread is discarded and when execution resumes no signal ++will be delivered. This is useful when your program stopped on account ++of a signal and would ordinarily see the signal when resumed with the ++@code{continue} command. ++ ++This command differs from the @code{signal} command in that the signal ++is just queued, execution is not resumed. And @code{queue-signal} cannot ++be used to pass a signal whose handling state has been set to @code{nopass} ++(@pxref{Signals}). ++@end table ++@c @end group ++ ++@xref{stepping into signal handlers}, for information on how stepping ++commands behave when the thread has a signal queued. ++ ++@node Returning ++@section Returning from a Function ++ ++@table @code ++@cindex returning from a function ++@kindex return ++@item return ++@itemx return @var{expression} ++You can cancel execution of a function call with the @code{return} ++command. If you give an ++@var{expression} argument, its value is used as the function's return ++value. ++@end table ++ ++When you use @code{return}, @value{GDBN} discards the selected stack frame ++(and all frames within it). You can think of this as making the ++discarded frame return prematurely. If you wish to specify a value to ++be returned, give that value as the argument to @code{return}. ++ ++This pops the selected stack frame (@pxref{Selection, ,Selecting a ++Frame}), and any other frames inside of it, leaving its caller as the ++innermost remaining frame. That frame becomes selected. The ++specified value is stored in the registers used for returning values ++of functions. ++ ++The @code{return} command does not resume execution; it leaves the ++program stopped in the state that would exist if the function had just ++returned. In contrast, the @code{finish} command (@pxref{Continuing ++and Stepping, ,Continuing and Stepping}) resumes execution until the ++selected stack frame returns naturally. ++ ++@value{GDBN} needs to know how the @var{expression} argument should be set for ++the inferior. The concrete registers assignment depends on the OS ABI and the ++type being returned by the selected stack frame. For example it is common for ++OS ABI to return floating point values in FPU registers while integer values in ++CPU registers. Still some ABIs return even floating point values in CPU ++registers. Larger integer widths (such as @code{long long int}) also have ++specific placement rules. @value{GDBN} already knows the OS ABI from its ++current target so it needs to find out also the type being returned to make the ++assignment into the right register(s). ++ ++Normally, the selected stack frame has debug info. @value{GDBN} will always ++use the debug info instead of the implicit type of @var{expression} when the ++debug info is available. For example, if you type @kbd{return -1}, and the ++function in the current stack frame is declared to return a @code{long long ++int}, @value{GDBN} transparently converts the implicit @code{int} value of -1 ++into a @code{long long int}: ++ ++@smallexample ++Breakpoint 1, func () at gdb.base/return-nodebug.c:29 ++29 return 31; ++(@value{GDBP}) return -1 ++Make func return now? (y or n) y ++#0 0x004004f6 in main () at gdb.base/return-nodebug.c:43 ++43 printf ("result=%lld\n", func ()); ++(@value{GDBP}) ++@end smallexample ++ ++However, if the selected stack frame does not have a debug info, e.g., if the ++function was compiled without debug info, @value{GDBN} has to find out the type ++to return from user. Specifying a different type by mistake may set the value ++in different inferior registers than the caller code expects. For example, ++typing @kbd{return -1} with its implicit type @code{int} would set only a part ++of a @code{long long int} result for a debug info less function (on 32-bit ++architectures). Therefore the user is required to specify the return type by ++an appropriate cast explicitly: ++ ++@smallexample ++Breakpoint 2, 0x0040050b in func () ++(@value{GDBP}) return -1 ++Return value type not available for selected stack frame. ++Please use an explicit cast of the value to return. ++(@value{GDBP}) return (long long int) -1 ++Make selected stack frame return now? (y or n) y ++#0 0x00400526 in main () ++(@value{GDBP}) ++@end smallexample ++ ++@node Calling ++@section Calling Program Functions ++ ++@table @code ++@cindex calling functions ++@cindex inferior functions, calling ++@item print @var{expr} ++Evaluate the expression @var{expr} and display the resulting value. ++The expression may include calls to functions in the program being ++debugged. ++ ++@kindex call ++@item call @var{expr} ++Evaluate the expression @var{expr} without displaying @code{void} ++returned values. ++ ++You can use this variant of the @code{print} command if you want to ++execute a function from your program that does not return anything ++(a.k.a.@: @dfn{a void function}), but without cluttering the output ++with @code{void} returned values that @value{GDBN} will otherwise ++print. If the result is not void, it is printed and saved in the ++value history. ++@end table ++ ++It is possible for the function you call via the @code{print} or ++@code{call} command to generate a signal (e.g., if there's a bug in ++the function, or if you passed it incorrect arguments). What happens ++in that case is controlled by the @code{set unwindonsignal} command. ++ ++Similarly, with a C@t{++} program it is possible for the function you ++call via the @code{print} or @code{call} command to generate an ++exception that is not handled due to the constraints of the dummy ++frame. In this case, any exception that is raised in the frame, but has ++an out-of-frame exception handler will not be found. GDB builds a ++dummy-frame for the inferior function call, and the unwinder cannot ++seek for exception handlers outside of this dummy-frame. What happens ++in that case is controlled by the ++@code{set unwind-on-terminating-exception} command. ++ ++@table @code ++@item set unwindonsignal ++@kindex set unwindonsignal ++@cindex unwind stack in called functions ++@cindex call dummy stack unwinding ++Set unwinding of the stack if a signal is received while in a function ++that @value{GDBN} called in the program being debugged. If set to on, ++@value{GDBN} unwinds the stack it created for the call and restores ++the context to what it was before the call. If set to off (the ++default), @value{GDBN} stops in the frame where the signal was ++received. ++ ++@item show unwindonsignal ++@kindex show unwindonsignal ++Show the current setting of stack unwinding in the functions called by ++@value{GDBN}. ++ ++@item set unwind-on-terminating-exception ++@kindex set unwind-on-terminating-exception ++@cindex unwind stack in called functions with unhandled exceptions ++@cindex call dummy stack unwinding on unhandled exception. ++Set unwinding of the stack if a C@t{++} exception is raised, but left ++unhandled while in a function that @value{GDBN} called in the program being ++debugged. If set to on (the default), @value{GDBN} unwinds the stack ++it created for the call and restores the context to what it was before ++the call. If set to off, @value{GDBN} the exception is delivered to ++the default C@t{++} exception handler and the inferior terminated. ++ ++@item show unwind-on-terminating-exception ++@kindex show unwind-on-terminating-exception ++Show the current setting of stack unwinding in the functions called by ++@value{GDBN}. ++ ++@item set may-call-functions ++@kindex set may-call-functions ++@cindex disabling calling functions in the program ++@cindex calling functions in the program, disabling ++Set permission to call functions in the program. ++This controls whether @value{GDBN} will attempt to call functions in ++the program, such as with expressions in the @code{print} command. It ++defaults to @code{on}. ++ ++To call a function in the program, @value{GDBN} has to temporarily ++modify the state of the inferior. This has potentially undesired side ++effects. Also, having @value{GDBN} call nested functions is likely to ++be erroneous and may even crash the program being debugged. You can ++avoid such hazards by forbidding @value{GDBN} from calling functions ++in the program being debugged. If calling functions in the program ++is forbidden, GDB will throw an error when a command (such as printing ++an expression) starts a function call in the program. ++ ++@item show may-call-functions ++@kindex show may-call-functions ++Show permission to call functions in the program. ++ ++@end table ++ ++@subsection Calling functions with no debug info ++ ++@cindex no debug info functions ++Sometimes, a function you wish to call is missing debug information. ++In such case, @value{GDBN} does not know the type of the function, ++including the types of the function's parameters. To avoid calling ++the inferior function incorrectly, which could result in the called ++function functioning erroneously and even crash, @value{GDBN} refuses ++to call the function unless you tell it the type of the function. ++ ++For prototyped (i.e.@: ANSI/ISO style) functions, there are two ways ++to do that. The simplest is to cast the call to the function's ++declared return type. For example: ++ ++@smallexample ++(@value{GDBP}) p getenv ("PATH") ++'getenv' has unknown return type; cast the call to its declared return type ++(@value{GDBP}) p (char *) getenv ("PATH") ++$1 = 0x7fffffffe7ba "/usr/local/bin:/"... ++@end smallexample ++ ++Casting the return type of a no-debug function is equivalent to ++casting the function to a pointer to a prototyped function that has a ++prototype that matches the types of the passed-in arguments, and ++calling that. I.e., the call above is equivalent to: ++ ++@smallexample ++(@value{GDBP}) p ((char * (*) (const char *)) getenv) ("PATH") ++@end smallexample ++ ++@noindent ++and given this prototyped C or C++ function with float parameters: ++ ++@smallexample ++float multiply (float v1, float v2) @{ return v1 * v2; @} ++@end smallexample ++ ++@noindent ++these calls are equivalent: ++ ++@smallexample ++(@value{GDBP}) p (float) multiply (2.0f, 3.0f) ++(@value{GDBP}) p ((float (*) (float, float)) multiply) (2.0f, 3.0f) ++@end smallexample ++ ++If the function you wish to call is declared as unprototyped (i.e.@: ++old K&R style), you must use the cast-to-function-pointer syntax, so ++that @value{GDBN} knows that it needs to apply default argument ++promotions (promote float arguments to double). @xref{ABI, float ++promotion}. For example, given this unprototyped C function with ++float parameters, and no debug info: ++ ++@smallexample ++float ++multiply_noproto (v1, v2) ++ float v1, v2; ++@{ ++ return v1 * v2; ++@} ++@end smallexample ++ ++@noindent ++you call it like this: ++ ++@smallexample ++ (@value{GDBP}) p ((float (*) ()) multiply_noproto) (2.0f, 3.0f) ++@end smallexample ++ ++@node Patching ++@section Patching Programs ++ ++@cindex patching binaries ++@cindex writing into executables ++@cindex writing into corefiles ++ ++By default, @value{GDBN} opens the file containing your program's ++executable code (or the corefile) read-only. This prevents accidental ++alterations to machine code; but it also prevents you from intentionally ++patching your program's binary. ++ ++If you'd like to be able to patch the binary, you can specify that ++explicitly with the @code{set write} command. For example, you might ++want to turn on internal debugging flags, or even to make emergency ++repairs. ++ ++@table @code ++@kindex set write ++@item set write on ++@itemx set write off ++If you specify @samp{set write on}, @value{GDBN} opens executable and ++core files for both reading and writing; if you specify @kbd{set write ++off} (the default), @value{GDBN} opens them read-only. ++ ++If you have already loaded a file, you must load it again (using the ++@code{exec-file} or @code{core-file} command) after changing @code{set ++write}, for your new setting to take effect. ++ ++@item show write ++@kindex show write ++Display whether executable files and core files are opened for writing ++as well as reading. ++@end table ++ ++@node Compiling and Injecting Code ++@section Compiling and injecting code in @value{GDBN} ++@cindex injecting code ++@cindex writing into executables ++@cindex compiling code ++ ++@value{GDBN} supports on-demand compilation and code injection into ++programs running under @value{GDBN}. GCC 5.0 or higher built with ++@file{libcc1.so} must be installed for this functionality to be enabled. ++This functionality is implemented with the following commands. ++ ++@table @code ++@kindex compile code ++@item compile code @var{source-code} ++@itemx compile code -raw @var{--} @var{source-code} ++Compile @var{source-code} with the compiler language found as the current ++language in @value{GDBN} (@pxref{Languages}). If compilation and ++injection is not supported with the current language specified in ++@value{GDBN}, or the compiler does not support this feature, an error ++message will be printed. If @var{source-code} compiles and links ++successfully, @value{GDBN} will load the object-code emitted, ++and execute it within the context of the currently selected inferior. ++It is important to note that the compiled code is executed immediately. ++After execution, the compiled code is removed from @value{GDBN} and any ++new types or variables you have defined will be deleted. ++ ++The command allows you to specify @var{source-code} in two ways. ++The simplest method is to provide a single line of code to the command. ++E.g.: ++ ++@smallexample ++compile code printf ("hello world\n"); ++@end smallexample ++ ++If you specify options on the command line as well as source code, they ++may conflict. The @samp{--} delimiter can be used to separate options ++from actual source code. E.g.: ++ ++@smallexample ++compile code -r -- printf ("hello world\n"); ++@end smallexample ++ ++Alternatively you can enter source code as multiple lines of text. To ++enter this mode, invoke the @samp{compile code} command without any text ++following the command. This will start the multiple-line editor and ++allow you to type as many lines of source code as required. When you ++have completed typing, enter @samp{end} on its own line to exit the ++editor. ++ ++@smallexample ++compile code ++>printf ("hello\n"); ++>printf ("world\n"); ++>end ++@end smallexample ++ ++Specifying @samp{-raw}, prohibits @value{GDBN} from wrapping the ++provided @var{source-code} in a callable scope. In this case, you must ++specify the entry point of the code by defining a function named ++@code{_gdb_expr_}. The @samp{-raw} code cannot access variables of the ++inferior. Using @samp{-raw} option may be needed for example when ++@var{source-code} requires @samp{#include} lines which may conflict with ++inferior symbols otherwise. ++ ++@kindex compile file ++@item compile file @var{filename} ++@itemx compile file -raw @var{filename} ++Like @code{compile code}, but take the source code from @var{filename}. ++ ++@smallexample ++compile file /home/user/example.c ++@end smallexample ++@end table ++ ++@table @code ++@item compile print [[@var{options}] --] @var{expr} ++@itemx compile print [[@var{options}] --] /@var{f} @var{expr} ++Compile and execute @var{expr} with the compiler language found as the ++current language in @value{GDBN} (@pxref{Languages}). By default the ++value of @var{expr} is printed in a format appropriate to its data type; ++you can choose a different format by specifying @samp{/@var{f}}, where ++@var{f} is a letter specifying the format; see @ref{Output Formats,,Output ++Formats}. The @code{compile print} command accepts the same options ++as the @code{print} command; see @ref{print options}. ++ ++@item compile print [[@var{options}] --] ++@itemx compile print [[@var{options}] --] /@var{f} ++@cindex reprint the last value ++Alternatively you can enter the expression (source code producing it) as ++multiple lines of text. To enter this mode, invoke the @samp{compile print} ++command without any text following the command. This will start the ++multiple-line editor. ++@end table ++ ++@noindent ++The process of compiling and injecting the code can be inspected using: ++ ++@table @code ++@anchor{set debug compile} ++@item set debug compile ++@cindex compile command debugging info ++Turns on or off display of @value{GDBN} process of compiling and ++injecting the code. The default is off. ++ ++@item show debug compile ++Displays the current state of displaying @value{GDBN} process of ++compiling and injecting the code. ++ ++@anchor{set debug compile-cplus-types} ++@item set debug compile-cplus-types ++@cindex compile C@t{++} type conversion ++Turns on or off the display of C@t{++} type conversion debugging information. ++The default is off. ++ ++@item show debug compile-cplus-types ++Displays the current state of displaying debugging information for ++C@t{++} type conversion. ++@end table ++ ++@subsection Compilation options for the @code{compile} command ++ ++@value{GDBN} needs to specify the right compilation options for the code ++to be injected, in part to make its ABI compatible with the inferior ++and in part to make the injected code compatible with @value{GDBN}'s ++injecting process. ++ ++@noindent ++The options used, in increasing precedence: ++ ++@table @asis ++@item target architecture and OS options (@code{gdbarch}) ++These options depend on target processor type and target operating ++system, usually they specify at least 32-bit (@code{-m32}) or 64-bit ++(@code{-m64}) compilation option. ++ ++@item compilation options recorded in the target ++@value{NGCC} (since version 4.7) stores the options used for compilation ++into @code{DW_AT_producer} part of DWARF debugging information according ++to the @value{NGCC} option @code{-grecord-gcc-switches}. One has to ++explicitly specify @code{-g} during inferior compilation otherwise ++@value{NGCC} produces no DWARF. This feature is only relevant for ++platforms where @code{-g} produces DWARF by default, otherwise one may ++try to enforce DWARF by using @code{-gdwarf-4}. ++ ++@item compilation options set by @code{set compile-args} ++@end table ++ ++@noindent ++You can override compilation options using the following command: ++ ++@table @code ++@item set compile-args ++@cindex compile command options override ++Set compilation options used for compiling and injecting code with the ++@code{compile} commands. These options override any conflicting ones ++from the target architecture and/or options stored during inferior ++compilation. ++ ++@item show compile-args ++Displays the current state of compilation options override. ++This does not show all the options actually used during compilation, ++use @ref{set debug compile} for that. ++@end table ++ ++@subsection Caveats when using the @code{compile} command ++ ++There are a few caveats to keep in mind when using the @code{compile} ++command. As the caveats are different per language, the table below ++highlights specific issues on a per language basis. ++ ++@table @asis ++@item C code examples and caveats ++When the language in @value{GDBN} is set to @samp{C}, the compiler will ++attempt to compile the source code with a @samp{C} compiler. The source ++code provided to the @code{compile} command will have much the same ++access to variables and types as it normally would if it were part of ++the program currently being debugged in @value{GDBN}. ++ ++Below is a sample program that forms the basis of the examples that ++follow. This program has been compiled and loaded into @value{GDBN}, ++much like any other normal debugging session. ++ ++@smallexample ++void function1 (void) ++@{ ++ int i = 42; ++ printf ("function 1\n"); ++@} ++ ++void function2 (void) ++@{ ++ int j = 12; ++ function1 (); ++@} ++ ++int main(void) ++@{ ++ int k = 6; ++ int *p; ++ function2 (); ++ return 0; ++@} ++@end smallexample ++ ++For the purposes of the examples in this section, the program above has ++been compiled, loaded into @value{GDBN}, stopped at the function ++@code{main}, and @value{GDBN} is awaiting input from the user. ++ ++To access variables and types for any program in @value{GDBN}, the ++program must be compiled and packaged with debug information. The ++@code{compile} command is not an exception to this rule. Without debug ++information, you can still use the @code{compile} command, but you will ++be very limited in what variables and types you can access. ++ ++So with that in mind, the example above has been compiled with debug ++information enabled. The @code{compile} command will have access to ++all variables and types (except those that may have been optimized ++out). Currently, as @value{GDBN} has stopped the program in the ++@code{main} function, the @code{compile} command would have access to ++the variable @code{k}. You could invoke the @code{compile} command ++and type some source code to set the value of @code{k}. You can also ++read it, or do anything with that variable you would normally do in ++@code{C}. Be aware that changes to inferior variables in the ++@code{compile} command are persistent. In the following example: ++ ++@smallexample ++compile code k = 3; ++@end smallexample ++ ++@noindent ++the variable @code{k} is now 3. It will retain that value until ++something else in the example program changes it, or another ++@code{compile} command changes it. ++ ++Normal scope and access rules apply to source code compiled and ++injected by the @code{compile} command. In the example, the variables ++@code{j} and @code{k} are not accessible yet, because the program is ++currently stopped in the @code{main} function, where these variables ++are not in scope. Therefore, the following command ++ ++@smallexample ++compile code j = 3; ++@end smallexample ++ ++@noindent ++will result in a compilation error message. ++ ++Once the program is continued, execution will bring these variables in ++scope, and they will become accessible; then the code you specify via ++the @code{compile} command will be able to access them. ++ ++You can create variables and types with the @code{compile} command as ++part of your source code. Variables and types that are created as part ++of the @code{compile} command are not visible to the rest of the program for ++the duration of its run. This example is valid: ++ ++@smallexample ++compile code int ff = 5; printf ("ff is %d\n", ff); ++@end smallexample ++ ++However, if you were to type the following into @value{GDBN} after that ++command has completed: ++ ++@smallexample ++compile code printf ("ff is %d\n'', ff); ++@end smallexample ++ ++@noindent ++a compiler error would be raised as the variable @code{ff} no longer ++exists. Object code generated and injected by the @code{compile} ++command is removed when its execution ends. Caution is advised ++when assigning to program variables values of variables created by the ++code submitted to the @code{compile} command. This example is valid: ++ ++@smallexample ++compile code int ff = 5; k = ff; ++@end smallexample ++ ++The value of the variable @code{ff} is assigned to @code{k}. The variable ++@code{k} does not require the existence of @code{ff} to maintain the value ++it has been assigned. However, pointers require particular care in ++assignment. If the source code compiled with the @code{compile} command ++changed the address of a pointer in the example program, perhaps to a ++variable created in the @code{compile} command, that pointer would point ++to an invalid location when the command exits. The following example ++would likely cause issues with your debugged program: ++ ++@smallexample ++compile code int ff = 5; p = &ff; ++@end smallexample ++ ++In this example, @code{p} would point to @code{ff} when the ++@code{compile} command is executing the source code provided to it. ++However, as variables in the (example) program persist with their ++assigned values, the variable @code{p} would point to an invalid ++location when the command exists. A general rule should be followed ++in that you should either assign @code{NULL} to any assigned pointers, ++or restore a valid location to the pointer before the command exits. ++ ++Similar caution must be exercised with any structs, unions, and typedefs ++defined in @code{compile} command. Types defined in the @code{compile} ++command will no longer be available in the next @code{compile} command. ++Therefore, if you cast a variable to a type defined in the ++@code{compile} command, care must be taken to ensure that any future ++need to resolve the type can be achieved. ++ ++@smallexample ++(gdb) compile code static struct a @{ int a; @} v = @{ 42 @}; argv = &v; ++(gdb) compile code printf ("%d\n", ((struct a *) argv)->a); ++gdb command line:1:36: error: dereferencing pointer to incomplete type ‘struct a’ ++Compilation failed. ++(gdb) compile code struct a @{ int a; @}; printf ("%d\n", ((struct a *) argv)->a); ++42 ++@end smallexample ++ ++Variables that have been optimized away by the compiler are not ++accessible to the code submitted to the @code{compile} command. ++Access to those variables will generate a compiler error which @value{GDBN} ++will print to the console. ++@end table ++ ++@subsection Compiler search for the @code{compile} command ++ ++@value{GDBN} needs to find @value{NGCC} for the inferior being debugged ++which may not be obvious for remote targets of different architecture ++than where @value{GDBN} is running. Environment variable @code{PATH} on ++@value{GDBN} host is searched for @value{NGCC} binary matching the ++target architecture and operating system. This search can be overriden ++by @code{set compile-gcc} @value{GDBN} command below. @code{PATH} is ++taken from shell that executed @value{GDBN}, it is not the value set by ++@value{GDBN} command @code{set environment}). @xref{Environment}. ++ ++ ++Specifically @code{PATH} is searched for binaries matching regular expression ++@code{@var{arch}(-[^-]*)?-@var{os}-gcc} according to the inferior target being ++debugged. @var{arch} is processor name --- multiarch is supported, so for ++example both @code{i386} and @code{x86_64} targets look for pattern ++@code{(x86_64|i.86)} and both @code{s390} and @code{s390x} targets look ++for pattern @code{s390x?}. @var{os} is currently supported only for ++pattern @code{linux(-gnu)?}. ++ ++On Posix hosts the compiler driver @value{GDBN} needs to find also ++shared library @file{libcc1.so} from the compiler. It is searched in ++default shared library search path (overridable with usual environment ++variable @code{LD_LIBRARY_PATH}), unrelated to @code{PATH} or @code{set ++compile-gcc} settings. Contrary to it @file{libcc1plugin.so} is found ++according to the installation of the found compiler --- as possibly ++specified by the @code{set compile-gcc} command. ++ ++@table @code ++@item set compile-gcc ++@cindex compile command driver filename override ++Set compilation command used for compiling and injecting code with the ++@code{compile} commands. If this option is not set (it is set to ++an empty string), the search described above will occur --- that is the ++default. ++ ++@item show compile-gcc ++Displays the current compile command @value{NGCC} driver filename. ++If set, it is the main command @command{gcc}, found usually for example ++under name @file{x86_64-linux-gnu-gcc}. ++@end table ++ ++@node GDB Files ++@chapter @value{GDBN} Files ++ ++@value{GDBN} needs to know the file name of the program to be debugged, ++both in order to read its symbol table and in order to start your ++program. To debug a core dump of a previous run, you must also tell ++@value{GDBN} the name of the core dump file. ++ ++@menu ++* Files:: Commands to specify files ++* File Caching:: Information about @value{GDBN}'s file caching ++* Separate Debug Files:: Debugging information in separate files ++* MiniDebugInfo:: Debugging information in a special section ++* Index Files:: Index files speed up GDB ++* Symbol Errors:: Errors reading symbol files ++* Data Files:: GDB data files ++@end menu ++ ++@node Files ++@section Commands to Specify Files ++ ++@cindex symbol table ++@cindex core dump file ++ ++You may want to specify executable and core dump file names. The usual ++way to do this is at start-up time, using the arguments to ++@value{GDBN}'s start-up commands (@pxref{Invocation, , Getting In and ++Out of @value{GDBN}}). ++ ++Occasionally it is necessary to change to a different file during a ++@value{GDBN} session. Or you may run @value{GDBN} and forget to ++specify a file you want to use. Or you are debugging a remote target ++via @code{gdbserver} (@pxref{Server, file, Using the @code{gdbserver} ++Program}). In these situations the @value{GDBN} commands to specify ++new files are useful. ++ ++@table @code ++@cindex executable file ++@kindex file ++@item file @var{filename} ++Use @var{filename} as the program to be debugged. It is read for its ++symbols and for the contents of pure memory. It is also the program ++executed when you use the @code{run} command. If you do not specify a ++directory and the file is not found in the @value{GDBN} working directory, ++@value{GDBN} uses the environment variable @code{PATH} as a list of ++directories to search, just as the shell does when looking for a program ++to run. You can change the value of this variable, for both @value{GDBN} ++and your program, using the @code{path} command. ++ ++@cindex unlinked object files ++@cindex patching object files ++You can load unlinked object @file{.o} files into @value{GDBN} using ++the @code{file} command. You will not be able to ``run'' an object ++file, but you can disassemble functions and inspect variables. Also, ++if the underlying BFD functionality supports it, you could use ++@kbd{gdb -write} to patch object files using this technique. Note ++that @value{GDBN} can neither interpret nor modify relocations in this ++case, so branches and some initialized variables will appear to go to ++the wrong place. But this feature is still handy from time to time. ++ ++@item file ++@code{file} with no argument makes @value{GDBN} discard any information it ++has on both executable file and the symbol table. ++ ++@kindex exec-file ++@item exec-file @r{[} @var{filename} @r{]} ++Specify that the program to be run (but not the symbol table) is found ++in @var{filename}. @value{GDBN} searches the environment variable @code{PATH} ++if necessary to locate your program. Omitting @var{filename} means to ++discard information on the executable file. ++ ++@kindex symbol-file ++@item symbol-file @r{[} @var{filename} @r{[} -o @var{offset} @r{]]} ++Read symbol table information from file @var{filename}. @code{PATH} is ++searched when necessary. Use the @code{file} command to get both symbol ++table and program to run from the same file. ++ ++If an optional @var{offset} is specified, it is added to the start ++address of each section in the symbol file. This is useful if the ++program is relocated at runtime, such as the Linux kernel with kASLR ++enabled. ++ ++@code{symbol-file} with no argument clears out @value{GDBN} information on your ++program's symbol table. ++ ++The @code{symbol-file} command causes @value{GDBN} to forget the contents of ++some breakpoints and auto-display expressions. This is because they may ++contain pointers to the internal data recording symbols and data types, ++which are part of the old symbol table data being discarded inside ++@value{GDBN}. ++ ++@code{symbol-file} does not repeat if you press @key{RET} again after ++executing it once. ++ ++When @value{GDBN} is configured for a particular environment, it ++understands debugging information in whatever format is the standard ++generated for that environment; you may use either a @sc{gnu} compiler, or ++other compilers that adhere to the local conventions. ++Best results are usually obtained from @sc{gnu} compilers; for example, ++using @code{@value{NGCC}} you can generate debugging information for ++optimized code. ++ ++For most kinds of object files, with the exception of old SVR3 systems ++using COFF, the @code{symbol-file} command does not normally read the ++symbol table in full right away. Instead, it scans the symbol table ++quickly to find which source files and which symbols are present. The ++details are read later, one source file at a time, as they are needed. ++ ++The purpose of this two-stage reading strategy is to make @value{GDBN} ++start up faster. For the most part, it is invisible except for ++occasional pauses while the symbol table details for a particular source ++file are being read. (The @code{set verbose} command can turn these ++pauses into messages if desired. @xref{Messages/Warnings, ,Optional ++Warnings and Messages}.) ++ ++We have not implemented the two-stage strategy for COFF yet. When the ++symbol table is stored in COFF format, @code{symbol-file} reads the ++symbol table data in full right away. Note that ``stabs-in-COFF'' ++still does the two-stage strategy, since the debug info is actually ++in stabs format. ++ ++@kindex readnow ++@cindex reading symbols immediately ++@cindex symbols, reading immediately ++@item symbol-file @r{[} -readnow @r{]} @var{filename} ++@itemx file @r{[} -readnow @r{]} @var{filename} ++You can override the @value{GDBN} two-stage strategy for reading symbol ++tables by using the @samp{-readnow} option with any of the commands that ++load symbol table information, if you want to be sure @value{GDBN} has the ++entire symbol table available. ++ ++@cindex @code{-readnever}, option for symbol-file command ++@cindex never read symbols ++@cindex symbols, never read ++@item symbol-file @r{[} -readnever @r{]} @var{filename} ++@itemx file @r{[} -readnever @r{]} @var{filename} ++You can instruct @value{GDBN} to never read the symbolic information ++contained in @var{filename} by using the @samp{-readnever} option. ++@xref{--readnever}. ++ ++@c FIXME: for now no mention of directories, since this seems to be in ++@c flux. 13mar1992 status is that in theory GDB would look either in ++@c current dir or in same dir as myprog; but issues like competing ++@c GDB's, or clutter in system dirs, mean that in practice right now ++@c only current dir is used. FFish says maybe a special GDB hierarchy ++@c (eg rooted in val of env var GDBSYMS) could exist for mappable symbol ++@c files. ++ ++@kindex core-file ++@item core-file @r{[}@var{filename}@r{]} ++@itemx core ++Specify the whereabouts of a core dump file to be used as the ``contents ++of memory''. Traditionally, core files contain only some parts of the ++address space of the process that generated them; @value{GDBN} can access the ++executable file itself for other parts. ++ ++@code{core-file} with no argument specifies that no core file is ++to be used. ++ ++Note that the core file is ignored when your program is actually running ++under @value{GDBN}. So, if you have been running your program and you ++wish to debug a core file instead, you must kill the subprocess in which ++the program is running. To do this, use the @code{kill} command ++(@pxref{Kill Process, ,Killing the Child Process}). ++ ++@kindex add-symbol-file ++@cindex dynamic linking ++@item add-symbol-file @var{filename} @r{[} -readnow @r{|} -readnever @r{]} @r{[} -o @var{offset} @r{]} @r{[} @var{textaddress} @r{]} @r{[} -s @var{section} @var{address} @dots{} @r{]} ++The @code{add-symbol-file} command reads additional symbol table ++information from the file @var{filename}. You would use this command ++when @var{filename} has been dynamically loaded (by some other means) ++into the program that is running. The @var{textaddress} parameter gives ++the memory address at which the file's text section has been loaded. ++You can additionally specify the base address of other sections using ++an arbitrary number of @samp{-s @var{section} @var{address}} pairs. ++If a section is omitted, @value{GDBN} will use its default addresses ++as found in @var{filename}. Any @var{address} or @var{textaddress} ++can be given as an expression. ++ ++If an optional @var{offset} is specified, it is added to the start ++address of each section, except those for which the address was ++specified explicitly. ++ ++The symbol table of the file @var{filename} is added to the symbol table ++originally read with the @code{symbol-file} command. You can use the ++@code{add-symbol-file} command any number of times; the new symbol data ++thus read is kept in addition to the old. ++ ++Changes can be reverted using the command @code{remove-symbol-file}. ++ ++@cindex relocatable object files, reading symbols from ++@cindex object files, relocatable, reading symbols from ++@cindex reading symbols from relocatable object files ++@cindex symbols, reading from relocatable object files ++@cindex @file{.o} files, reading symbols from ++Although @var{filename} is typically a shared library file, an ++executable file, or some other object file which has been fully ++relocated for loading into a process, you can also load symbolic ++information from relocatable @file{.o} files, as long as: ++ ++@itemize @bullet ++@item ++the file's symbolic information refers only to linker symbols defined in ++that file, not to symbols defined by other object files, ++@item ++every section the file's symbolic information refers to has actually ++been loaded into the inferior, as it appears in the file, and ++@item ++you can determine the address at which every section was loaded, and ++provide these to the @code{add-symbol-file} command. ++@end itemize ++ ++@noindent ++Some embedded operating systems, like Sun Chorus and VxWorks, can load ++relocatable files into an already running program; such systems ++typically make the requirements above easy to meet. However, it's ++important to recognize that many native systems use complex link ++procedures (@code{.linkonce} section factoring and C@t{++} constructor table ++assembly, for example) that make the requirements difficult to meet. In ++general, one cannot assume that using @code{add-symbol-file} to read a ++relocatable object file's symbolic information will have the same effect ++as linking the relocatable object file into the program in the normal ++way. ++ ++@code{add-symbol-file} does not repeat if you press @key{RET} after using it. ++ ++@kindex remove-symbol-file ++@item remove-symbol-file @var{filename} ++@item remove-symbol-file -a @var{address} ++Remove a symbol file added via the @code{add-symbol-file} command. The ++file to remove can be identified by its @var{filename} or by an @var{address} ++that lies within the boundaries of this symbol file in memory. Example: ++ ++@smallexample ++(gdb) add-symbol-file /home/user/gdb/mylib.so 0x7ffff7ff9480 ++add symbol table from file "/home/user/gdb/mylib.so" at ++ .text_addr = 0x7ffff7ff9480 ++(y or n) y ++Reading symbols from /home/user/gdb/mylib.so... ++(gdb) remove-symbol-file -a 0x7ffff7ff9480 ++Remove symbol table from file "/home/user/gdb/mylib.so"? (y or n) y ++(gdb) ++@end smallexample ++ ++ ++@code{remove-symbol-file} does not repeat if you press @key{RET} after using it. ++ ++@kindex add-symbol-file-from-memory ++@cindex @code{syscall DSO} ++@cindex load symbols from memory ++@item add-symbol-file-from-memory @var{address} ++Load symbols from the given @var{address} in a dynamically loaded ++object file whose image is mapped directly into the inferior's memory. ++For example, the Linux kernel maps a @code{syscall DSO} into each ++process's address space; this DSO provides kernel-specific code for ++some system calls. The argument can be any expression whose ++evaluation yields the address of the file's shared object file header. ++For this command to work, you must have used @code{symbol-file} or ++@code{exec-file} commands in advance. ++ ++@kindex section ++@item section @var{section} @var{addr} ++The @code{section} command changes the base address of the named ++@var{section} of the exec file to @var{addr}. This can be used if the ++exec file does not contain section addresses, (such as in the ++@code{a.out} format), or when the addresses specified in the file ++itself are wrong. Each section must be changed separately. The ++@code{info files} command, described below, lists all the sections and ++their addresses. ++ ++@kindex info files ++@kindex info target ++@item info files ++@itemx info target ++@code{info files} and @code{info target} are synonymous; both print the ++current target (@pxref{Targets, ,Specifying a Debugging Target}), ++including the names of the executable and core dump files currently in ++use by @value{GDBN}, and the files from which symbols were loaded. The ++command @code{help target} lists all possible targets rather than ++current ones. ++ ++@kindex maint info sections ++@item maint info sections ++Another command that can give you extra information about program sections ++is @code{maint info sections}. In addition to the section information ++displayed by @code{info files}, this command displays the flags and file ++offset of each section in the executable and core dump files. In addition, ++@code{maint info sections} provides the following command options (which ++may be arbitrarily combined): ++ ++@table @code ++@item ALLOBJ ++Display sections for all loaded object files, including shared libraries. ++@item @var{sections} ++Display info only for named @var{sections}. ++@item @var{section-flags} ++Display info only for sections for which @var{section-flags} are true. ++The section flags that @value{GDBN} currently knows about are: ++@table @code ++@item ALLOC ++Section will have space allocated in the process when loaded. ++Set for all sections except those containing debug information. ++@item LOAD ++Section will be loaded from the file into the child process memory. ++Set for pre-initialized code and data, clear for @code{.bss} sections. ++@item RELOC ++Section needs to be relocated before loading. ++@item READONLY ++Section cannot be modified by the child process. ++@item CODE ++Section contains executable code only. ++@item DATA ++Section contains data only (no executable code). ++@item ROM ++Section will reside in ROM. ++@item CONSTRUCTOR ++Section contains data for constructor/destructor lists. ++@item HAS_CONTENTS ++Section is not empty. ++@item NEVER_LOAD ++An instruction to the linker to not output the section. ++@item COFF_SHARED_LIBRARY ++A notification to the linker that the section contains ++COFF shared library information. ++@item IS_COMMON ++Section contains common symbols. ++@end table ++@end table ++@kindex set trust-readonly-sections ++@cindex read-only sections ++@item set trust-readonly-sections on ++Tell @value{GDBN} that readonly sections in your object file ++really are read-only (i.e.@: that their contents will not change). ++In that case, @value{GDBN} can fetch values from these sections ++out of the object file, rather than from the target program. ++For some targets (notably embedded ones), this can be a significant ++enhancement to debugging performance. ++ ++The default is off. ++ ++@item set trust-readonly-sections off ++Tell @value{GDBN} not to trust readonly sections. This means that ++the contents of the section might change while the program is running, ++and must therefore be fetched from the target when needed. ++ ++@item show trust-readonly-sections ++Show the current setting of trusting readonly sections. ++@end table ++ ++All file-specifying commands allow both absolute and relative file names ++as arguments. @value{GDBN} always converts the file name to an absolute file ++name and remembers it that way. ++ ++@cindex shared libraries ++@anchor{Shared Libraries} ++@value{GDBN} supports @sc{gnu}/Linux, MS-Windows, SunOS, ++Darwin/Mach-O, SVr4, IBM RS/6000 AIX, QNX Neutrino, FDPIC (FR-V), and ++DSBT (TIC6X) shared libraries. ++ ++On MS-Windows @value{GDBN} must be linked with the Expat library to support ++shared libraries. @xref{Expat}. ++ ++@value{GDBN} automatically loads symbol definitions from shared libraries ++when you use the @code{run} command, or when you examine a core file. ++(Before you issue the @code{run} command, @value{GDBN} does not understand ++references to a function in a shared library, however---unless you are ++debugging a core file). ++ ++@c FIXME: some @value{GDBN} release may permit some refs to undef ++@c FIXME...symbols---eg in a break cmd---assuming they are from a shared ++@c FIXME...lib; check this from time to time when updating manual ++ ++There are times, however, when you may wish to not automatically load ++symbol definitions from shared libraries, such as when they are ++particularly large or there are many of them. ++ ++To control the automatic loading of shared library symbols, use the ++commands: ++ ++@table @code ++@kindex set auto-solib-add ++@item set auto-solib-add @var{mode} ++If @var{mode} is @code{on}, symbols from all shared object libraries ++will be loaded automatically when the inferior begins execution, you ++attach to an independently started inferior, or when the dynamic linker ++informs @value{GDBN} that a new library has been loaded. If @var{mode} ++is @code{off}, symbols must be loaded manually, using the ++@code{sharedlibrary} command. The default value is @code{on}. ++ ++@cindex memory used for symbol tables ++If your program uses lots of shared libraries with debug info that ++takes large amounts of memory, you can decrease the @value{GDBN} ++memory footprint by preventing it from automatically loading the ++symbols from shared libraries. To that end, type @kbd{set ++auto-solib-add off} before running the inferior, then load each ++library whose debug symbols you do need with @kbd{sharedlibrary ++@var{regexp}}, where @var{regexp} is a regular expression that matches ++the libraries whose symbols you want to be loaded. ++ ++@kindex show auto-solib-add ++@item show auto-solib-add ++Display the current autoloading mode. ++@end table ++ ++@cindex load shared library ++To explicitly load shared library symbols, use the @code{sharedlibrary} ++command: ++ ++@table @code ++@kindex info sharedlibrary ++@kindex info share ++@item info share @var{regex} ++@itemx info sharedlibrary @var{regex} ++Print the names of the shared libraries which are currently loaded ++that match @var{regex}. If @var{regex} is omitted then print ++all shared libraries that are loaded. ++ ++@kindex info dll ++@item info dll @var{regex} ++This is an alias of @code{info sharedlibrary}. ++ ++@kindex sharedlibrary ++@kindex share ++@item sharedlibrary @var{regex} ++@itemx share @var{regex} ++Load shared object library symbols for files matching a ++Unix regular expression. ++As with files loaded automatically, it only loads shared libraries ++required by your program for a core file or after typing @code{run}. If ++@var{regex} is omitted all shared libraries required by your program are ++loaded. ++ ++@item nosharedlibrary ++@kindex nosharedlibrary ++@cindex unload symbols from shared libraries ++Unload all shared object library symbols. This discards all symbols ++that have been loaded from all shared libraries. Symbols from shared ++libraries that were loaded by explicit user requests are not ++discarded. ++@end table ++ ++Sometimes you may wish that @value{GDBN} stops and gives you control ++when any of shared library events happen. The best way to do this is ++to use @code{catch load} and @code{catch unload} (@pxref{Set ++Catchpoints}). ++ ++@value{GDBN} also supports the @code{set stop-on-solib-events} ++command for this. This command exists for historical reasons. It is ++less useful than setting a catchpoint, because it does not allow for ++conditions or commands as a catchpoint does. ++ ++@table @code ++@item set stop-on-solib-events ++@kindex set stop-on-solib-events ++This command controls whether @value{GDBN} should give you control ++when the dynamic linker notifies it about some shared library event. ++The most common event of interest is loading or unloading of a new ++shared library. ++ ++@item show stop-on-solib-events ++@kindex show stop-on-solib-events ++Show whether @value{GDBN} stops and gives you control when shared ++library events happen. ++@end table ++ ++Shared libraries are also supported in many cross or remote debugging ++configurations. @value{GDBN} needs to have access to the target's libraries; ++this can be accomplished either by providing copies of the libraries ++on the host system, or by asking @value{GDBN} to automatically retrieve the ++libraries from the target. If copies of the target libraries are ++provided, they need to be the same as the target libraries, although the ++copies on the target can be stripped as long as the copies on the host are ++not. ++ ++@cindex where to look for shared libraries ++For remote debugging, you need to tell @value{GDBN} where the target ++libraries are, so that it can load the correct copies---otherwise, it ++may try to load the host's libraries. @value{GDBN} has two variables ++to specify the search directories for target libraries. ++ ++@table @code ++@cindex prefix for executable and shared library file names ++@cindex system root, alternate ++@kindex set solib-absolute-prefix ++@kindex set sysroot ++@item set sysroot @var{path} ++Use @var{path} as the system root for the program being debugged. Any ++absolute shared library paths will be prefixed with @var{path}; many ++runtime loaders store the absolute paths to the shared library in the ++target program's memory. When starting processes remotely, and when ++attaching to already-running processes (local or remote), their ++executable filenames will be prefixed with @var{path} if reported to ++@value{GDBN} as absolute by the operating system. If you use ++@code{set sysroot} to find executables and shared libraries, they need ++to be laid out in the same way that they are on the target, with ++e.g.@: a @file{/bin}, @file{/lib} and @file{/usr/lib} hierarchy under ++@var{path}. ++ ++If @var{path} starts with the sequence @file{target:} and the target ++system is remote then @value{GDBN} will retrieve the target binaries ++from the remote system. This is only supported when using a remote ++target that supports the @code{remote get} command (@pxref{File ++Transfer,,Sending files to a remote system}). The part of @var{path} ++following the initial @file{target:} (if present) is used as system ++root prefix on the remote file system. If @var{path} starts with the ++sequence @file{remote:} this is converted to the sequence ++@file{target:} by @code{set sysroot}@footnote{Historically the ++functionality to retrieve binaries from the remote system was ++provided by prefixing @var{path} with @file{remote:}}. If you want ++to specify a local system root using a directory that happens to be ++named @file{target:} or @file{remote:}, you need to use some ++equivalent variant of the name like @file{./target:}. ++ ++For targets with an MS-DOS based filesystem, such as MS-Windows and ++SymbianOS, @value{GDBN} tries prefixing a few variants of the target ++absolute file name with @var{path}. But first, on Unix hosts, ++@value{GDBN} converts all backslash directory separators into forward ++slashes, because the backslash is not a directory separator on Unix: ++ ++@smallexample ++ c:\foo\bar.dll @result{} c:/foo/bar.dll ++@end smallexample ++ ++Then, @value{GDBN} attempts prefixing the target file name with ++@var{path}, and looks for the resulting file name in the host file ++system: ++ ++@smallexample ++ c:/foo/bar.dll @result{} /path/to/sysroot/c:/foo/bar.dll ++@end smallexample ++ ++If that does not find the binary, @value{GDBN} tries removing ++the @samp{:} character from the drive spec, both for convenience, and, ++for the case of the host file system not supporting file names with ++colons: ++ ++@smallexample ++ c:/foo/bar.dll @result{} /path/to/sysroot/c/foo/bar.dll ++@end smallexample ++ ++This makes it possible to have a system root that mirrors a target ++with more than one drive. E.g., you may want to setup your local ++copies of the target system shared libraries like so (note @samp{c} vs ++@samp{z}): ++ ++@smallexample ++ @file{/path/to/sysroot/c/sys/bin/foo.dll} ++ @file{/path/to/sysroot/c/sys/bin/bar.dll} ++ @file{/path/to/sysroot/z/sys/bin/bar.dll} ++@end smallexample ++ ++@noindent ++and point the system root at @file{/path/to/sysroot}, so that ++@value{GDBN} can find the correct copies of both ++@file{c:\sys\bin\foo.dll}, and @file{z:\sys\bin\bar.dll}. ++ ++If that still does not find the binary, @value{GDBN} tries ++removing the whole drive spec from the target file name: ++ ++@smallexample ++ c:/foo/bar.dll @result{} /path/to/sysroot/foo/bar.dll ++@end smallexample ++ ++This last lookup makes it possible to not care about the drive name, ++if you don't want or need to. ++ ++The @code{set solib-absolute-prefix} command is an alias for @code{set ++sysroot}. ++ ++@cindex default system root ++@cindex @samp{--with-sysroot} ++You can set the default system root by using the configure-time ++@samp{--with-sysroot} option. If the system root is inside ++@value{GDBN}'s configured binary prefix (set with @samp{--prefix} or ++@samp{--exec-prefix}), then the default system root will be updated ++automatically if the installed @value{GDBN} is moved to a new ++location. ++ ++@kindex show sysroot ++@item show sysroot ++Display the current executable and shared library prefix. ++ ++@kindex set solib-search-path ++@item set solib-search-path @var{path} ++If this variable is set, @var{path} is a colon-separated list of ++directories to search for shared libraries. @samp{solib-search-path} ++is used after @samp{sysroot} fails to locate the library, or if the ++path to the library is relative instead of absolute. If you want to ++use @samp{solib-search-path} instead of @samp{sysroot}, be sure to set ++@samp{sysroot} to a nonexistent directory to prevent @value{GDBN} from ++finding your host's libraries. @samp{sysroot} is preferred; setting ++it to a nonexistent directory may interfere with automatic loading ++of shared library symbols. ++ ++@kindex show solib-search-path ++@item show solib-search-path ++Display the current shared library search path. ++ ++@cindex DOS file-name semantics of file names. ++@kindex set target-file-system-kind (unix|dos-based|auto) ++@kindex show target-file-system-kind ++@item set target-file-system-kind @var{kind} ++Set assumed file system kind for target reported file names. ++ ++Shared library file names as reported by the target system may not ++make sense as is on the system @value{GDBN} is running on. For ++example, when remote debugging a target that has MS-DOS based file ++system semantics, from a Unix host, the target may be reporting to ++@value{GDBN} a list of loaded shared libraries with file names such as ++@file{c:\Windows\kernel32.dll}. On Unix hosts, there's no concept of ++drive letters, so the @samp{c:\} prefix is not normally understood as ++indicating an absolute file name, and neither is the backslash ++normally considered a directory separator character. In that case, ++the native file system would interpret this whole absolute file name ++as a relative file name with no directory components. This would make ++it impossible to point @value{GDBN} at a copy of the remote target's ++shared libraries on the host using @code{set sysroot}, and impractical ++with @code{set solib-search-path}. Setting ++@code{target-file-system-kind} to @code{dos-based} tells @value{GDBN} ++to interpret such file names similarly to how the target would, and to ++map them to file names valid on @value{GDBN}'s native file system ++semantics. The value of @var{kind} can be @code{"auto"}, in addition ++to one of the supported file system kinds. In that case, @value{GDBN} ++tries to determine the appropriate file system variant based on the ++current target's operating system (@pxref{ABI, ,Configuring the ++Current ABI}). The supported file system settings are: ++ ++@table @code ++@item unix ++Instruct @value{GDBN} to assume the target file system is of Unix ++kind. Only file names starting the forward slash (@samp{/}) character ++are considered absolute, and the directory separator character is also ++the forward slash. ++ ++@item dos-based ++Instruct @value{GDBN} to assume the target file system is DOS based. ++File names starting with either a forward slash, or a drive letter ++followed by a colon (e.g., @samp{c:}), are considered absolute, and ++both the slash (@samp{/}) and the backslash (@samp{\\}) characters are ++considered directory separators. ++ ++@item auto ++Instruct @value{GDBN} to use the file system kind associated with the ++target operating system (@pxref{ABI, ,Configuring the Current ABI}). ++This is the default. ++@end table ++@end table ++ ++@cindex file name canonicalization ++@cindex base name differences ++When processing file names provided by the user, @value{GDBN} ++frequently needs to compare them to the file names recorded in the ++program's debug info. Normally, @value{GDBN} compares just the ++@dfn{base names} of the files as strings, which is reasonably fast ++even for very large programs. (The base name of a file is the last ++portion of its name, after stripping all the leading directories.) ++This shortcut in comparison is based upon the assumption that files ++cannot have more than one base name. This is usually true, but ++references to files that use symlinks or similar filesystem ++facilities violate that assumption. If your program records files ++using such facilities, or if you provide file names to @value{GDBN} ++using symlinks etc., you can set @code{basenames-may-differ} to ++@code{true} to instruct @value{GDBN} to completely canonicalize each ++pair of file names it needs to compare. This will make file-name ++comparisons accurate, but at a price of a significant slowdown. ++ ++@table @code ++@item set basenames-may-differ ++@kindex set basenames-may-differ ++Set whether a source file may have multiple base names. ++ ++@item show basenames-may-differ ++@kindex show basenames-may-differ ++Show whether a source file may have multiple base names. ++@end table ++ ++@node File Caching ++@section File Caching ++@cindex caching of opened files ++@cindex caching of bfd objects ++ ++To speed up file loading, and reduce memory usage, @value{GDBN} will ++reuse the @code{bfd} objects used to track open files. @xref{Top, , ++BFD, bfd, The Binary File Descriptor Library}. The following commands ++allow visibility and control of the caching behavior. ++ ++@table @code ++@kindex maint info bfds ++@item maint info bfds ++This prints information about each @code{bfd} object that is known to ++@value{GDBN}. ++ ++@kindex maint set bfd-sharing ++@kindex maint show bfd-sharing ++@kindex bfd caching ++@item maint set bfd-sharing ++@item maint show bfd-sharing ++Control whether @code{bfd} objects can be shared. When sharing is ++enabled @value{GDBN} reuses already open @code{bfd} objects rather ++than reopening the same file. Turning sharing off does not cause ++already shared @code{bfd} objects to be unshared, but all future files ++that are opened will create a new @code{bfd} object. Similarly, ++re-enabling sharing does not cause multiple existing @code{bfd} ++objects to be collapsed into a single shared @code{bfd} object. ++ ++@kindex set debug bfd-cache @var{level} ++@kindex bfd caching ++@item set debug bfd-cache @var{level} ++Turns on debugging of the bfd cache, setting the level to @var{level}. ++ ++@kindex show debug bfd-cache ++@kindex bfd caching ++@item show debug bfd-cache ++Show the current debugging level of the bfd cache. ++@end table ++ ++@node Separate Debug Files ++@section Debugging Information in Separate Files ++@cindex separate debugging information files ++@cindex debugging information in separate files ++@cindex @file{.debug} subdirectories ++@cindex debugging information directory, global ++@cindex global debugging information directories ++@cindex build ID, and separate debugging files ++@cindex @file{.build-id} directory ++ ++@value{GDBN} allows you to put a program's debugging information in a ++file separate from the executable itself, in a way that allows ++@value{GDBN} to find and load the debugging information automatically. ++Since debugging information can be very large---sometimes larger ++than the executable code itself---some systems distribute debugging ++information for their executables in separate files, which users can ++install only when they need to debug a problem. ++ ++@value{GDBN} supports two ways of specifying the separate debug info ++file: ++ ++@itemize @bullet ++@item ++The executable contains a @dfn{debug link} that specifies the name of ++the separate debug info file. The separate debug file's name is ++usually @file{@var{executable}.debug}, where @var{executable} is the ++name of the corresponding executable file without leading directories ++(e.g., @file{ls.debug} for @file{/usr/bin/ls}). In addition, the ++debug link specifies a 32-bit @dfn{Cyclic Redundancy Check} (CRC) ++checksum for the debug file, which @value{GDBN} uses to validate that ++the executable and the debug file came from the same build. ++ ++@item ++@anchor{build ID} ++The executable contains a @dfn{build ID}, a unique bit string that is ++also present in the corresponding debug info file. (This is supported ++only on some operating systems, when using the ELF or PE file formats ++for binary files and the @sc{gnu} Binutils.) For more details about ++this feature, see the description of the @option{--build-id} ++command-line option in @ref{Options, , Command Line Options, ld, ++The GNU Linker}. The debug info file's name is not specified ++explicitly by the build ID, but can be computed from the build ID, see ++below. ++@end itemize ++ ++Depending on the way the debug info file is specified, @value{GDBN} ++uses two different methods of looking for the debug file: ++ ++@itemize @bullet ++@item ++For the ``debug link'' method, @value{GDBN} looks up the named file in ++the directory of the executable file, then in a subdirectory of that ++directory named @file{.debug}, and finally under each one of the ++global debug directories, in a subdirectory whose name is identical to ++the leading directories of the executable's absolute file name. (On ++MS-Windows/MS-DOS, the drive letter of the executable's leading ++directories is converted to a one-letter subdirectory, i.e.@: ++@file{d:/usr/bin/} is converted to @file{/d/usr/bin/}, because Windows ++filesystems disallow colons in file names.) ++ ++@item ++For the ``build ID'' method, @value{GDBN} looks in the ++@file{.build-id} subdirectory of each one of the global debug directories for ++a file named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the ++first 2 hex characters of the build ID bit string, and @var{nnnnnnnn} ++are the rest of the bit string. (Real build ID strings are 32 or more ++hex characters, not 10.) ++@end itemize ++ ++So, for example, suppose you ask @value{GDBN} to debug ++@file{/usr/bin/ls}, which has a debug link that specifies the ++file @file{ls.debug}, and a build ID whose value in hex is ++@code{abcdef1234}. If the list of the global debug directories includes ++@file{/usr/lib/debug}, then @value{GDBN} will look for the following ++debug information files, in the indicated order: ++ ++@itemize @minus ++@item ++@file{/usr/lib/debug/.build-id/ab/cdef1234.debug} ++@item ++@file{/usr/bin/ls.debug} ++@item ++@file{/usr/bin/.debug/ls.debug} ++@item ++@file{/usr/lib/debug/usr/bin/ls.debug}. ++@end itemize ++ ++@anchor{debug-file-directory} ++Global debugging info directories default to what is set by @value{GDBN} ++configure option @option{--with-separate-debug-dir}. During @value{GDBN} run ++you can also set the global debugging info directories, and view the list ++@value{GDBN} is currently using. ++ ++@table @code ++ ++@kindex set debug-file-directory ++@item set debug-file-directory @var{directories} ++Set the directories which @value{GDBN} searches for separate debugging ++information files to @var{directory}. Multiple path components can be set ++concatenating them by a path separator. ++ ++@kindex show debug-file-directory ++@item show debug-file-directory ++Show the directories @value{GDBN} searches for separate debugging ++information files. ++ ++@end table ++ ++@cindex @code{.gnu_debuglink} sections ++@cindex debug link sections ++A debug link is a special section of the executable file named ++@code{.gnu_debuglink}. The section must contain: ++ ++@itemize ++@item ++A filename, with any leading directory components removed, followed by ++a zero byte, ++@item ++zero to three bytes of padding, as needed to reach the next four-byte ++boundary within the section, and ++@item ++a four-byte CRC checksum, stored in the same endianness used for the ++executable file itself. The checksum is computed on the debugging ++information file's full contents by the function given below, passing ++zero as the @var{crc} argument. ++@end itemize ++ ++Any executable file format can carry a debug link, as long as it can ++contain a section named @code{.gnu_debuglink} with the contents ++described above. ++ ++@cindex @code{.note.gnu.build-id} sections ++@cindex build ID sections ++The build ID is a special section in the executable file (and in other ++ELF binary files that @value{GDBN} may consider). This section is ++often named @code{.note.gnu.build-id}, but that name is not mandatory. ++It contains unique identification for the built files---the ID remains ++the same across multiple builds of the same build tree. The default ++algorithm SHA1 produces 160 bits (40 hexadecimal characters) of the ++content for the build ID string. The same section with an identical ++value is present in the original built binary with symbols, in its ++stripped variant, and in the separate debugging information file. ++ ++The debugging information file itself should be an ordinary ++executable, containing a full set of linker symbols, sections, and ++debugging information. The sections of the debugging information file ++should have the same names, addresses, and sizes as the original file, ++but they need not contain any data---much like a @code{.bss} section ++in an ordinary executable. ++ ++The @sc{gnu} binary utilities (Binutils) package includes the ++@samp{objcopy} utility that can produce ++the separated executable / debugging information file pairs using the ++following commands: ++ ++@smallexample ++@kbd{objcopy --only-keep-debug foo foo.debug} ++@kbd{strip -g foo} ++@end smallexample ++ ++@noindent ++These commands remove the debugging ++information from the executable file @file{foo} and place it in the file ++@file{foo.debug}. You can use the first, second or both methods to link the ++two files: ++ ++@itemize @bullet ++@item ++The debug link method needs the following additional command to also leave ++behind a debug link in @file{foo}: ++ ++@smallexample ++@kbd{objcopy --add-gnu-debuglink=foo.debug foo} ++@end smallexample ++ ++Ulrich Drepper's @file{elfutils} package, starting with version 0.53, contains ++a version of the @code{strip} command such that the command @kbd{strip foo -f ++foo.debug} has the same functionality as the two @code{objcopy} commands and ++the @code{ln -s} command above, together. ++ ++@item ++Build ID gets embedded into the main executable using @code{ld --build-id} or ++the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. Build ID support plus ++compatibility fixes for debug files separation are present in @sc{gnu} binary ++utilities (Binutils) package since version 2.18. ++@end itemize ++ ++@noindent ++ ++@cindex CRC algorithm definition ++The CRC used in @code{.gnu_debuglink} is the CRC-32 defined in ++IEEE 802.3 using the polynomial: ++ ++@c TexInfo requires naked braces for multi-digit exponents for Tex ++@c output, but this causes HTML output to barf. HTML has to be set using ++@c raw commands. So we end up having to specify this equation in 2 ++@c different ways! ++@ifhtml ++@display ++@html ++ x32 + x26 + x23 + x22 + x16 + x12 + x11 ++ + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 ++@end html ++@end display ++@end ifhtml ++@ifnothtml ++@display ++ @math{x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} + x^{11}} ++ @math{+ x^{10} + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1} ++@end display ++@end ifnothtml ++ ++The function is computed byte at a time, taking the least ++significant bit of each byte first. The initial pattern ++@code{0xffffffff} is used, to ensure leading zeros affect the CRC and ++the final result is inverted to ensure trailing zeros also affect the ++CRC. ++ ++@emph{Note:} This is the same CRC polynomial as used in handling the ++@dfn{Remote Serial Protocol} @code{qCRC} packet (@pxref{qCRC packet}). ++However in the case of the Remote Serial Protocol, the CRC is computed ++@emph{most} significant bit first, and the result is not inverted, so ++trailing zeros have no effect on the CRC value. ++ ++To complete the description, we show below the code of the function ++which produces the CRC used in @code{.gnu_debuglink}. Inverting the ++initially supplied @code{crc} argument means that an initial call to ++this function passing in zero will start computing the CRC using ++@code{0xffffffff}. ++ ++@kindex gnu_debuglink_crc32 ++@smallexample ++unsigned long ++gnu_debuglink_crc32 (unsigned long crc, ++ unsigned char *buf, size_t len) ++@{ ++ static const unsigned long crc32_table[256] = ++ @{ ++ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, ++ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, ++ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, ++ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, ++ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, ++ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, ++ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, ++ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, ++ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, ++ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, ++ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, ++ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, ++ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, ++ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, ++ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, ++ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, ++ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, ++ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, ++ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, ++ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, ++ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, ++ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, ++ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, ++ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, ++ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, ++ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, ++ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, ++ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, ++ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, ++ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, ++ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, ++ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, ++ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, ++ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, ++ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, ++ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, ++ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, ++ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, ++ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, ++ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, ++ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, ++ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, ++ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, ++ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, ++ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, ++ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, ++ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, ++ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, ++ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, ++ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, ++ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, ++ 0x2d02ef8d ++ @}; ++ unsigned char *end; ++ ++ crc = ~crc & 0xffffffff; ++ for (end = buf + len; buf < end; ++buf) ++ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); ++ return ~crc & 0xffffffff; ++@} ++@end smallexample ++ ++@noindent ++This computation does not apply to the ``build ID'' method. ++ ++@node MiniDebugInfo ++@section Debugging information in a special section ++@cindex separate debug sections ++@cindex @samp{.gnu_debugdata} section ++ ++Some systems ship pre-built executables and libraries that have a ++special @samp{.gnu_debugdata} section. This feature is called ++@dfn{MiniDebugInfo}. This section holds an LZMA-compressed object and ++is used to supply extra symbols for backtraces. ++ ++The intent of this section is to provide extra minimal debugging ++information for use in simple backtraces. It is not intended to be a ++replacement for full separate debugging information (@pxref{Separate ++Debug Files}). The example below shows the intended use; however, ++@value{GDBN} does not currently put restrictions on what sort of ++debugging information might be included in the section. ++ ++@value{GDBN} has support for this extension. If the section exists, ++then it is used provided that no other source of debugging information ++can be found, and that @value{GDBN} was configured with LZMA support. ++ ++This section can be easily created using @command{objcopy} and other ++standard utilities: ++ ++@smallexample ++# Extract the dynamic symbols from the main binary, there is no need ++# to also have these in the normal symbol table. ++nm -D @var{binary} --format=posix --defined-only \ ++ | awk '@{ print $1 @}' | sort > dynsyms ++ ++# Extract all the text (i.e. function) symbols from the debuginfo. ++# (Note that we actually also accept "D" symbols, for the benefit ++# of platforms like PowerPC64 that use function descriptors.) ++nm @var{binary} --format=posix --defined-only \ ++ | awk '@{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 @}' \ ++ | sort > funcsyms ++ ++# Keep all the function symbols not already in the dynamic symbol ++# table. ++comm -13 dynsyms funcsyms > keep_symbols ++ ++# Separate full debug info into debug binary. ++objcopy --only-keep-debug @var{binary} debug ++ ++# Copy the full debuginfo, keeping only a minimal set of symbols and ++# removing some unnecessary sections. ++objcopy -S --remove-section .gdb_index --remove-section .comment \ ++ --keep-symbols=keep_symbols debug mini_debuginfo ++ ++# Drop the full debug info from the original binary. ++strip --strip-all -R .comment @var{binary} ++ ++# Inject the compressed data into the .gnu_debugdata section of the ++# original binary. ++xz mini_debuginfo ++objcopy --add-section .gnu_debugdata=mini_debuginfo.xz @var{binary} ++@end smallexample ++ ++@node Index Files ++@section Index Files Speed Up @value{GDBN} ++@cindex index files ++@cindex @samp{.gdb_index} section ++ ++When @value{GDBN} finds a symbol file, it scans the symbols in the ++file in order to construct an internal symbol table. This lets most ++@value{GDBN} operations work quickly---at the cost of a delay early ++on. For large programs, this delay can be quite lengthy, so ++@value{GDBN} provides a way to build an index, which speeds up ++startup. ++ ++For convenience, @value{GDBN} comes with a program, ++@command{gdb-add-index}, which can be used to add the index to a ++symbol file. It takes the symbol file as its only argument: ++ ++@smallexample ++$ gdb-add-index symfile ++@end smallexample ++ ++@xref{gdb-add-index}. ++ ++It is also possible to do the work manually. Here is what ++@command{gdb-add-index} does behind the curtains. ++ ++The index is stored as a section in the symbol file. @value{GDBN} can ++write the index to a file, then you can put it into the symbol file ++using @command{objcopy}. ++ ++To create an index file, use the @code{save gdb-index} command: ++ ++@table @code ++@item save gdb-index [-dwarf-5] @var{directory} ++@kindex save gdb-index ++Create index files for all symbol files currently known by ++@value{GDBN}. For each known @var{symbol-file}, this command by ++default creates it produces a single file ++@file{@var{symbol-file}.gdb-index}. If you invoke this command with ++the @option{-dwarf-5} option, it produces 2 files: ++@file{@var{symbol-file}.debug_names} and ++@file{@var{symbol-file}.debug_str}. The files are created in the ++given @var{directory}. ++@end table ++ ++Once you have created an index file you can merge it into your symbol ++file, here named @file{symfile}, using @command{objcopy}: ++ ++@smallexample ++$ objcopy --add-section .gdb_index=symfile.gdb-index \ ++ --set-section-flags .gdb_index=readonly symfile symfile ++@end smallexample ++ ++Or for @code{-dwarf-5}: ++ ++@smallexample ++$ objcopy --dump-section .debug_str=symfile.debug_str.new symfile ++$ cat symfile.debug_str >>symfile.debug_str.new ++$ objcopy --add-section .debug_names=symfile.gdb-index \ ++ --set-section-flags .debug_names=readonly \ ++ --update-section .debug_str=symfile.debug_str.new symfile symfile ++@end smallexample ++ ++@value{GDBN} will normally ignore older versions of @file{.gdb_index} ++sections that have been deprecated. Usually they are deprecated because ++they are missing a new feature or have performance issues. ++To tell @value{GDBN} to use a deprecated index section anyway ++specify @code{set use-deprecated-index-sections on}. ++The default is @code{off}. ++This can speed up startup, but may result in some functionality being lost. ++@xref{Index Section Format}. ++ ++@emph{Warning:} Setting @code{use-deprecated-index-sections} to @code{on} ++must be done before gdb reads the file. The following will not work: ++ ++@smallexample ++$ gdb -ex "set use-deprecated-index-sections on" ++@end smallexample ++ ++Instead you must do, for example, ++ ++@smallexample ++$ gdb -iex "set use-deprecated-index-sections on" ++@end smallexample ++ ++Indices only work when using DWARF debugging information, not stabs. ++ ++@subsection Automatic symbol index cache ++ ++@cindex automatic symbol index cache ++It is possible for @value{GDBN} to automatically save a copy of this index in a ++cache on disk and retrieve it from there when loading the same binary in the ++future. This feature can be turned on with @kbd{set index-cache on}. The ++following commands can be used to tweak the behavior of the index cache. ++ ++@table @code ++ ++@kindex set index-cache ++@item set index-cache on ++@itemx set index-cache off ++Enable or disable the use of the symbol index cache. ++ ++@item set index-cache directory @var{directory} ++@kindex show index-cache ++@itemx show index-cache directory ++Set/show the directory where index files will be saved. ++ ++The default value for this directory depends on the host platform. On ++most systems, the index is cached in the @file{gdb} subdirectory of ++the directory pointed to by the @env{XDG_CACHE_HOME} environment ++variable, if it is defined, else in the @file{.cache/gdb} subdirectory ++of your home directory. However, on some systems, the default may ++differ according to local convention. ++ ++There is no limit on the disk space used by index cache. It is perfectly safe ++to delete the content of that directory to free up disk space. ++ ++@item show index-cache stats ++Print the number of cache hits and misses since the launch of @value{GDBN}. ++ ++@end table ++ ++@node Symbol Errors ++@section Errors Reading Symbol Files ++ ++While reading a symbol file, @value{GDBN} occasionally encounters problems, ++such as symbol types it does not recognize, or known bugs in compiler ++output. By default, @value{GDBN} does not notify you of such problems, since ++they are relatively common and primarily of interest to people ++debugging compilers. If you are interested in seeing information ++about ill-constructed symbol tables, you can either ask @value{GDBN} to print ++only one message about each such type of problem, no matter how many ++times the problem occurs; or you can ask @value{GDBN} to print more messages, ++to see how many times the problems occur, with the @code{set ++complaints} command (@pxref{Messages/Warnings, ,Optional Warnings and ++Messages}). ++ ++The messages currently printed, and their meanings, include: ++ ++@table @code ++@item inner block not inside outer block in @var{symbol} ++ ++The symbol information shows where symbol scopes begin and end ++(such as at the start of a function or a block of statements). This ++error indicates that an inner scope block is not fully contained ++in its outer scope blocks. ++ ++@value{GDBN} circumvents the problem by treating the inner block as if it had ++the same scope as the outer block. In the error message, @var{symbol} ++may be shown as ``@code{(don't know)}'' if the outer block is not a ++function. ++ ++@item block at @var{address} out of order ++ ++The symbol information for symbol scope blocks should occur in ++order of increasing addresses. This error indicates that it does not ++do so. ++ ++@value{GDBN} does not circumvent this problem, and has trouble ++locating symbols in the source file whose symbols it is reading. (You ++can often determine what source file is affected by specifying ++@code{set verbose on}. @xref{Messages/Warnings, ,Optional Warnings and ++Messages}.) ++ ++@item bad block start address patched ++ ++The symbol information for a symbol scope block has a start address ++smaller than the address of the preceding source line. This is known ++to occur in the SunOS 4.1.1 (and earlier) C compiler. ++ ++@value{GDBN} circumvents the problem by treating the symbol scope block as ++starting on the previous source line. ++ ++@item bad string table offset in symbol @var{n} ++ ++@cindex foo ++Symbol number @var{n} contains a pointer into the string table which is ++larger than the size of the string table. ++ ++@value{GDBN} circumvents the problem by considering the symbol to have the ++name @code{foo}, which may cause other problems if many symbols end up ++with this name. ++ ++@item unknown symbol type @code{0x@var{nn}} ++ ++The symbol information contains new data types that @value{GDBN} does ++not yet know how to read. @code{0x@var{nn}} is the symbol type of the ++uncomprehended information, in hexadecimal. ++ ++@value{GDBN} circumvents the error by ignoring this symbol information. ++This usually allows you to debug your program, though certain symbols ++are not accessible. If you encounter such a problem and feel like ++debugging it, you can debug @code{@value{GDBP}} with itself, breakpoint ++on @code{complain}, then go up to the function @code{read_dbx_symtab} ++and examine @code{*bufp} to see the symbol. ++ ++@item stub type has NULL name ++ ++@value{GDBN} could not find the full definition for a struct or class. ++ ++@item const/volatile indicator missing (ok if using g++ v1.x), got@dots{} ++The symbol information for a C@t{++} member function is missing some ++information that recent versions of the compiler should have output for ++it. ++ ++@item info mismatch between compiler and debugger ++ ++@value{GDBN} could not parse a type specification output by the compiler. ++ ++@end table ++ ++@node Data Files ++@section GDB Data Files ++ ++@cindex prefix for data files ++@value{GDBN} will sometimes read an auxiliary data file. These files ++are kept in a directory known as the @dfn{data directory}. ++ ++You can set the data directory's name, and view the name @value{GDBN} ++is currently using. ++ ++@table @code ++@kindex set data-directory ++@item set data-directory @var{directory} ++Set the directory which @value{GDBN} searches for auxiliary data files ++to @var{directory}. ++ ++@kindex show data-directory ++@item show data-directory ++Show the directory @value{GDBN} searches for auxiliary data files. ++@end table ++ ++@cindex default data directory ++@cindex @samp{--with-gdb-datadir} ++You can set the default data directory by using the configure-time ++@samp{--with-gdb-datadir} option. If the data directory is inside ++@value{GDBN}'s configured binary prefix (set with @samp{--prefix} or ++@samp{--exec-prefix}), then the default data directory will be updated ++automatically if the installed @value{GDBN} is moved to a new ++location. ++ ++The data directory may also be specified with the ++@code{--data-directory} command line option. ++@xref{Mode Options}. ++ ++@node Targets ++@chapter Specifying a Debugging Target ++ ++@cindex debugging target ++A @dfn{target} is the execution environment occupied by your program. ++ ++Often, @value{GDBN} runs in the same host environment as your program; ++in that case, the debugging target is specified as a side effect when ++you use the @code{file} or @code{core} commands. When you need more ++flexibility---for example, running @value{GDBN} on a physically separate ++host, or controlling a standalone system over a serial port or a ++realtime system over a TCP/IP connection---you can use the @code{target} ++command to specify one of the target types configured for @value{GDBN} ++(@pxref{Target Commands, ,Commands for Managing Targets}). ++ ++@cindex target architecture ++It is possible to build @value{GDBN} for several different @dfn{target ++architectures}. When @value{GDBN} is built like that, you can choose ++one of the available architectures with the @kbd{set architecture} ++command. ++ ++@table @code ++@kindex set architecture ++@kindex show architecture ++@item set architecture @var{arch} ++This command sets the current target architecture to @var{arch}. The ++value of @var{arch} can be @code{"auto"}, in addition to one of the ++supported architectures. ++ ++@item show architecture ++Show the current target architecture. ++ ++@item set processor ++@itemx processor ++@kindex set processor ++@kindex show processor ++These are alias commands for, respectively, @code{set architecture} ++and @code{show architecture}. ++@end table ++ ++@menu ++* Active Targets:: Active targets ++* Target Commands:: Commands for managing targets ++* Byte Order:: Choosing target byte order ++@end menu ++ ++@node Active Targets ++@section Active Targets ++ ++@cindex stacking targets ++@cindex active targets ++@cindex multiple targets ++ ++There are multiple classes of targets such as: processes, executable files or ++recording sessions. Core files belong to the process class, making core file ++and process mutually exclusive. Otherwise, @value{GDBN} can work concurrently ++on multiple active targets, one in each class. This allows you to (for ++example) start a process and inspect its activity, while still having access to ++the executable file after the process finishes. Or if you start process ++recording (@pxref{Reverse Execution}) and @code{reverse-step} there, you are ++presented a virtual layer of the recording target, while the process target ++remains stopped at the chronologically last point of the process execution. ++ ++Use the @code{core-file} and @code{exec-file} commands to select a new core ++file or executable target (@pxref{Files, ,Commands to Specify Files}). To ++specify as a target a process that is already running, use the @code{attach} ++command (@pxref{Attach, ,Debugging an Already-running Process}). ++ ++@node Target Commands ++@section Commands for Managing Targets ++ ++@table @code ++@item target @var{type} @var{parameters} ++Connects the @value{GDBN} host environment to a target machine or ++process. A target is typically a protocol for talking to debugging ++facilities. You use the argument @var{type} to specify the type or ++protocol of the target machine. ++ ++Further @var{parameters} are interpreted by the target protocol, but ++typically include things like device names or host names to connect ++with, process numbers, and baud rates. ++ ++The @code{target} command does not repeat if you press @key{RET} again ++after executing the command. ++ ++@kindex help target ++@item help target ++Displays the names of all targets available. To display targets ++currently selected, use either @code{info target} or @code{info files} ++(@pxref{Files, ,Commands to Specify Files}). ++ ++@item help target @var{name} ++Describe a particular target, including any parameters necessary to ++select it. ++ ++@kindex set gnutarget ++@item set gnutarget @var{args} ++@value{GDBN} uses its own library BFD to read your files. @value{GDBN} ++knows whether it is reading an @dfn{executable}, ++a @dfn{core}, or a @dfn{.o} file; however, you can specify the file format ++with the @code{set gnutarget} command. Unlike most @code{target} commands, ++with @code{gnutarget} the @code{target} refers to a program, not a machine. ++ ++@quotation ++@emph{Warning:} To specify a file format with @code{set gnutarget}, ++you must know the actual BFD name. ++@end quotation ++ ++@noindent ++@xref{Files, , Commands to Specify Files}. ++ ++@kindex show gnutarget ++@item show gnutarget ++Use the @code{show gnutarget} command to display what file format ++@code{gnutarget} is set to read. If you have not set @code{gnutarget}, ++@value{GDBN} will determine the file format for each file automatically, ++and @code{show gnutarget} displays @samp{The current BFD target is "auto"}. ++@end table ++ ++@cindex common targets ++Here are some common targets (available, or not, depending on the GDB ++configuration): ++ ++@table @code ++@kindex target ++@item target exec @var{program} ++@cindex executable file target ++An executable file. @samp{target exec @var{program}} is the same as ++@samp{exec-file @var{program}}. ++ ++@item target core @var{filename} ++@cindex core dump file target ++A core dump file. @samp{target core @var{filename}} is the same as ++@samp{core-file @var{filename}}. ++ ++@item target remote @var{medium} ++@cindex remote target ++A remote system connected to @value{GDBN} via a serial line or network ++connection. This command tells @value{GDBN} to use its own remote ++protocol over @var{medium} for debugging. @xref{Remote Debugging}. ++ ++For example, if you have a board connected to @file{/dev/ttya} on the ++machine running @value{GDBN}, you could say: ++ ++@smallexample ++target remote /dev/ttya ++@end smallexample ++ ++@code{target remote} supports the @code{load} command. This is only ++useful if you have some other way of getting the stub to the target ++system, and you can put it somewhere in memory where it won't get ++clobbered by the download. ++ ++@item target sim @r{[}@var{simargs}@r{]} @dots{} ++@cindex built-in simulator target ++Builtin CPU simulator. @value{GDBN} includes simulators for most architectures. ++In general, ++@smallexample ++ target sim ++ load ++ run ++@end smallexample ++@noindent ++works; however, you cannot assume that a specific memory map, device ++drivers, or even basic I/O is available, although some simulators do ++provide these. For info about any processor-specific simulator details, ++see the appropriate section in @ref{Embedded Processors, ,Embedded ++Processors}. ++ ++@item target native ++@cindex native target ++Setup for local/native process debugging. Useful to make the ++@code{run} command spawn native processes (likewise @code{attach}, ++etc.@:) even when @code{set auto-connect-native-target} is @code{off} ++(@pxref{set auto-connect-native-target}). ++ ++@end table ++ ++Different targets are available on different configurations of @value{GDBN}; ++your configuration may have more or fewer targets. ++ ++Many remote targets require you to download the executable's code once ++you've successfully established a connection. You may wish to control ++various aspects of this process. ++ ++@table @code ++ ++@item set hash ++@kindex set hash@r{, for remote monitors} ++@cindex hash mark while downloading ++This command controls whether a hash mark @samp{#} is displayed while ++downloading a file to the remote monitor. If on, a hash mark is ++displayed after each S-record is successfully downloaded to the ++monitor. ++ ++@item show hash ++@kindex show hash@r{, for remote monitors} ++Show the current status of displaying the hash mark. ++ ++@item set debug monitor ++@kindex set debug monitor ++@cindex display remote monitor communications ++Enable or disable display of communications messages between ++@value{GDBN} and the remote monitor. ++ ++@item show debug monitor ++@kindex show debug monitor ++Show the current status of displaying communications between ++@value{GDBN} and the remote monitor. ++@end table ++ ++@table @code ++ ++@kindex load @var{filename} @var{offset} ++@item load @var{filename} @var{offset} ++@anchor{load} ++Depending on what remote debugging facilities are configured into ++@value{GDBN}, the @code{load} command may be available. Where it exists, it ++is meant to make @var{filename} (an executable) available for debugging ++on the remote system---by downloading, or dynamic linking, for example. ++@code{load} also records the @var{filename} symbol table in @value{GDBN}, like ++the @code{add-symbol-file} command. ++ ++If your @value{GDBN} does not have a @code{load} command, attempting to ++execute it gets the error message ``@code{You can't do that when your ++target is @dots{}}'' ++ ++The file is loaded at whatever address is specified in the executable. ++For some object file formats, you can specify the load address when you ++link the program; for other formats, like a.out, the object file format ++specifies a fixed address. ++@c FIXME! This would be a good place for an xref to the GNU linker doc. ++ ++It is also possible to tell @value{GDBN} to load the executable file at a ++specific offset described by the optional argument @var{offset}. When ++@var{offset} is provided, @var{filename} must also be provided. ++ ++Depending on the remote side capabilities, @value{GDBN} may be able to ++load programs into flash memory. ++ ++@code{load} does not repeat if you press @key{RET} again after using it. ++@end table ++ ++@table @code ++ ++@kindex flash-erase ++@item flash-erase ++@anchor{flash-erase} ++ ++Erases all known flash memory regions on the target. ++ ++@end table ++ ++@node Byte Order ++@section Choosing Target Byte Order ++ ++@cindex choosing target byte order ++@cindex target byte order ++ ++Some types of processors, such as the @acronym{MIPS}, PowerPC, and Renesas SH, ++offer the ability to run either big-endian or little-endian byte ++orders. Usually the executable or symbol will include a bit to ++designate the endian-ness, and you will not need to worry about ++which to use. However, you may still find it useful to adjust ++@value{GDBN}'s idea of processor endian-ness manually. ++ ++@table @code ++@kindex set endian ++@item set endian big ++Instruct @value{GDBN} to assume the target is big-endian. ++ ++@item set endian little ++Instruct @value{GDBN} to assume the target is little-endian. ++ ++@item set endian auto ++Instruct @value{GDBN} to use the byte order associated with the ++executable. ++ ++@item show endian ++Display @value{GDBN}'s current idea of the target byte order. ++ ++@end table ++ ++If the @code{set endian auto} mode is in effect and no executable has ++been selected, then the endianness used is the last one chosen either ++by one of the @code{set endian big} and @code{set endian little} ++commands or by inferring from the last executable used. If no ++endianness has been previously chosen, then the default for this mode ++is inferred from the target @value{GDBN} has been built for, and is ++@code{little} if the name of the target CPU has an @code{el} suffix ++and @code{big} otherwise. ++ ++Note that these commands merely adjust interpretation of symbolic ++data on the host, and that they have absolutely no effect on the ++target system. ++ ++ ++@node Remote Debugging ++@chapter Debugging Remote Programs ++@cindex remote debugging ++ ++If you are trying to debug a program running on a machine that cannot run ++@value{GDBN} in the usual way, it is often useful to use remote debugging. ++For example, you might use remote debugging on an operating system kernel, ++or on a small system which does not have a general purpose operating system ++powerful enough to run a full-featured debugger. ++ ++Some configurations of @value{GDBN} have special serial or TCP/IP interfaces ++to make this work with particular debugging targets. In addition, ++@value{GDBN} comes with a generic serial protocol (specific to @value{GDBN}, ++but not specific to any particular target system) which you can use if you ++write the remote stubs---the code that runs on the remote system to ++communicate with @value{GDBN}. ++ ++Other remote targets may be available in your ++configuration of @value{GDBN}; use @code{help target} to list them. ++ ++@menu ++* Connecting:: Connecting to a remote target ++* File Transfer:: Sending files to a remote system ++* Server:: Using the gdbserver program ++* Remote Configuration:: Remote configuration ++* Remote Stub:: Implementing a remote stub ++@end menu ++ ++@node Connecting ++@section Connecting to a Remote Target ++@cindex remote debugging, connecting ++@cindex @code{gdbserver}, connecting ++@cindex remote debugging, types of connections ++@cindex @code{gdbserver}, types of connections ++@cindex @code{gdbserver}, @code{target remote} mode ++@cindex @code{gdbserver}, @code{target extended-remote} mode ++ ++This section describes how to connect to a remote target, including the ++types of connections and their differences, how to set up executable and ++symbol files on the host and target, and the commands used for ++connecting to and disconnecting from the remote target. ++ ++@subsection Types of Remote Connections ++ ++@value{GDBN} supports two types of remote connections, @code{target remote} ++mode and @code{target extended-remote} mode. Note that many remote targets ++support only @code{target remote} mode. There are several major ++differences between the two types of connections, enumerated here: ++ ++@table @asis ++ ++@cindex remote debugging, detach and program exit ++@item Result of detach or program exit ++@strong{With target remote mode:} When the debugged program exits or you ++detach from it, @value{GDBN} disconnects from the target. When using ++@code{gdbserver}, @code{gdbserver} will exit. ++ ++@strong{With target extended-remote mode:} When the debugged program exits or ++you detach from it, @value{GDBN} remains connected to the target, even ++though no program is running. You can rerun the program, attach to a ++running program, or use @code{monitor} commands specific to the target. ++ ++When using @code{gdbserver} in this case, it does not exit unless it was ++invoked using the @option{--once} option. If the @option{--once} option ++was not used, you can ask @code{gdbserver} to exit using the ++@code{monitor exit} command (@pxref{Monitor Commands for gdbserver}). ++ ++@item Specifying the program to debug ++For both connection types you use the @code{file} command to specify the ++program on the host system. If you are using @code{gdbserver} there are ++some differences in how to specify the location of the program on the ++target. ++ ++@strong{With target remote mode:} You must either specify the program to debug ++on the @code{gdbserver} command line or use the @option{--attach} option ++(@pxref{Attaching to a program,,Attaching to a Running Program}). ++ ++@cindex @option{--multi}, @code{gdbserver} option ++@strong{With target extended-remote mode:} You may specify the program to debug ++on the @code{gdbserver} command line, or you can load the program or attach ++to it using @value{GDBN} commands after connecting to @code{gdbserver}. ++ ++@anchor{--multi Option in Types of Remote Connnections} ++You can start @code{gdbserver} without supplying an initial command to run ++or process ID to attach. To do this, use the @option{--multi} command line ++option. Then you can connect using @code{target extended-remote} and start ++the program you want to debug (see below for details on using the ++@code{run} command in this scenario). Note that the conditions under which ++@code{gdbserver} terminates depend on how @value{GDBN} connects to it ++(@code{target remote} or @code{target extended-remote}). The ++@option{--multi} option to @code{gdbserver} has no influence on that. ++ ++@item The @code{run} command ++@strong{With target remote mode:} The @code{run} command is not ++supported. Once a connection has been established, you can use all ++the usual @value{GDBN} commands to examine and change data. The ++remote program is already running, so you can use commands like ++@kbd{step} and @kbd{continue}. ++ ++@strong{With target extended-remote mode:} The @code{run} command is ++supported. The @code{run} command uses the value set by ++@code{set remote exec-file} (@pxref{set remote exec-file}) to select ++the program to run. Command line arguments are supported, except for ++wildcard expansion and I/O redirection (@pxref{Arguments}). ++ ++If you specify the program to debug on the command line, then the ++@code{run} command is not required to start execution, and you can ++resume using commands like @kbd{step} and @kbd{continue} as with ++@code{target remote} mode. ++ ++@anchor{Attaching in Types of Remote Connections} ++@item Attaching ++@strong{With target remote mode:} The @value{GDBN} command @code{attach} is ++not supported. To attach to a running program using @code{gdbserver}, you ++must use the @option{--attach} option (@pxref{Running gdbserver}). ++ ++@strong{With target extended-remote mode:} To attach to a running program, ++you may use the @code{attach} command after the connection has been ++established. If you are using @code{gdbserver}, you may also invoke ++@code{gdbserver} using the @option{--attach} option ++(@pxref{Running gdbserver}). ++ ++Some remote targets allow @value{GDBN} to determine the executable file running ++in the process the debugger is attaching to. In such a case, @value{GDBN} ++uses the value of @code{exec-file-mismatch} to handle a possible mismatch ++between the executable file name running in the process and the name of the ++current exec-file loaded by @value{GDBN} (@pxref{set exec-file-mismatch}). ++ ++@end table ++ ++@anchor{Host and target files} ++@subsection Host and Target Files ++@cindex remote debugging, symbol files ++@cindex symbol files, remote debugging ++ ++@value{GDBN}, running on the host, needs access to symbol and debugging ++information for your program running on the target. This requires ++access to an unstripped copy of your program, and possibly any associated ++symbol files. Note that this section applies equally to both @code{target ++remote} mode and @code{target extended-remote} mode. ++ ++Some remote targets (@pxref{qXfer executable filename read}, and ++@pxref{Host I/O Packets}) allow @value{GDBN} to access program files over ++the same connection used to communicate with @value{GDBN}. With such a ++target, if the remote program is unstripped, the only command you need is ++@code{target remote} (or @code{target extended-remote}). ++ ++If the remote program is stripped, or the target does not support remote ++program file access, start up @value{GDBN} using the name of the local ++unstripped copy of your program as the first argument, or use the ++@code{file} command. Use @code{set sysroot} to specify the location (on ++the host) of target libraries (unless your @value{GDBN} was compiled with ++the correct sysroot using @code{--with-sysroot}). Alternatively, you ++may use @code{set solib-search-path} to specify how @value{GDBN} locates ++target libraries. ++ ++The symbol file and target libraries must exactly match the executable ++and libraries on the target, with one exception: the files on the host ++system should not be stripped, even if the files on the target system ++are. Mismatched or missing files will lead to confusing results ++during debugging. On @sc{gnu}/Linux targets, mismatched or missing ++files may also prevent @code{gdbserver} from debugging multi-threaded ++programs. ++ ++@subsection Remote Connection Commands ++@cindex remote connection commands ++@value{GDBN} can communicate with the target over a serial line, a ++local Unix domain socket, or ++over an @acronym{IP} network using @acronym{TCP} or @acronym{UDP}. In ++each case, @value{GDBN} uses the same protocol for debugging your ++program; only the medium carrying the debugging packets varies. The ++@code{target remote} and @code{target extended-remote} commands ++establish a connection to the target. Both commands accept the same ++arguments, which indicate the medium to use: ++ ++@table @code ++ ++@item target remote @var{serial-device} ++@itemx target extended-remote @var{serial-device} ++@cindex serial line, @code{target remote} ++Use @var{serial-device} to communicate with the target. For example, ++to use a serial line connected to the device named @file{/dev/ttyb}: ++ ++@smallexample ++target remote /dev/ttyb ++@end smallexample ++ ++If you're using a serial line, you may want to give @value{GDBN} the ++@samp{--baud} option, or use the @code{set serial baud} command ++(@pxref{Remote Configuration, set serial baud}) before the ++@code{target} command. ++ ++@item target remote @var{local-socket} ++@itemx target extended-remote @var{local-socket} ++@cindex local socket, @code{target remote} ++@cindex Unix domain socket ++Use @var{local-socket} to communicate with the target. For example, ++to use a local Unix domain socket bound to the file system entry @file{/tmp/gdb-socket0}: ++ ++@smallexample ++target remote /tmp/gdb-socket0 ++@end smallexample ++ ++Note that this command has the same form as the command to connect ++to a serial line. @value{GDBN} will automatically determine which ++kind of file you have specified and will make the appropriate kind ++of connection. ++This feature is not available if the host system does not support ++Unix domain sockets. ++ ++@item target remote @code{@var{host}:@var{port}} ++@itemx target remote @code{[@var{host}]:@var{port}} ++@itemx target remote @code{tcp:@var{host}:@var{port}} ++@itemx target remote @code{tcp:[@var{host}]:@var{port}} ++@itemx target remote @code{tcp4:@var{host}:@var{port}} ++@itemx target remote @code{tcp6:@var{host}:@var{port}} ++@itemx target remote @code{tcp6:[@var{host}]:@var{port}} ++@itemx target extended-remote @code{@var{host}:@var{port}} ++@itemx target extended-remote @code{[@var{host}]:@var{port}} ++@itemx target extended-remote @code{tcp:@var{host}:@var{port}} ++@itemx target extended-remote @code{tcp:[@var{host}]:@var{port}} ++@itemx target extended-remote @code{tcp4:@var{host}:@var{port}} ++@itemx target extended-remote @code{tcp6:@var{host}:@var{port}} ++@itemx target extended-remote @code{tcp6:[@var{host}]:@var{port}} ++@cindex @acronym{TCP} port, @code{target remote} ++Debug using a @acronym{TCP} connection to @var{port} on @var{host}. ++The @var{host} may be either a host name, a numeric @acronym{IPv4} ++address, or a numeric @acronym{IPv6} address (with or without the ++square brackets to separate the address from the port); @var{port} ++must be a decimal number. The @var{host} could be the target machine ++itself, if it is directly connected to the net, or it might be a ++terminal server which in turn has a serial line to the target. ++ ++For example, to connect to port 2828 on a terminal server named ++@code{manyfarms}: ++ ++@smallexample ++target remote manyfarms:2828 ++@end smallexample ++ ++To connect to port 2828 on a terminal server whose address is ++@code{2001:0db8:85a3:0000:0000:8a2e:0370:7334}, you can either use the ++square bracket syntax: ++ ++@smallexample ++target remote [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:2828 ++@end smallexample ++ ++@noindent ++or explicitly specify the @acronym{IPv6} protocol: ++ ++@smallexample ++target remote tcp6:2001:0db8:85a3:0000:0000:8a2e:0370:7334:2828 ++@end smallexample ++ ++This last example may be confusing to the reader, because there is no ++visible separation between the hostname and the port number. ++Therefore, we recommend the user to provide @acronym{IPv6} addresses ++using square brackets for clarity. However, it is important to ++mention that for @value{GDBN} there is no ambiguity: the number after ++the last colon is considered to be the port number. ++ ++If your remote target is actually running on the same machine as your ++debugger session (e.g.@: a simulator for your target running on the ++same host), you can omit the hostname. For example, to connect to ++port 1234 on your local machine: ++ ++@smallexample ++target remote :1234 ++@end smallexample ++@noindent ++ ++Note that the colon is still required here. ++ ++@item target remote @code{udp:@var{host}:@var{port}} ++@itemx target remote @code{udp:[@var{host}]:@var{port}} ++@itemx target remote @code{udp4:@var{host}:@var{port}} ++@itemx target remote @code{udp6:[@var{host}]:@var{port}} ++@itemx target extended-remote @code{udp:@var{host}:@var{port}} ++@itemx target extended-remote @code{udp:@var{host}:@var{port}} ++@itemx target extended-remote @code{udp:[@var{host}]:@var{port}} ++@itemx target extended-remote @code{udp4:@var{host}:@var{port}} ++@itemx target extended-remote @code{udp6:@var{host}:@var{port}} ++@itemx target extended-remote @code{udp6:[@var{host}]:@var{port}} ++@cindex @acronym{UDP} port, @code{target remote} ++Debug using @acronym{UDP} packets to @var{port} on @var{host}. For example, to ++connect to @acronym{UDP} port 2828 on a terminal server named @code{manyfarms}: ++ ++@smallexample ++target remote udp:manyfarms:2828 ++@end smallexample ++ ++When using a @acronym{UDP} connection for remote debugging, you should ++keep in mind that the `U' stands for ``Unreliable''. @acronym{UDP} ++can silently drop packets on busy or unreliable networks, which will ++cause havoc with your debugging session. ++ ++@item target remote | @var{command} ++@itemx target extended-remote | @var{command} ++@cindex pipe, @code{target remote} to ++Run @var{command} in the background and communicate with it using a ++pipe. The @var{command} is a shell command, to be parsed and expanded ++by the system's command shell, @code{/bin/sh}; it should expect remote ++protocol packets on its standard input, and send replies on its ++standard output. You could use this to run a stand-alone simulator ++that speaks the remote debugging protocol, to make net connections ++using programs like @code{ssh}, or for other similar tricks. ++ ++If @var{command} closes its standard output (perhaps by exiting), ++@value{GDBN} will try to send it a @code{SIGTERM} signal. (If the ++program has already exited, this will have no effect.) ++ ++@end table ++ ++@cindex interrupting remote programs ++@cindex remote programs, interrupting ++Whenever @value{GDBN} is waiting for the remote program, if you type the ++interrupt character (often @kbd{Ctrl-c}), @value{GDBN} attempts to stop the ++program. This may or may not succeed, depending in part on the hardware ++and the serial drivers the remote system uses. If you type the ++interrupt character once again, @value{GDBN} displays this prompt: ++ ++@smallexample ++Interrupted while waiting for the program. ++Give up (and stop debugging it)? (y or n) ++@end smallexample ++ ++In @code{target remote} mode, if you type @kbd{y}, @value{GDBN} abandons ++the remote debugging session. (If you decide you want to try again later, ++you can use @kbd{target remote} again to connect once more.) If you type ++@kbd{n}, @value{GDBN} goes back to waiting. ++ ++In @code{target extended-remote} mode, typing @kbd{n} will leave ++@value{GDBN} connected to the target. ++ ++@table @code ++@kindex detach (remote) ++@item detach ++When you have finished debugging the remote program, you can use the ++@code{detach} command to release it from @value{GDBN} control. ++Detaching from the target normally resumes its execution, but the results ++will depend on your particular remote stub. After the @code{detach} ++command in @code{target remote} mode, @value{GDBN} is free to connect to ++another target. In @code{target extended-remote} mode, @value{GDBN} is ++still connected to the target. ++ ++@kindex disconnect ++@item disconnect ++The @code{disconnect} command closes the connection to the target, and ++the target is generally not resumed. It will wait for @value{GDBN} ++(this instance or another one) to connect and continue debugging. After ++the @code{disconnect} command, @value{GDBN} is again free to connect to ++another target. ++ ++@cindex send command to remote monitor ++@cindex extend @value{GDBN} for remote targets ++@cindex add new commands for external monitor ++@kindex monitor ++@item monitor @var{cmd} ++This command allows you to send arbitrary commands directly to the ++remote monitor. Since @value{GDBN} doesn't care about the commands it ++sends like this, this command is the way to extend @value{GDBN}---you ++can add new commands that only the external monitor will understand ++and implement. ++@end table ++ ++@node File Transfer ++@section Sending files to a remote system ++@cindex remote target, file transfer ++@cindex file transfer ++@cindex sending files to remote systems ++ ++Some remote targets offer the ability to transfer files over the same ++connection used to communicate with @value{GDBN}. This is convenient ++for targets accessible through other means, e.g.@: @sc{gnu}/Linux systems ++running @code{gdbserver} over a network interface. For other targets, ++e.g.@: embedded devices with only a single serial port, this may be ++the only way to upload or download files. ++ ++Not all remote targets support these commands. ++ ++@table @code ++@kindex remote put ++@item remote put @var{hostfile} @var{targetfile} ++Copy file @var{hostfile} from the host system (the machine running ++@value{GDBN}) to @var{targetfile} on the target system. ++ ++@kindex remote get ++@item remote get @var{targetfile} @var{hostfile} ++Copy file @var{targetfile} from the target system to @var{hostfile} ++on the host system. ++ ++@kindex remote delete ++@item remote delete @var{targetfile} ++Delete @var{targetfile} from the target system. ++ ++@end table ++ ++@node Server ++@section Using the @code{gdbserver} Program ++ ++@kindex gdbserver ++@cindex remote connection without stubs ++@code{gdbserver} is a control program for Unix-like systems, which ++allows you to connect your program with a remote @value{GDBN} via ++@code{target remote} or @code{target extended-remote}---but without ++linking in the usual debugging stub. ++ ++@code{gdbserver} is not a complete replacement for the debugging stubs, ++because it requires essentially the same operating-system facilities ++that @value{GDBN} itself does. In fact, a system that can run ++@code{gdbserver} to connect to a remote @value{GDBN} could also run ++@value{GDBN} locally! @code{gdbserver} is sometimes useful nevertheless, ++because it is a much smaller program than @value{GDBN} itself. It is ++also easier to port than all of @value{GDBN}, so you may be able to get ++started more quickly on a new system by using @code{gdbserver}. ++Finally, if you develop code for real-time systems, you may find that ++the tradeoffs involved in real-time operation make it more convenient to ++do as much development work as possible on another system, for example ++by cross-compiling. You can use @code{gdbserver} to make a similar ++choice for debugging. ++ ++@value{GDBN} and @code{gdbserver} communicate via either a serial line ++or a TCP connection, using the standard @value{GDBN} remote serial ++protocol. ++ ++@quotation ++@emph{Warning:} @code{gdbserver} does not have any built-in security. ++Do not run @code{gdbserver} connected to any public network; a ++@value{GDBN} connection to @code{gdbserver} provides access to the ++target system with the same privileges as the user running ++@code{gdbserver}. ++@end quotation ++ ++@anchor{Running gdbserver} ++@subsection Running @code{gdbserver} ++@cindex arguments, to @code{gdbserver} ++@cindex @code{gdbserver}, command-line arguments ++ ++Run @code{gdbserver} on the target system. You need a copy of the ++program you want to debug, including any libraries it requires. ++@code{gdbserver} does not need your program's symbol table, so you can ++strip the program if necessary to save space. @value{GDBN} on the host ++system does all the symbol handling. ++ ++To use the server, you must tell it how to communicate with @value{GDBN}; ++the name of your program; and the arguments for your program. The usual ++syntax is: ++ ++@smallexample ++target> gdbserver @var{comm} @var{program} [ @var{args} @dots{} ] ++@end smallexample ++ ++@var{comm} is either a device name (to use a serial line), or a TCP ++hostname and portnumber, or @code{-} or @code{stdio} to use ++stdin/stdout of @code{gdbserver}. ++For example, to debug Emacs with the argument ++@samp{foo.txt} and communicate with @value{GDBN} over the serial port ++@file{/dev/com1}: ++ ++@smallexample ++target> gdbserver /dev/com1 emacs foo.txt ++@end smallexample ++ ++@code{gdbserver} waits passively for the host @value{GDBN} to communicate ++with it. ++ ++To use a TCP connection instead of a serial line: ++ ++@smallexample ++target> gdbserver host:2345 emacs foo.txt ++@end smallexample ++ ++The only difference from the previous example is the first argument, ++specifying that you are communicating with the host @value{GDBN} via ++TCP. The @samp{host:2345} argument means that @code{gdbserver} is to ++expect a TCP connection from machine @samp{host} to local TCP port 2345. ++(Currently, the @samp{host} part is ignored.) You can choose any number ++you want for the port number as long as it does not conflict with any ++TCP ports already in use on the target system (for example, @code{23} is ++reserved for @code{telnet}).@footnote{If you choose a port number that ++conflicts with another service, @code{gdbserver} prints an error message ++and exits.} You must use the same port number with the host @value{GDBN} ++@code{target remote} command. ++ ++The @code{stdio} connection is useful when starting @code{gdbserver} ++with ssh: ++ ++@smallexample ++(gdb) target remote | ssh -T hostname gdbserver - hello ++@end smallexample ++ ++The @samp{-T} option to ssh is provided because we don't need a remote pty, ++and we don't want escape-character handling. Ssh does this by default when ++a command is provided, the flag is provided to make it explicit. ++You could elide it if you want to. ++ ++Programs started with stdio-connected gdbserver have @file{/dev/null} for ++@code{stdin}, and @code{stdout},@code{stderr} are sent back to gdb for ++display through a pipe connected to gdbserver. ++Both @code{stdout} and @code{stderr} use the same pipe. ++ ++@anchor{Attaching to a program} ++@subsubsection Attaching to a Running Program ++@cindex attach to a program, @code{gdbserver} ++@cindex @option{--attach}, @code{gdbserver} option ++ ++On some targets, @code{gdbserver} can also attach to running programs. ++This is accomplished via the @code{--attach} argument. The syntax is: ++ ++@smallexample ++target> gdbserver --attach @var{comm} @var{pid} ++@end smallexample ++ ++@var{pid} is the process ID of a currently running process. It isn't ++necessary to point @code{gdbserver} at a binary for the running process. ++ ++In @code{target extended-remote} mode, you can also attach using the ++@value{GDBN} attach command ++(@pxref{Attaching in Types of Remote Connections}). ++ ++@pindex pidof ++You can debug processes by name instead of process ID if your target has the ++@code{pidof} utility: ++ ++@smallexample ++target> gdbserver --attach @var{comm} `pidof @var{program}` ++@end smallexample ++ ++In case more than one copy of @var{program} is running, or @var{program} ++has multiple threads, most versions of @code{pidof} support the ++@code{-s} option to only return the first process ID. ++ ++@subsubsection TCP port allocation lifecycle of @code{gdbserver} ++ ++This section applies only when @code{gdbserver} is run to listen on a TCP ++port. ++ ++@code{gdbserver} normally terminates after all of its debugged processes have ++terminated in @kbd{target remote} mode. On the other hand, for @kbd{target ++extended-remote}, @code{gdbserver} stays running even with no processes left. ++@value{GDBN} normally terminates the spawned debugged process on its exit, ++which normally also terminates @code{gdbserver} in the @kbd{target remote} ++mode. Therefore, when the connection drops unexpectedly, and @value{GDBN} ++cannot ask @code{gdbserver} to kill its debugged processes, @code{gdbserver} ++stays running even in the @kbd{target remote} mode. ++ ++When @code{gdbserver} stays running, @value{GDBN} can connect to it again later. ++Such reconnecting is useful for features like @ref{disconnected tracing}. For ++completeness, at most one @value{GDBN} can be connected at a time. ++ ++@cindex @option{--once}, @code{gdbserver} option ++By default, @code{gdbserver} keeps the listening TCP port open, so that ++subsequent connections are possible. However, if you start @code{gdbserver} ++with the @option{--once} option, it will stop listening for any further ++connection attempts after connecting to the first @value{GDBN} session. This ++means no further connections to @code{gdbserver} will be possible after the ++first one. It also means @code{gdbserver} will terminate after the first ++connection with remote @value{GDBN} has closed, even for unexpectedly closed ++connections and even in the @kbd{target extended-remote} mode. The ++@option{--once} option allows reusing the same port number for connecting to ++multiple instances of @code{gdbserver} running on the same host, since each ++instance closes its port after the first connection. ++ ++@anchor{Other Command-Line Arguments for gdbserver} ++@subsubsection Other Command-Line Arguments for @code{gdbserver} ++ ++You can use the @option{--multi} option to start @code{gdbserver} without ++specifying a program to debug or a process to attach to. Then you can ++attach in @code{target extended-remote} mode and run or attach to a ++program. For more information, ++@pxref{--multi Option in Types of Remote Connnections}. ++ ++@cindex @option{--debug}, @code{gdbserver} option ++The @option{--debug} option tells @code{gdbserver} to display extra ++status information about the debugging process. ++@cindex @option{--remote-debug}, @code{gdbserver} option ++The @option{--remote-debug} option tells @code{gdbserver} to display ++remote protocol debug output. ++@cindex @option{--debug-file}, @code{gdbserver} option ++@cindex @code{gdbserver}, send all debug output to a single file ++The @option{--debug-file=@var{filename}} option tells @code{gdbserver} to ++write any debug output to the given @var{filename}. These options are intended ++for @code{gdbserver} development and for bug reports to the developers. ++ ++@cindex @option{--debug-format}, @code{gdbserver} option ++The @option{--debug-format=option1[,option2,...]} option tells ++@code{gdbserver} to include additional information in each output. ++Possible options are: ++ ++@table @code ++@item none ++Turn off all extra information in debugging output. ++@item all ++Turn on all extra information in debugging output. ++@item timestamps ++Include a timestamp in each line of debugging output. ++@end table ++ ++Options are processed in order. Thus, for example, if @option{none} ++appears last then no additional information is added to debugging output. ++ ++@cindex @option{--wrapper}, @code{gdbserver} option ++The @option{--wrapper} option specifies a wrapper to launch programs ++for debugging. The option should be followed by the name of the ++wrapper, then any command-line arguments to pass to the wrapper, then ++@kbd{--} indicating the end of the wrapper arguments. ++ ++@code{gdbserver} runs the specified wrapper program with a combined ++command line including the wrapper arguments, then the name of the ++program to debug, then any arguments to the program. The wrapper ++runs until it executes your program, and then @value{GDBN} gains control. ++ ++You can use any program that eventually calls @code{execve} with ++its arguments as a wrapper. Several standard Unix utilities do ++this, e.g.@: @code{env} and @code{nohup}. Any Unix shell script ending ++with @code{exec "$@@"} will also work. ++ ++For example, you can use @code{env} to pass an environment variable to ++the debugged program, without setting the variable in @code{gdbserver}'s ++environment: ++ ++@smallexample ++$ gdbserver --wrapper env LD_PRELOAD=libtest.so -- :2222 ./testprog ++@end smallexample ++ ++@cindex @option{--selftest} ++The @option{--selftest} option runs the self tests in @code{gdbserver}: ++ ++@smallexample ++$ gdbserver --selftest ++Ran 2 unit tests, 0 failed ++@end smallexample ++ ++These tests are disabled in release. ++@subsection Connecting to @code{gdbserver} ++ ++The basic procedure for connecting to the remote target is: ++@itemize ++ ++@item ++Run @value{GDBN} on the host system. ++ ++@item ++Make sure you have the necessary symbol files ++(@pxref{Host and target files}). ++Load symbols for your application using the @code{file} command before you ++connect. Use @code{set sysroot} to locate target libraries (unless your ++@value{GDBN} was compiled with the correct sysroot using ++@code{--with-sysroot}). ++ ++@item ++Connect to your target (@pxref{Connecting,,Connecting to a Remote Target}). ++For TCP connections, you must start up @code{gdbserver} prior to using ++the @code{target} command. Otherwise you may get an error whose ++text depends on the host system, but which usually looks something like ++@samp{Connection refused}. Don't use the @code{load} ++command in @value{GDBN} when using @code{target remote} mode, since the ++program is already on the target. ++ ++@end itemize ++ ++@anchor{Monitor Commands for gdbserver} ++@subsection Monitor Commands for @code{gdbserver} ++@cindex monitor commands, for @code{gdbserver} ++ ++During a @value{GDBN} session using @code{gdbserver}, you can use the ++@code{monitor} command to send special requests to @code{gdbserver}. ++Here are the available commands. ++ ++@table @code ++@item monitor help ++List the available monitor commands. ++ ++@item monitor set debug 0 ++@itemx monitor set debug 1 ++Disable or enable general debugging messages. ++ ++@item monitor set remote-debug 0 ++@itemx monitor set remote-debug 1 ++Disable or enable specific debugging messages associated with the remote ++protocol (@pxref{Remote Protocol}). ++ ++@item monitor set debug-file filename ++@itemx monitor set debug-file ++Send any debug output to the given file, or to stderr. ++ ++@item monitor set debug-format option1@r{[},option2,...@r{]} ++Specify additional text to add to debugging messages. ++Possible options are: ++ ++@table @code ++@item none ++Turn off all extra information in debugging output. ++@item all ++Turn on all extra information in debugging output. ++@item timestamps ++Include a timestamp in each line of debugging output. ++@end table ++ ++Options are processed in order. Thus, for example, if @option{none} ++appears last then no additional information is added to debugging output. ++ ++@item monitor set libthread-db-search-path [PATH] ++@cindex gdbserver, search path for @code{libthread_db} ++When this command is issued, @var{path} is a colon-separated list of ++directories to search for @code{libthread_db} (@pxref{Threads,,set ++libthread-db-search-path}). If you omit @var{path}, ++@samp{libthread-db-search-path} will be reset to its default value. ++ ++The special entry @samp{$pdir} for @samp{libthread-db-search-path} is ++not supported in @code{gdbserver}. ++ ++@item monitor exit ++Tell gdbserver to exit immediately. This command should be followed by ++@code{disconnect} to close the debugging session. @code{gdbserver} will ++detach from any attached processes and kill any processes it created. ++Use @code{monitor exit} to terminate @code{gdbserver} at the end ++of a multi-process mode debug session. ++ ++@end table ++ ++@subsection Tracepoints support in @code{gdbserver} ++@cindex tracepoints support in @code{gdbserver} ++ ++On some targets, @code{gdbserver} supports tracepoints, fast ++tracepoints and static tracepoints. ++ ++For fast or static tracepoints to work, a special library called the ++@dfn{in-process agent} (IPA), must be loaded in the inferior process. ++This library is built and distributed as an integral part of ++@code{gdbserver}. In addition, support for static tracepoints ++requires building the in-process agent library with static tracepoints ++support. At present, the UST (LTTng Userspace Tracer, ++@url{http://lttng.org/ust}) tracing engine is supported. This support ++is automatically available if UST development headers are found in the ++standard include path when @code{gdbserver} is built, or if ++@code{gdbserver} was explicitly configured using @option{--with-ust} ++to point at such headers. You can explicitly disable the support ++using @option{--with-ust=no}. ++ ++There are several ways to load the in-process agent in your program: ++ ++@table @code ++@item Specifying it as dependency at link time ++ ++You can link your program dynamically with the in-process agent ++library. On most systems, this is accomplished by adding ++@code{-linproctrace} to the link command. ++ ++@item Using the system's preloading mechanisms ++ ++You can force loading the in-process agent at startup time by using ++your system's support for preloading shared libraries. Many Unixes ++support the concept of preloading user defined libraries. In most ++cases, you do that by specifying @code{LD_PRELOAD=libinproctrace.so} ++in the environment. See also the description of @code{gdbserver}'s ++@option{--wrapper} command line option. ++ ++@item Using @value{GDBN} to force loading the agent at run time ++ ++On some systems, you can force the inferior to load a shared library, ++by calling a dynamic loader function in the inferior that takes care ++of dynamically looking up and loading a shared library. On most Unix ++systems, the function is @code{dlopen}. You'll use the @code{call} ++command for that. For example: ++ ++@smallexample ++(@value{GDBP}) call dlopen ("libinproctrace.so", ...) ++@end smallexample ++ ++Note that on most Unix systems, for the @code{dlopen} function to be ++available, the program needs to be linked with @code{-ldl}. ++@end table ++ ++On systems that have a userspace dynamic loader, like most Unix ++systems, when you connect to @code{gdbserver} using @code{target ++remote}, you'll find that the program is stopped at the dynamic ++loader's entry point, and no shared library has been loaded in the ++program's address space yet, including the in-process agent. In that ++case, before being able to use any of the fast or static tracepoints ++features, you need to let the loader run and load the shared ++libraries. The simplest way to do that is to run the program to the ++main procedure. E.g., if debugging a C or C@t{++} program, start ++@code{gdbserver} like so: ++ ++@smallexample ++$ gdbserver :9999 myprogram ++@end smallexample ++ ++Start GDB and connect to @code{gdbserver} like so, and run to main: ++ ++@smallexample ++$ gdb myprogram ++(@value{GDBP}) target remote myhost:9999 ++0x00007f215893ba60 in ?? () from /lib64/ld-linux-x86-64.so.2 ++(@value{GDBP}) b main ++(@value{GDBP}) continue ++@end smallexample ++ ++The in-process tracing agent library should now be loaded into the ++process; you can confirm it with the @code{info sharedlibrary} ++command, which will list @file{libinproctrace.so} as loaded in the ++process. You are now ready to install fast tracepoints, list static ++tracepoint markers, probe static tracepoints markers, and start ++tracing. ++ ++@node Remote Configuration ++@section Remote Configuration ++ ++@kindex set remote ++@kindex show remote ++This section documents the configuration options available when ++debugging remote programs. For the options related to the File I/O ++extensions of the remote protocol, see @ref{system, ++system-call-allowed}. ++ ++@table @code ++@item set remoteaddresssize @var{bits} ++@cindex address size for remote targets ++@cindex bits in remote address ++Set the maximum size of address in a memory packet to the specified ++number of bits. @value{GDBN} will mask off the address bits above ++that number, when it passes addresses to the remote target. The ++default value is the number of bits in the target's address. ++ ++@item show remoteaddresssize ++Show the current value of remote address size in bits. ++ ++@item set serial baud @var{n} ++@cindex baud rate for remote targets ++Set the baud rate for the remote serial I/O to @var{n} baud. The ++value is used to set the speed of the serial port used for debugging ++remote targets. ++ ++@item show serial baud ++Show the current speed of the remote connection. ++ ++@item set serial parity @var{parity} ++Set the parity for the remote serial I/O. Supported values of @var{parity} are: ++@code{even}, @code{none}, and @code{odd}. The default is @code{none}. ++ ++@item show serial parity ++Show the current parity of the serial port. ++ ++@item set remotebreak ++@cindex interrupt remote programs ++@cindex BREAK signal instead of Ctrl-C ++@anchor{set remotebreak} ++If set to on, @value{GDBN} sends a @code{BREAK} signal to the remote ++when you type @kbd{Ctrl-c} to interrupt the program running ++on the remote. If set to off, @value{GDBN} sends the @samp{Ctrl-C} ++character instead. The default is off, since most remote systems ++expect to see @samp{Ctrl-C} as the interrupt signal. ++ ++@item show remotebreak ++Show whether @value{GDBN} sends @code{BREAK} or @samp{Ctrl-C} to ++interrupt the remote program. ++ ++@item set remoteflow on ++@itemx set remoteflow off ++@kindex set remoteflow ++Enable or disable hardware flow control (@code{RTS}/@code{CTS}) ++on the serial port used to communicate to the remote target. ++ ++@item show remoteflow ++@kindex show remoteflow ++Show the current setting of hardware flow control. ++ ++@item set remotelogbase @var{base} ++Set the base (a.k.a.@: radix) of logging serial protocol ++communications to @var{base}. Supported values of @var{base} are: ++@code{ascii}, @code{octal}, and @code{hex}. The default is ++@code{ascii}. ++ ++@item show remotelogbase ++Show the current setting of the radix for logging remote serial ++protocol. ++ ++@item set remotelogfile @var{file} ++@cindex record serial communications on file ++Record remote serial communications on the named @var{file}. The ++default is not to record at all. ++ ++@item show remotelogfile ++Show the current setting of the file name on which to record the ++serial communications. ++ ++@item set remotetimeout @var{num} ++@cindex timeout for serial communications ++@cindex remote timeout ++Set the timeout limit to wait for the remote target to respond to ++@var{num} seconds. The default is 2 seconds. ++ ++@item show remotetimeout ++Show the current number of seconds to wait for the remote target ++responses. ++ ++@cindex limit hardware breakpoints and watchpoints ++@cindex remote target, limit break- and watchpoints ++@anchor{set remote hardware-watchpoint-limit} ++@anchor{set remote hardware-breakpoint-limit} ++@item set remote hardware-watchpoint-limit @var{limit} ++@itemx set remote hardware-breakpoint-limit @var{limit} ++Restrict @value{GDBN} to using @var{limit} remote hardware watchpoints ++or breakpoints. The @var{limit} can be set to 0 to disable hardware ++watchpoints or breakpoints, and @code{unlimited} for unlimited ++watchpoints or breakpoints. ++ ++@item show remote hardware-watchpoint-limit ++@itemx show remote hardware-breakpoint-limit ++Show the current limit for the number of hardware watchpoints or ++breakpoints that @value{GDBN} can use. ++ ++@cindex limit hardware watchpoints length ++@cindex remote target, limit watchpoints length ++@anchor{set remote hardware-watchpoint-length-limit} ++@item set remote hardware-watchpoint-length-limit @var{limit} ++Restrict @value{GDBN} to using @var{limit} bytes for the maximum ++length of a remote hardware watchpoint. A @var{limit} of 0 disables ++hardware watchpoints and @code{unlimited} allows watchpoints of any ++length. ++ ++@item show remote hardware-watchpoint-length-limit ++Show the current limit (in bytes) of the maximum length of ++a remote hardware watchpoint. ++ ++@item set remote exec-file @var{filename} ++@itemx show remote exec-file ++@anchor{set remote exec-file} ++@cindex executable file, for remote target ++Select the file used for @code{run} with @code{target ++extended-remote}. This should be set to a filename valid on the ++target system. If it is not set, the target will use a default ++filename (e.g.@: the last program run). ++ ++@item set remote interrupt-sequence ++@cindex interrupt remote programs ++@cindex select Ctrl-C, BREAK or BREAK-g ++Allow the user to select one of @samp{Ctrl-C}, a @code{BREAK} or ++@samp{BREAK-g} as the ++sequence to the remote target in order to interrupt the execution. ++@samp{Ctrl-C} is a default. Some system prefers @code{BREAK} which ++is high level of serial line for some certain time. ++Linux kernel prefers @samp{BREAK-g}, a.k.a Magic SysRq g. ++It is @code{BREAK} signal followed by character @code{g}. ++ ++@item show interrupt-sequence ++Show which of @samp{Ctrl-C}, @code{BREAK} or @code{BREAK-g} ++is sent by @value{GDBN} to interrupt the remote program. ++@code{BREAK-g} is BREAK signal followed by @code{g} and ++also known as Magic SysRq g. ++ ++@item set remote interrupt-on-connect ++@cindex send interrupt-sequence on start ++Specify whether interrupt-sequence is sent to remote target when ++@value{GDBN} connects to it. This is mostly needed when you debug ++Linux kernel. Linux kernel expects @code{BREAK} followed by @code{g} ++which is known as Magic SysRq g in order to connect @value{GDBN}. ++ ++@item show interrupt-on-connect ++Show whether interrupt-sequence is sent ++to remote target when @value{GDBN} connects to it. ++ ++@kindex set tcp ++@kindex show tcp ++@item set tcp auto-retry on ++@cindex auto-retry, for remote TCP target ++Enable auto-retry for remote TCP connections. This is useful if the remote ++debugging agent is launched in parallel with @value{GDBN}; there is a race ++condition because the agent may not become ready to accept the connection ++before @value{GDBN} attempts to connect. When auto-retry is ++enabled, if the initial attempt to connect fails, @value{GDBN} reattempts ++to establish the connection using the timeout specified by ++@code{set tcp connect-timeout}. ++ ++@item set tcp auto-retry off ++Do not auto-retry failed TCP connections. ++ ++@item show tcp auto-retry ++Show the current auto-retry setting. ++ ++@item set tcp connect-timeout @var{seconds} ++@itemx set tcp connect-timeout unlimited ++@cindex connection timeout, for remote TCP target ++@cindex timeout, for remote target connection ++Set the timeout for establishing a TCP connection to the remote target to ++@var{seconds}. The timeout affects both polling to retry failed connections ++(enabled by @code{set tcp auto-retry on}) and waiting for connections ++that are merely slow to complete, and represents an approximate cumulative ++value. If @var{seconds} is @code{unlimited}, there is no timeout and ++@value{GDBN} will keep attempting to establish a connection forever, ++unless interrupted with @kbd{Ctrl-c}. The default is 15 seconds. ++ ++@item show tcp connect-timeout ++Show the current connection timeout setting. ++@end table ++ ++@cindex remote packets, enabling and disabling ++The @value{GDBN} remote protocol autodetects the packets supported by ++your debugging stub. If you need to override the autodetection, you ++can use these commands to enable or disable individual packets. Each ++packet can be set to @samp{on} (the remote target supports this ++packet), @samp{off} (the remote target does not support this packet), ++or @samp{auto} (detect remote target support for this packet). They ++all default to @samp{auto}. For more information about each packet, ++see @ref{Remote Protocol}. ++ ++During normal use, you should not have to use any of these commands. ++If you do, that may be a bug in your remote debugging stub, or a bug ++in @value{GDBN}. You may want to report the problem to the ++@value{GDBN} developers. ++ ++For each packet @var{name}, the command to enable or disable the ++packet is @code{set remote @var{name}-packet}. The available settings ++are: ++ ++@multitable @columnfractions 0.28 0.32 0.25 ++@item Command Name ++@tab Remote Packet ++@tab Related Features ++ ++@item @code{fetch-register} ++@tab @code{p} ++@tab @code{info registers} ++ ++@item @code{set-register} ++@tab @code{P} ++@tab @code{set} ++ ++@item @code{binary-download} ++@tab @code{X} ++@tab @code{load}, @code{set} ++ ++@item @code{read-aux-vector} ++@tab @code{qXfer:auxv:read} ++@tab @code{info auxv} ++ ++@item @code{symbol-lookup} ++@tab @code{qSymbol} ++@tab Detecting multiple threads ++ ++@item @code{attach} ++@tab @code{vAttach} ++@tab @code{attach} ++ ++@item @code{verbose-resume} ++@tab @code{vCont} ++@tab Stepping or resuming multiple threads ++ ++@item @code{run} ++@tab @code{vRun} ++@tab @code{run} ++ ++@item @code{software-breakpoint} ++@tab @code{Z0} ++@tab @code{break} ++ ++@item @code{hardware-breakpoint} ++@tab @code{Z1} ++@tab @code{hbreak} ++ ++@item @code{write-watchpoint} ++@tab @code{Z2} ++@tab @code{watch} ++ ++@item @code{read-watchpoint} ++@tab @code{Z3} ++@tab @code{rwatch} ++ ++@item @code{access-watchpoint} ++@tab @code{Z4} ++@tab @code{awatch} ++ ++@item @code{pid-to-exec-file} ++@tab @code{qXfer:exec-file:read} ++@tab @code{attach}, @code{run} ++ ++@item @code{target-features} ++@tab @code{qXfer:features:read} ++@tab @code{set architecture} ++ ++@item @code{library-info} ++@tab @code{qXfer:libraries:read} ++@tab @code{info sharedlibrary} ++ ++@item @code{memory-map} ++@tab @code{qXfer:memory-map:read} ++@tab @code{info mem} ++ ++@item @code{read-sdata-object} ++@tab @code{qXfer:sdata:read} ++@tab @code{print $_sdata} ++ ++@item @code{read-siginfo-object} ++@tab @code{qXfer:siginfo:read} ++@tab @code{print $_siginfo} ++ ++@item @code{write-siginfo-object} ++@tab @code{qXfer:siginfo:write} ++@tab @code{set $_siginfo} ++ ++@item @code{threads} ++@tab @code{qXfer:threads:read} ++@tab @code{info threads} ++ ++@item @code{get-thread-local-@*storage-address} ++@tab @code{qGetTLSAddr} ++@tab Displaying @code{__thread} variables ++ ++@item @code{get-thread-information-block-address} ++@tab @code{qGetTIBAddr} ++@tab Display MS-Windows Thread Information Block. ++ ++@item @code{search-memory} ++@tab @code{qSearch:memory} ++@tab @code{find} ++ ++@item @code{supported-packets} ++@tab @code{qSupported} ++@tab Remote communications parameters ++ ++@item @code{catch-syscalls} ++@tab @code{QCatchSyscalls} ++@tab @code{catch syscall} ++ ++@item @code{pass-signals} ++@tab @code{QPassSignals} ++@tab @code{handle @var{signal}} ++ ++@item @code{program-signals} ++@tab @code{QProgramSignals} ++@tab @code{handle @var{signal}} ++ ++@item @code{hostio-close-packet} ++@tab @code{vFile:close} ++@tab @code{remote get}, @code{remote put} ++ ++@item @code{hostio-open-packet} ++@tab @code{vFile:open} ++@tab @code{remote get}, @code{remote put} ++ ++@item @code{hostio-pread-packet} ++@tab @code{vFile:pread} ++@tab @code{remote get}, @code{remote put} ++ ++@item @code{hostio-pwrite-packet} ++@tab @code{vFile:pwrite} ++@tab @code{remote get}, @code{remote put} ++ ++@item @code{hostio-unlink-packet} ++@tab @code{vFile:unlink} ++@tab @code{remote delete} ++ ++@item @code{hostio-readlink-packet} ++@tab @code{vFile:readlink} ++@tab Host I/O ++ ++@item @code{hostio-fstat-packet} ++@tab @code{vFile:fstat} ++@tab Host I/O ++ ++@item @code{hostio-setfs-packet} ++@tab @code{vFile:setfs} ++@tab Host I/O ++ ++@item @code{noack-packet} ++@tab @code{QStartNoAckMode} ++@tab Packet acknowledgment ++ ++@item @code{osdata} ++@tab @code{qXfer:osdata:read} ++@tab @code{info os} ++ ++@item @code{query-attached} ++@tab @code{qAttached} ++@tab Querying remote process attach state. ++ ++@item @code{trace-buffer-size} ++@tab @code{QTBuffer:size} ++@tab @code{set trace-buffer-size} ++ ++@item @code{trace-status} ++@tab @code{qTStatus} ++@tab @code{tstatus} ++ ++@item @code{traceframe-info} ++@tab @code{qXfer:traceframe-info:read} ++@tab Traceframe info ++ ++@item @code{install-in-trace} ++@tab @code{InstallInTrace} ++@tab Install tracepoint in tracing ++ ++@item @code{disable-randomization} ++@tab @code{QDisableRandomization} ++@tab @code{set disable-randomization} ++ ++@item @code{startup-with-shell} ++@tab @code{QStartupWithShell} ++@tab @code{set startup-with-shell} ++ ++@item @code{environment-hex-encoded} ++@tab @code{QEnvironmentHexEncoded} ++@tab @code{set environment} ++ ++@item @code{environment-unset} ++@tab @code{QEnvironmentUnset} ++@tab @code{unset environment} ++ ++@item @code{environment-reset} ++@tab @code{QEnvironmentReset} ++@tab @code{Reset the inferior environment (i.e., unset user-set variables)} ++ ++@item @code{set-working-dir} ++@tab @code{QSetWorkingDir} ++@tab @code{set cwd} ++ ++@item @code{conditional-breakpoints-packet} ++@tab @code{Z0 and Z1} ++@tab @code{Support for target-side breakpoint condition evaluation} ++ ++@item @code{multiprocess-extensions} ++@tab @code{multiprocess extensions} ++@tab Debug multiple processes and remote process PID awareness ++ ++@item @code{swbreak-feature} ++@tab @code{swbreak stop reason} ++@tab @code{break} ++ ++@item @code{hwbreak-feature} ++@tab @code{hwbreak stop reason} ++@tab @code{hbreak} ++ ++@item @code{fork-event-feature} ++@tab @code{fork stop reason} ++@tab @code{fork} ++ ++@item @code{vfork-event-feature} ++@tab @code{vfork stop reason} ++@tab @code{vfork} ++ ++@item @code{exec-event-feature} ++@tab @code{exec stop reason} ++@tab @code{exec} ++ ++@item @code{thread-events} ++@tab @code{QThreadEvents} ++@tab Tracking thread lifetime. ++ ++@item @code{no-resumed-stop-reply} ++@tab @code{no resumed thread left stop reply} ++@tab Tracking thread lifetime. ++ ++@end multitable ++ ++@node Remote Stub ++@section Implementing a Remote Stub ++ ++@cindex debugging stub, example ++@cindex remote stub, example ++@cindex stub example, remote debugging ++The stub files provided with @value{GDBN} implement the target side of the ++communication protocol, and the @value{GDBN} side is implemented in the ++@value{GDBN} source file @file{remote.c}. Normally, you can simply allow ++these subroutines to communicate, and ignore the details. (If you're ++implementing your own stub file, you can still ignore the details: start ++with one of the existing stub files. @file{sparc-stub.c} is the best ++organized, and therefore the easiest to read.) ++ ++@cindex remote serial debugging, overview ++To debug a program running on another machine (the debugging ++@dfn{target} machine), you must first arrange for all the usual ++prerequisites for the program to run by itself. For example, for a C ++program, you need: ++ ++@enumerate ++@item ++A startup routine to set up the C runtime environment; these usually ++have a name like @file{crt0}. The startup routine may be supplied by ++your hardware supplier, or you may have to write your own. ++ ++@item ++A C subroutine library to support your program's ++subroutine calls, notably managing input and output. ++ ++@item ++A way of getting your program to the other machine---for example, a ++download program. These are often supplied by the hardware ++manufacturer, but you may have to write your own from hardware ++documentation. ++@end enumerate ++ ++The next step is to arrange for your program to use a serial port to ++communicate with the machine where @value{GDBN} is running (the @dfn{host} ++machine). In general terms, the scheme looks like this: ++ ++@table @emph ++@item On the host, ++@value{GDBN} already understands how to use this protocol; when everything ++else is set up, you can simply use the @samp{target remote} command ++(@pxref{Targets,,Specifying a Debugging Target}). ++ ++@item On the target, ++you must link with your program a few special-purpose subroutines that ++implement the @value{GDBN} remote serial protocol. The file containing these ++subroutines is called a @dfn{debugging stub}. ++ ++On certain remote targets, you can use an auxiliary program ++@code{gdbserver} instead of linking a stub into your program. ++@xref{Server,,Using the @code{gdbserver} Program}, for details. ++@end table ++ ++The debugging stub is specific to the architecture of the remote ++machine; for example, use @file{sparc-stub.c} to debug programs on ++@sc{sparc} boards. ++ ++@cindex remote serial stub list ++These working remote stubs are distributed with @value{GDBN}: ++ ++@table @code ++ ++@item i386-stub.c ++@cindex @file{i386-stub.c} ++@cindex Intel ++@cindex i386 ++For Intel 386 and compatible architectures. ++ ++@item m68k-stub.c ++@cindex @file{m68k-stub.c} ++@cindex Motorola 680x0 ++@cindex m680x0 ++For Motorola 680x0 architectures. ++ ++@item sh-stub.c ++@cindex @file{sh-stub.c} ++@cindex Renesas ++@cindex SH ++For Renesas SH architectures. ++ ++@item sparc-stub.c ++@cindex @file{sparc-stub.c} ++@cindex Sparc ++For @sc{sparc} architectures. ++ ++@item sparcl-stub.c ++@cindex @file{sparcl-stub.c} ++@cindex Fujitsu ++@cindex SparcLite ++For Fujitsu @sc{sparclite} architectures. ++ ++@end table ++ ++The @file{README} file in the @value{GDBN} distribution may list other ++recently added stubs. ++ ++@menu ++* Stub Contents:: What the stub can do for you ++* Bootstrapping:: What you must do for the stub ++* Debug Session:: Putting it all together ++@end menu ++ ++@node Stub Contents ++@subsection What the Stub Can Do for You ++ ++@cindex remote serial stub ++The debugging stub for your architecture supplies these three ++subroutines: ++ ++@table @code ++@item set_debug_traps ++@findex set_debug_traps ++@cindex remote serial stub, initialization ++This routine arranges for @code{handle_exception} to run when your ++program stops. You must call this subroutine explicitly in your ++program's startup code. ++ ++@item handle_exception ++@findex handle_exception ++@cindex remote serial stub, main routine ++This is the central workhorse, but your program never calls it ++explicitly---the setup code arranges for @code{handle_exception} to ++run when a trap is triggered. ++ ++@code{handle_exception} takes control when your program stops during ++execution (for example, on a breakpoint), and mediates communications ++with @value{GDBN} on the host machine. This is where the communications ++protocol is implemented; @code{handle_exception} acts as the @value{GDBN} ++representative on the target machine. It begins by sending summary ++information on the state of your program, then continues to execute, ++retrieving and transmitting any information @value{GDBN} needs, until you ++execute a @value{GDBN} command that makes your program resume; at that point, ++@code{handle_exception} returns control to your own code on the target ++machine. ++ ++@item breakpoint ++@cindex @code{breakpoint} subroutine, remote ++Use this auxiliary subroutine to make your program contain a ++breakpoint. Depending on the particular situation, this may be the only ++way for @value{GDBN} to get control. For instance, if your target ++machine has some sort of interrupt button, you won't need to call this; ++pressing the interrupt button transfers control to ++@code{handle_exception}---in effect, to @value{GDBN}. On some machines, ++simply receiving characters on the serial port may also trigger a trap; ++again, in that situation, you don't need to call @code{breakpoint} from ++your own program---simply running @samp{target remote} from the host ++@value{GDBN} session gets control. ++ ++Call @code{breakpoint} if none of these is true, or if you simply want ++to make certain your program stops at a predetermined point for the ++start of your debugging session. ++@end table ++ ++@node Bootstrapping ++@subsection What You Must Do for the Stub ++ ++@cindex remote stub, support routines ++The debugging stubs that come with @value{GDBN} are set up for a particular ++chip architecture, but they have no information about the rest of your ++debugging target machine. ++ ++First of all you need to tell the stub how to communicate with the ++serial port. ++ ++@table @code ++@item int getDebugChar() ++@findex getDebugChar ++Write this subroutine to read a single character from the serial port. ++It may be identical to @code{getchar} for your target system; a ++different name is used to allow you to distinguish the two if you wish. ++ ++@item void putDebugChar(int) ++@findex putDebugChar ++Write this subroutine to write a single character to the serial port. ++It may be identical to @code{putchar} for your target system; a ++different name is used to allow you to distinguish the two if you wish. ++@end table ++ ++@cindex control C, and remote debugging ++@cindex interrupting remote targets ++If you want @value{GDBN} to be able to stop your program while it is ++running, you need to use an interrupt-driven serial driver, and arrange ++for it to stop when it receives a @code{^C} (@samp{\003}, the control-C ++character). That is the character which @value{GDBN} uses to tell the ++remote system to stop. ++ ++Getting the debugging target to return the proper status to @value{GDBN} ++probably requires changes to the standard stub; one quick and dirty way ++is to just execute a breakpoint instruction (the ``dirty'' part is that ++@value{GDBN} reports a @code{SIGTRAP} instead of a @code{SIGINT}). ++ ++Other routines you need to supply are: ++ ++@table @code ++@item void exceptionHandler (int @var{exception_number}, void *@var{exception_address}) ++@findex exceptionHandler ++Write this function to install @var{exception_address} in the exception ++handling tables. You need to do this because the stub does not have any ++way of knowing what the exception handling tables on your target system ++are like (for example, the processor's table might be in @sc{rom}, ++containing entries which point to a table in @sc{ram}). ++The @var{exception_number} specifies the exception which should be changed; ++its meaning is architecture-dependent (for example, different numbers ++might represent divide by zero, misaligned access, etc). When this ++exception occurs, control should be transferred directly to ++@var{exception_address}, and the processor state (stack, registers, ++and so on) should be just as it is when a processor exception occurs. So if ++you want to use a jump instruction to reach @var{exception_address}, it ++should be a simple jump, not a jump to subroutine. ++ ++For the 386, @var{exception_address} should be installed as an interrupt ++gate so that interrupts are masked while the handler runs. The gate ++should be at privilege level 0 (the most privileged level). The ++@sc{sparc} and 68k stubs are able to mask interrupts themselves without ++help from @code{exceptionHandler}. ++ ++@item void flush_i_cache() ++@findex flush_i_cache ++On @sc{sparc} and @sc{sparclite} only, write this subroutine to flush the ++instruction cache, if any, on your target machine. If there is no ++instruction cache, this subroutine may be a no-op. ++ ++On target machines that have instruction caches, @value{GDBN} requires this ++function to make certain that the state of your program is stable. ++@end table ++ ++@noindent ++You must also make sure this library routine is available: ++ ++@table @code ++@item void *memset(void *, int, int) ++@findex memset ++This is the standard library function @code{memset} that sets an area of ++memory to a known value. If you have one of the free versions of ++@code{libc.a}, @code{memset} can be found there; otherwise, you must ++either obtain it from your hardware manufacturer, or write your own. ++@end table ++ ++If you do not use the GNU C compiler, you may need other standard ++library subroutines as well; this varies from one stub to another, ++but in general the stubs are likely to use any of the common library ++subroutines which @code{@value{NGCC}} generates as inline code. ++ ++ ++@node Debug Session ++@subsection Putting it All Together ++ ++@cindex remote serial debugging summary ++In summary, when your program is ready to debug, you must follow these ++steps. ++ ++@enumerate ++@item ++Make sure you have defined the supporting low-level routines ++(@pxref{Bootstrapping,,What You Must Do for the Stub}): ++@display ++@code{getDebugChar}, @code{putDebugChar}, ++@code{flush_i_cache}, @code{memset}, @code{exceptionHandler}. ++@end display ++ ++@item ++Insert these lines in your program's startup code, before the main ++procedure is called: ++ ++@smallexample ++set_debug_traps(); ++breakpoint(); ++@end smallexample ++ ++On some machines, when a breakpoint trap is raised, the hardware ++automatically makes the PC point to the instruction after the ++breakpoint. If your machine doesn't do that, you may need to adjust ++@code{handle_exception} to arrange for it to return to the instruction ++after the breakpoint on this first invocation, so that your program ++doesn't keep hitting the initial breakpoint instead of making ++progress. ++ ++@item ++For the 680x0 stub only, you need to provide a variable called ++@code{exceptionHook}. Normally you just use: ++ ++@smallexample ++void (*exceptionHook)() = 0; ++@end smallexample ++ ++@noindent ++but if before calling @code{set_debug_traps}, you set it to point to a ++function in your program, that function is called when ++@code{@value{GDBN}} continues after stopping on a trap (for example, bus ++error). The function indicated by @code{exceptionHook} is called with ++one parameter: an @code{int} which is the exception number. ++ ++@item ++Compile and link together: your program, the @value{GDBN} debugging stub for ++your target architecture, and the supporting subroutines. ++ ++@item ++Make sure you have a serial connection between your target machine and ++the @value{GDBN} host, and identify the serial port on the host. ++ ++@item ++@c The "remote" target now provides a `load' command, so we should ++@c document that. FIXME. ++Download your program to your target machine (or get it there by ++whatever means the manufacturer provides), and start it. ++ ++@item ++Start @value{GDBN} on the host, and connect to the target ++(@pxref{Connecting,,Connecting to a Remote Target}). ++ ++@end enumerate ++ ++@node Configurations ++@chapter Configuration-Specific Information ++ ++While nearly all @value{GDBN} commands are available for all native and ++cross versions of the debugger, there are some exceptions. This chapter ++describes things that are only available in certain configurations. ++ ++There are three major categories of configurations: native ++configurations, where the host and target are the same, embedded ++operating system configurations, which are usually the same for several ++different processor architectures, and bare embedded processors, which ++are quite different from each other. ++ ++@menu ++* Native:: ++* Embedded OS:: ++* Embedded Processors:: ++* Architectures:: ++@end menu ++ ++@node Native ++@section Native ++ ++This section describes details specific to particular native ++configurations. ++ ++@menu ++* BSD libkvm Interface:: Debugging BSD kernel memory images ++* Process Information:: Process information ++* DJGPP Native:: Features specific to the DJGPP port ++* Cygwin Native:: Features specific to the Cygwin port ++* Hurd Native:: Features specific to @sc{gnu} Hurd ++* Darwin:: Features specific to Darwin ++* FreeBSD:: Features specific to FreeBSD ++@end menu ++ ++@node BSD libkvm Interface ++@subsection BSD libkvm Interface ++ ++@cindex libkvm ++@cindex kernel memory image ++@cindex kernel crash dump ++ ++BSD-derived systems (FreeBSD/NetBSD/OpenBSD) have a kernel memory ++interface that provides a uniform interface for accessing kernel virtual ++memory images, including live systems and crash dumps. @value{GDBN} ++uses this interface to allow you to debug live kernels and kernel crash ++dumps on many native BSD configurations. This is implemented as a ++special @code{kvm} debugging target. For debugging a live system, load ++the currently running kernel into @value{GDBN} and connect to the ++@code{kvm} target: ++ ++@smallexample ++(@value{GDBP}) @b{target kvm} ++@end smallexample ++ ++For debugging crash dumps, provide the file name of the crash dump as an ++argument: ++ ++@smallexample ++(@value{GDBP}) @b{target kvm /var/crash/bsd.0} ++@end smallexample ++ ++Once connected to the @code{kvm} target, the following commands are ++available: ++ ++@table @code ++@kindex kvm ++@item kvm pcb ++Set current context from the @dfn{Process Control Block} (PCB) address. ++ ++@item kvm proc ++Set current context from proc address. This command isn't available on ++modern FreeBSD systems. ++@end table ++ ++@node Process Information ++@subsection Process Information ++@cindex /proc ++@cindex examine process image ++@cindex process info via @file{/proc} ++ ++Some operating systems provide interfaces to fetch additional ++information about running processes beyond memory and per-thread ++register state. If @value{GDBN} is configured for an operating system ++with a supported interface, the command @code{info proc} is available ++to report information about the process running your program, or about ++any process running on your system. ++ ++One supported interface is a facility called @samp{/proc} that can be ++used to examine the image of a running process using file-system ++subroutines. This facility is supported on @sc{gnu}/Linux and Solaris ++systems. ++ ++On FreeBSD and NetBSD systems, system control nodes are used to query ++process information. ++ ++In addition, some systems may provide additional process information ++in core files. Note that a core file may include a subset of the ++information available from a live process. Process information is ++currently available from cores created on @sc{gnu}/Linux and FreeBSD ++systems. ++ ++@table @code ++@kindex info proc ++@cindex process ID ++@item info proc ++@itemx info proc @var{process-id} ++Summarize available information about a process. If a ++process ID is specified by @var{process-id}, display information about ++that process; otherwise display information about the program being ++debugged. The summary includes the debugged process ID, the command ++line used to invoke it, its current working directory, and its ++executable file's absolute file name. ++ ++On some systems, @var{process-id} can be of the form ++@samp{[@var{pid}]/@var{tid}} which specifies a certain thread ID ++within a process. If the optional @var{pid} part is missing, it means ++a thread from the process being debugged (the leading @samp{/} still ++needs to be present, or else @value{GDBN} will interpret the number as ++a process ID rather than a thread ID). ++ ++@item info proc cmdline ++@cindex info proc cmdline ++Show the original command line of the process. This command is ++supported on @sc{gnu}/Linux, FreeBSD and NetBSD. ++ ++@item info proc cwd ++@cindex info proc cwd ++Show the current working directory of the process. This command is ++supported on @sc{gnu}/Linux, FreeBSD and NetBSD. ++ ++@item info proc exe ++@cindex info proc exe ++Show the name of executable of the process. This command is supported ++on @sc{gnu}/Linux, FreeBSD and NetBSD. ++ ++@item info proc files ++@cindex info proc files ++Show the file descriptors open by the process. For each open file ++descriptor, @value{GDBN} shows its number, type (file, directory, ++character device, socket), file pointer offset, and the name of the ++resource open on the descriptor. The resource name can be a file name ++(for files, directories, and devices) or a protocol followed by socket ++address (for network connections). This command is supported on ++FreeBSD. ++ ++This example shows the open file descriptors for a process using a ++tty for standard input and output as well as two network sockets: ++ ++@smallexample ++(gdb) info proc files 22136 ++process 22136 ++Open files: ++ ++ FD Type Offset Flags Name ++ text file - r-------- /usr/bin/ssh ++ ctty chr - rw------- /dev/pts/20 ++ cwd dir - r-------- /usr/home/john ++ root dir - r-------- / ++ 0 chr 0x32933a4 rw------- /dev/pts/20 ++ 1 chr 0x32933a4 rw------- /dev/pts/20 ++ 2 chr 0x32933a4 rw------- /dev/pts/20 ++ 3 socket 0x0 rw----n-- tcp4 10.0.1.2:53014 -> 10.0.1.10:22 ++ 4 socket 0x0 rw------- unix stream:/tmp/ssh-FIt89oAzOn5f/agent.2456 ++@end smallexample ++ ++@item info proc mappings ++@cindex memory address space mappings ++Report the memory address space ranges accessible in a process. On ++Solaris, FreeBSD and NetBSD systems, each memory range includes information ++on whether the process has read, write, or execute access rights to each ++range. On @sc{gnu}/Linux, FreeBSD and NetBSD systems, each memory range ++includes the object file which is mapped to that range. ++ ++@item info proc stat ++@itemx info proc status ++@cindex process detailed status information ++Show additional process-related information, including the user ID and ++group ID; virtual memory usage; the signals that are pending, blocked, ++and ignored; its TTY; its consumption of system and user time; its ++stack size; its @samp{nice} value; etc. These commands are supported ++on @sc{gnu}/Linux, FreeBSD and NetBSD. ++ ++For @sc{gnu}/Linux systems, see the @samp{proc} man page for more ++information (type @kbd{man 5 proc} from your shell prompt). ++ ++For FreeBSD and NetBSD systems, @code{info proc stat} is an alias for ++@code{info proc status}. ++ ++@item info proc all ++Show all the information about the process described under all of the ++above @code{info proc} subcommands. ++ ++@ignore ++@comment These sub-options of 'info proc' were not included when ++@comment procfs.c was re-written. Keep their descriptions around ++@comment against the day when someone finds the time to put them back in. ++@kindex info proc times ++@item info proc times ++Starting time, user CPU time, and system CPU time for your program and ++its children. ++ ++@kindex info proc id ++@item info proc id ++Report on the process IDs related to your program: its own process ID, ++the ID of its parent, the process group ID, and the session ID. ++@end ignore ++ ++@item set procfs-trace ++@kindex set procfs-trace ++@cindex @code{procfs} API calls ++This command enables and disables tracing of @code{procfs} API calls. ++ ++@item show procfs-trace ++@kindex show procfs-trace ++Show the current state of @code{procfs} API call tracing. ++ ++@item set procfs-file @var{file} ++@kindex set procfs-file ++Tell @value{GDBN} to write @code{procfs} API trace to the named ++@var{file}. @value{GDBN} appends the trace info to the previous ++contents of the file. The default is to display the trace on the ++standard output. ++ ++@item show procfs-file ++@kindex show procfs-file ++Show the file to which @code{procfs} API trace is written. ++ ++@item proc-trace-entry ++@itemx proc-trace-exit ++@itemx proc-untrace-entry ++@itemx proc-untrace-exit ++@kindex proc-trace-entry ++@kindex proc-trace-exit ++@kindex proc-untrace-entry ++@kindex proc-untrace-exit ++These commands enable and disable tracing of entries into and exits ++from the @code{syscall} interface. ++ ++@item info pidlist ++@kindex info pidlist ++@cindex process list, QNX Neutrino ++For QNX Neutrino only, this command displays the list of all the ++processes and all the threads within each process. ++ ++@item info meminfo ++@kindex info meminfo ++@cindex mapinfo list, QNX Neutrino ++For QNX Neutrino only, this command displays the list of all mapinfos. ++@end table ++ ++@node DJGPP Native ++@subsection Features for Debugging @sc{djgpp} Programs ++@cindex @sc{djgpp} debugging ++@cindex native @sc{djgpp} debugging ++@cindex MS-DOS-specific commands ++ ++@cindex DPMI ++@sc{djgpp} is a port of the @sc{gnu} development tools to MS-DOS and ++MS-Windows. @sc{djgpp} programs are 32-bit protected-mode programs ++that use the @dfn{DPMI} (DOS Protected-Mode Interface) API to run on ++top of real-mode DOS systems and their emulations. ++ ++@value{GDBN} supports native debugging of @sc{djgpp} programs, and ++defines a few commands specific to the @sc{djgpp} port. This ++subsection describes those commands. ++ ++@table @code ++@kindex info dos ++@item info dos ++This is a prefix of @sc{djgpp}-specific commands which print ++information about the target system and important OS structures. ++ ++@kindex sysinfo ++@cindex MS-DOS system info ++@cindex free memory information (MS-DOS) ++@item info dos sysinfo ++This command displays assorted information about the underlying ++platform: the CPU type and features, the OS version and flavor, the ++DPMI version, and the available conventional and DPMI memory. ++ ++@cindex GDT ++@cindex LDT ++@cindex IDT ++@cindex segment descriptor tables ++@cindex descriptor tables display ++@item info dos gdt ++@itemx info dos ldt ++@itemx info dos idt ++These 3 commands display entries from, respectively, Global, Local, ++and Interrupt Descriptor Tables (GDT, LDT, and IDT). The descriptor ++tables are data structures which store a descriptor for each segment ++that is currently in use. The segment's selector is an index into a ++descriptor table; the table entry for that index holds the ++descriptor's base address and limit, and its attributes and access ++rights. ++ ++A typical @sc{djgpp} program uses 3 segments: a code segment, a data ++segment (used for both data and the stack), and a DOS segment (which ++allows access to DOS/BIOS data structures and absolute addresses in ++conventional memory). However, the DPMI host will usually define ++additional segments in order to support the DPMI environment. ++ ++@cindex garbled pointers ++These commands allow to display entries from the descriptor tables. ++Without an argument, all entries from the specified table are ++displayed. An argument, which should be an integer expression, means ++display a single entry whose index is given by the argument. For ++example, here's a convenient way to display information about the ++debugged program's data segment: ++ ++@smallexample ++@exdent @code{(@value{GDBP}) info dos ldt $ds} ++@exdent @code{0x13f: base=0x11970000 limit=0x0009ffff 32-Bit Data (Read/Write, Exp-up)} ++@end smallexample ++ ++@noindent ++This comes in handy when you want to see whether a pointer is outside ++the data segment's limit (i.e.@: @dfn{garbled}). ++ ++@cindex page tables display (MS-DOS) ++@item info dos pde ++@itemx info dos pte ++These two commands display entries from, respectively, the Page ++Directory and the Page Tables. Page Directories and Page Tables are ++data structures which control how virtual memory addresses are mapped ++into physical addresses. A Page Table includes an entry for every ++page of memory that is mapped into the program's address space; there ++may be several Page Tables, each one holding up to 4096 entries. A ++Page Directory has up to 4096 entries, one each for every Page Table ++that is currently in use. ++ ++Without an argument, @kbd{info dos pde} displays the entire Page ++Directory, and @kbd{info dos pte} displays all the entries in all of ++the Page Tables. An argument, an integer expression, given to the ++@kbd{info dos pde} command means display only that entry from the Page ++Directory table. An argument given to the @kbd{info dos pte} command ++means display entries from a single Page Table, the one pointed to by ++the specified entry in the Page Directory. ++ ++@cindex direct memory access (DMA) on MS-DOS ++These commands are useful when your program uses @dfn{DMA} (Direct ++Memory Access), which needs physical addresses to program the DMA ++controller. ++ ++These commands are supported only with some DPMI servers. ++ ++@cindex physical address from linear address ++@item info dos address-pte @var{addr} ++This command displays the Page Table entry for a specified linear ++address. The argument @var{addr} is a linear address which should ++already have the appropriate segment's base address added to it, ++because this command accepts addresses which may belong to @emph{any} ++segment. For example, here's how to display the Page Table entry for ++the page where a variable @code{i} is stored: ++ ++@smallexample ++@exdent @code{(@value{GDBP}) info dos address-pte __djgpp_base_address + (char *)&i} ++@exdent @code{Page Table entry for address 0x11a00d30:} ++@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30} ++@end smallexample ++ ++@noindent ++This says that @code{i} is stored at offset @code{0xd30} from the page ++whose physical base address is @code{0x02698000}, and shows all the ++attributes of that page. ++ ++Note that you must cast the addresses of variables to a @code{char *}, ++since otherwise the value of @code{__djgpp_base_address}, the base ++address of all variables and functions in a @sc{djgpp} program, will ++be added using the rules of C pointer arithmetics: if @code{i} is ++declared an @code{int}, @value{GDBN} will add 4 times the value of ++@code{__djgpp_base_address} to the address of @code{i}. ++ ++Here's another example, it displays the Page Table entry for the ++transfer buffer: ++ ++@smallexample ++@exdent @code{(@value{GDBP}) info dos address-pte *((unsigned *)&_go32_info_block + 3)} ++@exdent @code{Page Table entry for address 0x29110:} ++@exdent @code{Base=0x00029000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0x110} ++@end smallexample ++ ++@noindent ++(The @code{+ 3} offset is because the transfer buffer's address is the ++3rd member of the @code{_go32_info_block} structure.) The output ++clearly shows that this DPMI server maps the addresses in conventional ++memory 1:1, i.e.@: the physical (@code{0x00029000} + @code{0x110}) and ++linear (@code{0x29110}) addresses are identical. ++ ++This command is supported only with some DPMI servers. ++@end table ++ ++@cindex DOS serial data link, remote debugging ++In addition to native debugging, the DJGPP port supports remote ++debugging via a serial data link. The following commands are specific ++to remote serial debugging in the DJGPP port of @value{GDBN}. ++ ++@table @code ++@kindex set com1base ++@kindex set com1irq ++@kindex set com2base ++@kindex set com2irq ++@kindex set com3base ++@kindex set com3irq ++@kindex set com4base ++@kindex set com4irq ++@item set com1base @var{addr} ++This command sets the base I/O port address of the @file{COM1} serial ++port. ++ ++@item set com1irq @var{irq} ++This command sets the @dfn{Interrupt Request} (@code{IRQ}) line to use ++for the @file{COM1} serial port. ++ ++There are similar commands @samp{set com2base}, @samp{set com3irq}, ++etc.@: for setting the port address and the @code{IRQ} lines for the ++other 3 COM ports. ++ ++@kindex show com1base ++@kindex show com1irq ++@kindex show com2base ++@kindex show com2irq ++@kindex show com3base ++@kindex show com3irq ++@kindex show com4base ++@kindex show com4irq ++The related commands @samp{show com1base}, @samp{show com1irq} etc.@: ++display the current settings of the base address and the @code{IRQ} ++lines used by the COM ports. ++ ++@item info serial ++@kindex info serial ++@cindex DOS serial port status ++This command prints the status of the 4 DOS serial ports. For each ++port, it prints whether it's active or not, its I/O base address and ++IRQ number, whether it uses a 16550-style FIFO, its baudrate, and the ++counts of various errors encountered so far. ++@end table ++ ++ ++@node Cygwin Native ++@subsection Features for Debugging MS Windows PE Executables ++@cindex MS Windows debugging ++@cindex native Cygwin debugging ++@cindex Cygwin-specific commands ++ ++@value{GDBN} supports native debugging of MS Windows programs, including ++DLLs with and without symbolic debugging information. ++ ++@cindex Ctrl-BREAK, MS-Windows ++@cindex interrupt debuggee on MS-Windows ++MS-Windows programs that call @code{SetConsoleMode} to switch off the ++special meaning of the @samp{Ctrl-C} keystroke cannot be interrupted ++by typing @kbd{C-c}. For this reason, @value{GDBN} on MS-Windows ++supports @kbd{C-@key{BREAK}} as an alternative interrupt key ++sequence, which can be used to interrupt the debuggee even if it ++ignores @kbd{C-c}. ++ ++There are various additional Cygwin-specific commands, described in ++this section. Working with DLLs that have no debugging symbols is ++described in @ref{Non-debug DLL Symbols}. ++ ++@table @code ++@kindex info w32 ++@item info w32 ++This is a prefix of MS Windows-specific commands which print ++information about the target system and important OS structures. ++ ++@item info w32 selector ++This command displays information returned by ++the Win32 API @code{GetThreadSelectorEntry} function. ++It takes an optional argument that is evaluated to ++a long value to give the information about this given selector. ++Without argument, this command displays information ++about the six segment registers. ++ ++@item info w32 thread-information-block ++This command displays thread specific information stored in the ++Thread Information Block (readable on the X86 CPU family using @code{$fs} ++selector for 32-bit programs and @code{$gs} for 64-bit programs). ++ ++@kindex signal-event ++@item signal-event @var{id} ++This command signals an event with user-provided @var{id}. Used to resume ++crashing process when attached to it using MS-Windows JIT debugging (AeDebug). ++ ++To use it, create or edit the following keys in ++@code{HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug} and/or ++@code{HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug} ++(for x86_64 versions): ++ ++@itemize @minus ++@item ++@code{Debugger} (REG_SZ) --- a command to launch the debugger. ++Suggested command is: @code{@var{fully-qualified-path-to-gdb.exe} -ex ++"attach %ld" -ex "signal-event %ld" -ex "continue"}. ++ ++The first @code{%ld} will be replaced by the process ID of the ++crashing process, the second @code{%ld} will be replaced by the ID of ++the event that blocks the crashing process, waiting for @value{GDBN} ++to attach. ++ ++@item ++@code{Auto} (REG_SZ) --- either @code{1} or @code{0}. @code{1} will ++make the system run debugger specified by the Debugger key ++automatically, @code{0} will cause a dialog box with ``OK'' and ++``Cancel'' buttons to appear, which allows the user to either ++terminate the crashing process (OK) or debug it (Cancel). ++@end itemize ++ ++@kindex set cygwin-exceptions ++@cindex debugging the Cygwin DLL ++@cindex Cygwin DLL, debugging ++@item set cygwin-exceptions @var{mode} ++If @var{mode} is @code{on}, @value{GDBN} will break on exceptions that ++happen inside the Cygwin DLL. If @var{mode} is @code{off}, ++@value{GDBN} will delay recognition of exceptions, and may ignore some ++exceptions which seem to be caused by internal Cygwin DLL ++``bookkeeping''. This option is meant primarily for debugging the ++Cygwin DLL itself; the default value is @code{off} to avoid annoying ++@value{GDBN} users with false @code{SIGSEGV} signals. ++ ++@kindex show cygwin-exceptions ++@item show cygwin-exceptions ++Displays whether @value{GDBN} will break on exceptions that happen ++inside the Cygwin DLL itself. ++ ++@kindex set new-console ++@item set new-console @var{mode} ++If @var{mode} is @code{on} the debuggee will ++be started in a new console on next start. ++If @var{mode} is @code{off}, the debuggee will ++be started in the same console as the debugger. ++ ++@kindex show new-console ++@item show new-console ++Displays whether a new console is used ++when the debuggee is started. ++ ++@kindex set new-group ++@item set new-group @var{mode} ++This boolean value controls whether the debuggee should ++start a new group or stay in the same group as the debugger. ++This affects the way the Windows OS handles ++@samp{Ctrl-C}. ++ ++@kindex show new-group ++@item show new-group ++Displays current value of new-group boolean. ++ ++@kindex set debugevents ++@item set debugevents ++This boolean value adds debug output concerning kernel events related ++to the debuggee seen by the debugger. This includes events that ++signal thread and process creation and exit, DLL loading and ++unloading, console interrupts, and debugging messages produced by the ++Windows @code{OutputDebugString} API call. ++ ++@kindex set debugexec ++@item set debugexec ++This boolean value adds debug output concerning execute events ++(such as resume thread) seen by the debugger. ++ ++@kindex set debugexceptions ++@item set debugexceptions ++This boolean value adds debug output concerning exceptions in the ++debuggee seen by the debugger. ++ ++@kindex set debugmemory ++@item set debugmemory ++This boolean value adds debug output concerning debuggee memory reads ++and writes by the debugger. ++ ++@kindex set shell ++@item set shell ++This boolean values specifies whether the debuggee is called ++via a shell or directly (default value is on). ++ ++@kindex show shell ++@item show shell ++Displays if the debuggee will be started with a shell. ++ ++@end table ++ ++@menu ++* Non-debug DLL Symbols:: Support for DLLs without debugging symbols ++@end menu ++ ++@node Non-debug DLL Symbols ++@subsubsection Support for DLLs without Debugging Symbols ++@cindex DLLs with no debugging symbols ++@cindex Minimal symbols and DLLs ++ ++Very often on windows, some of the DLLs that your program relies on do ++not include symbolic debugging information (for example, ++@file{kernel32.dll}). When @value{GDBN} doesn't recognize any debugging ++symbols in a DLL, it relies on the minimal amount of symbolic ++information contained in the DLL's export table. This section ++describes working with such symbols, known internally to @value{GDBN} as ++``minimal symbols''. ++ ++Note that before the debugged program has started execution, no DLLs ++will have been loaded. The easiest way around this problem is simply to ++start the program --- either by setting a breakpoint or letting the ++program run once to completion. ++ ++@subsubsection DLL Name Prefixes ++ ++In keeping with the naming conventions used by the Microsoft debugging ++tools, DLL export symbols are made available with a prefix based on the ++DLL name, for instance @code{KERNEL32!CreateFileA}. The plain name is ++also entered into the symbol table, so @code{CreateFileA} is often ++sufficient. In some cases there will be name clashes within a program ++(particularly if the executable itself includes full debugging symbols) ++necessitating the use of the fully qualified name when referring to the ++contents of the DLL. Use single-quotes around the name to avoid the ++exclamation mark (``!'') being interpreted as a language operator. ++ ++Note that the internal name of the DLL may be all upper-case, even ++though the file name of the DLL is lower-case, or vice-versa. Since ++symbols within @value{GDBN} are @emph{case-sensitive} this may cause ++some confusion. If in doubt, try the @code{info functions} and ++@code{info variables} commands or even @code{maint print msymbols} ++(@pxref{Symbols}). Here's an example: ++ ++@smallexample ++(@value{GDBP}) info function CreateFileA ++All functions matching regular expression "CreateFileA": ++ ++Non-debugging symbols: ++0x77e885f4 CreateFileA ++0x77e885f4 KERNEL32!CreateFileA ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) info function ! ++All functions matching regular expression "!": ++ ++Non-debugging symbols: ++0x6100114c cygwin1!__assert ++0x61004034 cygwin1!_dll_crt0@@0 ++0x61004240 cygwin1!dll_crt0(per_process *) ++[etc...] ++@end smallexample ++ ++@subsubsection Working with Minimal Symbols ++ ++Symbols extracted from a DLL's export table do not contain very much ++type information. All that @value{GDBN} can do is guess whether a symbol ++refers to a function or variable depending on the linker section that ++contains the symbol. Also note that the actual contents of the memory ++contained in a DLL are not available unless the program is running. This ++means that you cannot examine the contents of a variable or disassemble ++a function within a DLL without a running program. ++ ++Variables are generally treated as pointers and dereferenced ++automatically. For this reason, it is often necessary to prefix a ++variable name with the address-of operator (``&'') and provide explicit ++type information in the command. Here's an example of the type of ++problem: ++ ++@smallexample ++(@value{GDBP}) print 'cygwin1!__argv' ++'cygwin1!__argv' has unknown type; cast it to its declared type ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) x 'cygwin1!__argv' ++'cygwin1!__argv' has unknown type; cast it to its declared type ++@end smallexample ++ ++And two possible solutions: ++ ++@smallexample ++(@value{GDBP}) print ((char **)'cygwin1!__argv')[0] ++$2 = 0x22fd98 "/cygdrive/c/mydirectory/myprogram" ++@end smallexample ++ ++@smallexample ++(@value{GDBP}) x/2x &'cygwin1!__argv' ++0x610c0aa8 : 0x10021608 0x00000000 ++(@value{GDBP}) x/x 0x10021608 ++0x10021608: 0x0022fd98 ++(@value{GDBP}) x/s 0x0022fd98 ++0x22fd98: "/cygdrive/c/mydirectory/myprogram" ++@end smallexample ++ ++Setting a break point within a DLL is possible even before the program ++starts execution. However, under these circumstances, @value{GDBN} can't ++examine the initial instructions of the function in order to skip the ++function's frame set-up code. You can work around this by using ``*&'' ++to set the breakpoint at a raw memory address: ++ ++@smallexample ++(@value{GDBP}) break *&'python22!PyOS_Readline' ++Breakpoint 1 at 0x1e04eff0 ++@end smallexample ++ ++The author of these extensions is not entirely convinced that setting a ++break point within a shared DLL like @file{kernel32.dll} is completely ++safe. ++ ++@node Hurd Native ++@subsection Commands Specific to @sc{gnu} Hurd Systems ++@cindex @sc{gnu} Hurd debugging ++ ++This subsection describes @value{GDBN} commands specific to the ++@sc{gnu} Hurd native debugging. ++ ++@table @code ++@item set signals ++@itemx set sigs ++@kindex set signals@r{, Hurd command} ++@kindex set sigs@r{, Hurd command} ++This command toggles the state of inferior signal interception by ++@value{GDBN}. Mach exceptions, such as breakpoint traps, are not ++affected by this command. @code{sigs} is a shorthand alias for ++@code{signals}. ++ ++@item show signals ++@itemx show sigs ++@kindex show signals@r{, Hurd command} ++@kindex show sigs@r{, Hurd command} ++Show the current state of intercepting inferior's signals. ++ ++@item set signal-thread ++@itemx set sigthread ++@kindex set signal-thread ++@kindex set sigthread ++This command tells @value{GDBN} which thread is the @code{libc} signal ++thread. That thread is run when a signal is delivered to a running ++process. @code{set sigthread} is the shorthand alias of @code{set ++signal-thread}. ++ ++@item show signal-thread ++@itemx show sigthread ++@kindex show signal-thread ++@kindex show sigthread ++These two commands show which thread will run when the inferior is ++delivered a signal. ++ ++@item set stopped ++@kindex set stopped@r{, Hurd command} ++This commands tells @value{GDBN} that the inferior process is stopped, ++as with the @code{SIGSTOP} signal. The stopped process can be ++continued by delivering a signal to it. ++ ++@item show stopped ++@kindex show stopped@r{, Hurd command} ++This command shows whether @value{GDBN} thinks the debuggee is ++stopped. ++ ++@item set exceptions ++@kindex set exceptions@r{, Hurd command} ++Use this command to turn off trapping of exceptions in the inferior. ++When exception trapping is off, neither breakpoints nor ++single-stepping will work. To restore the default, set exception ++trapping on. ++ ++@item show exceptions ++@kindex show exceptions@r{, Hurd command} ++Show the current state of trapping exceptions in the inferior. ++ ++@item set task pause ++@kindex set task@r{, Hurd commands} ++@cindex task attributes (@sc{gnu} Hurd) ++@cindex pause current task (@sc{gnu} Hurd) ++This command toggles task suspension when @value{GDBN} has control. ++Setting it to on takes effect immediately, and the task is suspended ++whenever @value{GDBN} gets control. Setting it to off will take ++effect the next time the inferior is continued. If this option is set ++to off, you can use @code{set thread default pause on} or @code{set ++thread pause on} (see below) to pause individual threads. ++ ++@item show task pause ++@kindex show task@r{, Hurd commands} ++Show the current state of task suspension. ++ ++@item set task detach-suspend-count ++@cindex task suspend count ++@cindex detach from task, @sc{gnu} Hurd ++This command sets the suspend count the task will be left with when ++@value{GDBN} detaches from it. ++ ++@item show task detach-suspend-count ++Show the suspend count the task will be left with when detaching. ++ ++@item set task exception-port ++@itemx set task excp ++@cindex task exception port, @sc{gnu} Hurd ++This command sets the task exception port to which @value{GDBN} will ++forward exceptions. The argument should be the value of the @dfn{send ++rights} of the task. @code{set task excp} is a shorthand alias. ++ ++@item set noninvasive ++@cindex noninvasive task options ++This command switches @value{GDBN} to a mode that is the least ++invasive as far as interfering with the inferior is concerned. This ++is the same as using @code{set task pause}, @code{set exceptions}, and ++@code{set signals} to values opposite to the defaults. ++ ++@item info send-rights ++@itemx info receive-rights ++@itemx info port-rights ++@itemx info port-sets ++@itemx info dead-names ++@itemx info ports ++@itemx info psets ++@cindex send rights, @sc{gnu} Hurd ++@cindex receive rights, @sc{gnu} Hurd ++@cindex port rights, @sc{gnu} Hurd ++@cindex port sets, @sc{gnu} Hurd ++@cindex dead names, @sc{gnu} Hurd ++These commands display information about, respectively, send rights, ++receive rights, port rights, port sets, and dead names of a task. ++There are also shorthand aliases: @code{info ports} for @code{info ++port-rights} and @code{info psets} for @code{info port-sets}. ++ ++@item set thread pause ++@kindex set thread@r{, Hurd command} ++@cindex thread properties, @sc{gnu} Hurd ++@cindex pause current thread (@sc{gnu} Hurd) ++This command toggles current thread suspension when @value{GDBN} has ++control. Setting it to on takes effect immediately, and the current ++thread is suspended whenever @value{GDBN} gets control. Setting it to ++off will take effect the next time the inferior is continued. ++Normally, this command has no effect, since when @value{GDBN} has ++control, the whole task is suspended. However, if you used @code{set ++task pause off} (see above), this command comes in handy to suspend ++only the current thread. ++ ++@item show thread pause ++@kindex show thread@r{, Hurd command} ++This command shows the state of current thread suspension. ++ ++@item set thread run ++This command sets whether the current thread is allowed to run. ++ ++@item show thread run ++Show whether the current thread is allowed to run. ++ ++@item set thread detach-suspend-count ++@cindex thread suspend count, @sc{gnu} Hurd ++@cindex detach from thread, @sc{gnu} Hurd ++This command sets the suspend count @value{GDBN} will leave on a ++thread when detaching. This number is relative to the suspend count ++found by @value{GDBN} when it notices the thread; use @code{set thread ++takeover-suspend-count} to force it to an absolute value. ++ ++@item show thread detach-suspend-count ++Show the suspend count @value{GDBN} will leave on the thread when ++detaching. ++ ++@item set thread exception-port ++@itemx set thread excp ++Set the thread exception port to which to forward exceptions. This ++overrides the port set by @code{set task exception-port} (see above). ++@code{set thread excp} is the shorthand alias. ++ ++@item set thread takeover-suspend-count ++Normally, @value{GDBN}'s thread suspend counts are relative to the ++value @value{GDBN} finds when it notices each thread. This command ++changes the suspend counts to be absolute instead. ++ ++@item set thread default ++@itemx show thread default ++@cindex thread default settings, @sc{gnu} Hurd ++Each of the above @code{set thread} commands has a @code{set thread ++default} counterpart (e.g., @code{set thread default pause}, @code{set ++thread default exception-port}, etc.). The @code{thread default} ++variety of commands sets the default thread properties for all ++threads; you can then change the properties of individual threads with ++the non-default commands. ++@end table ++ ++@node Darwin ++@subsection Darwin ++@cindex Darwin ++ ++@value{GDBN} provides the following commands specific to the Darwin target: ++ ++@table @code ++@item set debug darwin @var{num} ++@kindex set debug darwin ++When set to a non zero value, enables debugging messages specific to ++the Darwin support. Higher values produce more verbose output. ++ ++@item show debug darwin ++@kindex show debug darwin ++Show the current state of Darwin messages. ++ ++@item set debug mach-o @var{num} ++@kindex set debug mach-o ++When set to a non zero value, enables debugging messages while ++@value{GDBN} is reading Darwin object files. (@dfn{Mach-O} is the ++file format used on Darwin for object and executable files.) Higher ++values produce more verbose output. This is a command to diagnose ++problems internal to @value{GDBN} and should not be needed in normal ++usage. ++ ++@item show debug mach-o ++@kindex show debug mach-o ++Show the current state of Mach-O file messages. ++ ++@item set mach-exceptions on ++@itemx set mach-exceptions off ++@kindex set mach-exceptions ++On Darwin, faults are first reported as a Mach exception and are then ++mapped to a Posix signal. Use this command to turn on trapping of ++Mach exceptions in the inferior. This might be sometimes useful to ++better understand the cause of a fault. The default is off. ++ ++@item show mach-exceptions ++@kindex show mach-exceptions ++Show the current state of exceptions trapping. ++@end table ++ ++@node FreeBSD ++@subsection FreeBSD ++@cindex FreeBSD ++ ++When the ABI of a system call is changed in the FreeBSD kernel, this ++is implemented by leaving a compatibility system call using the old ++ABI at the existing number and allocating a new system call number for ++the version using the new ABI. As a convenience, when a system call ++is caught by name (@pxref{catch syscall}), compatibility system calls ++are also caught. ++ ++For example, FreeBSD 12 introduced a new variant of the @code{kevent} ++system call and catching the @code{kevent} system call by name catches ++both variants: ++ ++@smallexample ++(@value{GDBP}) catch syscall kevent ++Catchpoint 1 (syscalls 'freebsd11_kevent' [363] 'kevent' [560]) ++(@value{GDBP}) ++@end smallexample ++ ++ ++@node Embedded OS ++@section Embedded Operating Systems ++ ++This section describes configurations involving the debugging of ++embedded operating systems that are available for several different ++architectures. ++ ++@value{GDBN} includes the ability to debug programs running on ++various real-time operating systems. ++ ++@node Embedded Processors ++@section Embedded Processors ++ ++This section goes into details specific to particular embedded ++configurations. ++ ++@cindex send command to simulator ++Whenever a specific embedded processor has a simulator, @value{GDBN} ++allows to send an arbitrary command to the simulator. ++ ++@table @code ++@item sim @var{command} ++@kindex sim@r{, a command} ++Send an arbitrary @var{command} string to the simulator. Consult the ++documentation for the specific simulator in use for information about ++acceptable commands. ++@end table ++ ++ ++@menu ++* ARC:: Synopsys ARC ++* ARM:: ARM ++* BPF:: eBPF ++* M68K:: Motorola M68K ++* MicroBlaze:: Xilinx MicroBlaze ++* MIPS Embedded:: MIPS Embedded ++* OpenRISC 1000:: OpenRISC 1000 (or1k) ++* PowerPC Embedded:: PowerPC Embedded ++* AVR:: Atmel AVR ++* CRIS:: CRIS ++* Super-H:: Renesas Super-H ++@end menu ++ ++@node ARC ++@subsection Synopsys ARC ++@cindex Synopsys ARC ++@cindex ARC specific commands ++@cindex ARC600 ++@cindex ARC700 ++@cindex ARC EM ++@cindex ARC HS ++ ++@value{GDBN} provides the following ARC-specific commands: ++ ++@table @code ++@item set debug arc ++@kindex set debug arc ++Control the level of ARC specific debug messages. Use 0 for no messages (the ++default), 1 for debug messages, and 2 for even more debug messages. ++ ++@item show debug arc ++@kindex show debug arc ++Show the level of ARC specific debugging in operation. ++ ++@item maint print arc arc-instruction @var{address} ++@kindex maint print arc arc-instruction ++Print internal disassembler information about instruction at a given address. ++ ++@end table ++ ++@node ARM ++@subsection ARM ++ ++@value{GDBN} provides the following ARM-specific commands: ++ ++@table @code ++@item set arm disassembler ++@kindex set arm ++This commands selects from a list of disassembly styles. The ++@code{"std"} style is the standard style. ++ ++@item show arm disassembler ++@kindex show arm ++Show the current disassembly style. ++ ++@item set arm apcs32 ++@cindex ARM 32-bit mode ++This command toggles ARM operation mode between 32-bit and 26-bit. ++ ++@item show arm apcs32 ++Display the current usage of the ARM 32-bit mode. ++ ++@item set arm fpu @var{fputype} ++This command sets the ARM floating-point unit (FPU) type. The ++argument @var{fputype} can be one of these: ++ ++@table @code ++@item auto ++Determine the FPU type by querying the OS ABI. ++@item softfpa ++Software FPU, with mixed-endian doubles on little-endian ARM ++processors. ++@item fpa ++GCC-compiled FPA co-processor. ++@item softvfp ++Software FPU with pure-endian doubles. ++@item vfp ++VFP co-processor. ++@end table ++ ++@item show arm fpu ++Show the current type of the FPU. ++ ++@item set arm abi ++This command forces @value{GDBN} to use the specified ABI. ++ ++@item show arm abi ++Show the currently used ABI. ++ ++@item set arm fallback-mode (arm|thumb|auto) ++@value{GDBN} uses the symbol table, when available, to determine ++whether instructions are ARM or Thumb. This command controls ++@value{GDBN}'s default behavior when the symbol table is not ++available. The default is @samp{auto}, which causes @value{GDBN} to ++use the current execution mode (from the @code{T} bit in the @code{CPSR} ++register). ++ ++@item show arm fallback-mode ++Show the current fallback instruction mode. ++ ++@item set arm force-mode (arm|thumb|auto) ++This command overrides use of the symbol table to determine whether ++instructions are ARM or Thumb. The default is @samp{auto}, which ++causes @value{GDBN} to use the symbol table and then the setting ++of @samp{set arm fallback-mode}. ++ ++@item show arm force-mode ++Show the current forced instruction mode. ++ ++@item set debug arm ++Toggle whether to display ARM-specific debugging messages from the ARM ++target support subsystem. ++ ++@item show debug arm ++Show whether ARM-specific debugging messages are enabled. ++@end table ++ ++@table @code ++@item target sim @r{[}@var{simargs}@r{]} @dots{} ++The @value{GDBN} ARM simulator accepts the following optional arguments. ++ ++@table @code ++@item --swi-support=@var{type} ++Tell the simulator which SWI interfaces to support. The argument ++@var{type} may be a comma separated list of the following values. ++The default value is @code{all}. ++ ++@table @code ++@item none ++@item demon ++@item angel ++@item redboot ++@item all ++@end table ++@end table ++@end table ++ ++@node BPF ++@subsection BPF ++ ++@table @code ++@item target sim @r{[}@var{simargs}@r{]} @dots{} ++The @value{GDBN} BPF simulator accepts the following optional arguments. ++ ++@table @code ++@item --skb-data-offset=@var{offset} ++Tell the simulator the offset, measured in bytes, of the ++@code{skb_data} field in the kernel @code{struct sk_buff} structure. ++This offset is used by some BPF specific-purpose load/store ++instructions. Defaults to 0. ++@end table ++@end table ++ ++@node M68K ++@subsection M68k ++ ++The Motorola m68k configuration includes ColdFire support. ++ ++@node MicroBlaze ++@subsection MicroBlaze ++@cindex Xilinx MicroBlaze ++@cindex XMD, Xilinx Microprocessor Debugger ++ ++The MicroBlaze is a soft-core processor supported on various Xilinx ++FPGAs, such as Spartan or Virtex series. Boards with these processors ++usually have JTAG ports which connect to a host system running the Xilinx ++Embedded Development Kit (EDK) or Software Development Kit (SDK). ++This host system is used to download the configuration bitstream to ++the target FPGA. The Xilinx Microprocessor Debugger (XMD) program ++communicates with the target board using the JTAG interface and ++presents a @code{gdbserver} interface to the board. By default ++@code{xmd} uses port @code{1234}. (While it is possible to change ++this default port, it requires the use of undocumented @code{xmd} ++commands. Contact Xilinx support if you need to do this.) ++ ++Use these GDB commands to connect to the MicroBlaze target processor. ++ ++@table @code ++@item target remote :1234 ++Use this command to connect to the target if you are running @value{GDBN} ++on the same system as @code{xmd}. ++ ++@item target remote @var{xmd-host}:1234 ++Use this command to connect to the target if it is connected to @code{xmd} ++running on a different system named @var{xmd-host}. ++ ++@item load ++Use this command to download a program to the MicroBlaze target. ++ ++@item set debug microblaze @var{n} ++Enable MicroBlaze-specific debugging messages if non-zero. ++ ++@item show debug microblaze @var{n} ++Show MicroBlaze-specific debugging level. ++@end table ++ ++@node MIPS Embedded ++@subsection @acronym{MIPS} Embedded ++ ++@noindent ++@value{GDBN} supports these special commands for @acronym{MIPS} targets: ++ ++@table @code ++@item set mipsfpu double ++@itemx set mipsfpu single ++@itemx set mipsfpu none ++@itemx set mipsfpu auto ++@itemx show mipsfpu ++@kindex set mipsfpu ++@kindex show mipsfpu ++@cindex @acronym{MIPS} remote floating point ++@cindex floating point, @acronym{MIPS} remote ++If your target board does not support the @acronym{MIPS} floating point ++coprocessor, you should use the command @samp{set mipsfpu none} (if you ++need this, you may wish to put the command in your @value{GDBN} init ++file). This tells @value{GDBN} how to find the return value of ++functions which return floating point values. It also allows ++@value{GDBN} to avoid saving the floating point registers when calling ++functions on the board. If you are using a floating point coprocessor ++with only single precision floating point support, as on the @sc{r4650} ++processor, use the command @samp{set mipsfpu single}. The default ++double precision floating point coprocessor may be selected using ++@samp{set mipsfpu double}. ++ ++In previous versions the only choices were double precision or no ++floating point, so @samp{set mipsfpu on} will select double precision ++and @samp{set mipsfpu off} will select no floating point. ++ ++As usual, you can inquire about the @code{mipsfpu} variable with ++@samp{show mipsfpu}. ++@end table ++ ++@node OpenRISC 1000 ++@subsection OpenRISC 1000 ++@cindex OpenRISC 1000 ++ ++@noindent ++The OpenRISC 1000 provides a free RISC instruction set architecture. It is ++mainly provided as a soft-core which can run on Xilinx, Altera and other ++FPGA's. ++ ++@value{GDBN} for OpenRISC supports the below commands when connecting to ++a target: ++ ++@table @code ++ ++@kindex target sim ++@item target sim ++ ++Runs the builtin CPU simulator which can run very basic ++programs but does not support most hardware functions like MMU. ++For more complex use cases the user is advised to run an external ++target, and connect using @samp{target remote}. ++ ++Example: @code{target sim} ++ ++@item set debug or1k ++Toggle whether to display OpenRISC-specific debugging messages from the ++OpenRISC target support subsystem. ++ ++@item show debug or1k ++Show whether OpenRISC-specific debugging messages are enabled. ++@end table ++ ++@node PowerPC Embedded ++@subsection PowerPC Embedded ++ ++@cindex DVC register ++@value{GDBN} supports using the DVC (Data Value Compare) register to ++implement in hardware simple hardware watchpoint conditions of the form: ++ ++@smallexample ++(@value{GDBP}) watch @var{ADDRESS|VARIABLE} \ ++ if @var{ADDRESS|VARIABLE} == @var{CONSTANT EXPRESSION} ++@end smallexample ++ ++The DVC register will be automatically used when @value{GDBN} detects ++such pattern in a condition expression, and the created watchpoint uses one ++debug register (either the @code{exact-watchpoints} option is on and the ++variable is scalar, or the variable has a length of one byte). This feature ++is available in native @value{GDBN} running on a Linux kernel version 2.6.34 ++or newer. ++ ++When running on PowerPC embedded processors, @value{GDBN} automatically uses ++ranged hardware watchpoints, unless the @code{exact-watchpoints} option is on, ++in which case watchpoints using only one debug register are created when ++watching variables of scalar types. ++ ++You can create an artificial array to watch an arbitrary memory ++region using one of the following commands (@pxref{Expressions}): ++ ++@smallexample ++(@value{GDBP}) watch *((char *) @var{address})@@@var{length} ++(@value{GDBP}) watch @{char[@var{length}]@} @var{address} ++@end smallexample ++ ++PowerPC embedded processors support masked watchpoints. See the discussion ++about the @code{mask} argument in @ref{Set Watchpoints}. ++ ++@cindex ranged breakpoint ++PowerPC embedded processors support hardware accelerated ++@dfn{ranged breakpoints}. A ranged breakpoint stops execution of ++the inferior whenever it executes an instruction at any address within ++the range it specifies. To set a ranged breakpoint in @value{GDBN}, ++use the @code{break-range} command. ++ ++@value{GDBN} provides the following PowerPC-specific commands: ++ ++@table @code ++@kindex break-range ++@item break-range @var{start-location}, @var{end-location} ++Set a breakpoint for an address range given by ++@var{start-location} and @var{end-location}, which can specify a function name, ++a line number, an offset of lines from the current line or from the start ++location, or an address of an instruction (see @ref{Specify Location}, ++for a list of all the possible ways to specify a @var{location}.) ++The breakpoint will stop execution of the inferior whenever it ++executes an instruction at any address within the specified range, ++(including @var{start-location} and @var{end-location}.) ++ ++@kindex set powerpc ++@item set powerpc soft-float ++@itemx show powerpc soft-float ++Force @value{GDBN} to use (or not use) a software floating point calling ++convention. By default, @value{GDBN} selects the calling convention based ++on the selected architecture and the provided executable file. ++ ++@item set powerpc vector-abi ++@itemx show powerpc vector-abi ++Force @value{GDBN} to use the specified calling convention for vector ++arguments and return values. The valid options are @samp{auto}; ++@samp{generic}, to avoid vector registers even if they are present; ++@samp{altivec}, to use AltiVec registers; and @samp{spe} to use SPE ++registers. By default, @value{GDBN} selects the calling convention ++based on the selected architecture and the provided executable file. ++ ++@item set powerpc exact-watchpoints ++@itemx show powerpc exact-watchpoints ++Allow @value{GDBN} to use only one debug register when watching a variable ++of scalar type, thus assuming that the variable is accessed through the ++address of its first byte. ++ ++@end table ++ ++@node AVR ++@subsection Atmel AVR ++@cindex AVR ++ ++When configured for debugging the Atmel AVR, @value{GDBN} supports the ++following AVR-specific commands: ++ ++@table @code ++@item info io_registers ++@kindex info io_registers@r{, AVR} ++@cindex I/O registers (Atmel AVR) ++This command displays information about the AVR I/O registers. For ++each register, @value{GDBN} prints its number and value. ++@end table ++ ++@node CRIS ++@subsection CRIS ++@cindex CRIS ++ ++When configured for debugging CRIS, @value{GDBN} provides the ++following CRIS-specific commands: ++ ++@table @code ++@item set cris-version @var{ver} ++@cindex CRIS version ++Set the current CRIS version to @var{ver}, either @samp{10} or @samp{32}. ++The CRIS version affects register names and sizes. This command is useful in ++case autodetection of the CRIS version fails. ++ ++@item show cris-version ++Show the current CRIS version. ++ ++@item set cris-dwarf2-cfi ++@cindex DWARF-2 CFI and CRIS ++Set the usage of DWARF-2 CFI for CRIS debugging. The default is @samp{on}. ++Change to @samp{off} when using @code{gcc-cris} whose version is below ++@code{R59}. ++ ++@item show cris-dwarf2-cfi ++Show the current state of using DWARF-2 CFI. ++ ++@item set cris-mode @var{mode} ++@cindex CRIS mode ++Set the current CRIS mode to @var{mode}. It should only be changed when ++debugging in guru mode, in which case it should be set to ++@samp{guru} (the default is @samp{normal}). ++ ++@item show cris-mode ++Show the current CRIS mode. ++@end table ++ ++@node Super-H ++@subsection Renesas Super-H ++@cindex Super-H ++ ++For the Renesas Super-H processor, @value{GDBN} provides these ++commands: ++ ++@table @code ++@item set sh calling-convention @var{convention} ++@kindex set sh calling-convention ++Set the calling-convention used when calling functions from @value{GDBN}. ++Allowed values are @samp{gcc}, which is the default setting, and @samp{renesas}. ++With the @samp{gcc} setting, functions are called using the @value{NGCC} calling ++convention. If the DWARF-2 information of the called function specifies ++that the function follows the Renesas calling convention, the function ++is called using the Renesas calling convention. If the calling convention ++is set to @samp{renesas}, the Renesas calling convention is always used, ++regardless of the DWARF-2 information. This can be used to override the ++default of @samp{gcc} if debug information is missing, or the compiler ++does not emit the DWARF-2 calling convention entry for a function. ++ ++@item show sh calling-convention ++@kindex show sh calling-convention ++Show the current calling convention setting. ++ ++@end table ++ ++ ++@node Architectures ++@section Architectures ++ ++This section describes characteristics of architectures that affect ++all uses of @value{GDBN} with the architecture, both native and cross. ++ ++@menu ++* AArch64:: ++* i386:: ++* Alpha:: ++* MIPS:: ++* HPPA:: HP PA architecture ++* PowerPC:: ++* Nios II:: ++* Sparc64:: ++* S12Z:: ++@end menu ++ ++@node AArch64 ++@subsection AArch64 ++@cindex AArch64 support ++ ++When @value{GDBN} is debugging the AArch64 architecture, it provides the ++following special commands: ++ ++@table @code ++@item set debug aarch64 ++@kindex set debug aarch64 ++This command determines whether AArch64 architecture-specific debugging ++messages are to be displayed. ++ ++@item show debug aarch64 ++Show whether AArch64 debugging messages are displayed. ++ ++@end table ++ ++@subsubsection AArch64 SVE. ++@cindex AArch64 SVE. ++ ++When @value{GDBN} is debugging the AArch64 architecture, if the Scalable Vector ++Extension (SVE) is present, then @value{GDBN} will provide the vector registers ++@code{$z0} through @code{$z31}, vector predicate registers @code{$p0} through ++@code{$p15}, and the @code{$ffr} register. In addition, the pseudo register ++@code{$vg} will be provided. This is the vector granule for the current thread ++and represents the number of 64-bit chunks in an SVE @code{z} register. ++ ++If the vector length changes, then the @code{$vg} register will be updated, ++but the lengths of the @code{z} and @code{p} registers will not change. This ++is a known limitation of @value{GDBN} and does not affect the execution of the ++target process. ++ ++@subsubsection AArch64 Pointer Authentication. ++@cindex AArch64 Pointer Authentication. ++ ++When @value{GDBN} is debugging the AArch64 architecture, and the program is ++using the v8.3-A feature Pointer Authentication (PAC), then whenever the link ++register @code{$lr} is pointing to an PAC function its value will be masked. ++When GDB prints a backtrace, any addresses that required unmasking will be ++postfixed with the marker [PAC]. When using the MI, this is printed as part ++of the @code{addr_flags} field. ++ ++@node i386 ++@subsection x86 Architecture-specific Issues ++ ++@table @code ++@item set struct-convention @var{mode} ++@kindex set struct-convention ++@cindex struct return convention ++@cindex struct/union returned in registers ++Set the convention used by the inferior to return @code{struct}s and ++@code{union}s from functions to @var{mode}. Possible values of ++@var{mode} are @code{"pcc"}, @code{"reg"}, and @code{"default"} (the ++default). @code{"default"} or @code{"pcc"} means that @code{struct}s ++are returned on the stack, while @code{"reg"} means that a ++@code{struct} or a @code{union} whose size is 1, 2, 4, or 8 bytes will ++be returned in a register. ++ ++@item show struct-convention ++@kindex show struct-convention ++Show the current setting of the convention to return @code{struct}s ++from functions. ++@end table ++ ++ ++@subsubsection Intel @dfn{Memory Protection Extensions} (MPX). ++@cindex Intel Memory Protection Extensions (MPX). ++ ++Memory Protection Extension (MPX) adds the bound registers @samp{BND0} ++@footnote{The register named with capital letters represent the architecture ++registers.} through @samp{BND3}. Bound registers store a pair of 64-bit values ++which are the lower bound and upper bound. Bounds are effective addresses or ++memory locations. The upper bounds are architecturally represented in 1's ++complement form. A bound having lower bound = 0, and upper bound = 0 ++(1's complement of all bits set) will allow access to the entire address space. ++ ++@samp{BND0} through @samp{BND3} are represented in @value{GDBN} as @samp{bnd0raw} ++through @samp{bnd3raw}. Pseudo registers @samp{bnd0} through @samp{bnd3} ++display the upper bound performing the complement of one operation on the ++upper bound value, i.e.@ when upper bound in @samp{bnd0raw} is 0 in the ++@value{GDBN} @samp{bnd0} it will be @code{0xfff@dots{}}. In this sense it ++can also be noted that the upper bounds are inclusive. ++ ++As an example, assume that the register BND0 holds bounds for a pointer having ++access allowed for the range between 0x32 and 0x71. The values present on ++bnd0raw and bnd registers are presented as follows: ++ ++@smallexample ++ bnd0raw = @{0x32, 0xffffffff8e@} ++ bnd0 = @{lbound = 0x32, ubound = 0x71@} : size 64 ++@end smallexample ++ ++This way the raw value can be accessed via bnd0raw@dots{}bnd3raw. Any ++change on bnd0@dots{}bnd3 or bnd0raw@dots{}bnd3raw is reflect on its ++counterpart. When the bnd0@dots{}bnd3 registers are displayed via ++Python, the display includes the memory size, in bits, accessible to ++the pointer. ++ ++Bounds can also be stored in bounds tables, which are stored in ++application memory. These tables store bounds for pointers by specifying ++the bounds pointer's value along with its bounds. Evaluating and changing ++bounds located in bound tables is therefore interesting while investigating ++bugs on MPX context. @value{GDBN} provides commands for this purpose: ++ ++@table @code ++@item show mpx bound @var{pointer} ++@kindex show mpx bound ++Display bounds of the given @var{pointer}. ++ ++@item set mpx bound @var{pointer}, @var{lbound}, @var{ubound} ++@kindex set mpx bound ++Set the bounds of a pointer in the bound table. ++This command takes three parameters: @var{pointer} is the pointers ++whose bounds are to be changed, @var{lbound} and @var{ubound} are new values ++for lower and upper bounds respectively. ++@end table ++ ++When you call an inferior function on an Intel MPX enabled program, ++GDB sets the inferior's bound registers to the init (disabled) state ++before calling the function. As a consequence, bounds checks for the ++pointer arguments passed to the function will always pass. ++ ++This is necessary because when you call an inferior function, the ++program is usually in the middle of the execution of other function. ++Since at that point bound registers are in an arbitrary state, not ++clearing them would lead to random bound violations in the called ++function. ++ ++You can still examine the influence of the bound registers on the ++execution of the called function by stopping the execution of the ++called function at its prologue, setting bound registers, and ++continuing the execution. For example: ++ ++@smallexample ++ $ break *upper ++ Breakpoint 2 at 0x4009de: file i386-mpx-call.c, line 47. ++ $ print upper (a, b, c, d, 1) ++ Breakpoint 2, upper (a=0x0, b=0x6e0000005b, c=0x0, d=0x0, len=48).... ++ $ print $bnd0 ++ @{lbound = 0x0, ubound = ffffffff@} : size -1 ++@end smallexample ++ ++At this last step the value of bnd0 can be changed for investigation of bound ++violations caused along the execution of the call. In order to know how to ++set the bound registers or bound table for the call consult the ABI. ++ ++@node Alpha ++@subsection Alpha ++ ++See the following section. ++ ++@node MIPS ++@subsection @acronym{MIPS} ++ ++@cindex stack on Alpha ++@cindex stack on @acronym{MIPS} ++@cindex Alpha stack ++@cindex @acronym{MIPS} stack ++Alpha- and @acronym{MIPS}-based computers use an unusual stack frame, which ++sometimes requires @value{GDBN} to search backward in the object code to ++find the beginning of a function. ++ ++@cindex response time, @acronym{MIPS} debugging ++To improve response time (especially for embedded applications, where ++@value{GDBN} may be restricted to a slow serial line for this search) ++you may want to limit the size of this search, using one of these ++commands: ++ ++@table @code ++@cindex @code{heuristic-fence-post} (Alpha, @acronym{MIPS}) ++@item set heuristic-fence-post @var{limit} ++Restrict @value{GDBN} to examining at most @var{limit} bytes in its ++search for the beginning of a function. A value of @var{0} (the ++default) means there is no limit. However, except for @var{0}, the ++larger the limit the more bytes @code{heuristic-fence-post} must search ++and therefore the longer it takes to run. You should only need to use ++this command when debugging a stripped executable. ++ ++@item show heuristic-fence-post ++Display the current limit. ++@end table ++ ++@noindent ++These commands are available @emph{only} when @value{GDBN} is configured ++for debugging programs on Alpha or @acronym{MIPS} processors. ++ ++Several @acronym{MIPS}-specific commands are available when debugging @acronym{MIPS} ++programs: ++ ++@table @code ++@item set mips abi @var{arg} ++@kindex set mips abi ++@cindex set ABI for @acronym{MIPS} ++Tell @value{GDBN} which @acronym{MIPS} ABI is used by the inferior. Possible ++values of @var{arg} are: ++ ++@table @samp ++@item auto ++The default ABI associated with the current binary (this is the ++default). ++@item o32 ++@item o64 ++@item n32 ++@item n64 ++@item eabi32 ++@item eabi64 ++@end table ++ ++@item show mips abi ++@kindex show mips abi ++Show the @acronym{MIPS} ABI used by @value{GDBN} to debug the inferior. ++ ++@item set mips compression @var{arg} ++@kindex set mips compression ++@cindex code compression, @acronym{MIPS} ++Tell @value{GDBN} which @acronym{MIPS} compressed ++@acronym{ISA, Instruction Set Architecture} encoding is used by the ++inferior. @value{GDBN} uses this for code disassembly and other ++internal interpretation purposes. This setting is only referred to ++when no executable has been associated with the debugging session or ++the executable does not provide information about the encoding it uses. ++Otherwise this setting is automatically updated from information ++provided by the executable. ++ ++Possible values of @var{arg} are @samp{mips16} and @samp{micromips}. ++The default compressed @acronym{ISA} encoding is @samp{mips16}, as ++executables containing @acronym{MIPS16} code frequently are not ++identified as such. ++ ++This setting is ``sticky''; that is, it retains its value across ++debugging sessions until reset either explicitly with this command or ++implicitly from an executable. ++ ++The compiler and/or assembler typically add symbol table annotations to ++identify functions compiled for the @acronym{MIPS16} or ++@acronym{microMIPS} @acronym{ISA}s. If these function-scope annotations ++are present, @value{GDBN} uses them in preference to the global ++compressed @acronym{ISA} encoding setting. ++ ++@item show mips compression ++@kindex show mips compression ++Show the @acronym{MIPS} compressed @acronym{ISA} encoding used by ++@value{GDBN} to debug the inferior. ++ ++@item set mipsfpu ++@itemx show mipsfpu ++@xref{MIPS Embedded, set mipsfpu}. ++ ++@item set mips mask-address @var{arg} ++@kindex set mips mask-address ++@cindex @acronym{MIPS} addresses, masking ++This command determines whether the most-significant 32 bits of 64-bit ++@acronym{MIPS} addresses are masked off. The argument @var{arg} can be ++@samp{on}, @samp{off}, or @samp{auto}. The latter is the default ++setting, which lets @value{GDBN} determine the correct value. ++ ++@item show mips mask-address ++@kindex show mips mask-address ++Show whether the upper 32 bits of @acronym{MIPS} addresses are masked off or ++not. ++ ++@item set remote-mips64-transfers-32bit-regs ++@kindex set remote-mips64-transfers-32bit-regs ++This command controls compatibility with 64-bit @acronym{MIPS} targets that ++transfer data in 32-bit quantities. If you have an old @acronym{MIPS} 64 target ++that transfers 32 bits for some registers, like @sc{sr} and @sc{fsr}, ++and 64 bits for other registers, set this option to @samp{on}. ++ ++@item show remote-mips64-transfers-32bit-regs ++@kindex show remote-mips64-transfers-32bit-regs ++Show the current setting of compatibility with older @acronym{MIPS} 64 targets. ++ ++@item set debug mips ++@kindex set debug mips ++This command turns on and off debugging messages for the @acronym{MIPS}-specific ++target code in @value{GDBN}. ++ ++@item show debug mips ++@kindex show debug mips ++Show the current setting of @acronym{MIPS} debugging messages. ++@end table ++ ++ ++@node HPPA ++@subsection HPPA ++@cindex HPPA support ++ ++When @value{GDBN} is debugging the HP PA architecture, it provides the ++following special commands: ++ ++@table @code ++@item set debug hppa ++@kindex set debug hppa ++This command determines whether HPPA architecture-specific debugging ++messages are to be displayed. ++ ++@item show debug hppa ++Show whether HPPA debugging messages are displayed. ++ ++@item maint print unwind @var{address} ++@kindex maint print unwind@r{, HPPA} ++This command displays the contents of the unwind table entry at the ++given @var{address}. ++ ++@end table ++ ++ ++@node PowerPC ++@subsection PowerPC ++@cindex PowerPC architecture ++ ++When @value{GDBN} is debugging the PowerPC architecture, it provides a set of ++pseudo-registers to enable inspection of 128-bit wide Decimal Floating Point ++numbers stored in the floating point registers. These values must be stored ++in two consecutive registers, always starting at an even register like ++@code{f0} or @code{f2}. ++ ++The pseudo-registers go from @code{$dl0} through @code{$dl15}, and are formed ++by joining the even/odd register pairs @code{f0} and @code{f1} for @code{$dl0}, ++@code{f2} and @code{f3} for @code{$dl1} and so on. ++ ++For POWER7 processors, @value{GDBN} provides a set of pseudo-registers, the 64-bit ++wide Extended Floating Point Registers (@samp{f32} through @samp{f63}). ++ ++@node Nios II ++@subsection Nios II ++@cindex Nios II architecture ++ ++When @value{GDBN} is debugging the Nios II architecture, ++it provides the following special commands: ++ ++@table @code ++ ++@item set debug nios2 ++@kindex set debug nios2 ++This command turns on and off debugging messages for the Nios II ++target code in @value{GDBN}. ++ ++@item show debug nios2 ++@kindex show debug nios2 ++Show the current setting of Nios II debugging messages. ++@end table ++ ++@node Sparc64 ++@subsection Sparc64 ++@cindex Sparc64 support ++@cindex Application Data Integrity ++@subsubsection ADI Support ++ ++The M7 processor supports an Application Data Integrity (ADI) feature that ++detects invalid data accesses. When software allocates memory and enables ++ADI on the allocated memory, it chooses a 4-bit version number, sets the ++version in the upper 4 bits of the 64-bit pointer to that data, and stores ++the 4-bit version in every cacheline of that data. Hardware saves the latter ++in spare bits in the cache and memory hierarchy. On each load and store, ++the processor compares the upper 4 VA (virtual address) bits to the ++cacheline's version. If there is a mismatch, the processor generates a ++version mismatch trap which can be either precise or disrupting. The trap ++is an error condition which the kernel delivers to the process as a SIGSEGV ++signal. ++ ++Note that only 64-bit applications can use ADI and need to be built with ++ADI-enabled. ++ ++Values of the ADI version tags, which are in granularity of a ++cacheline (64 bytes), can be viewed or modified. ++ ++ ++@table @code ++@kindex adi examine ++@item adi (examine | x) [ / @var{n} ] @var{addr} ++ ++The @code{adi examine} command displays the value of one ADI version tag per ++cacheline. ++ ++@var{n} is a decimal integer specifying the number in bytes; the default ++is 1. It specifies how much ADI version information, at the ratio of 1:ADI ++block size, to display. ++ ++@var{addr} is the address in user address space where you want @value{GDBN} ++to begin displaying the ADI version tags. ++ ++Below is an example of displaying ADI versions of variable "shmaddr". ++ ++@smallexample ++(@value{GDBP}) adi x/100 shmaddr ++ 0xfff800010002c000: 0 0 ++@end smallexample ++ ++@kindex adi assign ++@item adi (assign | a) [ / @var{n} ] @var{addr} = @var{tag} ++ ++The @code{adi assign} command is used to assign new ADI version tag ++to an address. ++ ++@var{n} is a decimal integer specifying the number in bytes; ++the default is 1. It specifies how much ADI version information, at the ++ratio of 1:ADI block size, to modify. ++ ++@var{addr} is the address in user address space where you want @value{GDBN} ++to begin modifying the ADI version tags. ++ ++@var{tag} is the new ADI version tag. ++ ++For example, do the following to modify then verify ADI versions of ++variable "shmaddr": ++ ++@smallexample ++(@value{GDBP}) adi a/100 shmaddr = 7 ++(@value{GDBP}) adi x/100 shmaddr ++ 0xfff800010002c000: 7 7 ++@end smallexample ++ ++@end table ++ ++@node S12Z ++@subsection S12Z ++@cindex S12Z support ++ ++When @value{GDBN} is debugging the S12Z architecture, ++it provides the following special command: ++ ++@table @code ++@item maint info bdccsr ++@kindex maint info bdccsr@r{, S12Z} ++This command displays the current value of the microprocessor's ++BDCCSR register. ++@end table ++ ++ ++@node Controlling GDB ++@chapter Controlling @value{GDBN} ++ ++You can alter the way @value{GDBN} interacts with you by using the ++@code{set} command. For commands controlling how @value{GDBN} displays ++data, see @ref{Print Settings, ,Print Settings}. Other settings are ++described here. ++ ++@menu ++* Prompt:: Prompt ++* Editing:: Command editing ++* Command History:: Command history ++* Screen Size:: Screen size ++* Output Styling:: Output styling ++* Numbers:: Numbers ++* ABI:: Configuring the current ABI ++* Auto-loading:: Automatically loading associated files ++* Messages/Warnings:: Optional warnings and messages ++* Debugging Output:: Optional messages about internal happenings ++* Other Misc Settings:: Other Miscellaneous Settings ++@end menu ++ ++@node Prompt ++@section Prompt ++ ++@cindex prompt ++ ++@value{GDBN} indicates its readiness to read a command by printing a string ++called the @dfn{prompt}. This string is normally @samp{(@value{GDBP})}. You ++can change the prompt string with the @code{set prompt} command. For ++instance, when debugging @value{GDBN} with @value{GDBN}, it is useful to change ++the prompt in one of the @value{GDBN} sessions so that you can always tell ++which one you are talking to. ++ ++@emph{Note:} @code{set prompt} does not add a space for you after the ++prompt you set. This allows you to set a prompt which ends in a space ++or a prompt that does not. ++ ++@table @code ++@kindex set prompt ++@item set prompt @var{newprompt} ++Directs @value{GDBN} to use @var{newprompt} as its prompt string henceforth. ++ ++@kindex show prompt ++@item show prompt ++Prints a line of the form: @samp{Gdb's prompt is: @var{your-prompt}} ++@end table ++ ++Versions of @value{GDBN} that ship with Python scripting enabled have ++prompt extensions. The commands for interacting with these extensions ++are: ++ ++@table @code ++@kindex set extended-prompt ++@item set extended-prompt @var{prompt} ++Set an extended prompt that allows for substitutions. ++@xref{gdb.prompt}, for a list of escape sequences that can be used for ++substitution. Any escape sequences specified as part of the prompt ++string are replaced with the corresponding strings each time the prompt ++is displayed. ++ ++For example: ++ ++@smallexample ++set extended-prompt Current working directory: \w (gdb) ++@end smallexample ++ ++Note that when an extended-prompt is set, it takes control of the ++@var{prompt_hook} hook. @xref{prompt_hook}, for further information. ++ ++@kindex show extended-prompt ++@item show extended-prompt ++Prints the extended prompt. Any escape sequences specified as part of ++the prompt string with @code{set extended-prompt}, are replaced with the ++corresponding strings each time the prompt is displayed. ++@end table ++ ++@node Editing ++@section Command Editing ++@cindex readline ++@cindex command line editing ++ ++@value{GDBN} reads its input commands via the @dfn{Readline} interface. This ++@sc{gnu} library provides consistent behavior for programs which provide a ++command line interface to the user. Advantages are @sc{gnu} Emacs-style ++or @dfn{vi}-style inline editing of commands, @code{csh}-like history ++substitution, and a storage and recall of command history across ++debugging sessions. ++ ++You may control the behavior of command line editing in @value{GDBN} with the ++command @code{set}. ++ ++@table @code ++@kindex set editing ++@cindex editing ++@item set editing ++@itemx set editing on ++Enable command line editing (enabled by default). ++ ++@item set editing off ++Disable command line editing. ++ ++@kindex show editing ++@item show editing ++Show whether command line editing is enabled. ++@end table ++ ++@ifset SYSTEM_READLINE ++@xref{Command Line Editing, , , rluserman, GNU Readline Library}, ++@end ifset ++@ifclear SYSTEM_READLINE ++@xref{Command Line Editing}, ++@end ifclear ++for more details about the Readline ++interface. Users unfamiliar with @sc{gnu} Emacs or @code{vi} are ++encouraged to read that chapter. ++ ++@cindex Readline application name ++@value{GDBN} sets the Readline application name to @samp{gdb}. This ++is useful for conditions in @file{.inputrc}. ++ ++@cindex operate-and-get-next ++@value{GDBN} defines a bindable Readline command, ++@code{operate-and-get-next}. This is bound to @kbd{C-o} by default. ++This command accepts the current line for execution and fetches the ++next line relative to the current line from the history for editing. ++Any argument is ignored. ++ ++@node Command History ++@section Command History ++@cindex command history ++ ++@value{GDBN} can keep track of the commands you type during your ++debugging sessions, so that you can be certain of precisely what ++happened. Use these commands to manage the @value{GDBN} command ++history facility. ++ ++@value{GDBN} uses the @sc{gnu} History library, a part of the Readline ++package, to provide the history facility. ++@ifset SYSTEM_READLINE ++@xref{Using History Interactively, , , history, GNU History Library}, ++@end ifset ++@ifclear SYSTEM_READLINE ++@xref{Using History Interactively}, ++@end ifclear ++for the detailed description of the History library. ++ ++To issue a command to @value{GDBN} without affecting certain aspects of ++the state which is seen by users, prefix it with @samp{server } ++(@pxref{Server Prefix}). This ++means that this command will not affect the command history, nor will it ++affect @value{GDBN}'s notion of which command to repeat if @key{RET} is ++pressed on a line by itself. ++ ++@cindex @code{server}, command prefix ++The server prefix does not affect the recording of values into the value ++history; to print a value without recording it into the value history, ++use the @code{output} command instead of the @code{print} command. ++ ++Here is the description of @value{GDBN} commands related to command ++history. ++ ++@table @code ++@cindex history substitution ++@cindex history file ++@kindex set history filename ++@cindex @env{GDBHISTFILE}, environment variable ++@item set history filename @r{[}@var{fname}@r{]} ++Set the name of the @value{GDBN} command history file to @var{fname}. ++This is the file where @value{GDBN} reads an initial command history ++list, and where it writes the command history from this session when it ++exits. You can access this list through history expansion or through ++the history command editing characters listed below. This file defaults ++to the value of the environment variable @code{GDBHISTFILE}, or to ++@file{./.gdb_history} (@file{./_gdb_history} on MS-DOS) if this variable ++is not set. ++ ++The @code{GDBHISTFILE} environment variable is read after processing ++any @value{GDBN} initialization files (@pxref{Startup}) and after ++processing any commands passed using command line options (for ++example, @code{-ex}). ++ ++If the @var{fname} argument is not given, or if the @code{GDBHISTFILE} ++is the empty string then @value{GDBN} will neither try to load an ++existing history file, nor will it try to save the history on exit. ++ ++@cindex save command history ++@kindex set history save ++@item set history save ++@itemx set history save on ++Record command history in a file, whose name may be specified with the ++@code{set history filename} command. By default, this option is ++disabled. The command history will be recorded when @value{GDBN} ++exits. If @code{set history filename} is set to the empty string then ++history saving is disabled, even when @code{set history save} is ++@code{on}. ++ ++@item set history save off ++Don't record the command history into the file specified by @code{set ++history filename} when @value{GDBN} exits. ++ ++@cindex history size ++@kindex set history size ++@cindex @env{GDBHISTSIZE}, environment variable ++@item set history size @var{size} ++@itemx set history size unlimited ++Set the number of commands which @value{GDBN} keeps in its history list. ++This defaults to the value of the environment variable @env{GDBHISTSIZE}, or ++to 256 if this variable is not set. Non-numeric values of @env{GDBHISTSIZE} ++are ignored. If @var{size} is @code{unlimited} or if @env{GDBHISTSIZE} is ++either a negative number or the empty string, then the number of commands ++@value{GDBN} keeps in the history list is unlimited. ++ ++The @code{GDBHISTSIZE} environment variable is read after processing ++any @value{GDBN} initialization files (@pxref{Startup}) and after ++processing any commands passed using command line options (for ++example, @code{-ex}). ++ ++@cindex remove duplicate history ++@kindex set history remove-duplicates ++@item set history remove-duplicates @var{count} ++@itemx set history remove-duplicates unlimited ++Control the removal of duplicate history entries in the command history list. ++If @var{count} is non-zero, @value{GDBN} will look back at the last @var{count} ++history entries and remove the first entry that is a duplicate of the current ++entry being added to the command history list. If @var{count} is ++@code{unlimited} then this lookbehind is unbounded. If @var{count} is 0, then ++removal of duplicate history entries is disabled. ++ ++Only history entries added during the current session are considered for ++removal. This option is set to 0 by default. ++ ++@end table ++ ++History expansion assigns special meaning to the character @kbd{!}. ++@ifset SYSTEM_READLINE ++@xref{Event Designators, , , history, GNU History Library}, ++@end ifset ++@ifclear SYSTEM_READLINE ++@xref{Event Designators}, ++@end ifclear ++for more details. ++ ++@cindex history expansion, turn on/off ++Since @kbd{!} is also the logical not operator in C, history expansion ++is off by default. If you decide to enable history expansion with the ++@code{set history expansion on} command, you may sometimes need to ++follow @kbd{!} (when it is used as logical not, in an expression) with ++a space or a tab to prevent it from being expanded. The readline ++history facilities do not attempt substitution on the strings ++@kbd{!=} and @kbd{!(}, even when history expansion is enabled. ++ ++The commands to control history expansion are: ++ ++@table @code ++@item set history expansion on ++@itemx set history expansion ++@kindex set history expansion ++Enable history expansion. History expansion is off by default. ++ ++@item set history expansion off ++Disable history expansion. ++ ++@c @group ++@kindex show history ++@item show history ++@itemx show history filename ++@itemx show history save ++@itemx show history size ++@itemx show history expansion ++These commands display the state of the @value{GDBN} history parameters. ++@code{show history} by itself displays all four states. ++@c @end group ++@end table ++ ++@table @code ++@kindex show commands ++@cindex show last commands ++@cindex display command history ++@item show commands ++Display the last ten commands in the command history. ++ ++@item show commands @var{n} ++Print ten commands centered on command number @var{n}. ++ ++@item show commands + ++Print ten commands just after the commands last printed. ++@end table ++ ++@node Screen Size ++@section Screen Size ++@cindex size of screen ++@cindex screen size ++@cindex pagination ++@cindex page size ++@cindex pauses in output ++ ++Certain commands to @value{GDBN} may produce large amounts of ++information output to the screen. To help you read all of it, ++@value{GDBN} pauses and asks you for input at the end of each page of ++output. Type @key{RET} when you want to see one more page of output, ++@kbd{q} to discard the remaining output, or @kbd{c} to continue ++without paging for the rest of the current command. Also, the screen ++width setting determines when to wrap lines of output. Depending on ++what is being printed, @value{GDBN} tries to break the line at a ++readable place, rather than simply letting it overflow onto the ++following line. ++ ++Normally @value{GDBN} knows the size of the screen from the terminal ++driver software. For example, on Unix @value{GDBN} uses the termcap data base ++together with the value of the @code{TERM} environment variable and the ++@code{stty rows} and @code{stty cols} settings. If this is not correct, ++you can override it with the @code{set height} and @code{set ++width} commands: ++ ++@table @code ++@kindex set height ++@kindex set width ++@kindex show width ++@kindex show height ++@item set height @var{lpp} ++@itemx set height unlimited ++@itemx show height ++@itemx set width @var{cpl} ++@itemx set width unlimited ++@itemx show width ++These @code{set} commands specify a screen height of @var{lpp} lines and ++a screen width of @var{cpl} characters. The associated @code{show} ++commands display the current settings. ++ ++If you specify a height of either @code{unlimited} or zero lines, ++@value{GDBN} does not pause during output no matter how long the ++output is. This is useful if output is to a file or to an editor ++buffer. ++ ++Likewise, you can specify @samp{set width unlimited} or @samp{set ++width 0} to prevent @value{GDBN} from wrapping its output. ++ ++@item set pagination on ++@itemx set pagination off ++@kindex set pagination ++Turn the output pagination on or off; the default is on. Turning ++pagination off is the alternative to @code{set height unlimited}. Note that ++running @value{GDBN} with the @option{--batch} option (@pxref{Mode ++Options, -batch}) also automatically disables pagination. ++ ++@item show pagination ++@kindex show pagination ++Show the current pagination mode. ++@end table ++ ++@node Output Styling ++@section Output Styling ++@cindex styling ++@cindex colors ++ ++@kindex set style ++@kindex show style ++@value{GDBN} can style its output on a capable terminal. This is ++enabled by default on most systems, but disabled by default when in ++batch mode (@pxref{Mode Options}). Various style settings are available; ++and styles can also be disabled entirely. ++ ++@table @code ++@item set style enabled @samp{on|off} ++Enable or disable all styling. The default is host-dependent, with ++most hosts defaulting to @samp{on}. ++ ++@item show style enabled ++Show the current state of styling. ++ ++@item set style sources @samp{on|off} ++Enable or disable source code styling. This affects whether source ++code, such as the output of the @code{list} command, is styled. Note ++that source styling only works if styling in general is enabled, and ++if @value{GDBN} was linked with the GNU Source Highlight library. The ++default is @samp{on}. ++ ++@item show style sources ++Show the current state of source code styling. ++@end table ++ ++Subcommands of @code{set style} control specific forms of styling. ++These subcommands all follow the same pattern: each style-able object ++can be styled with a foreground color, a background color, and an ++intensity. ++ ++For example, the style of file names can be controlled using the ++@code{set style filename} group of commands: ++ ++@table @code ++@item set style filename background @var{color} ++Set the background to @var{color}. Valid colors are @samp{none} ++(meaning the terminal's default color), @samp{black}, @samp{red}, ++@samp{green}, @samp{yellow}, @samp{blue}, @samp{magenta}, @samp{cyan}, ++and@samp{white}. ++ ++@item set style filename foreground @var{color} ++Set the foreground to @var{color}. Valid colors are @samp{none} ++(meaning the terminal's default color), @samp{black}, @samp{red}, ++@samp{green}, @samp{yellow}, @samp{blue}, @samp{magenta}, @samp{cyan}, ++and@samp{white}. ++ ++@item set style filename intensity @var{value} ++Set the intensity to @var{value}. Valid intensities are @samp{normal} ++(the default), @samp{bold}, and @samp{dim}. ++@end table ++ ++The @code{show style} command and its subcommands are styling ++a style name in their output using its own style. ++So, use @command{show style} to see the complete list of styles, ++their characteristics and the visual aspect of each style. ++ ++The style-able objects are: ++@table @code ++@item filename ++Control the styling of file names. By default, this style's ++foreground color is green. ++ ++@item function ++Control the styling of function names. These are managed with the ++@code{set style function} family of commands. By default, this ++style's foreground color is yellow. ++ ++@item variable ++Control the styling of variable names. These are managed with the ++@code{set style variable} family of commands. By default, this style's ++foreground color is cyan. ++ ++@item address ++Control the styling of addresses. These are managed with the ++@code{set style address} family of commands. By default, this style's ++foreground color is blue. ++ ++@item title ++Control the styling of titles. These are managed with the ++@code{set style title} family of commands. By default, this style's ++intensity is bold. Commands are using the title style to improve ++the readability of large output. For example, the commands ++@command{apropos} and @command{help} are using the title style ++for the command names. ++ ++@item highlight ++Control the styling of highlightings. These are managed with the ++@code{set style highlight} family of commands. By default, this style's ++foreground color is red. Commands are using the highlight style to draw ++the user attention to some specific parts of their output. For example, ++the command @command{apropos -v REGEXP} uses the highlight style to ++mark the documentation parts matching @var{regexp}. ++ ++@item tui-border ++Control the styling of the TUI border. Note that, unlike other ++styling options, only the color of the border can be controlled via ++@code{set style}. This was done for compatibility reasons, as TUI ++controls to set the border's intensity predated the addition of ++general styling to @value{GDBN}. @xref{TUI Configuration}. ++ ++@item tui-active-border ++Control the styling of the active TUI border; that is, the TUI window ++that has the focus. ++ ++@end table ++ ++@node Numbers ++@section Numbers ++@cindex number representation ++@cindex entering numbers ++ ++You can always enter numbers in octal, decimal, or hexadecimal in ++@value{GDBN} by the usual conventions: octal numbers begin with ++@samp{0}, decimal numbers end with @samp{.}, and hexadecimal numbers ++begin with @samp{0x}. Numbers that neither begin with @samp{0} or ++@samp{0x}, nor end with a @samp{.} are, by default, entered in base ++10; likewise, the default display for numbers---when no particular ++format is specified---is base 10. You can change the default base for ++both input and output with the commands described below. ++ ++@table @code ++@kindex set input-radix ++@item set input-radix @var{base} ++Set the default base for numeric input. Supported choices ++for @var{base} are decimal 8, 10, or 16. The base must itself be ++specified either unambiguously or using the current input radix; for ++example, any of ++ ++@smallexample ++set input-radix 012 ++set input-radix 10. ++set input-radix 0xa ++@end smallexample ++ ++@noindent ++sets the input base to decimal. On the other hand, @samp{set input-radix 10} ++leaves the input radix unchanged, no matter what it was, since ++@samp{10}, being without any leading or trailing signs of its base, is ++interpreted in the current radix. Thus, if the current radix is 16, ++@samp{10} is interpreted in hex, i.e.@: as 16 decimal, which doesn't ++change the radix. ++ ++@kindex set output-radix ++@item set output-radix @var{base} ++Set the default base for numeric display. Supported choices ++for @var{base} are decimal 8, 10, or 16. The base must itself be ++specified either unambiguously or using the current input radix. ++ ++@kindex show input-radix ++@item show input-radix ++Display the current default base for numeric input. ++ ++@kindex show output-radix ++@item show output-radix ++Display the current default base for numeric display. ++ ++@item set radix @r{[}@var{base}@r{]} ++@itemx show radix ++@kindex set radix ++@kindex show radix ++These commands set and show the default base for both input and output ++of numbers. @code{set radix} sets the radix of input and output to ++the same base; without an argument, it resets the radix back to its ++default value of 10. ++ ++@end table ++ ++@node ABI ++@section Configuring the Current ABI ++ ++@value{GDBN} can determine the @dfn{ABI} (Application Binary Interface) of your ++application automatically. However, sometimes you need to override its ++conclusions. Use these commands to manage @value{GDBN}'s view of the ++current ABI. ++ ++@cindex OS ABI ++@kindex set osabi ++@kindex show osabi ++@cindex Newlib OS ABI and its influence on the longjmp handling ++ ++One @value{GDBN} configuration can debug binaries for multiple operating ++system targets, either via remote debugging or native emulation. ++@value{GDBN} will autodetect the @dfn{OS ABI} (Operating System ABI) in use, ++but you can override its conclusion using the @code{set osabi} command. ++One example where this is useful is in debugging of binaries which use ++an alternate C library (e.g.@: @sc{uClibc} for @sc{gnu}/Linux) which does ++not have the same identifying marks that the standard C library for your ++platform provides. ++ ++When @value{GDBN} is debugging the AArch64 architecture, it provides a ++``Newlib'' OS ABI. This is useful for handling @code{setjmp} and ++@code{longjmp} when debugging binaries that use the @sc{newlib} C library. ++The ``Newlib'' OS ABI can be selected by @code{set osabi Newlib}. ++ ++@table @code ++@item show osabi ++Show the OS ABI currently in use. ++ ++@item set osabi ++With no argument, show the list of registered available OS ABI's. ++ ++@item set osabi @var{abi} ++Set the current OS ABI to @var{abi}. ++@end table ++ ++@cindex float promotion ++ ++Generally, the way that an argument of type @code{float} is passed to a ++function depends on whether the function is prototyped. For a prototyped ++(i.e.@: ANSI/ISO style) function, @code{float} arguments are passed unchanged, ++according to the architecture's convention for @code{float}. For unprototyped ++(i.e.@: K&R style) functions, @code{float} arguments are first promoted to type ++@code{double} and then passed. ++ ++Unfortunately, some forms of debug information do not reliably indicate whether ++a function is prototyped. If @value{GDBN} calls a function that is not marked ++as prototyped, it consults @kbd{set coerce-float-to-double}. ++ ++@table @code ++@kindex set coerce-float-to-double ++@item set coerce-float-to-double ++@itemx set coerce-float-to-double on ++Arguments of type @code{float} will be promoted to @code{double} when passed ++to an unprototyped function. This is the default setting. ++ ++@item set coerce-float-to-double off ++Arguments of type @code{float} will be passed directly to unprototyped ++functions. ++ ++@kindex show coerce-float-to-double ++@item show coerce-float-to-double ++Show the current setting of promoting @code{float} to @code{double}. ++@end table ++ ++@kindex set cp-abi ++@kindex show cp-abi ++@value{GDBN} needs to know the ABI used for your program's C@t{++} ++objects. The correct C@t{++} ABI depends on which C@t{++} compiler was ++used to build your application. @value{GDBN} only fully supports ++programs with a single C@t{++} ABI; if your program contains code using ++multiple C@t{++} ABI's or if @value{GDBN} can not identify your ++program's ABI correctly, you can tell @value{GDBN} which ABI to use. ++Currently supported ABI's include ``gnu-v2'', for @code{g++} versions ++before 3.0, ``gnu-v3'', for @code{g++} versions 3.0 and later, and ++``hpaCC'' for the HP ANSI C@t{++} compiler. Other C@t{++} compilers may ++use the ``gnu-v2'' or ``gnu-v3'' ABI's as well. The default setting is ++``auto''. ++ ++@table @code ++@item show cp-abi ++Show the C@t{++} ABI currently in use. ++ ++@item set cp-abi ++With no argument, show the list of supported C@t{++} ABI's. ++ ++@item set cp-abi @var{abi} ++@itemx set cp-abi auto ++Set the current C@t{++} ABI to @var{abi}, or return to automatic detection. ++@end table ++ ++@node Auto-loading ++@section Automatically loading associated files ++@cindex auto-loading ++ ++@value{GDBN} sometimes reads files with commands and settings automatically, ++without being explicitly told so by the user. We call this feature ++@dfn{auto-loading}. While auto-loading is useful for automatically adapting ++@value{GDBN} to the needs of your project, it can sometimes produce unexpected ++results or introduce security risks (e.g., if the file comes from untrusted ++sources). ++ ++@menu ++* Init File in the Current Directory:: @samp{set/show/info auto-load local-gdbinit} ++* libthread_db.so.1 file:: @samp{set/show/info auto-load libthread-db} ++ ++* Auto-loading safe path:: @samp{set/show/info auto-load safe-path} ++* Auto-loading verbose mode:: @samp{set/show debug auto-load} ++@end menu ++ ++There are various kinds of files @value{GDBN} can automatically load. ++In addition to these files, @value{GDBN} supports auto-loading code written ++in various extension languages. @xref{Auto-loading extensions}. ++ ++Note that loading of these associated files (including the local @file{.gdbinit} ++file) requires accordingly configured @code{auto-load safe-path} ++(@pxref{Auto-loading safe path}). ++ ++For these reasons, @value{GDBN} includes commands and options to let you ++control when to auto-load files and which files should be auto-loaded. ++ ++@table @code ++@anchor{set auto-load off} ++@kindex set auto-load off ++@item set auto-load off ++Globally disable loading of all auto-loaded files. ++You may want to use this command with the @samp{-iex} option ++(@pxref{Option -init-eval-command}) such as: ++@smallexample ++$ @kbd{gdb -iex "set auto-load off" untrusted-executable corefile} ++@end smallexample ++ ++Be aware that system init file (@pxref{System-wide configuration}) ++and init files from your home directory (@pxref{Home Directory Init File}) ++still get read (as they come from generally trusted directories). ++To prevent @value{GDBN} from auto-loading even those init files, use the ++@option{-nx} option (@pxref{Mode Options}), in addition to ++@code{set auto-load no}. ++ ++@anchor{show auto-load} ++@kindex show auto-load ++@item show auto-load ++Show whether auto-loading of each specific @samp{auto-load} file(s) is enabled ++or disabled. ++ ++@smallexample ++(gdb) show auto-load ++gdb-scripts: Auto-loading of canned sequences of commands scripts is on. ++libthread-db: Auto-loading of inferior specific libthread_db is on. ++local-gdbinit: Auto-loading of .gdbinit script from current directory ++ is on. ++python-scripts: Auto-loading of Python scripts is on. ++safe-path: List of directories from which it is safe to auto-load files ++ is $debugdir:$datadir/auto-load. ++scripts-directory: List of directories from which to load auto-loaded scripts ++ is $debugdir:$datadir/auto-load. ++@end smallexample ++ ++@anchor{info auto-load} ++@kindex info auto-load ++@item info auto-load ++Print whether each specific @samp{auto-load} file(s) have been auto-loaded or ++not. ++ ++@smallexample ++(gdb) info auto-load ++gdb-scripts: ++Loaded Script ++Yes /home/user/gdb/gdb-gdb.gdb ++libthread-db: No auto-loaded libthread-db. ++local-gdbinit: Local .gdbinit file "/home/user/gdb/.gdbinit" has been ++ loaded. ++python-scripts: ++Loaded Script ++Yes /home/user/gdb/gdb-gdb.py ++@end smallexample ++@end table ++ ++These are @value{GDBN} control commands for the auto-loading: ++ ++@multitable @columnfractions .5 .5 ++@item @xref{set auto-load off}. ++@tab Disable auto-loading globally. ++@item @xref{show auto-load}. ++@tab Show setting of all kinds of files. ++@item @xref{info auto-load}. ++@tab Show state of all kinds of files. ++@item @xref{set auto-load gdb-scripts}. ++@tab Control for @value{GDBN} command scripts. ++@item @xref{show auto-load gdb-scripts}. ++@tab Show setting of @value{GDBN} command scripts. ++@item @xref{info auto-load gdb-scripts}. ++@tab Show state of @value{GDBN} command scripts. ++@item @xref{set auto-load python-scripts}. ++@tab Control for @value{GDBN} Python scripts. ++@item @xref{show auto-load python-scripts}. ++@tab Show setting of @value{GDBN} Python scripts. ++@item @xref{info auto-load python-scripts}. ++@tab Show state of @value{GDBN} Python scripts. ++@item @xref{set auto-load guile-scripts}. ++@tab Control for @value{GDBN} Guile scripts. ++@item @xref{show auto-load guile-scripts}. ++@tab Show setting of @value{GDBN} Guile scripts. ++@item @xref{info auto-load guile-scripts}. ++@tab Show state of @value{GDBN} Guile scripts. ++@item @xref{set auto-load scripts-directory}. ++@tab Control for @value{GDBN} auto-loaded scripts location. ++@item @xref{show auto-load scripts-directory}. ++@tab Show @value{GDBN} auto-loaded scripts location. ++@item @xref{add-auto-load-scripts-directory}. ++@tab Add directory for auto-loaded scripts location list. ++@item @xref{set auto-load local-gdbinit}. ++@tab Control for init file in the current directory. ++@item @xref{show auto-load local-gdbinit}. ++@tab Show setting of init file in the current directory. ++@item @xref{info auto-load local-gdbinit}. ++@tab Show state of init file in the current directory. ++@item @xref{set auto-load libthread-db}. ++@tab Control for thread debugging library. ++@item @xref{show auto-load libthread-db}. ++@tab Show setting of thread debugging library. ++@item @xref{info auto-load libthread-db}. ++@tab Show state of thread debugging library. ++@item @xref{set auto-load safe-path}. ++@tab Control directories trusted for automatic loading. ++@item @xref{show auto-load safe-path}. ++@tab Show directories trusted for automatic loading. ++@item @xref{add-auto-load-safe-path}. ++@tab Add directory trusted for automatic loading. ++@end multitable ++ ++@node Init File in the Current Directory ++@subsection Automatically loading init file in the current directory ++@cindex auto-loading init file in the current directory ++ ++By default, @value{GDBN} reads and executes the canned sequences of commands ++from init file (if any) in the current working directory, ++see @ref{Init File in the Current Directory during Startup}. ++ ++Note that loading of this local @file{.gdbinit} file also requires accordingly ++configured @code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++ ++@table @code ++@anchor{set auto-load local-gdbinit} ++@kindex set auto-load local-gdbinit ++@item set auto-load local-gdbinit [on|off] ++Enable or disable the auto-loading of canned sequences of commands ++(@pxref{Sequences}) found in init file in the current directory. ++ ++@anchor{show auto-load local-gdbinit} ++@kindex show auto-load local-gdbinit ++@item show auto-load local-gdbinit ++Show whether auto-loading of canned sequences of commands from init file in the ++current directory is enabled or disabled. ++ ++@anchor{info auto-load local-gdbinit} ++@kindex info auto-load local-gdbinit ++@item info auto-load local-gdbinit ++Print whether canned sequences of commands from init file in the ++current directory have been auto-loaded. ++@end table ++ ++@node libthread_db.so.1 file ++@subsection Automatically loading thread debugging library ++@cindex auto-loading libthread_db.so.1 ++ ++This feature is currently present only on @sc{gnu}/Linux native hosts. ++ ++@value{GDBN} reads in some cases thread debugging library from places specific ++to the inferior (@pxref{set libthread-db-search-path}). ++ ++The special @samp{libthread-db-search-path} entry @samp{$sdir} is processed ++without checking this @samp{set auto-load libthread-db} switch as system ++libraries have to be trusted in general. In all other cases of ++@samp{libthread-db-search-path} entries @value{GDBN} checks first if @samp{set ++auto-load libthread-db} is enabled before trying to open such thread debugging ++library. ++ ++Note that loading of this debugging library also requires accordingly configured ++@code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++ ++@table @code ++@anchor{set auto-load libthread-db} ++@kindex set auto-load libthread-db ++@item set auto-load libthread-db [on|off] ++Enable or disable the auto-loading of inferior specific thread debugging library. ++ ++@anchor{show auto-load libthread-db} ++@kindex show auto-load libthread-db ++@item show auto-load libthread-db ++Show whether auto-loading of inferior specific thread debugging library is ++enabled or disabled. ++ ++@anchor{info auto-load libthread-db} ++@kindex info auto-load libthread-db ++@item info auto-load libthread-db ++Print the list of all loaded inferior specific thread debugging libraries and ++for each such library print list of inferior @var{pid}s using it. ++@end table ++ ++@node Auto-loading safe path ++@subsection Security restriction for auto-loading ++@cindex auto-loading safe-path ++ ++As the files of inferior can come from untrusted source (such as submitted by ++an application user) @value{GDBN} does not always load any files automatically. ++@value{GDBN} provides the @samp{set auto-load safe-path} setting to list ++directories trusted for loading files not explicitly requested by user. ++Each directory can also be a shell wildcard pattern. ++ ++If the path is not set properly you will see a warning and the file will not ++get loaded: ++ ++@smallexample ++$ ./gdb -q ./gdb ++Reading symbols from /home/user/gdb/gdb... ++warning: File "/home/user/gdb/gdb-gdb.gdb" auto-loading has been ++ declined by your `auto-load safe-path' set ++ to "$debugdir:$datadir/auto-load". ++warning: File "/home/user/gdb/gdb-gdb.py" auto-loading has been ++ declined by your `auto-load safe-path' set ++ to "$debugdir:$datadir/auto-load". ++@end smallexample ++ ++@noindent ++To instruct @value{GDBN} to go ahead and use the init files anyway, ++invoke @value{GDBN} like this: ++ ++@smallexample ++$ gdb -q -iex "set auto-load safe-path /home/user/gdb" ./gdb ++@end smallexample ++ ++The list of trusted directories is controlled by the following commands: ++ ++@table @code ++@anchor{set auto-load safe-path} ++@kindex set auto-load safe-path ++@item set auto-load safe-path @r{[}@var{directories}@r{]} ++Set the list of directories (and their subdirectories) trusted for automatic ++loading and execution of scripts. You can also enter a specific trusted file. ++Each directory can also be a shell wildcard pattern; wildcards do not match ++directory separator - see @code{FNM_PATHNAME} for system function @code{fnmatch} ++(@pxref{Wildcard Matching, fnmatch, , libc, GNU C Library Reference Manual}). ++If you omit @var{directories}, @samp{auto-load safe-path} will be reset to ++its default value as specified during @value{GDBN} compilation. ++ ++The list of directories uses path separator (@samp{:} on GNU and Unix ++systems, @samp{;} on MS-Windows and MS-DOS) to separate directories, similarly ++to the @env{PATH} environment variable. ++ ++@anchor{show auto-load safe-path} ++@kindex show auto-load safe-path ++@item show auto-load safe-path ++Show the list of directories trusted for automatic loading and execution of ++scripts. ++ ++@anchor{add-auto-load-safe-path} ++@kindex add-auto-load-safe-path ++@item add-auto-load-safe-path ++Add an entry (or list of entries) to the list of directories trusted for ++automatic loading and execution of scripts. Multiple entries may be delimited ++by the host platform path separator in use. ++@end table ++ ++This variable defaults to what @code{--with-auto-load-dir} has been configured ++to (@pxref{with-auto-load-dir}). @file{$debugdir} and @file{$datadir} ++substitution applies the same as for @ref{set auto-load scripts-directory}. ++The default @code{set auto-load safe-path} value can be also overriden by ++@value{GDBN} configuration option @option{--with-auto-load-safe-path}. ++ ++Setting this variable to @file{/} disables this security protection, ++corresponding @value{GDBN} configuration option is ++@option{--without-auto-load-safe-path}. ++This variable is supposed to be set to the system directories writable by the ++system superuser only. Users can add their source directories in init files in ++their home directories (@pxref{Home Directory Init File}). See also deprecated ++init file in the current directory ++(@pxref{Init File in the Current Directory during Startup}). ++ ++To force @value{GDBN} to load the files it declined to load in the previous ++example, you could use one of the following ways: ++ ++@table @asis ++@item @file{~/.gdbinit}: @samp{add-auto-load-safe-path ~/src/gdb} ++Specify this trusted directory (or a file) as additional component of the list. ++You have to specify also any existing directories displayed by ++by @samp{show auto-load safe-path} (such as @samp{/usr:/bin} in this example). ++ ++@item @kbd{gdb -iex "set auto-load safe-path /usr:/bin:~/src/gdb" @dots{}} ++Specify this directory as in the previous case but just for a single ++@value{GDBN} session. ++ ++@item @kbd{gdb -iex "set auto-load safe-path /" @dots{}} ++Disable auto-loading safety for a single @value{GDBN} session. ++This assumes all the files you debug during this @value{GDBN} session will come ++from trusted sources. ++ ++@item @kbd{./configure --without-auto-load-safe-path} ++During compilation of @value{GDBN} you may disable any auto-loading safety. ++This assumes all the files you will ever debug with this @value{GDBN} come from ++trusted sources. ++@end table ++ ++On the other hand you can also explicitly forbid automatic files loading which ++also suppresses any such warning messages: ++ ++@table @asis ++@item @kbd{gdb -iex "set auto-load no" @dots{}} ++You can use @value{GDBN} command-line option for a single @value{GDBN} session. ++ ++@item @file{~/.gdbinit}: @samp{set auto-load no} ++Disable auto-loading globally for the user ++(@pxref{Home Directory Init File}). While it is improbable, you could also ++use system init file instead (@pxref{System-wide configuration}). ++@end table ++ ++This setting applies to the file names as entered by user. If no entry matches ++@value{GDBN} tries as a last resort to also resolve all the file names into ++their canonical form (typically resolving symbolic links) and compare the ++entries again. @value{GDBN} already canonicalizes most of the filenames on its ++own before starting the comparison so a canonical form of directories is ++recommended to be entered. ++ ++@node Auto-loading verbose mode ++@subsection Displaying files tried for auto-load ++@cindex auto-loading verbose mode ++ ++For better visibility of all the file locations where you can place scripts to ++be auto-loaded with inferior --- or to protect yourself against accidental ++execution of untrusted scripts --- @value{GDBN} provides a feature for printing ++all the files attempted to be loaded. Both existing and non-existing files may ++be printed. ++ ++For example the list of directories from which it is safe to auto-load files ++(@pxref{Auto-loading safe path}) applies also to canonicalized filenames which ++may not be too obvious while setting it up. ++ ++@smallexample ++(gdb) set debug auto-load on ++(gdb) file ~/src/t/true ++auto-load: Loading canned sequences of commands script "/tmp/true-gdb.gdb" ++ for objfile "/tmp/true". ++auto-load: Updating directories of "/usr:/opt". ++auto-load: Using directory "/usr". ++auto-load: Using directory "/opt". ++warning: File "/tmp/true-gdb.gdb" auto-loading has been declined ++ by your `auto-load safe-path' set to "/usr:/opt". ++@end smallexample ++ ++@table @code ++@anchor{set debug auto-load} ++@kindex set debug auto-load ++@item set debug auto-load [on|off] ++Set whether to print the filenames attempted to be auto-loaded. ++ ++@anchor{show debug auto-load} ++@kindex show debug auto-load ++@item show debug auto-load ++Show whether printing of the filenames attempted to be auto-loaded is turned ++on or off. ++@end table ++ ++@node Messages/Warnings ++@section Optional Warnings and Messages ++ ++@cindex verbose operation ++@cindex optional warnings ++By default, @value{GDBN} is silent about its inner workings. If you are ++running on a slow machine, you may want to use the @code{set verbose} ++command. This makes @value{GDBN} tell you when it does a lengthy ++internal operation, so you will not think it has crashed. ++ ++Currently, the messages controlled by @code{set verbose} are those ++which announce that the symbol table for a source file is being read; ++see @code{symbol-file} in @ref{Files, ,Commands to Specify Files}. ++ ++@table @code ++@kindex set verbose ++@item set verbose on ++Enables @value{GDBN} output of certain informational messages. ++ ++@item set verbose off ++Disables @value{GDBN} output of certain informational messages. ++ ++@kindex show verbose ++@item show verbose ++Displays whether @code{set verbose} is on or off. ++@end table ++ ++By default, if @value{GDBN} encounters bugs in the symbol table of an ++object file, it is silent; but if you are debugging a compiler, you may ++find this information useful (@pxref{Symbol Errors, ,Errors Reading ++Symbol Files}). ++ ++@table @code ++ ++@kindex set complaints ++@item set complaints @var{limit} ++Permits @value{GDBN} to output @var{limit} complaints about each type of ++unusual symbols before becoming silent about the problem. Set ++@var{limit} to zero to suppress all complaints; set it to a large number ++to prevent complaints from being suppressed. ++ ++@kindex show complaints ++@item show complaints ++Displays how many symbol complaints @value{GDBN} is permitted to produce. ++ ++@end table ++ ++@anchor{confirmation requests} ++By default, @value{GDBN} is cautious, and asks what sometimes seems to be a ++lot of stupid questions to confirm certain commands. For example, if ++you try to run a program which is already running: ++ ++@smallexample ++(@value{GDBP}) run ++The program being debugged has been started already. ++Start it from the beginning? (y or n) ++@end smallexample ++ ++If you are willing to unflinchingly face the consequences of your own ++commands, you can disable this ``feature'': ++ ++@table @code ++ ++@kindex set confirm ++@cindex flinching ++@cindex confirmation ++@cindex stupid questions ++@item set confirm off ++Disables confirmation requests. Note that running @value{GDBN} with ++the @option{--batch} option (@pxref{Mode Options, -batch}) also ++automatically disables confirmation requests. ++ ++@item set confirm on ++Enables confirmation requests (the default). ++ ++@kindex show confirm ++@item show confirm ++Displays state of confirmation requests. ++ ++@end table ++ ++@cindex command tracing ++If you need to debug user-defined commands or sourced files you may find it ++useful to enable @dfn{command tracing}. In this mode each command will be ++printed as it is executed, prefixed with one or more @samp{+} symbols, the ++quantity denoting the call depth of each command. ++ ++@table @code ++@kindex set trace-commands ++@cindex command scripts, debugging ++@item set trace-commands on ++Enable command tracing. ++@item set trace-commands off ++Disable command tracing. ++@item show trace-commands ++Display the current state of command tracing. ++@end table ++ ++@node Debugging Output ++@section Optional Messages about Internal Happenings ++@cindex optional debugging messages ++ ++@value{GDBN} has commands that enable optional debugging messages from ++various @value{GDBN} subsystems; normally these commands are of ++interest to @value{GDBN} maintainers, or when reporting a bug. This ++section documents those commands. ++ ++@table @code ++@kindex set exec-done-display ++@item set exec-done-display ++Turns on or off the notification of asynchronous commands' ++completion. When on, @value{GDBN} will print a message when an ++asynchronous command finishes its execution. The default is off. ++@kindex show exec-done-display ++@item show exec-done-display ++Displays the current setting of asynchronous command completion ++notification. ++@kindex set debug ++@cindex ARM AArch64 ++@item set debug aarch64 ++Turns on or off display of debugging messages related to ARM AArch64. ++The default is off. ++@kindex show debug ++@item show debug aarch64 ++Displays the current state of displaying debugging messages related to ++ARM AArch64. ++@cindex gdbarch debugging info ++@cindex architecture debugging info ++@item set debug arch ++Turns on or off display of gdbarch debugging info. The default is off ++@item show debug arch ++Displays the current state of displaying gdbarch debugging info. ++@item set debug aix-solib ++@cindex AIX shared library debugging ++Control display of debugging messages from the AIX shared library ++support module. The default is off. ++@item show debug aix-thread ++Show the current state of displaying AIX shared library debugging messages. ++@item set debug aix-thread ++@cindex AIX threads ++Display debugging messages about inner workings of the AIX thread ++module. ++@item show debug aix-thread ++Show the current state of AIX thread debugging info display. ++@item set debug check-physname ++@cindex physname ++Check the results of the ``physname'' computation. When reading DWARF ++debugging information for C@t{++}, @value{GDBN} attempts to compute ++each entity's name. @value{GDBN} can do this computation in two ++different ways, depending on exactly what information is present. ++When enabled, this setting causes @value{GDBN} to compute the names ++both ways and display any discrepancies. ++@item show debug check-physname ++Show the current state of ``physname'' checking. ++@item set debug coff-pe-read ++@cindex COFF/PE exported symbols ++Control display of debugging messages related to reading of COFF/PE ++exported symbols. The default is off. ++@item show debug coff-pe-read ++Displays the current state of displaying debugging messages related to ++reading of COFF/PE exported symbols. ++@item set debug dwarf-die ++@cindex DWARF DIEs ++Dump DWARF DIEs after they are read in. ++The value is the number of nesting levels to print. ++A value of zero turns off the display. ++@item show debug dwarf-die ++Show the current state of DWARF DIE debugging. ++@item set debug dwarf-line ++@cindex DWARF Line Tables ++Turns on or off display of debugging messages related to reading ++DWARF line tables. The default is 0 (off). ++A value of 1 provides basic information. ++A value greater than 1 provides more verbose information. ++@item show debug dwarf-line ++Show the current state of DWARF line table debugging. ++@item set debug dwarf-read ++@cindex DWARF Reading ++Turns on or off display of debugging messages related to reading ++DWARF debug info. The default is 0 (off). ++A value of 1 provides basic information. ++A value greater than 1 provides more verbose information. ++@item show debug dwarf-read ++Show the current state of DWARF reader debugging. ++@item set debug displaced ++@cindex displaced stepping debugging info ++Turns on or off display of @value{GDBN} debugging info for the ++displaced stepping support. The default is off. ++@item show debug displaced ++Displays the current state of displaying @value{GDBN} debugging info ++related to displaced stepping. ++@item set debug event ++@cindex event debugging info ++Turns on or off display of @value{GDBN} event debugging info. The ++default is off. ++@item show debug event ++Displays the current state of displaying @value{GDBN} event debugging ++info. ++@item set debug expression ++@cindex expression debugging info ++Turns on or off display of debugging info about @value{GDBN} ++expression parsing. The default is off. ++@item show debug expression ++Displays the current state of displaying debugging info about ++@value{GDBN} expression parsing. ++@item set debug fbsd-lwp ++@cindex FreeBSD LWP debug messages ++Turns on or off debugging messages from the FreeBSD LWP debug support. ++@item show debug fbsd-lwp ++Show the current state of FreeBSD LWP debugging messages. ++@item set debug fbsd-nat ++@cindex FreeBSD native target debug messages ++Turns on or off debugging messages from the FreeBSD native target. ++@item show debug fbsd-nat ++Show the current state of FreeBSD native target debugging messages. ++@item set debug frame ++@cindex frame debugging info ++Turns on or off display of @value{GDBN} frame debugging info. The ++default is off. ++@item show debug frame ++Displays the current state of displaying @value{GDBN} frame debugging ++info. ++@item set debug gnu-nat ++@cindex @sc{gnu}/Hurd debug messages ++Turn on or off debugging messages from the @sc{gnu}/Hurd debug support. ++@item show debug gnu-nat ++Show the current state of @sc{gnu}/Hurd debugging messages. ++@item set debug infrun ++@cindex inferior debugging info ++Turns on or off display of @value{GDBN} debugging info for running the inferior. ++The default is off. @file{infrun.c} contains GDB's runtime state machine used ++for implementing operations such as single-stepping the inferior. ++@item show debug infrun ++Displays the current state of @value{GDBN} inferior debugging. ++@item set debug jit ++@cindex just-in-time compilation, debugging messages ++Turn on or off debugging messages from JIT debug support. ++@item show debug jit ++Displays the current state of @value{GDBN} JIT debugging. ++@item set debug lin-lwp ++@cindex @sc{gnu}/Linux LWP debug messages ++@cindex Linux lightweight processes ++Turn on or off debugging messages from the Linux LWP debug support. ++@item show debug lin-lwp ++Show the current state of Linux LWP debugging messages. ++@item set debug linux-namespaces ++@cindex @sc{gnu}/Linux namespaces debug messages ++Turn on or off debugging messages from the Linux namespaces debug support. ++@item show debug linux-namespaces ++Show the current state of Linux namespaces debugging messages. ++@item set debug mach-o ++@cindex Mach-O symbols processing ++Control display of debugging messages related to Mach-O symbols ++processing. The default is off. ++@item show debug mach-o ++Displays the current state of displaying debugging messages related to ++reading of COFF/PE exported symbols. ++@item set debug notification ++@cindex remote async notification debugging info ++Turn on or off debugging messages about remote async notification. ++The default is off. ++@item show debug notification ++Displays the current state of remote async notification debugging messages. ++@item set debug observer ++@cindex observer debugging info ++Turns on or off display of @value{GDBN} observer debugging. This ++includes info such as the notification of observable events. ++@item show debug observer ++Displays the current state of observer debugging. ++@item set debug overload ++@cindex C@t{++} overload debugging info ++Turns on or off display of @value{GDBN} C@t{++} overload debugging ++info. This includes info such as ranking of functions, etc. The default ++is off. ++@item show debug overload ++Displays the current state of displaying @value{GDBN} C@t{++} overload ++debugging info. ++@cindex expression parser, debugging info ++@cindex debug expression parser ++@item set debug parser ++Turns on or off the display of expression parser debugging output. ++Internally, this sets the @code{yydebug} variable in the expression ++parser. @xref{Tracing, , Tracing Your Parser, bison, Bison}, for ++details. The default is off. ++@item show debug parser ++Show the current state of expression parser debugging. ++@cindex packets, reporting on stdout ++@cindex serial connections, debugging ++@cindex debug remote protocol ++@cindex remote protocol debugging ++@cindex display remote packets ++@item set debug remote ++Turns on or off display of reports on all packets sent back and forth across ++the serial line to the remote machine. The info is printed on the ++@value{GDBN} standard output stream. The default is off. ++@item show debug remote ++Displays the state of display of remote packets. ++ ++@item set debug remote-packet-max-chars ++Sets the maximum number of characters to display for each remote packet when ++@code{set debug remote} is on. This is useful to prevent @value{GDBN} from ++displaying lengthy remote packets and polluting the console. ++ ++The default value is @code{512}, which means @value{GDBN} will truncate each ++remote packet after 512 bytes. ++ ++Setting this option to @code{unlimited} will disable truncation and will output ++the full length of the remote packets. ++@item show debug remote-packet-max-chars ++Displays the number of bytes to output for remote packet debugging. ++ ++@item set debug separate-debug-file ++Turns on or off display of debug output about separate debug file search. ++@item show debug separate-debug-file ++Displays the state of separate debug file search debug output. ++ ++@item set debug serial ++Turns on or off display of @value{GDBN} serial debugging info. The ++default is off. ++@item show debug serial ++Displays the current state of displaying @value{GDBN} serial debugging ++info. ++@item set debug solib-frv ++@cindex FR-V shared-library debugging ++Turn on or off debugging messages for FR-V shared-library code. ++@item show debug solib-frv ++Display the current state of FR-V shared-library code debugging ++messages. ++@item set debug symbol-lookup ++@cindex symbol lookup ++Turns on or off display of debugging messages related to symbol lookup. ++The default is 0 (off). ++A value of 1 provides basic information. ++A value greater than 1 provides more verbose information. ++@item show debug symbol-lookup ++Show the current state of symbol lookup debugging messages. ++@item set debug symfile ++@cindex symbol file functions ++Turns on or off display of debugging messages related to symbol file functions. ++The default is off. @xref{Files}. ++@item show debug symfile ++Show the current state of symbol file debugging messages. ++@item set debug symtab-create ++@cindex symbol table creation ++Turns on or off display of debugging messages related to symbol table creation. ++The default is 0 (off). ++A value of 1 provides basic information. ++A value greater than 1 provides more verbose information. ++@item show debug symtab-create ++Show the current state of symbol table creation debugging. ++@item set debug target ++@cindex target debugging info ++Turns on or off display of @value{GDBN} target debugging info. This info ++includes what is going on at the target level of GDB, as it happens. The ++default is 0. Set it to 1 to track events, and to 2 to also track the ++value of large memory transfers. ++@item show debug target ++Displays the current state of displaying @value{GDBN} target debugging ++info. ++@item set debug timestamp ++@cindex timestamping debugging info ++Turns on or off display of timestamps with @value{GDBN} debugging info. ++When enabled, seconds and microseconds are displayed before each debugging ++message. ++@item show debug timestamp ++Displays the current state of displaying timestamps with @value{GDBN} ++debugging info. ++@item set debug varobj ++@cindex variable object debugging info ++Turns on or off display of @value{GDBN} variable object debugging ++info. The default is off. ++@item show debug varobj ++Displays the current state of displaying @value{GDBN} variable object ++debugging info. ++@item set debug xml ++@cindex XML parser debugging ++Turn on or off debugging messages for built-in XML parsers. ++@item show debug xml ++Displays the current state of XML debugging messages. ++@end table ++ ++@node Other Misc Settings ++@section Other Miscellaneous Settings ++@cindex miscellaneous settings ++ ++@table @code ++@kindex set interactive-mode ++@item set interactive-mode ++If @code{on}, forces @value{GDBN} to assume that GDB was started ++in a terminal. In practice, this means that @value{GDBN} should wait ++for the user to answer queries generated by commands entered at ++the command prompt. If @code{off}, forces @value{GDBN} to operate ++in the opposite mode, and it uses the default answers to all queries. ++If @code{auto} (the default), @value{GDBN} tries to determine whether ++its standard input is a terminal, and works in interactive-mode if it ++is, non-interactively otherwise. ++ ++In the vast majority of cases, the debugger should be able to guess ++correctly which mode should be used. But this setting can be useful ++in certain specific cases, such as running a MinGW @value{GDBN} ++inside a cygwin window. ++ ++@kindex show interactive-mode ++@item show interactive-mode ++Displays whether the debugger is operating in interactive mode or not. ++@end table ++ ++@node Extending GDB ++@chapter Extending @value{GDBN} ++@cindex extending GDB ++ ++@value{GDBN} provides several mechanisms for extension. ++@value{GDBN} also provides the ability to automatically load ++extensions when it reads a file for debugging. This allows the ++user to automatically customize @value{GDBN} for the program ++being debugged. ++ ++@menu ++* Sequences:: Canned Sequences of @value{GDBN} Commands ++* Python:: Extending @value{GDBN} using Python ++* Guile:: Extending @value{GDBN} using Guile ++* Auto-loading extensions:: Automatically loading extensions ++* Multiple Extension Languages:: Working with multiple extension languages ++* Aliases:: Creating new spellings of existing commands ++@end menu ++ ++To facilitate the use of extension languages, @value{GDBN} is capable ++of evaluating the contents of a file. When doing so, @value{GDBN} ++can recognize which extension language is being used by looking at ++the filename extension. Files with an unrecognized filename extension ++are always treated as a @value{GDBN} Command Files. ++@xref{Command Files,, Command files}. ++ ++You can control how @value{GDBN} evaluates these files with the following ++setting: ++ ++@table @code ++@kindex set script-extension ++@kindex show script-extension ++@item set script-extension off ++All scripts are always evaluated as @value{GDBN} Command Files. ++ ++@item set script-extension soft ++The debugger determines the scripting language based on filename ++extension. If this scripting language is supported, @value{GDBN} ++evaluates the script using that language. Otherwise, it evaluates ++the file as a @value{GDBN} Command File. ++ ++@item set script-extension strict ++The debugger determines the scripting language based on filename ++extension, and evaluates the script using that language. If the ++language is not supported, then the evaluation fails. ++ ++@item show script-extension ++Display the current value of the @code{script-extension} option. ++ ++@end table ++ ++@ifset SYSTEM_GDBINIT_DIR ++This setting is not used for files in the system-wide gdbinit directory. ++Files in that directory must have an extension matching their language, ++or have a @file{.gdb} extension to be interpreted as regular @value{GDBN} ++commands. @xref{Startup}. ++@end ifset ++ ++@node Sequences ++@section Canned Sequences of Commands ++ ++Aside from breakpoint commands (@pxref{Break Commands, ,Breakpoint ++Command Lists}), @value{GDBN} provides two ways to store sequences of ++commands for execution as a unit: user-defined commands and command ++files. ++ ++@menu ++* Define:: How to define your own commands ++* Hooks:: Hooks for user-defined commands ++* Command Files:: How to write scripts of commands to be stored in a file ++* Output:: Commands for controlled output ++* Auto-loading sequences:: Controlling auto-loaded command files ++@end menu ++ ++@node Define ++@subsection User-defined Commands ++ ++@cindex user-defined command ++@cindex arguments, to user-defined commands ++A @dfn{user-defined command} is a sequence of @value{GDBN} commands to ++which you assign a new name as a command. This is done with the ++@code{define} command. User commands may accept an unlimited number of arguments ++separated by whitespace. Arguments are accessed within the user command ++via @code{$arg0@dots{}$argN}. A trivial example: ++ ++@smallexample ++define adder ++ print $arg0 + $arg1 + $arg2 ++end ++@end smallexample ++ ++@noindent ++To execute the command use: ++ ++@smallexample ++adder 1 2 3 ++@end smallexample ++ ++@noindent ++This defines the command @code{adder}, which prints the sum of ++its three arguments. Note the arguments are text substitutions, so they may ++reference variables, use complex expressions, or even perform inferior ++functions calls. ++ ++@cindex argument count in user-defined commands ++@cindex how many arguments (user-defined commands) ++In addition, @code{$argc} may be used to find out how many arguments have ++been passed. ++ ++@smallexample ++define adder ++ if $argc == 2 ++ print $arg0 + $arg1 ++ end ++ if $argc == 3 ++ print $arg0 + $arg1 + $arg2 ++ end ++end ++@end smallexample ++ ++Combining with the @code{eval} command (@pxref{eval}) makes it easier ++to process a variable number of arguments: ++ ++@smallexample ++define adder ++ set $i = 0 ++ set $sum = 0 ++ while $i < $argc ++ eval "set $sum = $sum + $arg%d", $i ++ set $i = $i + 1 ++ end ++ print $sum ++end ++@end smallexample ++ ++@table @code ++ ++@kindex define ++@item define @var{commandname} ++Define a command named @var{commandname}. If there is already a command ++by that name, you are asked to confirm that you want to redefine it. ++The argument @var{commandname} may be a bare command name consisting of letters, ++numbers, dashes, dots, and underscores. It may also start with any ++predefined or user-defined prefix command. ++For example, @samp{define target my-target} creates ++a user-defined @samp{target my-target} command. ++ ++The definition of the command is made up of other @value{GDBN} command lines, ++which are given following the @code{define} command. The end of these ++commands is marked by a line containing @code{end}. ++ ++@kindex document ++@kindex end@r{ (user-defined commands)} ++@item document @var{commandname} ++Document the user-defined command @var{commandname}, so that it can be ++accessed by @code{help}. The command @var{commandname} must already be ++defined. This command reads lines of documentation just as @code{define} ++reads the lines of the command definition, ending with @code{end}. ++After the @code{document} command is finished, @code{help} on command ++@var{commandname} displays the documentation you have written. ++ ++You may use the @code{document} command again to change the ++documentation of a command. Redefining the command with @code{define} ++does not change the documentation. ++ ++@kindex define-prefix ++@item define-prefix @var{commandname} ++Define or mark the command @var{commandname} as a user-defined prefix ++command. Once marked, @var{commandname} can be used as prefix command ++by the @code{define} command. ++Note that @code{define-prefix} can be used with a not yet defined ++@var{commandname}. In such a case, @var{commandname} is defined as ++an empty user-defined command. ++In case you redefine a command that was marked as a user-defined ++prefix command, the subcommands of the redefined command are kept ++(and @value{GDBN} indicates so to the user). ++ ++Example: ++@example ++(gdb) define-prefix abc ++(gdb) define-prefix abc def ++(gdb) define abc def ++Type commands for definition of "abc def". ++End with a line saying just "end". ++>echo command initial def\n ++>end ++(gdb) define abc def ghi ++Type commands for definition of "abc def ghi". ++End with a line saying just "end". ++>echo command ghi\n ++>end ++(gdb) define abc def ++Keeping subcommands of prefix command "def". ++Redefine command "def"? (y or n) y ++Type commands for definition of "abc def". ++End with a line saying just "end". ++>echo command def\n ++>end ++(gdb) abc def ghi ++command ghi ++(gdb) abc def ++command def ++(gdb) ++@end example ++ ++@kindex dont-repeat ++@cindex don't repeat command ++@item dont-repeat ++Used inside a user-defined command, this tells @value{GDBN} that this ++command should not be repeated when the user hits @key{RET} ++(@pxref{Command Syntax, repeat last command}). ++ ++@kindex help user-defined ++@item help user-defined ++List all user-defined commands and all python commands defined in class ++COMMAND_USER. The first line of the documentation or docstring is ++included (if any). ++ ++@kindex show user ++@item show user ++@itemx show user @var{commandname} ++Display the @value{GDBN} commands used to define @var{commandname} (but ++not its documentation). If no @var{commandname} is given, display the ++definitions for all user-defined commands. ++This does not work for user-defined python commands. ++ ++@cindex infinite recursion in user-defined commands ++@kindex show max-user-call-depth ++@kindex set max-user-call-depth ++@item show max-user-call-depth ++@itemx set max-user-call-depth ++The value of @code{max-user-call-depth} controls how many recursion ++levels are allowed in user-defined commands before @value{GDBN} suspects an ++infinite recursion and aborts the command. ++This does not apply to user-defined python commands. ++@end table ++ ++In addition to the above commands, user-defined commands frequently ++use control flow commands, described in @ref{Command Files}. ++ ++When user-defined commands are executed, the ++commands of the definition are not printed. An error in any command ++stops execution of the user-defined command. ++ ++If used interactively, commands that would ask for confirmation proceed ++without asking when used inside a user-defined command. Many @value{GDBN} ++commands that normally print messages to say what they are doing omit the ++messages when used in a user-defined command. ++ ++@node Hooks ++@subsection User-defined Command Hooks ++@cindex command hooks ++@cindex hooks, for commands ++@cindex hooks, pre-command ++ ++@kindex hook ++You may define @dfn{hooks}, which are a special kind of user-defined ++command. Whenever you run the command @samp{foo}, if the user-defined ++command @samp{hook-foo} exists, it is executed (with no arguments) ++before that command. ++ ++@cindex hooks, post-command ++@kindex hookpost ++A hook may also be defined which is run after the command you executed. ++Whenever you run the command @samp{foo}, if the user-defined command ++@samp{hookpost-foo} exists, it is executed (with no arguments) after ++that command. Post-execution hooks may exist simultaneously with ++pre-execution hooks, for the same command. ++ ++It is valid for a hook to call the command which it hooks. If this ++occurs, the hook is not re-executed, thereby avoiding infinite recursion. ++ ++@c It would be nice if hookpost could be passed a parameter indicating ++@c if the command it hooks executed properly or not. FIXME! ++ ++@kindex stop@r{, a pseudo-command} ++In addition, a pseudo-command, @samp{stop} exists. Defining ++(@samp{hook-stop}) makes the associated commands execute every time ++execution stops in your program: before breakpoint commands are run, ++displays are printed, or the stack frame is printed. ++ ++For example, to ignore @code{SIGALRM} signals while ++single-stepping, but treat them normally during normal execution, ++you could define: ++ ++@smallexample ++define hook-stop ++handle SIGALRM nopass ++end ++ ++define hook-run ++handle SIGALRM pass ++end ++ ++define hook-continue ++handle SIGALRM pass ++end ++@end smallexample ++ ++As a further example, to hook at the beginning and end of the @code{echo} ++command, and to add extra text to the beginning and end of the message, ++you could define: ++ ++@smallexample ++define hook-echo ++echo <<<--- ++end ++ ++define hookpost-echo ++echo --->>>\n ++end ++ ++(@value{GDBP}) echo Hello World ++<<<---Hello World--->>> ++(@value{GDBP}) ++ ++@end smallexample ++ ++You can define a hook for any single-word command in @value{GDBN}, but ++not for command aliases; you should define a hook for the basic command ++name, e.g.@: @code{backtrace} rather than @code{bt}. ++@c FIXME! So how does Joe User discover whether a command is an alias ++@c or not? ++You can hook a multi-word command by adding @code{hook-} or ++@code{hookpost-} to the last word of the command, e.g.@: ++@samp{define target hook-remote} to add a hook to @samp{target remote}. ++ ++If an error occurs during the execution of your hook, execution of ++@value{GDBN} commands stops and @value{GDBN} issues a prompt ++(before the command that you actually typed had a chance to run). ++ ++If you try to define a hook which does not match any known command, you ++get a warning from the @code{define} command. ++ ++@node Command Files ++@subsection Command Files ++ ++@cindex command files ++@cindex scripting commands ++A command file for @value{GDBN} is a text file made of lines that are ++@value{GDBN} commands. Comments (lines starting with @kbd{#}) may ++also be included. An empty line in a command file does nothing; it ++does not mean to repeat the last command, as it would from the ++terminal. ++ ++You can request the execution of a command file with the @code{source} ++command. Note that the @code{source} command is also used to evaluate ++scripts that are not Command Files. The exact behavior can be configured ++using the @code{script-extension} setting. ++@xref{Extending GDB,, Extending GDB}. ++ ++@table @code ++@kindex source ++@cindex execute commands from a file ++@item source [-s] [-v] @var{filename} ++Execute the command file @var{filename}. ++@end table ++ ++The lines in a command file are generally executed sequentially, ++unless the order of execution is changed by one of the ++@emph{flow-control commands} described below. The commands are not ++printed as they are executed. An error in any command terminates ++execution of the command file and control is returned to the console. ++ ++@value{GDBN} first searches for @var{filename} in the current directory. ++If the file is not found there, and @var{filename} does not specify a ++directory, then @value{GDBN} also looks for the file on the source search path ++(specified with the @samp{directory} command); ++except that @file{$cdir} is not searched because the compilation directory ++is not relevant to scripts. ++ ++If @code{-s} is specified, then @value{GDBN} searches for @var{filename} ++on the search path even if @var{filename} specifies a directory. ++The search is done by appending @var{filename} to each element of the ++search path. So, for example, if @var{filename} is @file{mylib/myscript} ++and the search path contains @file{/home/user} then @value{GDBN} will ++look for the script @file{/home/user/mylib/myscript}. ++The search is also done if @var{filename} is an absolute path. ++For example, if @var{filename} is @file{/tmp/myscript} and ++the search path contains @file{/home/user} then @value{GDBN} will ++look for the script @file{/home/user/tmp/myscript}. ++For DOS-like systems, if @var{filename} contains a drive specification, ++it is stripped before concatenation. For example, if @var{filename} is ++@file{d:myscript} and the search path contains @file{c:/tmp} then @value{GDBN} ++will look for the script @file{c:/tmp/myscript}. ++ ++If @code{-v}, for verbose mode, is given then @value{GDBN} displays ++each command as it is executed. The option must be given before ++@var{filename}, and is interpreted as part of the filename anywhere else. ++ ++Commands that would ask for confirmation if used interactively proceed ++without asking when used in a command file. Many @value{GDBN} commands that ++normally print messages to say what they are doing omit the messages ++when called from command files. ++ ++@value{GDBN} also accepts command input from standard input. In this ++mode, normal output goes to standard output and error output goes to ++standard error. Errors in a command file supplied on standard input do ++not terminate execution of the command file---execution continues with ++the next command. ++ ++@smallexample ++gdb < cmds > log 2>&1 ++@end smallexample ++ ++(The syntax above will vary depending on the shell used.) This example ++will execute commands from the file @file{cmds}. All output and errors ++would be directed to @file{log}. ++ ++Since commands stored on command files tend to be more general than ++commands typed interactively, they frequently need to deal with ++complicated situations, such as different or unexpected values of ++variables and symbols, changes in how the program being debugged is ++built, etc. @value{GDBN} provides a set of flow-control commands to ++deal with these complexities. Using these commands, you can write ++complex scripts that loop over data structures, execute commands ++conditionally, etc. ++ ++@table @code ++@kindex if ++@kindex else ++@item if ++@itemx else ++This command allows to include in your script conditionally executed ++commands. The @code{if} command takes a single argument, which is an ++expression to evaluate. It is followed by a series of commands that ++are executed only if the expression is true (its value is nonzero). ++There can then optionally be an @code{else} line, followed by a series ++of commands that are only executed if the expression was false. The ++end of the list is marked by a line containing @code{end}. ++ ++@kindex while ++@item while ++This command allows to write loops. Its syntax is similar to ++@code{if}: the command takes a single argument, which is an expression ++to evaluate, and must be followed by the commands to execute, one per ++line, terminated by an @code{end}. These commands are called the ++@dfn{body} of the loop. The commands in the body of @code{while} are ++executed repeatedly as long as the expression evaluates to true. ++ ++@kindex loop_break ++@item loop_break ++This command exits the @code{while} loop in whose body it is included. ++Execution of the script continues after that @code{while}s @code{end} ++line. ++ ++@kindex loop_continue ++@item loop_continue ++This command skips the execution of the rest of the body of commands ++in the @code{while} loop in whose body it is included. Execution ++branches to the beginning of the @code{while} loop, where it evaluates ++the controlling expression. ++ ++@kindex end@r{ (if/else/while commands)} ++@item end ++Terminate the block of commands that are the body of @code{if}, ++@code{else}, or @code{while} flow-control commands. ++@end table ++ ++ ++@node Output ++@subsection Commands for Controlled Output ++ ++During the execution of a command file or a user-defined command, normal ++@value{GDBN} output is suppressed; the only output that appears is what is ++explicitly printed by the commands in the definition. This section ++describes three commands useful for generating exactly the output you ++want. ++ ++@table @code ++@kindex echo ++@item echo @var{text} ++@c I do not consider backslash-space a standard C escape sequence ++@c because it is not in ANSI. ++Print @var{text}. Nonprinting characters can be included in ++@var{text} using C escape sequences, such as @samp{\n} to print a ++newline. @strong{No newline is printed unless you specify one.} ++In addition to the standard C escape sequences, a backslash followed ++by a space stands for a space. This is useful for displaying a ++string with spaces at the beginning or the end, since leading and ++trailing spaces are otherwise trimmed from all arguments. ++To print @samp{@w{ }and foo =@w{ }}, use the command ++@samp{echo \@w{ }and foo = \@w{ }}. ++ ++A backslash at the end of @var{text} can be used, as in C, to continue ++the command onto subsequent lines. For example, ++ ++@smallexample ++echo This is some text\n\ ++which is continued\n\ ++onto several lines.\n ++@end smallexample ++ ++produces the same output as ++ ++@smallexample ++echo This is some text\n ++echo which is continued\n ++echo onto several lines.\n ++@end smallexample ++ ++@kindex output ++@item output @var{expression} ++Print the value of @var{expression} and nothing but that value: no ++newlines, no @samp{$@var{nn} = }. The value is not entered in the ++value history either. @xref{Expressions, ,Expressions}, for more information ++on expressions. ++ ++@item output/@var{fmt} @var{expression} ++Print the value of @var{expression} in format @var{fmt}. You can use ++the same formats as for @code{print}. @xref{Output Formats,,Output ++Formats}, for more information. ++ ++@kindex printf ++@item printf @var{template}, @var{expressions}@dots{} ++Print the values of one or more @var{expressions} under the control of ++the string @var{template}. To print several values, make ++@var{expressions} be a comma-separated list of individual expressions, ++which may be either numbers or pointers. Their values are printed as ++specified by @var{template}, exactly as a C program would do by ++executing the code below: ++ ++@smallexample ++printf (@var{template}, @var{expressions}@dots{}); ++@end smallexample ++ ++As in @code{C} @code{printf}, ordinary characters in @var{template} ++are printed verbatim, while @dfn{conversion specification} introduced ++by the @samp{%} character cause subsequent @var{expressions} to be ++evaluated, their values converted and formatted according to type and ++style information encoded in the conversion specifications, and then ++printed. ++ ++For example, you can print two values in hex like this: ++ ++@smallexample ++printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo ++@end smallexample ++ ++@code{printf} supports all the standard @code{C} conversion ++specifications, including the flags and modifiers between the @samp{%} ++character and the conversion letter, with the following exceptions: ++ ++@itemize @bullet ++@item ++The argument-ordering modifiers, such as @samp{2$}, are not supported. ++ ++@item ++The modifier @samp{*} is not supported for specifying precision or ++width. ++ ++@item ++The @samp{'} flag (for separation of digits into groups according to ++@code{LC_NUMERIC'}) is not supported. ++ ++@item ++The type modifiers @samp{hh}, @samp{j}, @samp{t}, and @samp{z} are not ++supported. ++ ++@item ++The conversion letter @samp{n} (as in @samp{%n}) is not supported. ++ ++@item ++The conversion letters @samp{a} and @samp{A} are not supported. ++@end itemize ++ ++@noindent ++Note that the @samp{ll} type modifier is supported only if the ++underlying @code{C} implementation used to build @value{GDBN} supports ++the @code{long long int} type, and the @samp{L} type modifier is ++supported only if @code{long double} type is available. ++ ++As in @code{C}, @code{printf} supports simple backslash-escape ++sequences, such as @code{\n}, @samp{\t}, @samp{\\}, @samp{\"}, ++@samp{\a}, and @samp{\f}, that consist of backslash followed by a ++single character. Octal and hexadecimal escape sequences are not ++supported. ++ ++Additionally, @code{printf} supports conversion specifications for DFP ++(@dfn{Decimal Floating Point}) types using the following length modifiers ++together with a floating point specifier. ++letters: ++ ++@itemize @bullet ++@item ++@samp{H} for printing @code{Decimal32} types. ++ ++@item ++@samp{D} for printing @code{Decimal64} types. ++ ++@item ++@samp{DD} for printing @code{Decimal128} types. ++@end itemize ++ ++If the underlying @code{C} implementation used to build @value{GDBN} has ++support for the three length modifiers for DFP types, other modifiers ++such as width and precision will also be available for @value{GDBN} to use. ++ ++In case there is no such @code{C} support, no additional modifiers will be ++available and the value will be printed in the standard way. ++ ++Here's an example of printing DFP types using the above conversion letters: ++@smallexample ++printf "D32: %Hf - D64: %Df - D128: %DDf\n",1.2345df,1.2E10dd,1.2E1dl ++@end smallexample ++ ++@anchor{eval} ++@kindex eval ++@item eval @var{template}, @var{expressions}@dots{} ++Convert the values of one or more @var{expressions} under the control of ++the string @var{template} to a command line, and call it. ++ ++@end table ++ ++@node Auto-loading sequences ++@subsection Controlling auto-loading native @value{GDBN} scripts ++@cindex native script auto-loading ++ ++When a new object file is read (for example, due to the @code{file} ++command, or because the inferior has loaded a shared library), ++@value{GDBN} will look for the command file @file{@var{objfile}-gdb.gdb}. ++@xref{Auto-loading extensions}. ++ ++Auto-loading can be enabled or disabled, ++and the list of auto-loaded scripts can be printed. ++ ++@table @code ++@anchor{set auto-load gdb-scripts} ++@kindex set auto-load gdb-scripts ++@item set auto-load gdb-scripts [on|off] ++Enable or disable the auto-loading of canned sequences of commands scripts. ++ ++@anchor{show auto-load gdb-scripts} ++@kindex show auto-load gdb-scripts ++@item show auto-load gdb-scripts ++Show whether auto-loading of canned sequences of commands scripts is enabled or ++disabled. ++ ++@anchor{info auto-load gdb-scripts} ++@kindex info auto-load gdb-scripts ++@cindex print list of auto-loaded canned sequences of commands scripts ++@item info auto-load gdb-scripts [@var{regexp}] ++Print the list of all canned sequences of commands scripts that @value{GDBN} ++auto-loaded. ++@end table ++ ++If @var{regexp} is supplied only canned sequences of commands scripts with ++matching names are printed. ++ ++@c Python docs live in a separate file. ++@include python.texi ++ ++@c Guile docs live in a separate file. ++@include guile.texi ++ ++@node Auto-loading extensions ++@section Auto-loading extensions ++@cindex auto-loading extensions ++ ++@value{GDBN} provides two mechanisms for automatically loading extensions ++when a new object file is read (for example, due to the @code{file} ++command, or because the inferior has loaded a shared library): ++@file{@var{objfile}-gdb.@var{ext}} and the @code{.debug_gdb_scripts} ++section of modern file formats like ELF. ++ ++@menu ++* objfile-gdb.ext file: objfile-gdbdotext file. The @file{@var{objfile}-gdb.@var{ext}} file ++* .debug_gdb_scripts section: dotdebug_gdb_scripts section. The @code{.debug_gdb_scripts} section ++* Which flavor to choose?:: ++@end menu ++ ++The auto-loading feature is useful for supplying application-specific ++debugging commands and features. ++ ++Auto-loading can be enabled or disabled, ++and the list of auto-loaded scripts can be printed. ++See the @samp{auto-loading} section of each extension language ++for more information. ++For @value{GDBN} command files see @ref{Auto-loading sequences}. ++For Python files see @ref{Python Auto-loading}. ++ ++Note that loading of this script file also requires accordingly configured ++@code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++ ++@node objfile-gdbdotext file ++@subsection The @file{@var{objfile}-gdb.@var{ext}} file ++@cindex @file{@var{objfile}-gdb.gdb} ++@cindex @file{@var{objfile}-gdb.py} ++@cindex @file{@var{objfile}-gdb.scm} ++ ++When a new object file is read, @value{GDBN} looks for a file named ++@file{@var{objfile}-gdb.@var{ext}} (we call it @var{script-name} below), ++where @var{objfile} is the object file's name and ++where @var{ext} is the file extension for the extension language: ++ ++@table @code ++@item @file{@var{objfile}-gdb.gdb} ++GDB's own command language ++@item @file{@var{objfile}-gdb.py} ++Python ++@item @file{@var{objfile}-gdb.scm} ++Guile ++@end table ++ ++@var{script-name} is formed by ensuring that the file name of @var{objfile} ++is absolute, following all symlinks, and resolving @code{.} and @code{..} ++components, and appending the @file{-gdb.@var{ext}} suffix. ++If this file exists and is readable, @value{GDBN} will evaluate it as a ++script in the specified extension language. ++ ++If this file does not exist, then @value{GDBN} will look for ++@var{script-name} file in all of the directories as specified below. ++(On MS-Windows/MS-DOS, the drive letter of the executable's leading ++directories is converted to a one-letter subdirectory, i.e.@: ++@file{d:/usr/bin/} is converted to @file{/d/usr/bin/}, because Windows ++filesystems disallow colons in file names.) ++ ++Note that loading of these files requires an accordingly configured ++@code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++ ++For object files using @file{.exe} suffix @value{GDBN} tries to load first the ++scripts normally according to its @file{.exe} filename. But if no scripts are ++found @value{GDBN} also tries script filenames matching the object file without ++its @file{.exe} suffix. This @file{.exe} stripping is case insensitive and it ++is attempted on any platform. This makes the script filenames compatible ++between Unix and MS-Windows hosts. ++ ++@table @code ++@anchor{set auto-load scripts-directory} ++@kindex set auto-load scripts-directory ++@item set auto-load scripts-directory @r{[}@var{directories}@r{]} ++Control @value{GDBN} auto-loaded scripts location. Multiple directory entries ++may be delimited by the host platform path separator in use ++(@samp{:} on Unix, @samp{;} on MS-Windows and MS-DOS). ++ ++Each entry here needs to be covered also by the security setting ++@code{set auto-load safe-path} (@pxref{set auto-load safe-path}). ++ ++@anchor{with-auto-load-dir} ++This variable defaults to @file{$debugdir:$datadir/auto-load}. The default ++@code{set auto-load safe-path} value can be also overriden by @value{GDBN} ++configuration option @option{--with-auto-load-dir}. ++ ++Any reference to @file{$debugdir} will get replaced by ++@var{debug-file-directory} value (@pxref{Separate Debug Files}) and any ++reference to @file{$datadir} will get replaced by @var{data-directory} which is ++determined at @value{GDBN} startup (@pxref{Data Files}). @file{$debugdir} and ++@file{$datadir} must be placed as a directory component --- either alone or ++delimited by @file{/} or @file{\} directory separators, depending on the host ++platform. ++ ++The list of directories uses path separator (@samp{:} on GNU and Unix ++systems, @samp{;} on MS-Windows and MS-DOS) to separate directories, similarly ++to the @env{PATH} environment variable. ++ ++@anchor{show auto-load scripts-directory} ++@kindex show auto-load scripts-directory ++@item show auto-load scripts-directory ++Show @value{GDBN} auto-loaded scripts location. ++ ++@anchor{add-auto-load-scripts-directory} ++@kindex add-auto-load-scripts-directory ++@item add-auto-load-scripts-directory @r{[}@var{directories}@dots{}@r{]} ++Add an entry (or list of entries) to the list of auto-loaded scripts locations. ++Multiple entries may be delimited by the host platform path separator in use. ++@end table ++ ++@value{GDBN} does not track which files it has already auto-loaded this way. ++@value{GDBN} will load the associated script every time the corresponding ++@var{objfile} is opened. ++So your @file{-gdb.@var{ext}} file should be careful to avoid errors if it ++is evaluated more than once. ++ ++@node dotdebug_gdb_scripts section ++@subsection The @code{.debug_gdb_scripts} section ++@cindex @code{.debug_gdb_scripts} section ++ ++For systems using file formats like ELF and COFF, ++when @value{GDBN} loads a new object file ++it will look for a special section named @code{.debug_gdb_scripts}. ++If this section exists, its contents is a list of null-terminated entries ++specifying scripts to load. Each entry begins with a non-null prefix byte that ++specifies the kind of entry, typically the extension language and whether the ++script is in a file or inlined in @code{.debug_gdb_scripts}. ++ ++The following entries are supported: ++ ++@table @code ++@item SECTION_SCRIPT_ID_PYTHON_FILE = 1 ++@item SECTION_SCRIPT_ID_SCHEME_FILE = 3 ++@item SECTION_SCRIPT_ID_PYTHON_TEXT = 4 ++@item SECTION_SCRIPT_ID_SCHEME_TEXT = 6 ++@end table ++ ++@subsubsection Script File Entries ++ ++If the entry specifies a file, @value{GDBN} will look for the file first ++in the current directory and then along the source search path ++(@pxref{Source Path, ,Specifying Source Directories}), ++except that @file{$cdir} is not searched, since the compilation ++directory is not relevant to scripts. ++ ++File entries can be placed in section @code{.debug_gdb_scripts} with, ++for example, this GCC macro for Python scripts. ++ ++@example ++/* Note: The "MS" section flags are to remove duplicates. */ ++#define DEFINE_GDB_PY_SCRIPT(script_name) \ ++ asm("\ ++.pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n\ ++.byte 1 /* Python */\n\ ++.asciz \"" script_name "\"\n\ ++.popsection \n\ ++"); ++@end example ++ ++@noindent ++For Guile scripts, replace @code{.byte 1} with @code{.byte 3}. ++Then one can reference the macro in a header or source file like this: ++ ++@example ++DEFINE_GDB_PY_SCRIPT ("my-app-scripts.py") ++@end example ++ ++The script name may include directories if desired. ++ ++Note that loading of this script file also requires accordingly configured ++@code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++ ++If the macro invocation is put in a header, any application or library ++using this header will get a reference to the specified script, ++and with the use of @code{"MS"} attributes on the section, the linker ++will remove duplicates. ++ ++@subsubsection Script Text Entries ++ ++Script text entries allow to put the executable script in the entry ++itself instead of loading it from a file. ++The first line of the entry, everything after the prefix byte and up to ++the first newline (@code{0xa}) character, is the script name, and must not ++contain any kind of space character, e.g., spaces or tabs. ++The rest of the entry, up to the trailing null byte, is the script to ++execute in the specified language. The name needs to be unique among ++all script names, as @value{GDBN} executes each script only once based ++on its name. ++ ++Here is an example from file @file{py-section-script.c} in the @value{GDBN} ++testsuite. ++ ++@example ++#include "symcat.h" ++#include "gdb/section-scripts.h" ++asm( ++".pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n" ++".byte " XSTRING (SECTION_SCRIPT_ID_PYTHON_TEXT) "\n" ++".ascii \"gdb.inlined-script\\n\"\n" ++".ascii \"class test_cmd (gdb.Command):\\n\"\n" ++".ascii \" def __init__ (self):\\n\"\n" ++".ascii \" super (test_cmd, self).__init__ (" ++ "\\\"test-cmd\\\", gdb.COMMAND_OBSCURE)\\n\"\n" ++".ascii \" def invoke (self, arg, from_tty):\\n\"\n" ++".ascii \" print (\\\"test-cmd output, arg = %s\\\" % arg)\\n\"\n" ++".ascii \"test_cmd ()\\n\"\n" ++".byte 0\n" ++".popsection\n" ++); ++@end example ++ ++Loading of inlined scripts requires a properly configured ++@code{auto-load safe-path} (@pxref{Auto-loading safe path}). ++The path to specify in @code{auto-load safe-path} is the path of the file ++containing the @code{.debug_gdb_scripts} section. ++ ++@node Which flavor to choose? ++@subsection Which flavor to choose? ++ ++Given the multiple ways of auto-loading extensions, it might not always ++be clear which one to choose. This section provides some guidance. ++ ++@noindent ++Benefits of the @file{-gdb.@var{ext}} way: ++ ++@itemize @bullet ++@item ++Can be used with file formats that don't support multiple sections. ++ ++@item ++Ease of finding scripts for public libraries. ++ ++Scripts specified in the @code{.debug_gdb_scripts} section are searched for ++in the source search path. ++For publicly installed libraries, e.g., @file{libstdc++}, there typically ++isn't a source directory in which to find the script. ++ ++@item ++Doesn't require source code additions. ++@end itemize ++ ++@noindent ++Benefits of the @code{.debug_gdb_scripts} way: ++ ++@itemize @bullet ++@item ++Works with static linking. ++ ++Scripts for libraries done the @file{-gdb.@var{ext}} way require an objfile to ++trigger their loading. When an application is statically linked the only ++objfile available is the executable, and it is cumbersome to attach all the ++scripts from all the input libraries to the executable's ++@file{-gdb.@var{ext}} script. ++ ++@item ++Works with classes that are entirely inlined. ++ ++Some classes can be entirely inlined, and thus there may not be an associated ++shared library to attach a @file{-gdb.@var{ext}} script to. ++ ++@item ++Scripts needn't be copied out of the source tree. ++ ++In some circumstances, apps can be built out of large collections of internal ++libraries, and the build infrastructure necessary to install the ++@file{-gdb.@var{ext}} scripts in a place where @value{GDBN} can find them is ++cumbersome. It may be easier to specify the scripts in the ++@code{.debug_gdb_scripts} section as relative paths, and add a path to the ++top of the source tree to the source search path. ++@end itemize ++ ++@node Multiple Extension Languages ++@section Multiple Extension Languages ++ ++The Guile and Python extension languages do not share any state, ++and generally do not interfere with each other. ++There are some things to be aware of, however. ++ ++@subsection Python comes first ++ ++Python was @value{GDBN}'s first extension language, and to avoid breaking ++existing behaviour Python comes first. This is generally solved by the ++``first one wins'' principle. @value{GDBN} maintains a list of enabled ++extension languages, and when it makes a call to an extension language, ++(say to pretty-print a value), it tries each in turn until an extension ++language indicates it has performed the request (e.g., has returned the ++pretty-printed form of a value). ++This extends to errors while performing such requests: If an error happens ++while, for example, trying to pretty-print an object then the error is ++reported and any following extension languages are not tried. ++ ++@node Aliases ++@section Creating new spellings of existing commands ++@cindex aliases for commands ++ ++It is often useful to define alternate spellings of existing commands. ++For example, if a new @value{GDBN} command defined in Python has ++a long name to type, it is handy to have an abbreviated version of it ++that involves less typing. ++ ++@value{GDBN} itself uses aliases. For example @samp{s} is an alias ++of the @samp{step} command even though it is otherwise an ambiguous ++abbreviation of other commands like @samp{set} and @samp{show}. ++ ++Aliases are also used to provide shortened or more common versions ++of multi-word commands. For example, @value{GDBN} provides the ++@samp{tty} alias of the @samp{set inferior-tty} command. ++ ++You can define a new alias with the @samp{alias} command. ++ ++@table @code ++ ++@kindex alias ++@item alias [-a] [--] @var{ALIAS} = @var{COMMAND} [DEFAULT-ARGS...] ++ ++@end table ++ ++@var{ALIAS} specifies the name of the new alias. ++Each word of @var{ALIAS} must consist of letters, numbers, dashes and ++underscores. ++ ++@var{COMMAND} specifies the name of an existing command ++that is being aliased. ++ ++@var{COMMAND} can also be the name of an existing alias. In this case, ++@var{COMMAND} cannot be an alias that has default arguments. ++ ++The @samp{-a} option specifies that the new alias is an abbreviation ++of the command. Abbreviations are not used in command completion. ++ ++The @samp{--} option specifies the end of options, ++and is useful when @var{ALIAS} begins with a dash. ++ ++You can specify @var{default-args} for your alias. ++These @var{default-args} will be automatically added before the alias ++arguments typed explicitly on the command line. ++ ++For example, the below defines an alias @code{btfullall} that shows all local ++variables and all frame arguments: ++@smallexample ++(@value{GDBP}) alias btfullall = backtrace -full -frame-arguments all ++@end smallexample ++ ++For more information about @var{default-args}, see @ref{Command aliases default args, ++,Automatically prepend default arguments to user-defined aliases}. ++ ++Here is a simple example showing how to make an abbreviation ++of a command so that there is less to type. ++Suppose you were tired of typing @samp{disas}, the current ++shortest unambiguous abbreviation of the @samp{disassemble} command ++and you wanted an even shorter version named @samp{di}. ++The following will accomplish this. ++ ++@smallexample ++(gdb) alias -a di = disas ++@end smallexample ++ ++Note that aliases are different from user-defined commands. ++With a user-defined command, you also need to write documentation ++for it with the @samp{document} command. ++An alias automatically picks up the documentation of the existing command. ++ ++Here is an example where we make @samp{elms} an abbreviation of ++@samp{elements} in the @samp{set print elements} command. ++This is to show that you can make an abbreviation of any part ++of a command. ++ ++@smallexample ++(gdb) alias -a set print elms = set print elements ++(gdb) alias -a show print elms = show print elements ++(gdb) set p elms 20 ++(gdb) show p elms ++Limit on string chars or array elements to print is 200. ++@end smallexample ++ ++Note that if you are defining an alias of a @samp{set} command, ++and you want to have an alias for the corresponding @samp{show} ++command, then you need to define the latter separately. ++ ++Unambiguously abbreviated commands are allowed in @var{COMMAND} and ++@var{ALIAS}, just as they are normally. ++ ++@smallexample ++(gdb) alias -a set pr elms = set p ele ++@end smallexample ++ ++Finally, here is an example showing the creation of a one word ++alias for a more complex command. ++This creates alias @samp{spe} of the command @samp{set print elements}. ++ ++@smallexample ++(gdb) alias spe = set print elements ++(gdb) spe 20 ++@end smallexample ++ ++@node Interpreters ++@chapter Command Interpreters ++@cindex command interpreters ++ ++@value{GDBN} supports multiple command interpreters, and some command ++infrastructure to allow users or user interface writers to switch ++between interpreters or run commands in other interpreters. ++ ++@value{GDBN} currently supports two command interpreters, the console ++interpreter (sometimes called the command-line interpreter or @sc{cli}) ++and the machine interface interpreter (or @sc{gdb/mi}). This manual ++describes both of these interfaces in great detail. ++ ++By default, @value{GDBN} will start with the console interpreter. ++However, the user may choose to start @value{GDBN} with another ++interpreter by specifying the @option{-i} or @option{--interpreter} ++startup options. Defined interpreters include: ++ ++@table @code ++@item console ++@cindex console interpreter ++The traditional console or command-line interpreter. This is the most often ++used interpreter with @value{GDBN}. With no interpreter specified at runtime, ++@value{GDBN} will use this interpreter. ++ ++@item mi ++@cindex mi interpreter ++The newest @sc{gdb/mi} interface (currently @code{mi3}). Used primarily ++by programs wishing to use @value{GDBN} as a backend for a debugger GUI ++or an IDE. For more information, see @ref{GDB/MI, ,The @sc{gdb/mi} ++Interface}. ++ ++@item mi3 ++@cindex mi3 interpreter ++The @sc{gdb/mi} interface introduced in @value{GDBN} 9.1. ++ ++@item mi2 ++@cindex mi2 interpreter ++The @sc{gdb/mi} interface introduced in @value{GDBN} 6.0. ++ ++@item mi1 ++@cindex mi1 interpreter ++The @sc{gdb/mi} interface introduced in @value{GDBN} 5.1. ++ ++@end table ++ ++@cindex invoke another interpreter ++ ++@kindex interpreter-exec ++You may execute commands in any interpreter from the current ++interpreter using the appropriate command. If you are running the ++console interpreter, simply use the @code{interpreter-exec} command: ++ ++@smallexample ++interpreter-exec mi "-data-list-register-names" ++@end smallexample ++ ++@sc{gdb/mi} has a similar command, although it is only available in versions of ++@value{GDBN} which support @sc{gdb/mi} version 2 (or greater). ++ ++Note that @code{interpreter-exec} only changes the interpreter for the ++duration of the specified command. It does not change the interpreter ++permanently. ++ ++@cindex start a new independent interpreter ++ ++Although you may only choose a single interpreter at startup, it is ++possible to run an independent interpreter on a specified input/output ++device (usually a tty). ++ ++For example, consider a debugger GUI or IDE that wants to provide a ++@value{GDBN} console view. It may do so by embedding a terminal ++emulator widget in its GUI, starting @value{GDBN} in the traditional ++command-line mode with stdin/stdout/stderr redirected to that ++terminal, and then creating an MI interpreter running on a specified ++input/output device. The console interpreter created by @value{GDBN} ++at startup handles commands the user types in the terminal widget, ++while the GUI controls and synchronizes state with @value{GDBN} using ++the separate MI interpreter. ++ ++To start a new secondary @dfn{user interface} running MI, use the ++@code{new-ui} command: ++ ++@kindex new-ui ++@cindex new user interface ++@smallexample ++new-ui @var{interpreter} @var{tty} ++@end smallexample ++ ++The @var{interpreter} parameter specifies the interpreter to run. ++This accepts the same values as the @code{interpreter-exec} command. ++For example, @samp{console}, @samp{mi}, @samp{mi2}, etc. The ++@var{tty} parameter specifies the name of the bidirectional file the ++interpreter uses for input/output, usually the name of a ++pseudoterminal slave on Unix systems. For example: ++ ++@smallexample ++(@value{GDBP}) new-ui mi /dev/pts/9 ++@end smallexample ++ ++@noindent ++runs an MI interpreter on @file{/dev/pts/9}. ++ ++@node TUI ++@chapter @value{GDBN} Text User Interface ++@cindex TUI ++@cindex Text User Interface ++ ++@menu ++* TUI Overview:: TUI overview ++* TUI Keys:: TUI key bindings ++* TUI Single Key Mode:: TUI single key mode ++* TUI Commands:: TUI-specific commands ++* TUI Configuration:: TUI configuration variables ++@end menu ++ ++The @value{GDBN} Text User Interface (TUI) is a terminal ++interface which uses the @code{curses} library to show the source ++file, the assembly output, the program registers and @value{GDBN} ++commands in separate text windows. The TUI mode is supported only ++on platforms where a suitable version of the @code{curses} library ++is available. ++ ++The TUI mode is enabled by default when you invoke @value{GDBN} as ++@samp{@value{GDBP} -tui}. ++You can also switch in and out of TUI mode while @value{GDBN} runs by ++using various TUI commands and key bindings, such as @command{tui ++enable} or @kbd{C-x C-a}. @xref{TUI Commands, ,TUI Commands}, and ++@ref{TUI Keys, ,TUI Key Bindings}. ++ ++@node TUI Overview ++@section TUI Overview ++ ++In TUI mode, @value{GDBN} can display several text windows: ++ ++@table @emph ++@item command ++This window is the @value{GDBN} command window with the @value{GDBN} ++prompt and the @value{GDBN} output. The @value{GDBN} input is still ++managed using readline. ++ ++@item source ++The source window shows the source file of the program. The current ++line and active breakpoints are displayed in this window. ++ ++@item assembly ++The assembly window shows the disassembly output of the program. ++ ++@item register ++This window shows the processor registers. Registers are highlighted ++when their values change. ++@end table ++ ++The source and assembly windows show the current program position ++by highlighting the current line and marking it with a @samp{>} marker. ++Breakpoints are indicated with two markers. The first marker ++indicates the breakpoint type: ++ ++@table @code ++@item B ++Breakpoint which was hit at least once. ++ ++@item b ++Breakpoint which was never hit. ++ ++@item H ++Hardware breakpoint which was hit at least once. ++ ++@item h ++Hardware breakpoint which was never hit. ++@end table ++ ++The second marker indicates whether the breakpoint is enabled or not: ++ ++@table @code ++@item + ++Breakpoint is enabled. ++ ++@item - ++Breakpoint is disabled. ++@end table ++ ++The source, assembly and register windows are updated when the current ++thread changes, when the frame changes, or when the program counter ++changes. ++ ++These windows are not all visible at the same time. The command ++window is always visible. The others can be arranged in several ++layouts: ++ ++@itemize @bullet ++@item ++source only, ++ ++@item ++assembly only, ++ ++@item ++source and assembly, ++ ++@item ++source and registers, or ++ ++@item ++assembly and registers. ++@end itemize ++ ++These are the standard layouts, but other layouts can be defined. ++ ++A status line above the command window shows the following information: ++ ++@table @emph ++@item target ++Indicates the current @value{GDBN} target. ++(@pxref{Targets, ,Specifying a Debugging Target}). ++ ++@item process ++Gives the current process or thread number. ++When no process is being debugged, this field is set to @code{No process}. ++ ++@item function ++Gives the current function name for the selected frame. ++The name is demangled if demangling is turned on (@pxref{Print Settings}). ++When there is no symbol corresponding to the current program counter, ++the string @code{??} is displayed. ++ ++@item line ++Indicates the current line number for the selected frame. ++When the current line number is not known, the string @code{??} is displayed. ++ ++@item pc ++Indicates the current program counter address. ++@end table ++ ++@node TUI Keys ++@section TUI Key Bindings ++@cindex TUI key bindings ++ ++The TUI installs several key bindings in the readline keymaps ++@ifset SYSTEM_READLINE ++(@pxref{Command Line Editing, , , rluserman, GNU Readline Library}). ++@end ifset ++@ifclear SYSTEM_READLINE ++(@pxref{Command Line Editing}). ++@end ifclear ++The following key bindings are installed for both TUI mode and the ++@value{GDBN} standard mode. ++ ++@table @kbd ++@kindex C-x C-a ++@item C-x C-a ++@kindex C-x a ++@itemx C-x a ++@kindex C-x A ++@itemx C-x A ++Enter or leave the TUI mode. When leaving the TUI mode, ++the curses window management stops and @value{GDBN} operates using ++its standard mode, writing on the terminal directly. When reentering ++the TUI mode, control is given back to the curses windows. ++The screen is then refreshed. ++ ++This key binding uses the bindable Readline function ++@code{tui-switch-mode}. ++ ++@kindex C-x 1 ++@item C-x 1 ++Use a TUI layout with only one window. The layout will ++either be @samp{source} or @samp{assembly}. When the TUI mode ++is not active, it will switch to the TUI mode. ++ ++Think of this key binding as the Emacs @kbd{C-x 1} binding. ++ ++This key binding uses the bindable Readline function ++@code{tui-delete-other-windows}. ++ ++@kindex C-x 2 ++@item C-x 2 ++Use a TUI layout with at least two windows. When the current ++layout already has two windows, the next layout with two windows is used. ++When a new layout is chosen, one window will always be common to the ++previous layout and the new one. ++ ++Think of it as the Emacs @kbd{C-x 2} binding. ++ ++This key binding uses the bindable Readline function ++@code{tui-change-windows}. ++ ++@kindex C-x o ++@item C-x o ++Change the active window. The TUI associates several key bindings ++(like scrolling and arrow keys) with the active window. This command ++gives the focus to the next TUI window. ++ ++Think of it as the Emacs @kbd{C-x o} binding. ++ ++This key binding uses the bindable Readline function ++@code{tui-other-window}. ++ ++@kindex C-x s ++@item C-x s ++Switch in and out of the TUI SingleKey mode that binds single ++keys to @value{GDBN} commands (@pxref{TUI Single Key Mode}). ++ ++This key binding uses the bindable Readline function ++@code{next-keymap}. ++@end table ++ ++The following key bindings only work in the TUI mode: ++ ++@table @asis ++@kindex PgUp ++@item @key{PgUp} ++Scroll the active window one page up. ++ ++@kindex PgDn ++@item @key{PgDn} ++Scroll the active window one page down. ++ ++@kindex Up ++@item @key{Up} ++Scroll the active window one line up. ++ ++@kindex Down ++@item @key{Down} ++Scroll the active window one line down. ++ ++@kindex Left ++@item @key{Left} ++Scroll the active window one column left. ++ ++@kindex Right ++@item @key{Right} ++Scroll the active window one column right. ++ ++@kindex C-L ++@item @kbd{C-L} ++Refresh the screen. ++@end table ++ ++Because the arrow keys scroll the active window in the TUI mode, they ++are not available for their normal use by readline unless the command ++window has the focus. When another window is active, you must use ++other readline key bindings such as @kbd{C-p}, @kbd{C-n}, @kbd{C-b} ++and @kbd{C-f} to control the command window. ++ ++@node TUI Single Key Mode ++@section TUI Single Key Mode ++@cindex TUI single key mode ++ ++The TUI also provides a @dfn{SingleKey} mode, which binds several ++frequently used @value{GDBN} commands to single keys. Type @kbd{C-x s} to ++switch into this mode, where the following key bindings are used: ++ ++@table @kbd ++@kindex c @r{(SingleKey TUI key)} ++@item c ++continue ++ ++@kindex d @r{(SingleKey TUI key)} ++@item d ++down ++ ++@kindex f @r{(SingleKey TUI key)} ++@item f ++finish ++ ++@kindex n @r{(SingleKey TUI key)} ++@item n ++next ++ ++@kindex o @r{(SingleKey TUI key)} ++@item o ++nexti. The shortcut letter @samp{o} stands for ``step Over''. ++ ++@kindex q @r{(SingleKey TUI key)} ++@item q ++exit the SingleKey mode. ++ ++@kindex r @r{(SingleKey TUI key)} ++@item r ++run ++ ++@kindex s @r{(SingleKey TUI key)} ++@item s ++step ++ ++@kindex i @r{(SingleKey TUI key)} ++@item i ++stepi. The shortcut letter @samp{i} stands for ``step Into''. ++ ++@kindex u @r{(SingleKey TUI key)} ++@item u ++up ++ ++@kindex v @r{(SingleKey TUI key)} ++@item v ++info locals ++ ++@kindex w @r{(SingleKey TUI key)} ++@item w ++where ++@end table ++ ++Other keys temporarily switch to the @value{GDBN} command prompt. ++The key that was pressed is inserted in the editing buffer so that ++it is possible to type most @value{GDBN} commands without interaction ++with the TUI SingleKey mode. Once the command is entered the TUI ++SingleKey mode is restored. The only way to permanently leave ++this mode is by typing @kbd{q} or @kbd{C-x s}. ++ ++@cindex SingleKey keymap name ++If @value{GDBN} was built with Readline 8.0 or later, the TUI ++SingleKey keymap will be named @samp{SingleKey}. This can be used in ++@file{.inputrc} to add additional bindings to this keymap. ++ ++@node TUI Commands ++@section TUI-specific Commands ++@cindex TUI commands ++ ++The TUI has specific commands to control the text windows. ++These commands are always available, even when @value{GDBN} is not in ++the TUI mode. When @value{GDBN} is in the standard mode, most ++of these commands will automatically switch to the TUI mode. ++ ++Note that if @value{GDBN}'s @code{stdout} is not connected to a ++terminal, or @value{GDBN} has been started with the machine interface ++interpreter (@pxref{GDB/MI, ,The @sc{gdb/mi} Interface}), most of ++these commands will fail with an error, because it would not be ++possible or desirable to enable curses window management. ++ ++@table @code ++@item tui enable ++@kindex tui enable ++Activate TUI mode. The last active TUI window layout will be used if ++TUI mode has previously been used in the current debugging session, ++otherwise a default layout is used. ++ ++@item tui disable ++@kindex tui disable ++Disable TUI mode, returning to the console interpreter. ++ ++@item info win ++@kindex info win ++List and give the size of all displayed windows. ++ ++@item tui new-layout @var{name} @var{window} @var{weight} @r{[}@var{window} @var{weight}@dots{}@r{]} ++@kindex tui new-layout ++Create a new TUI layout. The new layout will be named @var{name}, and ++can be accessed using the @code{layout} command (see below). ++ ++Each @var{window} parameter is either the name of a window to display, ++or a window description. The windows will be displayed from top to ++bottom in the order listed. ++ ++The names of the windows are the same as the ones given to the ++@code{focus} command (see below); additional, the @code{status} ++window can be specified. Note that, because it is of fixed height, ++the weight assigned to the status window is of no importance. It is ++conventional to use @samp{0} here. ++ ++A window description looks a bit like an invocation of @code{tui ++new-layout}, and is of the form ++@{@r{[}@code{-horizontal}@r{]}@var{window} @var{weight} @r{[}@var{window} @var{weight}@dots{}@r{]}@}. ++ ++This specifies a sub-layout. If @code{-horizontal} is given, the ++windows in this description will be arranged side-by-side, rather than ++top-to-bottom. ++ ++Each @var{weight} is an integer. It is the weight of this window ++relative to all the other windows in the layout. These numbers are ++used to calculate how much of the screen is given to each window. ++ ++For example: ++ ++@example ++(gdb) tui new-layout example src 1 regs 1 status 0 cmd 1 ++@end example ++ ++Here, the new layout is called @samp{example}. It shows the source ++and register windows, followed by the status window, and then finally ++the command window. The non-status windows all have the same weight, ++so the terminal will be split into three roughly equal sections. ++ ++Here is a more complex example, showing a horizontal layout: ++ ++@example ++(gdb) tui new-layout example @{-horizontal src 1 asm 1@} 2 status 0 cmd 1 ++@end example ++ ++This will result in side-by-side source and assembly windows; with the ++status and command window being beneath these, filling the entire ++width of the terminal. Because they have weight 2, the source and ++assembly windows will be twice the height of the command window. ++ ++@item layout @var{name} ++@kindex layout ++Changes which TUI windows are displayed. The @var{name} parameter ++controls which layout is shown. It can be either one of the built-in ++layout names, or the name of a layout defined by the user using ++@code{tui new-layout}. ++ ++The built-in layouts are as follows: ++ ++@table @code ++@item next ++Display the next layout. ++ ++@item prev ++Display the previous layout. ++ ++@item src ++Display the source and command windows. ++ ++@item asm ++Display the assembly and command windows. ++ ++@item split ++Display the source, assembly, and command windows. ++ ++@item regs ++When in @code{src} layout display the register, source, and command ++windows. When in @code{asm} or @code{split} layout display the ++register, assembler, and command windows. ++@end table ++ ++@item focus @var{name} ++@kindex focus ++Changes which TUI window is currently active for scrolling. The ++@var{name} parameter can be any of the following: ++ ++@table @code ++@item next ++Make the next window active for scrolling. ++ ++@item prev ++Make the previous window active for scrolling. ++ ++@item src ++Make the source window active for scrolling. ++ ++@item asm ++Make the assembly window active for scrolling. ++ ++@item regs ++Make the register window active for scrolling. ++ ++@item cmd ++Make the command window active for scrolling. ++@end table ++ ++@item refresh ++@kindex refresh ++Refresh the screen. This is similar to typing @kbd{C-L}. ++ ++@item tui reg @var{group} ++@kindex tui reg ++Changes the register group displayed in the tui register window to ++@var{group}. If the register window is not currently displayed this ++command will cause the register window to be displayed. The list of ++register groups, as well as their order is target specific. The ++following groups are available on most targets: ++@table @code ++@item next ++Repeatedly selecting this group will cause the display to cycle ++through all of the available register groups. ++ ++@item prev ++Repeatedly selecting this group will cause the display to cycle ++through all of the available register groups in the reverse order to ++@var{next}. ++ ++@item general ++Display the general registers. ++@item float ++Display the floating point registers. ++@item system ++Display the system registers. ++@item vector ++Display the vector registers. ++@item all ++Display all registers. ++@end table ++ ++@item update ++@kindex update ++Update the source window and the current execution point. ++ ++@item winheight @var{name} +@var{count} ++@itemx winheight @var{name} -@var{count} ++@kindex winheight ++Change the height of the window @var{name} by @var{count} ++lines. Positive counts increase the height, while negative counts ++decrease it. The @var{name} parameter can be one of @code{src} (the ++source window), @code{cmd} (the command window), @code{asm} (the ++disassembly window), or @code{regs} (the register display window). ++@end table ++ ++@node TUI Configuration ++@section TUI Configuration Variables ++@cindex TUI configuration variables ++ ++Several configuration variables control the appearance of TUI windows. ++ ++@table @code ++@item set tui border-kind @var{kind} ++@kindex set tui border-kind ++Select the border appearance for the source, assembly and register windows. ++The possible values are the following: ++@table @code ++@item space ++Use a space character to draw the border. ++ ++@item ascii ++Use @sc{ascii} characters @samp{+}, @samp{-} and @samp{|} to draw the border. ++ ++@item acs ++Use the Alternate Character Set to draw the border. The border is ++drawn using character line graphics if the terminal supports them. ++@end table ++ ++@item set tui border-mode @var{mode} ++@kindex set tui border-mode ++@itemx set tui active-border-mode @var{mode} ++@kindex set tui active-border-mode ++Select the display attributes for the borders of the inactive windows ++or the active window. The @var{mode} can be one of the following: ++@table @code ++@item normal ++Use normal attributes to display the border. ++ ++@item standout ++Use standout mode. ++ ++@item reverse ++Use reverse video mode. ++ ++@item half ++Use half bright mode. ++ ++@item half-standout ++Use half bright and standout mode. ++ ++@item bold ++Use extra bright or bold mode. ++ ++@item bold-standout ++Use extra bright or bold and standout mode. ++@end table ++ ++@item set tui tab-width @var{nchars} ++@kindex set tui tab-width ++@kindex tabset ++Set the width of tab stops to be @var{nchars} characters. This ++setting affects the display of TAB characters in the source and ++assembly windows. ++ ++@item set tui compact-source @r{[}on@r{|}off@r{]} ++@kindex set tui compact-source ++Set whether the TUI source window is displayed in ``compact'' form. ++The default display uses more space for line numbers and starts the ++source text at the next tab stop; the compact display uses only as ++much space as is needed for the line numbers in the current file, and ++only a single space to separate the line numbers from the source. ++@end table ++ ++Note that the colors of the TUI borders can be controlled using the ++appropriate @code{set style} commands. @xref{Output Styling}. ++ ++@node Emacs ++@chapter Using @value{GDBN} under @sc{gnu} Emacs ++ ++@cindex Emacs ++@cindex @sc{gnu} Emacs ++A special interface allows you to use @sc{gnu} Emacs to view (and ++edit) the source files for the program you are debugging with ++@value{GDBN}. ++ ++To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the ++executable file you want to debug as an argument. This command starts ++@value{GDBN} as a subprocess of Emacs, with input and output through a newly ++created Emacs buffer. ++@c (Do not use the @code{-tui} option to run @value{GDBN} from Emacs.) ++ ++Running @value{GDBN} under Emacs can be just like running @value{GDBN} normally except for two ++things: ++ ++@itemize @bullet ++@item ++All ``terminal'' input and output goes through an Emacs buffer, called ++the GUD buffer. ++ ++This applies both to @value{GDBN} commands and their output, and to the input ++and output done by the program you are debugging. ++ ++This is useful because it means that you can copy the text of previous ++commands and input them again; you can even use parts of the output ++in this way. ++ ++All the facilities of Emacs' Shell mode are available for interacting ++with your program. In particular, you can send signals the usual ++way---for example, @kbd{C-c C-c} for an interrupt, @kbd{C-c C-z} for a ++stop. ++ ++@item ++@value{GDBN} displays source code through Emacs. ++ ++Each time @value{GDBN} displays a stack frame, Emacs automatically finds the ++source file for that frame and puts an arrow (@samp{=>}) at the ++left margin of the current line. Emacs uses a separate buffer for ++source display, and splits the screen to show both your @value{GDBN} session ++and the source. ++ ++Explicit @value{GDBN} @code{list} or search commands still produce output as ++usual, but you probably have no reason to use them from Emacs. ++@end itemize ++ ++We call this @dfn{text command mode}. Emacs 22.1, and later, also uses ++a graphical mode, enabled by default, which provides further buffers ++that can control the execution and describe the state of your program. ++@xref{GDB Graphical Interface,,, Emacs, The @sc{gnu} Emacs Manual}. ++ ++If you specify an absolute file name when prompted for the @kbd{M-x ++gdb} argument, then Emacs sets your current working directory to where ++your program resides. If you only specify the file name, then Emacs ++sets your current working directory to the directory associated ++with the previous buffer. In this case, @value{GDBN} may find your ++program by searching your environment's @code{PATH} variable, but on ++some operating systems it might not find the source. So, although the ++@value{GDBN} input and output session proceeds normally, the auxiliary ++buffer does not display the current source and line of execution. ++ ++The initial working directory of @value{GDBN} is printed on the top ++line of the GUD buffer and this serves as a default for the commands ++that specify files for @value{GDBN} to operate on. @xref{Files, ++,Commands to Specify Files}. ++ ++By default, @kbd{M-x gdb} calls the program called @file{gdb}. If you ++need to call @value{GDBN} by a different name (for example, if you ++keep several configurations around, with different names) you can ++customize the Emacs variable @code{gud-gdb-command-name} to run the ++one you want. ++ ++In the GUD buffer, you can use these special Emacs commands in ++addition to the standard Shell mode commands: ++ ++@table @kbd ++@item C-h m ++Describe the features of Emacs' GUD Mode. ++ ++@item C-c C-s ++Execute to another source line, like the @value{GDBN} @code{step} command; also ++update the display window to show the current file and location. ++ ++@item C-c C-n ++Execute to next source line in this function, skipping all function ++calls, like the @value{GDBN} @code{next} command. Then update the display window ++to show the current file and location. ++ ++@item C-c C-i ++Execute one instruction, like the @value{GDBN} @code{stepi} command; update ++display window accordingly. ++ ++@item C-c C-f ++Execute until exit from the selected stack frame, like the @value{GDBN} ++@code{finish} command. ++ ++@item C-c C-r ++Continue execution of your program, like the @value{GDBN} @code{continue} ++command. ++ ++@item C-c < ++Go up the number of frames indicated by the numeric argument ++(@pxref{Arguments, , Numeric Arguments, Emacs, The @sc{gnu} Emacs Manual}), ++like the @value{GDBN} @code{up} command. ++ ++@item C-c > ++Go down the number of frames indicated by the numeric argument, like the ++@value{GDBN} @code{down} command. ++@end table ++ ++In any source file, the Emacs command @kbd{C-x @key{SPC}} (@code{gud-break}) ++tells @value{GDBN} to set a breakpoint on the source line point is on. ++ ++In text command mode, if you type @kbd{M-x speedbar}, Emacs displays a ++separate frame which shows a backtrace when the GUD buffer is current. ++Move point to any frame in the stack and type @key{RET} to make it ++become the current frame and display the associated source in the ++source buffer. Alternatively, click @kbd{Mouse-2} to make the ++selected frame become the current one. In graphical mode, the ++speedbar displays watch expressions. ++ ++If you accidentally delete the source-display buffer, an easy way to get ++it back is to type the command @code{f} in the @value{GDBN} buffer, to ++request a frame display; when you run under Emacs, this recreates ++the source buffer if necessary to show you the context of the current ++frame. ++ ++The source files displayed in Emacs are in ordinary Emacs buffers ++which are visiting the source files in the usual way. You can edit ++the files with these buffers if you wish; but keep in mind that @value{GDBN} ++communicates with Emacs in terms of line numbers. If you add or ++delete lines from the text, the line numbers that @value{GDBN} knows cease ++to correspond properly with the code. ++ ++A more detailed description of Emacs' interaction with @value{GDBN} is ++given in the Emacs manual (@pxref{Debuggers,,, Emacs, The @sc{gnu} ++Emacs Manual}). ++ ++@node GDB/MI ++@chapter The @sc{gdb/mi} Interface ++ ++@unnumberedsec Function and Purpose ++ ++@cindex @sc{gdb/mi}, its purpose ++@sc{gdb/mi} is a line based machine oriented text interface to ++@value{GDBN} and is activated by specifying using the ++@option{--interpreter} command line option (@pxref{Mode Options}). It ++is specifically intended to support the development of systems which ++use the debugger as just one small component of a larger system. ++ ++This chapter is a specification of the @sc{gdb/mi} interface. It is written ++in the form of a reference manual. ++ ++Note that @sc{gdb/mi} is still under construction, so some of the ++features described below are incomplete and subject to change ++(@pxref{GDB/MI Development and Front Ends, , @sc{gdb/mi} Development and Front Ends}). ++ ++@unnumberedsec Notation and Terminology ++ ++@cindex notational conventions, for @sc{gdb/mi} ++This chapter uses the following notation: ++ ++@itemize @bullet ++@item ++@code{|} separates two alternatives. ++ ++@item ++@code{[ @var{something} ]} indicates that @var{something} is optional: ++it may or may not be given. ++ ++@item ++@code{( @var{group} )*} means that @var{group} inside the parentheses ++may repeat zero or more times. ++ ++@item ++@code{( @var{group} )+} means that @var{group} inside the parentheses ++may repeat one or more times. ++ ++@item ++@code{"@var{string}"} means a literal @var{string}. ++@end itemize ++ ++@ignore ++@heading Dependencies ++@end ignore ++ ++@menu ++* GDB/MI General Design:: ++* GDB/MI Command Syntax:: ++* GDB/MI Compatibility with CLI:: ++* GDB/MI Development and Front Ends:: ++* GDB/MI Output Records:: ++* GDB/MI Simple Examples:: ++* GDB/MI Command Description Format:: ++* GDB/MI Breakpoint Commands:: ++* GDB/MI Catchpoint Commands:: ++* GDB/MI Program Context:: ++* GDB/MI Thread Commands:: ++* GDB/MI Ada Tasking Commands:: ++* GDB/MI Program Execution:: ++* GDB/MI Stack Manipulation:: ++* GDB/MI Variable Objects:: ++* GDB/MI Data Manipulation:: ++* GDB/MI Tracepoint Commands:: ++* GDB/MI Symbol Query:: ++* GDB/MI File Commands:: ++@ignore ++* GDB/MI Kod Commands:: ++* GDB/MI Memory Overlay Commands:: ++* GDB/MI Signal Handling Commands:: ++@end ignore ++* GDB/MI Target Manipulation:: ++* GDB/MI File Transfer Commands:: ++* GDB/MI Ada Exceptions Commands:: ++* GDB/MI Support Commands:: ++* GDB/MI Miscellaneous Commands:: ++@end menu ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI General Design ++@section @sc{gdb/mi} General Design ++@cindex GDB/MI General Design ++ ++Interaction of a @sc{GDB/MI} frontend with @value{GDBN} involves three ++parts---commands sent to @value{GDBN}, responses to those commands ++and notifications. Each command results in exactly one response, ++indicating either successful completion of the command, or an error. ++For the commands that do not resume the target, the response contains the ++requested information. For the commands that resume the target, the ++response only indicates whether the target was successfully resumed. ++Notifications is the mechanism for reporting changes in the state of the ++target, or in @value{GDBN} state, that cannot conveniently be associated with ++a command and reported as part of that command response. ++ ++The important examples of notifications are: ++@itemize @bullet ++ ++@item ++Exec notifications. These are used to report changes in ++target state---when a target is resumed, or stopped. It would not ++be feasible to include this information in response of resuming ++commands, because one resume commands can result in multiple events in ++different threads. Also, quite some time may pass before any event ++happens in the target, while a frontend needs to know whether the resuming ++command itself was successfully executed. ++ ++@item ++Console output, and status notifications. Console output ++notifications are used to report output of CLI commands, as well as ++diagnostics for other commands. Status notifications are used to ++report the progress of a long-running operation. Naturally, including ++this information in command response would mean no output is produced ++until the command is finished, which is undesirable. ++ ++@item ++General notifications. Commands may have various side effects on ++the @value{GDBN} or target state beyond their official purpose. For example, ++a command may change the selected thread. Although such changes can ++be included in command response, using notification allows for more ++orthogonal frontend design. ++ ++@end itemize ++ ++There's no guarantee that whenever an MI command reports an error, ++@value{GDBN} or the target are in any specific state, and especially, ++the state is not reverted to the state before the MI command was ++processed. Therefore, whenever an MI command results in an error, ++we recommend that the frontend refreshes all the information shown in ++the user interface. ++ ++ ++@menu ++* Context management:: ++* Asynchronous and non-stop modes:: ++* Thread groups:: ++@end menu ++ ++@node Context management ++@subsection Context management ++ ++@subsubsection Threads and Frames ++ ++In most cases when @value{GDBN} accesses the target, this access is ++done in context of a specific thread and frame (@pxref{Frames}). ++Often, even when accessing global data, the target requires that a thread ++be specified. The CLI interface maintains the selected thread and frame, ++and supplies them to target on each command. This is convenient, ++because a command line user would not want to specify that information ++explicitly on each command, and because user interacts with ++@value{GDBN} via a single terminal, so no confusion is possible as ++to what thread and frame are the current ones. ++ ++In the case of MI, the concept of selected thread and frame is less ++useful. First, a frontend can easily remember this information ++itself. Second, a graphical frontend can have more than one window, ++each one used for debugging a different thread, and the frontend might ++want to access additional threads for internal purposes. This ++increases the risk that by relying on implicitly selected thread, the ++frontend may be operating on a wrong one. Therefore, each MI command ++should explicitly specify which thread and frame to operate on. To ++make it possible, each MI command accepts the @samp{--thread} and ++@samp{--frame} options, the value to each is @value{GDBN} global ++identifier for thread and frame to operate on. ++ ++Usually, each top-level window in a frontend allows the user to select ++a thread and a frame, and remembers the user selection for further ++operations. However, in some cases @value{GDBN} may suggest that the ++current thread or frame be changed. For example, when stopping on a ++breakpoint it is reasonable to switch to the thread where breakpoint is ++hit. For another example, if the user issues the CLI @samp{thread} or ++@samp{frame} commands via the frontend, it is desirable to change the ++frontend's selection to the one specified by user. @value{GDBN} ++communicates the suggestion to change current thread and frame using the ++@samp{=thread-selected} notification. ++ ++Note that historically, MI shares the selected thread with CLI, so ++frontends used the @code{-thread-select} to execute commands in the ++right context. However, getting this to work right is cumbersome. The ++simplest way is for frontend to emit @code{-thread-select} command ++before every command. This doubles the number of commands that need ++to be sent. The alternative approach is to suppress @code{-thread-select} ++if the selected thread in @value{GDBN} is supposed to be identical to the ++thread the frontend wants to operate on. However, getting this ++optimization right can be tricky. In particular, if the frontend ++sends several commands to @value{GDBN}, and one of the commands changes the ++selected thread, then the behaviour of subsequent commands will ++change. So, a frontend should either wait for response from such ++problematic commands, or explicitly add @code{-thread-select} for ++all subsequent commands. No frontend is known to do this exactly ++right, so it is suggested to just always pass the @samp{--thread} and ++@samp{--frame} options. ++ ++@subsubsection Language ++ ++The execution of several commands depends on which language is selected. ++By default, the current language (@pxref{show language}) is used. ++But for commands known to be language-sensitive, it is recommended ++to use the @samp{--language} option. This option takes one argument, ++which is the name of the language to use while executing the command. ++For instance: ++ ++@smallexample ++-data-evaluate-expression --language c "sizeof (void*)" ++^done,value="4" ++(gdb) ++@end smallexample ++ ++The valid language names are the same names accepted by the ++@samp{set language} command (@pxref{Manually}), excluding @samp{auto}, ++@samp{local} or @samp{unknown}. ++ ++@node Asynchronous and non-stop modes ++@subsection Asynchronous command execution and non-stop mode ++ ++On some targets, @value{GDBN} is capable of processing MI commands ++even while the target is running. This is called @dfn{asynchronous ++command execution} (@pxref{Background Execution}). The frontend may ++specify a preference for asynchronous execution using the ++@code{-gdb-set mi-async 1} command, which should be emitted before ++either running the executable or attaching to the target. After the ++frontend has started the executable or attached to the target, it can ++find if asynchronous execution is enabled using the ++@code{-list-target-features} command. ++ ++@table @code ++@item -gdb-set mi-async on ++@item -gdb-set mi-async off ++Set whether MI is in asynchronous mode. ++ ++When @code{off}, which is the default, MI execution commands (e.g., ++@code{-exec-continue}) are foreground commands, and @value{GDBN} waits ++for the program to stop before processing further commands. ++ ++When @code{on}, MI execution commands are background execution ++commands (e.g., @code{-exec-continue} becomes the equivalent of the ++@code{c&} CLI command), and so @value{GDBN} is capable of processing ++MI commands even while the target is running. ++ ++@item -gdb-show mi-async ++Show whether MI asynchronous mode is enabled. ++@end table ++ ++Note: In @value{GDBN} version 7.7 and earlier, this option was called ++@code{target-async} instead of @code{mi-async}, and it had the effect ++of both putting MI in asynchronous mode and making CLI background ++commands possible. CLI background commands are now always possible ++``out of the box'' if the target supports them. The old spelling is ++kept as a deprecated alias for backwards compatibility. ++ ++Even if @value{GDBN} can accept a command while target is running, ++many commands that access the target do not work when the target is ++running. Therefore, asynchronous command execution is most useful ++when combined with non-stop mode (@pxref{Non-Stop Mode}). Then, ++it is possible to examine the state of one thread, while other threads ++are running. ++ ++When a given thread is running, MI commands that try to access the ++target in the context of that thread may not work, or may work only on ++some targets. In particular, commands that try to operate on thread's ++stack will not work, on any target. Commands that read memory, or ++modify breakpoints, may work or not work, depending on the target. Note ++that even commands that operate on global state, such as @code{print}, ++@code{set}, and breakpoint commands, still access the target in the ++context of a specific thread, so frontend should try to find a ++stopped thread and perform the operation on that thread (using the ++@samp{--thread} option). ++ ++Which commands will work in the context of a running thread is ++highly target dependent. However, the two commands ++@code{-exec-interrupt}, to stop a thread, and @code{-thread-info}, ++to find the state of a thread, will always work. ++ ++@node Thread groups ++@subsection Thread groups ++@value{GDBN} may be used to debug several processes at the same time. ++On some platforms, @value{GDBN} may support debugging of several ++hardware systems, each one having several cores with several different ++processes running on each core. This section describes the MI ++mechanism to support such debugging scenarios. ++ ++The key observation is that regardless of the structure of the ++target, MI can have a global list of threads, because most commands that ++accept the @samp{--thread} option do not need to know what process that ++thread belongs to. Therefore, it is not necessary to introduce ++neither additional @samp{--process} option, nor an notion of the ++current process in the MI interface. The only strictly new feature ++that is required is the ability to find how the threads are grouped ++into processes. ++ ++To allow the user to discover such grouping, and to support arbitrary ++hierarchy of machines/cores/processes, MI introduces the concept of a ++@dfn{thread group}. Thread group is a collection of threads and other ++thread groups. A thread group always has a string identifier, a type, ++and may have additional attributes specific to the type. A new ++command, @code{-list-thread-groups}, returns the list of top-level ++thread groups, which correspond to processes that @value{GDBN} is ++debugging at the moment. By passing an identifier of a thread group ++to the @code{-list-thread-groups} command, it is possible to obtain ++the members of specific thread group. ++ ++To allow the user to easily discover processes, and other objects, he ++wishes to debug, a concept of @dfn{available thread group} is ++introduced. Available thread group is an thread group that ++@value{GDBN} is not debugging, but that can be attached to, using the ++@code{-target-attach} command. The list of available top-level thread ++groups can be obtained using @samp{-list-thread-groups --available}. ++In general, the content of a thread group may be only retrieved only ++after attaching to that thread group. ++ ++Thread groups are related to inferiors (@pxref{Inferiors Connections and ++Programs}). Each inferior corresponds to a thread group of a special ++type @samp{process}, and some additional operations are permitted on ++such thread groups. ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Command Syntax ++@section @sc{gdb/mi} Command Syntax ++ ++@menu ++* GDB/MI Input Syntax:: ++* GDB/MI Output Syntax:: ++@end menu ++ ++@node GDB/MI Input Syntax ++@subsection @sc{gdb/mi} Input Syntax ++ ++@cindex input syntax for @sc{gdb/mi} ++@cindex @sc{gdb/mi}, input syntax ++@table @code ++@item @var{command} @expansion{} ++@code{@var{cli-command} | @var{mi-command}} ++ ++@item @var{cli-command} @expansion{} ++@code{[ @var{token} ] @var{cli-command} @var{nl}}, where ++@var{cli-command} is any existing @value{GDBN} CLI command. ++ ++@item @var{mi-command} @expansion{} ++@code{[ @var{token} ] "-" @var{operation} ( " " @var{option} )* ++@code{[} " --" @code{]} ( " " @var{parameter} )* @var{nl}} ++ ++@item @var{token} @expansion{} ++"any sequence of digits" ++ ++@item @var{option} @expansion{} ++@code{"-" @var{parameter} [ " " @var{parameter} ]} ++ ++@item @var{parameter} @expansion{} ++@code{@var{non-blank-sequence} | @var{c-string}} ++ ++@item @var{operation} @expansion{} ++@emph{any of the operations described in this chapter} ++ ++@item @var{non-blank-sequence} @expansion{} ++@emph{anything, provided it doesn't contain special characters such as ++"-", @var{nl}, """ and of course " "} ++ ++@item @var{c-string} @expansion{} ++@code{""" @var{seven-bit-iso-c-string-content} """} ++ ++@item @var{nl} @expansion{} ++@code{CR | CR-LF} ++@end table ++ ++@noindent ++Notes: ++ ++@itemize @bullet ++@item ++The CLI commands are still handled by the @sc{mi} interpreter; their ++output is described below. ++ ++@item ++The @code{@var{token}}, when present, is passed back when the command ++finishes. ++ ++@item ++Some @sc{mi} commands accept optional arguments as part of the parameter ++list. Each option is identified by a leading @samp{-} (dash) and may be ++followed by an optional argument parameter. Options occur first in the ++parameter list and can be delimited from normal parameters using ++@samp{--} (this is useful when some parameters begin with a dash). ++@end itemize ++ ++Pragmatics: ++ ++@itemize @bullet ++@item ++We want easy access to the existing CLI syntax (for debugging). ++ ++@item ++We want it to be easy to spot a @sc{mi} operation. ++@end itemize ++ ++@node GDB/MI Output Syntax ++@subsection @sc{gdb/mi} Output Syntax ++ ++@cindex output syntax of @sc{gdb/mi} ++@cindex @sc{gdb/mi}, output syntax ++The output from @sc{gdb/mi} consists of zero or more out-of-band records ++followed, optionally, by a single result record. This result record ++is for the most recent command. The sequence of output records is ++terminated by @samp{(gdb)}. ++ ++If an input command was prefixed with a @code{@var{token}} then the ++corresponding output for that command will also be prefixed by that same ++@var{token}. ++ ++@table @code ++@item @var{output} @expansion{} ++@code{( @var{out-of-band-record} )* [ @var{result-record} ] "(gdb)" @var{nl}} ++ ++@item @var{result-record} @expansion{} ++@code{ [ @var{token} ] "^" @var{result-class} ( "," @var{result} )* @var{nl}} ++ ++@item @var{out-of-band-record} @expansion{} ++@code{@var{async-record} | @var{stream-record}} ++ ++@item @var{async-record} @expansion{} ++@code{@var{exec-async-output} | @var{status-async-output} | @var{notify-async-output}} ++ ++@item @var{exec-async-output} @expansion{} ++@code{[ @var{token} ] "*" @var{async-output nl}} ++ ++@item @var{status-async-output} @expansion{} ++@code{[ @var{token} ] "+" @var{async-output nl}} ++ ++@item @var{notify-async-output} @expansion{} ++@code{[ @var{token} ] "=" @var{async-output nl}} ++ ++@item @var{async-output} @expansion{} ++@code{@var{async-class} ( "," @var{result} )*} ++ ++@item @var{result-class} @expansion{} ++@code{"done" | "running" | "connected" | "error" | "exit"} ++ ++@item @var{async-class} @expansion{} ++@code{"stopped" | @var{others}} (where @var{others} will be added ++depending on the needs---this is still in development). ++ ++@item @var{result} @expansion{} ++@code{ @var{variable} "=" @var{value}} ++ ++@item @var{variable} @expansion{} ++@code{ @var{string} } ++ ++@item @var{value} @expansion{} ++@code{ @var{const} | @var{tuple} | @var{list} } ++ ++@item @var{const} @expansion{} ++@code{@var{c-string}} ++ ++@item @var{tuple} @expansion{} ++@code{ "@{@}" | "@{" @var{result} ( "," @var{result} )* "@}" } ++ ++@item @var{list} @expansion{} ++@code{ "[]" | "[" @var{value} ( "," @var{value} )* "]" | "[" ++@var{result} ( "," @var{result} )* "]" } ++ ++@item @var{stream-record} @expansion{} ++@code{@var{console-stream-output} | @var{target-stream-output} | @var{log-stream-output}} ++ ++@item @var{console-stream-output} @expansion{} ++@code{"~" @var{c-string nl}} ++ ++@item @var{target-stream-output} @expansion{} ++@code{"@@" @var{c-string nl}} ++ ++@item @var{log-stream-output} @expansion{} ++@code{"&" @var{c-string nl}} ++ ++@item @var{nl} @expansion{} ++@code{CR | CR-LF} ++ ++@item @var{token} @expansion{} ++@emph{any sequence of digits}. ++@end table ++ ++@noindent ++Notes: ++ ++@itemize @bullet ++@item ++All output sequences end in a single line containing a period. ++ ++@item ++The @code{@var{token}} is from the corresponding request. Note that ++for all async output, while the token is allowed by the grammar and ++may be output by future versions of @value{GDBN} for select async ++output messages, it is generally omitted. Frontends should treat ++all async output as reporting general changes in the state of the ++target and there should be no need to associate async output to any ++prior command. ++ ++@item ++@cindex status output in @sc{gdb/mi} ++@var{status-async-output} contains on-going status information about the ++progress of a slow operation. It can be discarded. All status output is ++prefixed by @samp{+}. ++ ++@item ++@cindex async output in @sc{gdb/mi} ++@var{exec-async-output} contains asynchronous state change on the target ++(stopped, started, disappeared). All async output is prefixed by ++@samp{*}. ++ ++@item ++@cindex notify output in @sc{gdb/mi} ++@var{notify-async-output} contains supplementary information that the ++client should handle (e.g., a new breakpoint information). All notify ++output is prefixed by @samp{=}. ++ ++@item ++@cindex console output in @sc{gdb/mi} ++@var{console-stream-output} is output that should be displayed as is in the ++console. It is the textual response to a CLI command. All the console ++output is prefixed by @samp{~}. ++ ++@item ++@cindex target output in @sc{gdb/mi} ++@var{target-stream-output} is the output produced by the target program. ++All the target output is prefixed by @samp{@@}. ++ ++@item ++@cindex log output in @sc{gdb/mi} ++@var{log-stream-output} is output text coming from @value{GDBN}'s internals, for ++instance messages that should be displayed as part of an error log. All ++the log output is prefixed by @samp{&}. ++ ++@item ++@cindex list output in @sc{gdb/mi} ++New @sc{gdb/mi} commands should only output @var{lists} containing ++@var{values}. ++ ++ ++@end itemize ++ ++@xref{GDB/MI Stream Records, , @sc{gdb/mi} Stream Records}, for more ++details about the various output records. ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Compatibility with CLI ++@section @sc{gdb/mi} Compatibility with CLI ++ ++@cindex compatibility, @sc{gdb/mi} and CLI ++@cindex @sc{gdb/mi}, compatibility with CLI ++ ++For the developers convenience CLI commands can be entered directly, ++but there may be some unexpected behaviour. For example, commands ++that query the user will behave as if the user replied yes, breakpoint ++command lists are not executed and some CLI commands, such as ++@code{if}, @code{when} and @code{define}, prompt for further input with ++@samp{>}, which is not valid MI output. ++ ++This feature may be removed at some stage in the future and it is ++recommended that front ends use the @code{-interpreter-exec} command ++(@pxref{-interpreter-exec}). ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Development and Front Ends ++@section @sc{gdb/mi} Development and Front Ends ++@cindex @sc{gdb/mi} development ++ ++The application which takes the MI output and presents the state of the ++program being debugged to the user is called a @dfn{front end}. ++ ++Since @sc{gdb/mi} is used by a variety of front ends to @value{GDBN}, changes ++to the MI interface may break existing usage. This section describes how the ++protocol changes and how to request previous version of the protocol when it ++does. ++ ++Some changes in MI need not break a carefully designed front end, and ++for these the MI version will remain unchanged. The following is a ++list of changes that may occur within one level, so front ends should ++parse MI output in a way that can handle them: ++ ++@itemize @bullet ++@item ++New MI commands may be added. ++ ++@item ++New fields may be added to the output of any MI command. ++ ++@item ++The range of values for fields with specified values, e.g., ++@code{in_scope} (@pxref{-var-update}) may be extended. ++ ++@c The format of field's content e.g type prefix, may change so parse it ++@c at your own risk. Yes, in general? ++ ++@c The order of fields may change? Shouldn't really matter but it might ++@c resolve inconsistencies. ++@end itemize ++ ++If the changes are likely to break front ends, the MI version level ++will be increased by one. The new versions of the MI protocol are not compatible ++with the old versions. Old versions of MI remain available, allowing front ends ++to keep using them until they are modified to use the latest MI version. ++ ++Since @code{--interpreter=mi} always points to the latest MI version, it is ++recommended that front ends request a specific version of MI when launching ++@value{GDBN} (e.g. @code{--interpreter=mi2}) to make sure they get an ++interpreter with the MI version they expect. ++ ++The following table gives a summary of the released versions of the MI ++interface: the version number, the version of GDB in which it first appeared ++and the breaking changes compared to the previous version. ++ ++@multitable @columnfractions .05 .05 .9 ++@headitem MI version @tab GDB version @tab Breaking changes ++ ++@item ++@center 1 ++@tab ++@center 5.1 ++@tab ++None ++ ++@item ++@center 2 ++@tab ++@center 6.0 ++@tab ++ ++@itemize ++@item ++The @code{-environment-pwd}, @code{-environment-directory} and ++@code{-environment-path} commands now returns values using the MI output ++syntax, rather than CLI output syntax. ++ ++@item ++@code{-var-list-children}'s @code{children} result field is now a list, rather ++than a tuple. ++ ++@item ++@code{-var-update}'s @code{changelist} result field is now a list, rather than ++a tuple. ++@end itemize ++ ++@item ++@center 3 ++@tab ++@center 9.1 ++@tab ++ ++@itemize ++@item ++The output of information about multi-location breakpoints has changed in the ++responses to the @code{-break-insert} and @code{-break-info} commands, as well ++as in the @code{=breakpoint-created} and @code{=breakpoint-modified} events. ++The multiple locations are now placed in a @code{locations} field, whose value ++is a list. ++@end itemize ++ ++@end multitable ++ ++If your front end cannot yet migrate to a more recent version of the ++MI protocol, you can nevertheless selectively enable specific features ++available in those recent MI versions, using the following commands: ++ ++@table @code ++ ++@item -fix-multi-location-breakpoint-output ++Use the output for multi-location breakpoints which was introduced by ++MI 3, even when using MI versions 2 or 1. This command has no ++effect when using MI version 3 or later. ++ ++@end table ++ ++The best way to avoid unexpected changes in MI that might break your front ++end is to make your project known to @value{GDBN} developers and ++follow development on @email{gdb@@sourceware.org} and ++@email{gdb-patches@@sourceware.org}. ++@cindex mailing lists ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Output Records ++@section @sc{gdb/mi} Output Records ++ ++@menu ++* GDB/MI Result Records:: ++* GDB/MI Stream Records:: ++* GDB/MI Async Records:: ++* GDB/MI Breakpoint Information:: ++* GDB/MI Frame Information:: ++* GDB/MI Thread Information:: ++* GDB/MI Ada Exception Information:: ++@end menu ++ ++@node GDB/MI Result Records ++@subsection @sc{gdb/mi} Result Records ++ ++@cindex result records in @sc{gdb/mi} ++@cindex @sc{gdb/mi}, result records ++In addition to a number of out-of-band notifications, the response to a ++@sc{gdb/mi} command includes one of the following result indications: ++ ++@table @code ++@findex ^done ++@item "^done" [ "," @var{results} ] ++The synchronous operation was successful, @code{@var{results}} are the return ++values. ++ ++@item "^running" ++@findex ^running ++This result record is equivalent to @samp{^done}. Historically, it ++was output instead of @samp{^done} if the command has resumed the ++target. This behaviour is maintained for backward compatibility, but ++all frontends should treat @samp{^done} and @samp{^running} ++identically and rely on the @samp{*running} output record to determine ++which threads are resumed. ++ ++@item "^connected" ++@findex ^connected ++@value{GDBN} has connected to a remote target. ++ ++@item "^error" "," "msg=" @var{c-string} [ "," "code=" @var{c-string} ] ++@findex ^error ++The operation failed. The @code{msg=@var{c-string}} variable contains ++the corresponding error message. ++ ++If present, the @code{code=@var{c-string}} variable provides an error ++code on which consumers can rely on to detect the corresponding ++error condition. At present, only one error code is defined: ++ ++@table @samp ++@item "undefined-command" ++Indicates that the command causing the error does not exist. ++@end table ++ ++@item "^exit" ++@findex ^exit ++@value{GDBN} has terminated. ++ ++@end table ++ ++@node GDB/MI Stream Records ++@subsection @sc{gdb/mi} Stream Records ++ ++@cindex @sc{gdb/mi}, stream records ++@cindex stream records in @sc{gdb/mi} ++@value{GDBN} internally maintains a number of output streams: the console, the ++target, and the log. The output intended for each of these streams is ++funneled through the @sc{gdb/mi} interface using @dfn{stream records}. ++ ++Each stream record begins with a unique @dfn{prefix character} which ++identifies its stream (@pxref{GDB/MI Output Syntax, , @sc{gdb/mi} Output ++Syntax}). In addition to the prefix, each stream record contains a ++@code{@var{string-output}}. This is either raw text (with an implicit new ++line) or a quoted C string (which does not contain an implicit newline). ++ ++@table @code ++@item "~" @var{string-output} ++The console output stream contains text that should be displayed in the ++CLI console window. It contains the textual responses to CLI commands. ++ ++@item "@@" @var{string-output} ++The target output stream contains any textual output from the running ++target. This is only present when GDB's event loop is truly ++asynchronous, which is currently only the case for remote targets. ++ ++@item "&" @var{string-output} ++The log stream contains debugging messages being produced by @value{GDBN}'s ++internals. ++@end table ++ ++@node GDB/MI Async Records ++@subsection @sc{gdb/mi} Async Records ++ ++@cindex async records in @sc{gdb/mi} ++@cindex @sc{gdb/mi}, async records ++@dfn{Async} records are used to notify the @sc{gdb/mi} client of ++additional changes that have occurred. Those changes can either be a ++consequence of @sc{gdb/mi} commands (e.g., a breakpoint modified) or a result of ++target activity (e.g., target stopped). ++ ++The following is the list of possible async records: ++ ++@table @code ++ ++@item *running,thread-id="@var{thread}" ++The target is now running. The @var{thread} field can be the global ++thread ID of the thread that is now running, and it can be ++@samp{all} if all threads are running. The frontend should assume ++that no interaction with a running thread is possible after this ++notification is produced. The frontend should not assume that this ++notification is output only once for any command. @value{GDBN} may ++emit this notification several times, either for different threads, ++because it cannot resume all threads together, or even for a single ++thread, if the thread must be stepped though some code before letting ++it run freely. ++ ++@item *stopped,reason="@var{reason}",thread-id="@var{id}",stopped-threads="@var{stopped}",core="@var{core}" ++The target has stopped. The @var{reason} field can have one of the ++following values: ++ ++@table @code ++@item breakpoint-hit ++A breakpoint was reached. ++@item watchpoint-trigger ++A watchpoint was triggered. ++@item read-watchpoint-trigger ++A read watchpoint was triggered. ++@item access-watchpoint-trigger ++An access watchpoint was triggered. ++@item function-finished ++An -exec-finish or similar CLI command was accomplished. ++@item location-reached ++An -exec-until or similar CLI command was accomplished. ++@item watchpoint-scope ++A watchpoint has gone out of scope. ++@item end-stepping-range ++An -exec-next, -exec-next-instruction, -exec-step, -exec-step-instruction or ++similar CLI command was accomplished. ++@item exited-signalled ++The inferior exited because of a signal. ++@item exited ++The inferior exited. ++@item exited-normally ++The inferior exited normally. ++@item signal-received ++A signal was received by the inferior. ++@item solib-event ++The inferior has stopped due to a library being loaded or unloaded. ++This can happen when @code{stop-on-solib-events} (@pxref{Files}) is ++set or when a @code{catch load} or @code{catch unload} catchpoint is ++in use (@pxref{Set Catchpoints}). ++@item fork ++The inferior has forked. This is reported when @code{catch fork} ++(@pxref{Set Catchpoints}) has been used. ++@item vfork ++The inferior has vforked. This is reported in when @code{catch vfork} ++(@pxref{Set Catchpoints}) has been used. ++@item syscall-entry ++The inferior entered a system call. This is reported when @code{catch ++syscall} (@pxref{Set Catchpoints}) has been used. ++@item syscall-return ++The inferior returned from a system call. This is reported when ++@code{catch syscall} (@pxref{Set Catchpoints}) has been used. ++@item exec ++The inferior called @code{exec}. This is reported when @code{catch exec} ++(@pxref{Set Catchpoints}) has been used. ++@end table ++ ++The @var{id} field identifies the global thread ID of the thread ++that directly caused the stop -- for example by hitting a breakpoint. ++Depending on whether all-stop ++mode is in effect (@pxref{All-Stop Mode}), @value{GDBN} may either ++stop all threads, or only the thread that directly triggered the stop. ++If all threads are stopped, the @var{stopped} field will have the ++value of @code{"all"}. Otherwise, the value of the @var{stopped} ++field will be a list of thread identifiers. Presently, this list will ++always include a single thread, but frontend should be prepared to see ++several threads in the list. The @var{core} field reports the ++processor core on which the stop event has happened. This field may be absent ++if such information is not available. ++ ++@item =thread-group-added,id="@var{id}" ++@itemx =thread-group-removed,id="@var{id}" ++A thread group was either added or removed. The @var{id} field ++contains the @value{GDBN} identifier of the thread group. When a thread ++group is added, it generally might not be associated with a running ++process. When a thread group is removed, its id becomes invalid and ++cannot be used in any way. ++ ++@item =thread-group-started,id="@var{id}",pid="@var{pid}" ++A thread group became associated with a running program, ++either because the program was just started or the thread group ++was attached to a program. The @var{id} field contains the ++@value{GDBN} identifier of the thread group. The @var{pid} field ++contains process identifier, specific to the operating system. ++ ++@item =thread-group-exited,id="@var{id}"[,exit-code="@var{code}"] ++A thread group is no longer associated with a running program, ++either because the program has exited, or because it was detached ++from. The @var{id} field contains the @value{GDBN} identifier of the ++thread group. The @var{code} field is the exit code of the inferior; it exists ++only when the inferior exited with some code. ++ ++@item =thread-created,id="@var{id}",group-id="@var{gid}" ++@itemx =thread-exited,id="@var{id}",group-id="@var{gid}" ++A thread either was created, or has exited. The @var{id} field ++contains the global @value{GDBN} identifier of the thread. The @var{gid} ++field identifies the thread group this thread belongs to. ++ ++@item =thread-selected,id="@var{id}"[,frame="@var{frame}"] ++Informs that the selected thread or frame were changed. This notification ++is not emitted as result of the @code{-thread-select} or ++@code{-stack-select-frame} commands, but is emitted whenever an MI command ++that is not documented to change the selected thread and frame actually ++changes them. In particular, invoking, directly or indirectly ++(via user-defined command), the CLI @code{thread} or @code{frame} commands, ++will generate this notification. Changing the thread or frame from another ++user interface (see @ref{Interpreters}) will also generate this notification. ++ ++The @var{frame} field is only present if the newly selected thread is ++stopped. See @ref{GDB/MI Frame Information} for the format of its value. ++ ++We suggest that in response to this notification, front ends ++highlight the selected thread and cause subsequent commands to apply to ++that thread. ++ ++@item =library-loaded,... ++Reports that a new library file was loaded by the program. This ++notification has 5 fields---@var{id}, @var{target-name}, ++@var{host-name}, @var{symbols-loaded} and @var{ranges}. The @var{id} field is an ++opaque identifier of the library. For remote debugging case, ++@var{target-name} and @var{host-name} fields give the name of the ++library file on the target, and on the host respectively. For native ++debugging, both those fields have the same value. The ++@var{symbols-loaded} field is emitted only for backward compatibility ++and should not be relied on to convey any useful information. The ++@var{thread-group} field, if present, specifies the id of the thread ++group in whose context the library was loaded. If the field is ++absent, it means the library was loaded in the context of all present ++thread groups. The @var{ranges} field specifies the ranges of addresses belonging ++to this library. ++ ++@item =library-unloaded,... ++Reports that a library was unloaded by the program. This notification ++has 3 fields---@var{id}, @var{target-name} and @var{host-name} with ++the same meaning as for the @code{=library-loaded} notification. ++The @var{thread-group} field, if present, specifies the id of the ++thread group in whose context the library was unloaded. If the field is ++absent, it means the library was unloaded in the context of all present ++thread groups. ++ ++@item =traceframe-changed,num=@var{tfnum},tracepoint=@var{tpnum} ++@itemx =traceframe-changed,end ++Reports that the trace frame was changed and its new number is ++@var{tfnum}. The number of the tracepoint associated with this trace ++frame is @var{tpnum}. ++ ++@item =tsv-created,name=@var{name},initial=@var{initial} ++Reports that the new trace state variable @var{name} is created with ++initial value @var{initial}. ++ ++@item =tsv-deleted,name=@var{name} ++@itemx =tsv-deleted ++Reports that the trace state variable @var{name} is deleted or all ++trace state variables are deleted. ++ ++@item =tsv-modified,name=@var{name},initial=@var{initial}[,current=@var{current}] ++Reports that the trace state variable @var{name} is modified with ++the initial value @var{initial}. The current value @var{current} of ++trace state variable is optional and is reported if the current ++value of trace state variable is known. ++ ++@item =breakpoint-created,bkpt=@{...@} ++@itemx =breakpoint-modified,bkpt=@{...@} ++@itemx =breakpoint-deleted,id=@var{number} ++Reports that a breakpoint was created, modified, or deleted, ++respectively. Only user-visible breakpoints are reported to the MI ++user. ++ ++The @var{bkpt} argument is of the same form as returned by the various ++breakpoint commands; @xref{GDB/MI Breakpoint Commands}. The ++@var{number} is the ordinal number of the breakpoint. ++ ++Note that if a breakpoint is emitted in the result record of a ++command, then it will not also be emitted in an async record. ++ ++@item =record-started,thread-group="@var{id}",method="@var{method}"[,format="@var{format}"] ++@itemx =record-stopped,thread-group="@var{id}" ++Execution log recording was either started or stopped on an ++inferior. The @var{id} is the @value{GDBN} identifier of the thread ++group corresponding to the affected inferior. ++ ++The @var{method} field indicates the method used to record execution. If the ++method in use supports multiple recording formats, @var{format} will be present ++and contain the currently used format. @xref{Process Record and Replay}, ++for existing method and format values. ++ ++@item =cmd-param-changed,param=@var{param},value=@var{value} ++Reports that a parameter of the command @code{set @var{param}} is ++changed to @var{value}. In the multi-word @code{set} command, ++the @var{param} is the whole parameter list to @code{set} command. ++For example, In command @code{set check type on}, @var{param} ++is @code{check type} and @var{value} is @code{on}. ++ ++@item =memory-changed,thread-group=@var{id},addr=@var{addr},len=@var{len}[,type="code"] ++Reports that bytes from @var{addr} to @var{data} + @var{len} were ++written in an inferior. The @var{id} is the identifier of the ++thread group corresponding to the affected inferior. The optional ++@code{type="code"} part is reported if the memory written to holds ++executable code. ++@end table ++ ++@node GDB/MI Breakpoint Information ++@subsection @sc{gdb/mi} Breakpoint Information ++ ++When @value{GDBN} reports information about a breakpoint, a ++tracepoint, a watchpoint, or a catchpoint, it uses a tuple with the ++following fields: ++ ++@table @code ++@item number ++The breakpoint number. ++ ++@item type ++The type of the breakpoint. For ordinary breakpoints this will be ++@samp{breakpoint}, but many values are possible. ++ ++@item catch-type ++If the type of the breakpoint is @samp{catchpoint}, then this ++indicates the exact type of catchpoint. ++ ++@item disp ++This is the breakpoint disposition---either @samp{del}, meaning that ++the breakpoint will be deleted at the next stop, or @samp{keep}, ++meaning that the breakpoint will not be deleted. ++ ++@item enabled ++This indicates whether the breakpoint is enabled, in which case the ++value is @samp{y}, or disabled, in which case the value is @samp{n}. ++Note that this is not the same as the field @code{enable}. ++ ++@item addr ++The address of the breakpoint. This may be a hexidecimal number, ++giving the address; or the string @samp{}, for a pending ++breakpoint; or the string @samp{}, for a breakpoint with ++multiple locations. This field will not be present if no address can ++be determined. For example, a watchpoint does not have an address. ++ ++@item addr_flags ++Optional field containing any flags related to the address. These flags are ++architecture-dependent; see @ref{Architectures} for their meaning for a ++particular CPU. ++ ++@item func ++If known, the function in which the breakpoint appears. ++If not known, this field is not present. ++ ++@item filename ++The name of the source file which contains this function, if known. ++If not known, this field is not present. ++ ++@item fullname ++The full file name of the source file which contains this function, if ++known. If not known, this field is not present. ++ ++@item line ++The line number at which this breakpoint appears, if known. ++If not known, this field is not present. ++ ++@item at ++If the source file is not known, this field may be provided. If ++provided, this holds the address of the breakpoint, possibly followed ++by a symbol name. ++ ++@item pending ++If this breakpoint is pending, this field is present and holds the ++text used to set the breakpoint, as entered by the user. ++ ++@item evaluated-by ++Where this breakpoint's condition is evaluated, either @samp{host} or ++@samp{target}. ++ ++@item thread ++If this is a thread-specific breakpoint, then this identifies the ++thread in which the breakpoint can trigger. ++ ++@item task ++If this breakpoint is restricted to a particular Ada task, then this ++field will hold the task identifier. ++ ++@item cond ++If the breakpoint is conditional, this is the condition expression. ++ ++@item ignore ++The ignore count of the breakpoint. ++ ++@item enable ++The enable count of the breakpoint. ++ ++@item traceframe-usage ++FIXME. ++ ++@item static-tracepoint-marker-string-id ++For a static tracepoint, the name of the static tracepoint marker. ++ ++@item mask ++For a masked watchpoint, this is the mask. ++ ++@item pass ++A tracepoint's pass count. ++ ++@item original-location ++The location of the breakpoint as originally specified by the user. ++This field is optional. ++ ++@item times ++The number of times the breakpoint has been hit. ++ ++@item installed ++This field is only given for tracepoints. This is either @samp{y}, ++meaning that the tracepoint is installed, or @samp{n}, meaning that it ++is not. ++ ++@item what ++Some extra data, the exact contents of which are type-dependent. ++ ++@item locations ++This field is present if the breakpoint has multiple locations. It is also ++exceptionally present if the breakpoint is enabled and has a single, disabled ++location. ++ ++The value is a list of locations. The format of a location is described below. ++ ++@end table ++ ++A location in a multi-location breakpoint is represented as a tuple with the ++following fields: ++ ++@table @code ++ ++@item number ++The location number as a dotted pair, like @samp{1.2}. The first digit is the ++number of the parent breakpoint. The second digit is the number of the ++location within that breakpoint. ++ ++@item enabled ++This indicates whether the location is enabled, in which case the ++value is @samp{y}, or disabled, in which case the value is @samp{n}. ++Note that this is not the same as the field @code{enable}. ++ ++@item addr ++The address of this location as an hexidecimal number. ++ ++@item addr_flags ++Optional field containing any flags related to the address. These flags are ++architecture-dependent; see @ref{Architectures} for their meaning for a ++particular CPU. ++ ++@item func ++If known, the function in which the location appears. ++If not known, this field is not present. ++ ++@item file ++The name of the source file which contains this location, if known. ++If not known, this field is not present. ++ ++@item fullname ++The full file name of the source file which contains this location, if ++known. If not known, this field is not present. ++ ++@item line ++The line number at which this location appears, if known. ++If not known, this field is not present. ++ ++@item thread-groups ++The thread groups this location is in. ++ ++@end table ++ ++For example, here is what the output of @code{-break-insert} ++(@pxref{GDB/MI Breakpoint Commands}) might be: ++ ++@smallexample ++-> -break-insert main ++<- ^done,bkpt=@{number="1",type="breakpoint",disp="keep", ++ enabled="y",addr="0x08048564",func="main",file="myprog.c", ++ fullname="/home/nickrob/myprog.c",line="68",thread-groups=["i1"], ++ times="0"@} ++<- (gdb) ++@end smallexample ++ ++@node GDB/MI Frame Information ++@subsection @sc{gdb/mi} Frame Information ++ ++Response from many MI commands includes an information about stack ++frame. This information is a tuple that may have the following ++fields: ++ ++@table @code ++@item level ++The level of the stack frame. The innermost frame has the level of ++zero. This field is always present. ++ ++@item func ++The name of the function corresponding to the frame. This field may ++be absent if @value{GDBN} is unable to determine the function name. ++ ++@item addr ++The code address for the frame. This field is always present. ++ ++@item addr_flags ++Optional field containing any flags related to the address. These flags are ++architecture-dependent; see @ref{Architectures} for their meaning for a ++particular CPU. ++ ++@item file ++The name of the source files that correspond to the frame's code ++address. This field may be absent. ++ ++@item line ++The source line corresponding to the frames' code address. This field ++may be absent. ++ ++@item from ++The name of the binary file (either executable or shared library) the ++corresponds to the frame's code address. This field may be absent. ++ ++@end table ++ ++@node GDB/MI Thread Information ++@subsection @sc{gdb/mi} Thread Information ++ ++Whenever @value{GDBN} has to report an information about a thread, it ++uses a tuple with the following fields. The fields are always present unless ++stated otherwise. ++ ++@table @code ++@item id ++The global numeric id assigned to the thread by @value{GDBN}. ++ ++@item target-id ++The target-specific string identifying the thread. ++ ++@item details ++Additional information about the thread provided by the target. ++It is supposed to be human-readable and not interpreted by the ++frontend. This field is optional. ++ ++@item name ++The name of the thread. If the user specified a name using the ++@code{thread name} command, then this name is given. Otherwise, if ++@value{GDBN} can extract the thread name from the target, then that ++name is given. If @value{GDBN} cannot find the thread name, then this ++field is omitted. ++ ++@item state ++The execution state of the thread, either @samp{stopped} or @samp{running}, ++depending on whether the thread is presently running. ++ ++@item frame ++The stack frame currently executing in the thread. This field is only present ++if the thread is stopped. Its format is documented in ++@ref{GDB/MI Frame Information}. ++ ++@item core ++The value of this field is an integer number of the processor core the ++thread was last seen on. This field is optional. ++@end table ++ ++@node GDB/MI Ada Exception Information ++@subsection @sc{gdb/mi} Ada Exception Information ++ ++Whenever a @code{*stopped} record is emitted because the program ++stopped after hitting an exception catchpoint (@pxref{Set Catchpoints}), ++@value{GDBN} provides the name of the exception that was raised via ++the @code{exception-name} field. Also, for exceptions that were raised ++with an exception message, @value{GDBN} provides that message via ++the @code{exception-message} field. ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Simple Examples ++@section Simple Examples of @sc{gdb/mi} Interaction ++@cindex @sc{gdb/mi}, simple examples ++ ++This subsection presents several simple examples of interaction using ++the @sc{gdb/mi} interface. In these examples, @samp{->} means that the ++following line is passed to @sc{gdb/mi} as input, while @samp{<-} means ++the output received from @sc{gdb/mi}. ++ ++Note the line breaks shown in the examples are here only for ++readability, they don't appear in the real output. ++ ++@subheading Setting a Breakpoint ++ ++Setting a breakpoint generates synchronous output which contains detailed ++information of the breakpoint. ++ ++@smallexample ++-> -break-insert main ++<- ^done,bkpt=@{number="1",type="breakpoint",disp="keep", ++ enabled="y",addr="0x08048564",func="main",file="myprog.c", ++ fullname="/home/nickrob/myprog.c",line="68",thread-groups=["i1"], ++ times="0"@} ++<- (gdb) ++@end smallexample ++ ++@subheading Program Execution ++ ++Program execution generates asynchronous records and MI gives the ++reason that execution stopped. ++ ++@smallexample ++-> -exec-run ++<- ^running ++<- (gdb) ++<- *stopped,reason="breakpoint-hit",disp="keep",bkptno="1",thread-id="0", ++ frame=@{addr="0x08048564",func="main", ++ args=[@{name="argc",value="1"@},@{name="argv",value="0xbfc4d4d4"@}], ++ file="myprog.c",fullname="/home/nickrob/myprog.c",line="68", ++ arch="i386:x86_64"@} ++<- (gdb) ++-> -exec-continue ++<- ^running ++<- (gdb) ++<- *stopped,reason="exited-normally" ++<- (gdb) ++@end smallexample ++ ++@subheading Quitting @value{GDBN} ++ ++Quitting @value{GDBN} just prints the result class @samp{^exit}. ++ ++@smallexample ++-> (gdb) ++<- -gdb-exit ++<- ^exit ++@end smallexample ++ ++Please note that @samp{^exit} is printed immediately, but it might ++take some time for @value{GDBN} to actually exit. During that time, @value{GDBN} ++performs necessary cleanups, including killing programs being debugged ++or disconnecting from debug hardware, so the frontend should wait till ++@value{GDBN} exits and should only forcibly kill @value{GDBN} if it ++fails to exit in reasonable time. ++ ++@subheading A Bad Command ++ ++Here's what happens if you pass a non-existent command: ++ ++@smallexample ++-> -rubbish ++<- ^error,msg="Undefined MI command: rubbish" ++<- (gdb) ++@end smallexample ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Command Description Format ++@section @sc{gdb/mi} Command Description Format ++ ++The remaining sections describe blocks of commands. Each block of ++commands is laid out in a fashion similar to this section. ++ ++@subheading Motivation ++ ++The motivation for this collection of commands. ++ ++@subheading Introduction ++ ++A brief introduction to this collection of commands as a whole. ++ ++@subheading Commands ++ ++For each command in the block, the following is described: ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -command @var{args}@dots{} ++@end smallexample ++ ++@subsubheading Result ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} CLI command(s), if any. ++ ++@subsubheading Example ++ ++Example(s) formatted for readability. Some of the described commands have ++not been implemented yet and these are labeled N.A.@: (not available). ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Breakpoint Commands ++@section @sc{gdb/mi} Breakpoint Commands ++ ++@cindex breakpoint commands for @sc{gdb/mi} ++@cindex @sc{gdb/mi}, breakpoint commands ++This section documents @sc{gdb/mi} commands for manipulating ++breakpoints. ++ ++@subheading The @code{-break-after} Command ++@findex -break-after ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-after @var{number} @var{count} ++@end smallexample ++ ++The breakpoint number @var{number} is not in effect until it has been ++hit @var{count} times. To see how this is reflected in the output of ++the @samp{-break-list} command, see the description of the ++@samp{-break-list} command below. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{ignore}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-insert main ++^done,bkpt=@{number="1",type="breakpoint",disp="keep", ++enabled="y",addr="0x000100d0",func="main",file="hello.c", ++fullname="/home/foo/hello.c",line="5",thread-groups=["i1"], ++times="0"@} ++(gdb) ++-break-after 1 3 ++~ ++^done ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="1",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x000100d0",func="main",file="hello.c",fullname="/home/foo/hello.c", ++line="5",thread-groups=["i1"],times="0",ignore="3"@}]@} ++(gdb) ++@end smallexample ++ ++@ignore ++@subheading The @code{-break-catch} Command ++@findex -break-catch ++@end ignore ++ ++@subheading The @code{-break-commands} Command ++@findex -break-commands ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-commands @var{number} [ @var{command1} ... @var{commandN} ] ++@end smallexample ++ ++Specifies the CLI commands that should be executed when breakpoint ++@var{number} is hit. The parameters @var{command1} to @var{commandN} ++are the commands. If no command is specified, any previously-set ++commands are cleared. @xref{Break Commands}. Typical use of this ++functionality is tracing a program, that is, printing of values of ++some variables whenever breakpoint is hit and then continuing. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{commands}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-insert main ++^done,bkpt=@{number="1",type="breakpoint",disp="keep", ++enabled="y",addr="0x000100d0",func="main",file="hello.c", ++fullname="/home/foo/hello.c",line="5",thread-groups=["i1"], ++times="0"@} ++(gdb) ++-break-commands 1 "print v" "continue" ++^done ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-condition} Command ++@findex -break-condition ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-condition @var{number} @var{expr} ++@end smallexample ++ ++Breakpoint @var{number} will stop the program only if the condition in ++@var{expr} is true. The condition becomes part of the ++@samp{-break-list} output (see the description of the @samp{-break-list} ++command below). ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{condition}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-condition 1 1 ++^done ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="1",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x000100d0",func="main",file="hello.c",fullname="/home/foo/hello.c", ++line="5",cond="1",thread-groups=["i1"],times="0",ignore="3"@}]@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-delete} Command ++@findex -break-delete ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-delete ( @var{breakpoint} )+ ++@end smallexample ++ ++Delete the breakpoint(s) whose number(s) are specified in the argument ++list. This is obviously reflected in the breakpoint list. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{delete}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-delete 1 ++^done ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="0",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[]@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-disable} Command ++@findex -break-disable ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-disable ( @var{breakpoint} )+ ++@end smallexample ++ ++Disable the named @var{breakpoint}(s). The field @samp{enabled} in the ++break list is now set to @samp{n} for the named @var{breakpoint}(s). ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{disable}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-disable 2 ++^done ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="1",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n", ++addr="0x000100d0",func="main",file="hello.c",fullname="/home/foo/hello.c", ++line="5",thread-groups=["i1"],times="0"@}]@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-enable} Command ++@findex -break-enable ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-enable ( @var{breakpoint} )+ ++@end smallexample ++ ++Enable (previously disabled) @var{breakpoint}(s). ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{enable}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-enable 2 ++^done ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="1",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", ++addr="0x000100d0",func="main",file="hello.c",fullname="/home/foo/hello.c", ++line="5",thread-groups=["i1"],times="0"@}]@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-info} Command ++@findex -break-info ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-info @var{breakpoint} ++@end smallexample ++ ++@c REDUNDANT??? ++Get information about a single breakpoint. ++ ++The result is a table of breakpoints. @xref{GDB/MI Breakpoint ++Information}, for details on the format of each breakpoint in the ++table. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info break @var{breakpoint}}. ++ ++@subsubheading Example ++N.A. ++ ++@subheading The @code{-break-insert} Command ++@findex -break-insert ++@anchor{-break-insert} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-insert [ -t ] [ -h ] [ -f ] [ -d ] [ -a ] ++ [ -c @var{condition} ] [ -i @var{ignore-count} ] ++ [ -p @var{thread-id} ] [ @var{location} ] ++@end smallexample ++ ++@noindent ++If specified, @var{location}, can be one of: ++ ++@table @var ++@item linespec location ++A linespec location. @xref{Linespec Locations}. ++ ++@item explicit location ++An explicit location. @sc{gdb/mi} explicit locations are ++analogous to the CLI's explicit locations using the option names ++listed below. @xref{Explicit Locations}. ++ ++@table @samp ++@item --source @var{filename} ++The source file name of the location. This option requires the use ++of either @samp{--function} or @samp{--line}. ++ ++@item --function @var{function} ++The name of a function or method. ++ ++@item --label @var{label} ++The name of a label. ++ ++@item --line @var{lineoffset} ++An absolute or relative line offset from the start of the location. ++@end table ++ ++@item address location ++An address location, *@var{address}. @xref{Address Locations}. ++@end table ++ ++@noindent ++The possible optional parameters of this command are: ++ ++@table @samp ++@item -t ++Insert a temporary breakpoint. ++@item -h ++Insert a hardware breakpoint. ++@item -f ++If @var{location} cannot be parsed (for example if it ++refers to unknown files or functions), create a pending ++breakpoint. Without this flag, @value{GDBN} will report ++an error, and won't create a breakpoint, if @var{location} ++cannot be parsed. ++@item -d ++Create a disabled breakpoint. ++@item -a ++Create a tracepoint. @xref{Tracepoints}. When this parameter ++is used together with @samp{-h}, a fast tracepoint is created. ++@item -c @var{condition} ++Make the breakpoint conditional on @var{condition}. ++@item -i @var{ignore-count} ++Initialize the @var{ignore-count}. ++@item -p @var{thread-id} ++Restrict the breakpoint to the thread with the specified global ++@var{thread-id}. ++@end table ++ ++@subsubheading Result ++ ++@xref{GDB/MI Breakpoint Information}, for details on the format of the ++resulting breakpoint. ++ ++Note: this format is open to change. ++@c An out-of-band breakpoint instead of part of the result? ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak}, ++@samp{hbreak}, and @samp{thbreak}. @c and @samp{rbreak}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-insert main ++^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c", ++fullname="/home/foo/recursive2.c,line="4",thread-groups=["i1"], ++times="0"@} ++(gdb) ++-break-insert -t foo ++^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c", ++fullname="/home/foo/recursive2.c,line="11",thread-groups=["i1"], ++times="0"@} ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="2",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x0001072c", func="main",file="recursive2.c", ++fullname="/home/foo/recursive2.c,"line="4",thread-groups=["i1"], ++times="0"@}, ++bkpt=@{number="2",type="breakpoint",disp="del",enabled="y", ++addr="0x00010774",func="foo",file="recursive2.c", ++fullname="/home/foo/recursive2.c",line="11",thread-groups=["i1"], ++times="0"@}]@} ++(gdb) ++@c -break-insert -r foo.* ++@c ~int foo(int, int); ++@c ^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c, ++@c "fullname="/home/foo/recursive2.c",line="11",thread-groups=["i1"], ++@c times="0"@} ++@c (gdb) ++@end smallexample ++ ++@subheading The @code{-dprintf-insert} Command ++@findex -dprintf-insert ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -dprintf-insert [ -t ] [ -f ] [ -d ] ++ [ -c @var{condition} ] [ -i @var{ignore-count} ] ++ [ -p @var{thread-id} ] [ @var{location} ] [ @var{format} ] ++ [ @var{argument} ] ++@end smallexample ++ ++@noindent ++If supplied, @var{location} may be specified the same way as for ++the @code{-break-insert} command. @xref{-break-insert}. ++ ++The possible optional parameters of this command are: ++ ++@table @samp ++@item -t ++Insert a temporary breakpoint. ++@item -f ++If @var{location} cannot be parsed (for example, if it ++refers to unknown files or functions), create a pending ++breakpoint. Without this flag, @value{GDBN} will report ++an error, and won't create a breakpoint, if @var{location} ++cannot be parsed. ++@item -d ++Create a disabled breakpoint. ++@item -c @var{condition} ++Make the breakpoint conditional on @var{condition}. ++@item -i @var{ignore-count} ++Set the ignore count of the breakpoint (@pxref{Conditions, ignore count}) ++to @var{ignore-count}. ++@item -p @var{thread-id} ++Restrict the breakpoint to the thread with the specified global ++@var{thread-id}. ++@end table ++ ++@subsubheading Result ++ ++@xref{GDB/MI Breakpoint Information}, for details on the format of the ++resulting breakpoint. ++ ++@c An out-of-band breakpoint instead of part of the result? ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{dprintf}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++4-dprintf-insert foo "At foo entry\n" ++4^done,bkpt=@{number="1",type="dprintf",disp="keep",enabled="y", ++addr="0x000000000040061b",func="foo",file="mi-dprintf.c", ++fullname="mi-dprintf.c",line="25",thread-groups=["i1"], ++times="0",script=@{"printf \"At foo entry\\n\"","continue"@}, ++original-location="foo"@} ++(gdb) ++5-dprintf-insert 26 "arg=%d, g=%d\n" arg g ++5^done,bkpt=@{number="2",type="dprintf",disp="keep",enabled="y", ++addr="0x000000000040062a",func="foo",file="mi-dprintf.c", ++fullname="mi-dprintf.c",line="26",thread-groups=["i1"], ++times="0",script=@{"printf \"arg=%d, g=%d\\n\", arg, g","continue"@}, ++original-location="mi-dprintf.c:26"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-list} Command ++@findex -break-list ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-list ++@end smallexample ++ ++Displays the list of inserted breakpoints, showing the following fields: ++ ++@table @samp ++@item Number ++number of the breakpoint ++@item Type ++type of the breakpoint: @samp{breakpoint} or @samp{watchpoint} ++@item Disposition ++should the breakpoint be deleted or disabled when it is hit: @samp{keep} ++or @samp{nokeep} ++@item Enabled ++is the breakpoint enabled or no: @samp{y} or @samp{n} ++@item Address ++memory location at which the breakpoint is set ++@item What ++logical location of the breakpoint, expressed by function name, file ++name, line number ++@item Thread-groups ++list of thread groups to which this breakpoint applies ++@item Times ++number of times the breakpoint has been hit ++@end table ++ ++If there are no breakpoints or watchpoints, the @code{BreakpointTable} ++@code{body} field is an empty list. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info break}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="2",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x000100d0",func="main",file="hello.c",line="5",thread-groups=["i1"], ++times="0"@}, ++bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", ++addr="0x00010114",func="foo",file="hello.c",fullname="/home/foo/hello.c", ++line="13",thread-groups=["i1"],times="0"@}]@} ++(gdb) ++@end smallexample ++ ++Here's an example of the result when there are no breakpoints: ++ ++@smallexample ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="0",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[]@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-break-passcount} Command ++@findex -break-passcount ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-passcount @var{tracepoint-number} @var{passcount} ++@end smallexample ++ ++Set the passcount for tracepoint @var{tracepoint-number} to ++@var{passcount}. If the breakpoint referred to by @var{tracepoint-number} ++is not a tracepoint, error is emitted. This corresponds to CLI ++command @samp{passcount}. ++ ++@subheading The @code{-break-watch} Command ++@findex -break-watch ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -break-watch [ -a | -r ] ++@end smallexample ++ ++Create a watchpoint. With the @samp{-a} option it will create an ++@dfn{access} watchpoint, i.e., a watchpoint that triggers either on a ++read from or on a write to the memory location. With the @samp{-r} ++option, the watchpoint created is a @dfn{read} watchpoint, i.e., it will ++trigger only when the memory location is accessed for reading. Without ++either of the options, the watchpoint created is a regular watchpoint, ++i.e., it will trigger when the memory location is accessed for writing. ++@xref{Set Watchpoints, , Setting Watchpoints}. ++ ++Note that @samp{-break-list} will report a single list of watchpoints and ++breakpoints inserted. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{watch}, @samp{awatch}, and ++@samp{rwatch}. ++ ++@subsubheading Example ++ ++Setting a watchpoint on a variable in the @code{main} function: ++ ++@smallexample ++(gdb) ++-break-watch x ++^done,wpt=@{number="2",exp="x"@} ++(gdb) ++-exec-continue ++^running ++(gdb) ++*stopped,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@}, ++value=@{old="-268439212",new="55"@}, ++frame=@{func="main",args=[],file="recursive2.c", ++fullname="/home/foo/bar/recursive2.c",line="5",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++Setting a watchpoint on a variable local to a function. @value{GDBN} will stop ++the program execution twice: first for the variable changing value, then ++for the watchpoint going out of scope. ++ ++@smallexample ++(gdb) ++-break-watch C ++^done,wpt=@{number="5",exp="C"@} ++(gdb) ++-exec-continue ++^running ++(gdb) ++*stopped,reason="watchpoint-trigger", ++wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@}, ++frame=@{func="callee4",args=[], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="13", ++arch="i386:x86_64"@} ++(gdb) ++-exec-continue ++^running ++(gdb) ++*stopped,reason="watchpoint-scope",wpnum="5", ++frame=@{func="callee3",args=[@{name="strarg", ++value="0x11940 \"A string argument.\""@}], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="18", ++arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++Listing breakpoints and watchpoints, at different points in the program ++execution. Note that once the watchpoint goes out of scope, it is ++deleted. ++ ++@smallexample ++(gdb) ++-break-watch C ++^done,wpt=@{number="2",exp="C"@} ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="2",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x00010734",func="callee4", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/devo/gdb/testsuite/gdb.mi/basics.c"line="8",thread-groups=["i1"], ++times="1"@}, ++bkpt=@{number="2",type="watchpoint",disp="keep", ++enabled="y",addr="",what="C",thread-groups=["i1"],times="0"@}]@} ++(gdb) ++-exec-continue ++^running ++(gdb) ++*stopped,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@}, ++value=@{old="-276895068",new="3"@}, ++frame=@{func="callee4",args=[], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="13", ++arch="i386:x86_64"@} ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="2",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x00010734",func="callee4", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/devo/gdb/testsuite/gdb.mi/basics.c",line="8",thread-groups=["i1"], ++times="1"@}, ++bkpt=@{number="2",type="watchpoint",disp="keep", ++enabled="y",addr="",what="C",thread-groups=["i1"],times="-5"@}]@} ++(gdb) ++-exec-continue ++^running ++^done,reason="watchpoint-scope",wpnum="2", ++frame=@{func="callee3",args=[@{name="strarg", ++value="0x11940 \"A string argument.\""@}], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="18", ++arch="i386:x86_64"@} ++(gdb) ++-break-list ++^done,BreakpointTable=@{nr_rows="1",nr_cols="6", ++hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, ++@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, ++@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, ++@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, ++@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, ++@{width="40",alignment="2",col_name="what",colhdr="What"@}], ++body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x00010734",func="callee4", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/devo/gdb/testsuite/gdb.mi/basics.c",line="8", ++thread-groups=["i1"],times="1"@}]@} ++(gdb) ++@end smallexample ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Catchpoint Commands ++@section @sc{gdb/mi} Catchpoint Commands ++ ++This section documents @sc{gdb/mi} commands for manipulating ++catchpoints. ++ ++@menu ++* Shared Library GDB/MI Catchpoint Commands:: ++* Ada Exception GDB/MI Catchpoint Commands:: ++* C++ Exception GDB/MI Catchpoint Commands:: ++@end menu ++ ++@node Shared Library GDB/MI Catchpoint Commands ++@subsection Shared Library @sc{gdb/mi} Catchpoints ++ ++@subheading The @code{-catch-load} Command ++@findex -catch-load ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-load [ -t ] [ -d ] @var{regexp} ++@end smallexample ++ ++Add a catchpoint for library load events. If the @samp{-t} option is used, ++the catchpoint is a temporary one (@pxref{Set Breaks, ,Setting ++Breakpoints}). If the @samp{-d} option is used, the catchpoint is created ++in a disabled state. The @samp{regexp} argument is a regular ++expression used to match the name of the loaded library. ++ ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{catch load}. ++ ++@subsubheading Example ++ ++@smallexample ++-catch-load -t foo.so ++^done,bkpt=@{number="1",type="catchpoint",disp="del",enabled="y", ++what="load of library matching foo.so",catch-type="load",times="0"@} ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-catch-unload} Command ++@findex -catch-unload ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-unload [ -t ] [ -d ] @var{regexp} ++@end smallexample ++ ++Add a catchpoint for library unload events. If the @samp{-t} option is ++used, the catchpoint is a temporary one (@pxref{Set Breaks, ,Setting ++Breakpoints}). If the @samp{-d} option is used, the catchpoint is ++created in a disabled state. The @samp{regexp} argument is a regular ++expression used to match the name of the unloaded library. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{catch unload}. ++ ++@subsubheading Example ++ ++@smallexample ++-catch-unload -d bar.so ++^done,bkpt=@{number="2",type="catchpoint",disp="keep",enabled="n", ++what="load of library matching bar.so",catch-type="unload",times="0"@} ++(gdb) ++@end smallexample ++ ++@node Ada Exception GDB/MI Catchpoint Commands ++@subsection Ada Exception @sc{gdb/mi} Catchpoints ++ ++The following @sc{gdb/mi} commands can be used to create catchpoints ++that stop the execution when Ada exceptions are being raised. ++ ++@subheading The @code{-catch-assert} Command ++@findex -catch-assert ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-assert [ -c @var{condition}] [ -d ] [ -t ] ++@end smallexample ++ ++Add a catchpoint for failed Ada assertions. ++ ++The possible optional parameters for this command are: ++ ++@table @samp ++@item -c @var{condition} ++Make the catchpoint conditional on @var{condition}. ++@item -d ++Create a disabled catchpoint. ++@item -t ++Create a temporary catchpoint. ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{catch assert}. ++ ++@subsubheading Example ++ ++@smallexample ++-catch-assert ++^done,bkptno="5",bkpt=@{number="5",type="breakpoint",disp="keep", ++enabled="y",addr="0x0000000000404888",what="failed Ada assertions", ++thread-groups=["i1"],times="0", ++original-location="__gnat_debug_raise_assert_failure"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-catch-exception} Command ++@findex -catch-exception ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-exception [ -c @var{condition}] [ -d ] [ -e @var{exception-name} ] ++ [ -t ] [ -u ] ++@end smallexample ++ ++Add a catchpoint stopping when Ada exceptions are raised. ++By default, the command stops the program when any Ada exception ++gets raised. But it is also possible, by using some of the ++optional parameters described below, to create more selective ++catchpoints. ++ ++The possible optional parameters for this command are: ++ ++@table @samp ++@item -c @var{condition} ++Make the catchpoint conditional on @var{condition}. ++@item -d ++Create a disabled catchpoint. ++@item -e @var{exception-name} ++Only stop when @var{exception-name} is raised. This option cannot ++be used combined with @samp{-u}. ++@item -t ++Create a temporary catchpoint. ++@item -u ++Stop only when an unhandled exception gets raised. This option ++cannot be used combined with @samp{-e}. ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{catch exception} ++and @samp{catch exception unhandled}. ++ ++@subsubheading Example ++ ++@smallexample ++-catch-exception -e Program_Error ++^done,bkptno="4",bkpt=@{number="4",type="breakpoint",disp="keep", ++enabled="y",addr="0x0000000000404874", ++what="`Program_Error' Ada exception", thread-groups=["i1"], ++times="0",original-location="__gnat_debug_raise_exception"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-catch-handlers} Command ++@findex -catch-handlers ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-handlers [ -c @var{condition}] [ -d ] [ -e @var{exception-name} ] ++ [ -t ] ++@end smallexample ++ ++Add a catchpoint stopping when Ada exceptions are handled. ++By default, the command stops the program when any Ada exception ++gets handled. But it is also possible, by using some of the ++optional parameters described below, to create more selective ++catchpoints. ++ ++The possible optional parameters for this command are: ++ ++@table @samp ++@item -c @var{condition} ++Make the catchpoint conditional on @var{condition}. ++@item -d ++Create a disabled catchpoint. ++@item -e @var{exception-name} ++Only stop when @var{exception-name} is handled. ++@item -t ++Create a temporary catchpoint. ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{catch handlers}. ++ ++@subsubheading Example ++ ++@smallexample ++-catch-handlers -e Constraint_Error ++^done,bkptno="4",bkpt=@{number="4",type="breakpoint",disp="keep", ++enabled="y",addr="0x0000000000402f68", ++what="`Constraint_Error' Ada exception handlers",thread-groups=["i1"], ++times="0",original-location="__gnat_begin_handler"@} ++(gdb) ++@end smallexample ++ ++@node C++ Exception GDB/MI Catchpoint Commands ++@subsection C@t{++} Exception @sc{gdb/mi} Catchpoints ++ ++The following @sc{gdb/mi} commands can be used to create catchpoints ++that stop the execution when C@t{++} exceptions are being throw, rethrown, ++or caught. ++ ++@subheading The @code{-catch-throw} Command ++@findex -catch-throw ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-throw [ -t ] [ -r @var{regexp}] ++@end smallexample ++ ++Stop when the debuggee throws a C@t{++} exception. If @var{regexp} is ++given, then only exceptions whose type matches the regular expression ++will be caught. ++ ++If @samp{-t} is given, then the catchpoint is enabled only for one ++stop, the catchpoint is automatically deleted after stopping once for ++the event. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{catch throw} ++and @samp{tcatch throw} (@pxref{Set Catchpoints}). ++ ++@subsubheading Example ++ ++@smallexample ++-catch-throw -r exception_type ++^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y", ++ what="exception throw",catch-type="throw", ++ thread-groups=["i1"], ++ regexp="exception_type",times="0"@} ++(gdb) ++-exec-run ++^running ++(gdb) ++~"\n" ++~"Catchpoint 1 (exception thrown), 0x00007ffff7ae00ed ++ in __cxa_throw () from /lib64/libstdc++.so.6\n" ++*stopped,bkptno="1",reason="breakpoint-hit",disp="keep", ++ frame=@{addr="0x00007ffff7ae00ed",func="__cxa_throw", ++ args=[],from="/lib64/libstdc++.so.6",arch="i386:x86-64"@}, ++ thread-id="1",stopped-threads="all",core="6" ++(gdb) ++@end smallexample ++ ++@subheading The @code{-catch-rethrow} Command ++@findex -catch-rethrow ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-rethrow [ -t ] [ -r @var{regexp}] ++@end smallexample ++ ++Stop when a C@t{++} exception is re-thrown. If @var{regexp} is given, ++then only exceptions whose type matches the regular expression will be ++caught. ++ ++If @samp{-t} is given, then the catchpoint is enabled only for one ++stop, the catchpoint is automatically deleted after the first event is ++caught. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{catch rethrow} ++and @samp{tcatch rethrow} (@pxref{Set Catchpoints}). ++ ++@subsubheading Example ++ ++@smallexample ++-catch-rethrow -r exception_type ++^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y", ++ what="exception rethrow",catch-type="rethrow", ++ thread-groups=["i1"], ++ regexp="exception_type",times="0"@} ++(gdb) ++-exec-run ++^running ++(gdb) ++~"\n" ++~"Catchpoint 1 (exception rethrown), 0x00007ffff7ae00ed ++ in __cxa_rethrow () from /lib64/libstdc++.so.6\n" ++*stopped,bkptno="1",reason="breakpoint-hit",disp="keep", ++ frame=@{addr="0x00007ffff7ae00ed",func="__cxa_rethrow", ++ args=[],from="/lib64/libstdc++.so.6",arch="i386:x86-64"@}, ++ thread-id="1",stopped-threads="all",core="6" ++(gdb) ++@end smallexample ++ ++@subheading The @code{-catch-catch} Command ++@findex -catch-catch ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -catch-catch [ -t ] [ -r @var{regexp}] ++@end smallexample ++ ++Stop when the debuggee catches a C@t{++} exception. If @var{regexp} ++is given, then only exceptions whose type matches the regular ++expression will be caught. ++ ++If @samp{-t} is given, then the catchpoint is enabled only for one ++stop, the catchpoint is automatically deleted after the first event is ++caught. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{catch catch} ++and @samp{tcatch catch} (@pxref{Set Catchpoints}). ++ ++@subsubheading Example ++ ++@smallexample ++-catch-catch -r exception_type ++^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y", ++ what="exception catch",catch-type="catch", ++ thread-groups=["i1"], ++ regexp="exception_type",times="0"@} ++(gdb) ++-exec-run ++^running ++(gdb) ++~"\n" ++~"Catchpoint 1 (exception caught), 0x00007ffff7ae00ed ++ in __cxa_begin_catch () from /lib64/libstdc++.so.6\n" ++*stopped,bkptno="1",reason="breakpoint-hit",disp="keep", ++ frame=@{addr="0x00007ffff7ae00ed",func="__cxa_begin_catch", ++ args=[],from="/lib64/libstdc++.so.6",arch="i386:x86-64"@}, ++ thread-id="1",stopped-threads="all",core="6" ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Program Context ++@section @sc{gdb/mi} Program Context ++ ++@subheading The @code{-exec-arguments} Command ++@findex -exec-arguments ++ ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-arguments @var{args} ++@end smallexample ++ ++Set the inferior program arguments, to be used in the next ++@samp{-exec-run}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{set args}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-exec-arguments -v word ++^done ++(gdb) ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-exec-show-arguments} Command ++@findex -exec-show-arguments ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-show-arguments ++@end smallexample ++ ++Print the arguments of the program. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{show args}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-environment-cd} Command ++@findex -environment-cd ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -environment-cd @var{pathdir} ++@end smallexample ++ ++Set @value{GDBN}'s working directory. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{cd}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-environment-directory} Command ++@findex -environment-directory ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -environment-directory [ -r ] [ @var{pathdir} ]+ ++@end smallexample ++ ++Add directories @var{pathdir} to beginning of search path for source files. ++If the @samp{-r} option is used, the search path is reset to the default ++search path. If directories @var{pathdir} are supplied in addition to the ++@samp{-r} option, the search path is first reset and then addition ++occurs as normal. ++Multiple directories may be specified, separated by blanks. Specifying ++multiple directories in a single command ++results in the directories added to the beginning of the ++search path in the same order they were presented in the command. ++If blanks are needed as ++part of a directory name, double-quotes should be used around ++the name. In the command output, the path will show up separated ++by the system directory-separator character. The directory-separator ++character must not be used ++in any directory name. ++If no directories are specified, the current search path is displayed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{dir}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb ++^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" ++(gdb) ++-environment-directory "" ++^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" ++(gdb) ++-environment-directory -r /home/jjohnstn/src/gdb /usr/src ++^done,source-path="/home/jjohnstn/src/gdb:/usr/src:$cdir:$cwd" ++(gdb) ++-environment-directory -r ++^done,source-path="$cdir:$cwd" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-environment-path} Command ++@findex -environment-path ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -environment-path [ -r ] [ @var{pathdir} ]+ ++@end smallexample ++ ++Add directories @var{pathdir} to beginning of search path for object files. ++If the @samp{-r} option is used, the search path is reset to the original ++search path that existed at gdb start-up. If directories @var{pathdir} are ++supplied in addition to the ++@samp{-r} option, the search path is first reset and then addition ++occurs as normal. ++Multiple directories may be specified, separated by blanks. Specifying ++multiple directories in a single command ++results in the directories added to the beginning of the ++search path in the same order they were presented in the command. ++If blanks are needed as ++part of a directory name, double-quotes should be used around ++the name. In the command output, the path will show up separated ++by the system directory-separator character. The directory-separator ++character must not be used ++in any directory name. ++If no directories are specified, the current path is displayed. ++ ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{path}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-environment-path ++^done,path="/usr/bin" ++(gdb) ++-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb /bin ++^done,path="/kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb:/bin:/usr/bin" ++(gdb) ++-environment-path -r /usr/local/bin ++^done,path="/usr/local/bin:/usr/bin" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-environment-pwd} Command ++@findex -environment-pwd ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -environment-pwd ++@end smallexample ++ ++Show the current working directory. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{pwd}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-environment-pwd ++^done,cwd="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb" ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Thread Commands ++@section @sc{gdb/mi} Thread Commands ++ ++ ++@subheading The @code{-thread-info} Command ++@findex -thread-info ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -thread-info [ @var{thread-id} ] ++@end smallexample ++ ++Reports information about either a specific thread, if the ++@var{thread-id} parameter is present, or about all threads. ++@var{thread-id} is the thread's global thread ID. When printing ++information about all threads, also reports the global ID of the ++current thread. ++ ++@subsubheading @value{GDBN} Command ++ ++The @samp{info thread} command prints the same information ++about all threads. ++ ++@subsubheading Result ++ ++The result contains the following attributes: ++ ++@table @samp ++@item threads ++A list of threads. The format of the elements of the list is described in ++@ref{GDB/MI Thread Information}. ++ ++@item current-thread-id ++The global id of the currently selected thread. This field is omitted if there ++is no selected thread (for example, when the selected inferior is not running, ++and therefore has no threads) or if a @var{thread-id} argument was passed to ++the command. ++ ++@end table ++ ++@subsubheading Example ++ ++@smallexample ++-thread-info ++^done,threads=[ ++@{id="2",target-id="Thread 0xb7e14b90 (LWP 21257)", ++ frame=@{level="0",addr="0xffffe410",func="__kernel_vsyscall", ++ args=[]@},state="running"@}, ++@{id="1",target-id="Thread 0xb7e156b0 (LWP 21254)", ++ frame=@{level="0",addr="0x0804891f",func="foo", ++ args=[@{name="i",value="10"@}], ++ file="/tmp/a.c",fullname="/tmp/a.c",line="158",arch="i386:x86_64"@}, ++ state="running"@}], ++current-thread-id="1" ++(gdb) ++@end smallexample ++ ++@subheading The @code{-thread-list-ids} Command ++@findex -thread-list-ids ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -thread-list-ids ++@end smallexample ++ ++Produces a list of the currently known global @value{GDBN} thread ids. ++At the end of the list it also prints the total number of such ++threads. ++ ++This command is retained for historical reasons, the ++@code{-thread-info} command should be used instead. ++ ++@subsubheading @value{GDBN} Command ++ ++Part of @samp{info threads} supplies the same information. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-thread-list-ids ++^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, ++current-thread-id="1",number-of-threads="3" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-thread-select} Command ++@findex -thread-select ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -thread-select @var{thread-id} ++@end smallexample ++ ++Make thread with global thread number @var{thread-id} the current ++thread. It prints the number of the new current thread, and the ++topmost frame for that thread. ++ ++This command is deprecated in favor of explicitly using the ++@samp{--thread} option to each command. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{thread}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-exec-next ++^running ++(gdb) ++*stopped,reason="end-stepping-range",thread-id="2",line="187", ++file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c" ++(gdb) ++-thread-list-ids ++^done, ++thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, ++number-of-threads="3" ++(gdb) ++-thread-select 3 ++^done,new-thread-id="3", ++frame=@{level="0",func="vprintf", ++args=[@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@}, ++@{name="arg",value="0x2"@}],file="vprintf.c",line="31",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Ada Tasking Commands ++@section @sc{gdb/mi} Ada Tasking Commands ++ ++@subheading The @code{-ada-task-info} Command ++@findex -ada-task-info ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -ada-task-info [ @var{task-id} ] ++@end smallexample ++ ++Reports information about either a specific Ada task, if the ++@var{task-id} parameter is present, or about all Ada tasks. ++ ++@subsubheading @value{GDBN} Command ++ ++The @samp{info tasks} command prints the same information ++about all Ada tasks (@pxref{Ada Tasks}). ++ ++@subsubheading Result ++ ++The result is a table of Ada tasks. The following columns are ++defined for each Ada task: ++ ++@table @samp ++@item current ++This field exists only for the current thread. It has the value @samp{*}. ++ ++@item id ++The identifier that @value{GDBN} uses to refer to the Ada task. ++ ++@item task-id ++The identifier that the target uses to refer to the Ada task. ++ ++@item thread-id ++The global thread identifier of the thread corresponding to the Ada ++task. ++ ++This field should always exist, as Ada tasks are always implemented ++on top of a thread. But if @value{GDBN} cannot find this corresponding ++thread for any reason, the field is omitted. ++ ++@item parent-id ++This field exists only when the task was created by another task. ++In this case, it provides the ID of the parent task. ++ ++@item priority ++The base priority of the task. ++ ++@item state ++The current state of the task. For a detailed description of the ++possible states, see @ref{Ada Tasks}. ++ ++@item name ++The name of the task. ++ ++@end table ++ ++@subsubheading Example ++ ++@smallexample ++-ada-task-info ++^done,tasks=@{nr_rows="3",nr_cols="8", ++hdr=[@{width="1",alignment="-1",col_name="current",colhdr=""@}, ++@{width="3",alignment="1",col_name="id",colhdr="ID"@}, ++@{width="9",alignment="1",col_name="task-id",colhdr="TID"@}, ++@{width="4",alignment="1",col_name="thread-id",colhdr=""@}, ++@{width="4",alignment="1",col_name="parent-id",colhdr="P-ID"@}, ++@{width="3",alignment="1",col_name="priority",colhdr="Pri"@}, ++@{width="22",alignment="-1",col_name="state",colhdr="State"@}, ++@{width="1",alignment="2",col_name="name",colhdr="Name"@}], ++body=[@{current="*",id="1",task-id=" 644010",thread-id="1",priority="48", ++state="Child Termination Wait",name="main_task"@}]@} ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Program Execution ++@section @sc{gdb/mi} Program Execution ++ ++These are the asynchronous commands which generate the out-of-band ++record @samp{*stopped}. Currently @value{GDBN} only really executes ++asynchronously with remote targets and this interaction is mimicked in ++other cases. ++ ++@subheading The @code{-exec-continue} Command ++@findex -exec-continue ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-continue [--reverse] [--all|--thread-group N] ++@end smallexample ++ ++Resumes the execution of the inferior program, which will continue ++to execute until it reaches a debugger stop event. If the ++@samp{--reverse} option is specified, execution resumes in reverse until ++it reaches a stop event. Stop events may include ++@itemize @bullet ++@item ++breakpoints or watchpoints ++@item ++signals or exceptions ++@item ++the end of the process (or its beginning under @samp{--reverse}) ++@item ++the end or beginning of a replay log if one is being used. ++@end itemize ++In all-stop mode (@pxref{All-Stop ++Mode}), may resume only one thread, or all threads, depending on the ++value of the @samp{scheduler-locking} variable. If @samp{--all} is ++specified, all threads (in all inferiors) will be resumed. The @samp{--all} option is ++ignored in all-stop mode. If the @samp{--thread-group} options is ++specified, then all threads in that thread group are resumed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} corresponding is @samp{continue}. ++ ++@subsubheading Example ++ ++@smallexample ++-exec-continue ++^running ++(gdb) ++@@Hello world ++*stopped,reason="breakpoint-hit",disp="keep",bkptno="2",frame=@{ ++func="foo",args=[],file="hello.c",fullname="/home/foo/bar/hello.c", ++line="13",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-finish} Command ++@findex -exec-finish ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-finish [--reverse] ++@end smallexample ++ ++Resumes the execution of the inferior program until the current ++function is exited. Displays the results returned by the function. ++If the @samp{--reverse} option is specified, resumes the reverse ++execution of the inferior program until the point where current ++function was called. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{finish}. ++ ++@subsubheading Example ++ ++Function returning @code{void}. ++ ++@smallexample ++-exec-finish ++^running ++(gdb) ++@@hello from foo ++*stopped,reason="function-finished",frame=@{func="main",args=[], ++file="hello.c",fullname="/home/foo/bar/hello.c",line="7",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++Function returning other than @code{void}. The name of the internal ++@value{GDBN} variable storing the result is printed, together with the ++value itself. ++ ++@smallexample ++-exec-finish ++^running ++(gdb) ++*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo", ++args=[@{name="a",value="1"],@{name="b",value="9"@}@}, ++file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++arch="i386:x86_64"@}, ++gdb-result-var="$1",return-value="0" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-interrupt} Command ++@findex -exec-interrupt ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-interrupt [--all|--thread-group N] ++@end smallexample ++ ++Interrupts the background execution of the target. Note how the token ++associated with the stop message is the one for the execution command ++that has been interrupted. The token for the interrupt itself only ++appears in the @samp{^done} output. If the user is trying to ++interrupt a non-running program, an error message will be printed. ++ ++Note that when asynchronous execution is enabled, this command is ++asynchronous just like other execution commands. That is, first the ++@samp{^done} response will be printed, and the target stop will be ++reported after that using the @samp{*stopped} notification. ++ ++In non-stop mode, only the context thread is interrupted by default. ++All threads (in all inferiors) will be interrupted if the ++@samp{--all} option is specified. If the @samp{--thread-group} ++option is specified, all threads in that group will be interrupted. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{interrupt}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++111-exec-continue ++111^running ++ ++(gdb) ++222-exec-interrupt ++222^done ++(gdb) ++111*stopped,signal-name="SIGINT",signal-meaning="Interrupt", ++frame=@{addr="0x00010140",func="foo",args=[],file="try.c", ++fullname="/home/foo/bar/try.c",line="13",arch="i386:x86_64"@} ++(gdb) ++ ++(gdb) ++-exec-interrupt ++^error,msg="mi_cmd_exec_interrupt: Inferior not executing." ++(gdb) ++@end smallexample ++ ++@subheading The @code{-exec-jump} Command ++@findex -exec-jump ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-jump @var{location} ++@end smallexample ++ ++Resumes execution of the inferior program at the location specified by ++parameter. @xref{Specify Location}, for a description of the ++different forms of @var{location}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{jump}. ++ ++@subsubheading Example ++ ++@smallexample ++-exec-jump foo.c:10 ++*running,thread-id="all" ++^running ++@end smallexample ++ ++ ++@subheading The @code{-exec-next} Command ++@findex -exec-next ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-next [--reverse] ++@end smallexample ++ ++Resumes execution of the inferior program, stopping when the beginning ++of the next source line is reached. ++ ++If the @samp{--reverse} option is specified, resumes reverse execution ++of the inferior program, stopping at the beginning of the previous ++source line. If you issue this command on the first line of a ++function, it will take you back to the caller of that function, to the ++source line where the function was called. ++ ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{next}. ++ ++@subsubheading Example ++ ++@smallexample ++-exec-next ++^running ++(gdb) ++*stopped,reason="end-stepping-range",line="8",file="hello.c" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-next-instruction} Command ++@findex -exec-next-instruction ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-next-instruction [--reverse] ++@end smallexample ++ ++Executes one machine instruction. If the instruction is a function ++call, continues until the function returns. If the program stops at an ++instruction in the middle of a source line, the address will be ++printed as well. ++ ++If the @samp{--reverse} option is specified, resumes reverse execution ++of the inferior program, stopping at the previous instruction. If the ++previously executed instruction was a return from another function, ++it will continue to execute in reverse until the call to that function ++(from the current stack frame) is reached. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{nexti}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-exec-next-instruction ++^running ++ ++(gdb) ++*stopped,reason="end-stepping-range", ++addr="0x000100d4",line="5",file="hello.c" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-return} Command ++@findex -exec-return ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-return ++@end smallexample ++ ++Makes current function return immediately. Doesn't execute the inferior. ++Displays the new current frame. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{return}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++200-break-insert callee4 ++200^done,bkpt=@{number="1",addr="0x00010734", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@} ++(gdb) ++000-exec-run ++000^running ++(gdb) ++000*stopped,reason="breakpoint-hit",disp="keep",bkptno="1", ++frame=@{func="callee4",args=[], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="8", ++arch="i386:x86_64"@} ++(gdb) ++205-break-delete ++205^done ++(gdb) ++111-exec-return ++111^done,frame=@{level="0",func="callee3", ++args=[@{name="strarg", ++value="0x11940 \"A string argument.\""@}], ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="18", ++arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-run} Command ++@findex -exec-run ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-run [ --all | --thread-group N ] [ --start ] ++@end smallexample ++ ++Starts execution of the inferior from the beginning. The inferior ++executes until either a breakpoint is encountered or the program ++exits. In the latter case the output will include an exit code, if ++the program has exited exceptionally. ++ ++When neither the @samp{--all} nor the @samp{--thread-group} option ++is specified, the current inferior is started. If the ++@samp{--thread-group} option is specified, it should refer to a thread ++group of type @samp{process}, and that thread group will be started. ++If the @samp{--all} option is specified, then all inferiors will be started. ++ ++Using the @samp{--start} option instructs the debugger to stop ++the execution at the start of the inferior's main subprogram, ++following the same behavior as the @code{start} command ++(@pxref{Starting}). ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{run}. ++ ++@subsubheading Examples ++ ++@smallexample ++(gdb) ++-break-insert main ++^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} ++(gdb) ++-exec-run ++^running ++(gdb) ++*stopped,reason="breakpoint-hit",disp="keep",bkptno="1", ++frame=@{func="main",args=[],file="recursive2.c", ++fullname="/home/foo/bar/recursive2.c",line="4",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++@noindent ++Program exited normally: ++ ++@smallexample ++(gdb) ++-exec-run ++^running ++(gdb) ++x = 55 ++*stopped,reason="exited-normally" ++(gdb) ++@end smallexample ++ ++@noindent ++Program exited exceptionally: ++ ++@smallexample ++(gdb) ++-exec-run ++^running ++(gdb) ++x = 55 ++*stopped,reason="exited",exit-code="01" ++(gdb) ++@end smallexample ++ ++Another way the program can terminate is if it receives a signal such as ++@code{SIGINT}. In this case, @sc{gdb/mi} displays this: ++ ++@smallexample ++(gdb) ++*stopped,reason="exited-signalled",signal-name="SIGINT", ++signal-meaning="Interrupt" ++@end smallexample ++ ++ ++@c @subheading -exec-signal ++ ++ ++@subheading The @code{-exec-step} Command ++@findex -exec-step ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-step [--reverse] ++@end smallexample ++ ++Resumes execution of the inferior program, stopping when the beginning ++of the next source line is reached, if the next source line is not a ++function call. If it is, stop at the first instruction of the called ++function. If the @samp{--reverse} option is specified, resumes reverse ++execution of the inferior program, stopping at the beginning of the ++previously executed source line. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{step}. ++ ++@subsubheading Example ++ ++Stepping into a function: ++ ++@smallexample ++-exec-step ++^running ++(gdb) ++*stopped,reason="end-stepping-range", ++frame=@{func="foo",args=[@{name="a",value="10"@}, ++@{name="b",value="0"@}],file="recursive2.c", ++fullname="/home/foo/bar/recursive2.c",line="11",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++Regular stepping: ++ ++@smallexample ++-exec-step ++^running ++(gdb) ++*stopped,reason="end-stepping-range",line="14",file="recursive2.c" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-step-instruction} Command ++@findex -exec-step-instruction ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-step-instruction [--reverse] ++@end smallexample ++ ++Resumes the inferior which executes one machine instruction. If the ++@samp{--reverse} option is specified, resumes reverse execution of the ++inferior program, stopping at the previously executed instruction. ++The output, once @value{GDBN} has stopped, will vary depending on ++whether we have stopped in the middle of a source line or not. In the ++former case, the address at which the program stopped will be printed ++as well. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{stepi}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-exec-step-instruction ++^running ++ ++(gdb) ++*stopped,reason="end-stepping-range", ++frame=@{func="foo",args=[],file="try.c", ++fullname="/home/foo/bar/try.c",line="10",arch="i386:x86_64"@} ++(gdb) ++-exec-step-instruction ++^running ++ ++(gdb) ++*stopped,reason="end-stepping-range", ++frame=@{addr="0x000100f4",func="foo",args=[],file="try.c", ++fullname="/home/foo/bar/try.c",line="10",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-exec-until} Command ++@findex -exec-until ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-until [ @var{location} ] ++@end smallexample ++ ++Executes the inferior until the @var{location} specified in the ++argument is reached. If there is no argument, the inferior executes ++until a source line greater than the current one is reached. The ++reason for stopping in this case will be @samp{location-reached}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{until}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-exec-until recursive2.c:6 ++^running ++(gdb) ++x = 55 ++*stopped,reason="location-reached",frame=@{func="main",args=[], ++file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="6", ++arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++@ignore ++@subheading -file-clear ++Is this going away???? ++@end ignore ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Stack Manipulation ++@section @sc{gdb/mi} Stack Manipulation Commands ++ ++@subheading The @code{-enable-frame-filters} Command ++@findex -enable-frame-filters ++ ++@smallexample ++-enable-frame-filters ++@end smallexample ++ ++@value{GDBN} allows Python-based frame filters to affect the output of ++the MI commands relating to stack traces. As there is no way to ++implement this in a fully backward-compatible way, a front end must ++request that this functionality be enabled. ++ ++Once enabled, this feature cannot be disabled. ++ ++Note that if Python support has not been compiled into @value{GDBN}, ++this command will still succeed (and do nothing). ++ ++@subheading The @code{-stack-info-frame} Command ++@findex -stack-info-frame ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-info-frame ++@end smallexample ++ ++Get info on the selected frame. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info frame} or @samp{frame} ++(without arguments). ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-stack-info-frame ++^done,frame=@{level="1",addr="0x0001076c",func="callee3", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="17", ++arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-stack-info-depth} Command ++@findex -stack-info-depth ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-info-depth [ @var{max-depth} ] ++@end smallexample ++ ++Return the depth of the stack. If the integer argument @var{max-depth} ++is specified, do not count beyond @var{max-depth} frames. ++ ++@subsubheading @value{GDBN} Command ++ ++There's no equivalent @value{GDBN} command. ++ ++@subsubheading Example ++ ++For a stack with frame levels 0 through 11: ++ ++@smallexample ++(gdb) ++-stack-info-depth ++^done,depth="12" ++(gdb) ++-stack-info-depth 4 ++^done,depth="4" ++(gdb) ++-stack-info-depth 12 ++^done,depth="12" ++(gdb) ++-stack-info-depth 11 ++^done,depth="11" ++(gdb) ++-stack-info-depth 13 ++^done,depth="12" ++(gdb) ++@end smallexample ++ ++@anchor{-stack-list-arguments} ++@subheading The @code{-stack-list-arguments} Command ++@findex -stack-list-arguments ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-list-arguments [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} ++ [ @var{low-frame} @var{high-frame} ] ++@end smallexample ++ ++Display a list of the arguments for the frames between @var{low-frame} ++and @var{high-frame} (inclusive). If @var{low-frame} and ++@var{high-frame} are not provided, list the arguments for the whole ++call stack. If the two arguments are equal, show the single frame ++at the corresponding level. It is an error if @var{low-frame} is ++larger than the actual number of frames. On the other hand, ++@var{high-frame} may be larger than the actual number of frames, in ++which case only existing frames will be returned. ++ ++If @var{print-values} is 0 or @code{--no-values}, print only the names of ++the variables; if it is 1 or @code{--all-values}, print also their ++values; and if it is 2 or @code{--simple-values}, print the name, ++type and value for simple data types, and the name and type for arrays, ++structures and unions. If the option @code{--no-frame-filters} is ++supplied, then Python frame filters will not be executed. ++ ++If the @code{--skip-unavailable} option is specified, arguments that ++are not available are not listed. Partially available arguments ++are still displayed, however. ++ ++Use of this command to obtain arguments in a single frame is ++deprecated in favor of the @samp{-stack-list-variables} command. ++ ++@subsubheading @value{GDBN} Command ++ ++@value{GDBN} does not have an equivalent command. @code{gdbtk} has a ++@samp{gdb_get_args} command which partially overlaps with the ++functionality of @samp{-stack-list-arguments}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-stack-list-frames ++^done, ++stack=[ ++frame=@{level="0",addr="0x00010734",func="callee4", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="8", ++arch="i386:x86_64"@}, ++frame=@{level="1",addr="0x0001076c",func="callee3", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="17", ++arch="i386:x86_64"@}, ++frame=@{level="2",addr="0x0001078c",func="callee2", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="22", ++arch="i386:x86_64"@}, ++frame=@{level="3",addr="0x000107b4",func="callee1", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="27", ++arch="i386:x86_64"@}, ++frame=@{level="4",addr="0x000107e0",func="main", ++file="../../../devo/gdb/testsuite/gdb.mi/basics.c", ++fullname="/home/foo/bar/devo/gdb/testsuite/gdb.mi/basics.c",line="32", ++arch="i386:x86_64"@}] ++(gdb) ++-stack-list-arguments 0 ++^done, ++stack-args=[ ++frame=@{level="0",args=[]@}, ++frame=@{level="1",args=[name="strarg"]@}, ++frame=@{level="2",args=[name="intarg",name="strarg"]@}, ++frame=@{level="3",args=[name="intarg",name="strarg",name="fltarg"]@}, ++frame=@{level="4",args=[]@}] ++(gdb) ++-stack-list-arguments 1 ++^done, ++stack-args=[ ++frame=@{level="0",args=[]@}, ++frame=@{level="1", ++ args=[@{name="strarg",value="0x11940 \"A string argument.\""@}]@}, ++frame=@{level="2",args=[ ++@{name="intarg",value="2"@}, ++@{name="strarg",value="0x11940 \"A string argument.\""@}]@}, ++@{frame=@{level="3",args=[ ++@{name="intarg",value="2"@}, ++@{name="strarg",value="0x11940 \"A string argument.\""@}, ++@{name="fltarg",value="3.5"@}]@}, ++frame=@{level="4",args=[]@}] ++(gdb) ++-stack-list-arguments 0 2 2 ++^done,stack-args=[frame=@{level="2",args=[name="intarg",name="strarg"]@}] ++(gdb) ++-stack-list-arguments 1 2 2 ++^done,stack-args=[frame=@{level="2", ++args=[@{name="intarg",value="2"@}, ++@{name="strarg",value="0x11940 \"A string argument.\""@}]@}] ++(gdb) ++@end smallexample ++ ++@c @subheading -stack-list-exception-handlers ++ ++ ++@anchor{-stack-list-frames} ++@subheading The @code{-stack-list-frames} Command ++@findex -stack-list-frames ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-list-frames [ --no-frame-filters @var{low-frame} @var{high-frame} ] ++@end smallexample ++ ++List the frames currently on the stack. For each frame it displays the ++following info: ++ ++@table @samp ++@item @var{level} ++The frame number, 0 being the topmost frame, i.e., the innermost function. ++@item @var{addr} ++The @code{$pc} value for that frame. ++@item @var{func} ++Function name. ++@item @var{file} ++File name of the source file where the function lives. ++@item @var{fullname} ++The full file name of the source file where the function lives. ++@item @var{line} ++Line number corresponding to the @code{$pc}. ++@item @var{from} ++The shared library where this function is defined. This is only given ++if the frame's function is not known. ++@item @var{arch} ++Frame's architecture. ++@end table ++ ++If invoked without arguments, this command prints a backtrace for the ++whole stack. If given two integer arguments, it shows the frames whose ++levels are between the two arguments (inclusive). If the two arguments ++are equal, it shows the single frame at the corresponding level. It is ++an error if @var{low-frame} is larger than the actual number of ++frames. On the other hand, @var{high-frame} may be larger than the ++actual number of frames, in which case only existing frames will be ++returned. If the option @code{--no-frame-filters} is supplied, then ++Python frame filters will not be executed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{backtrace} and @samp{where}. ++ ++@subsubheading Example ++ ++Full stack backtrace: ++ ++@smallexample ++(gdb) ++-stack-list-frames ++^done,stack= ++[frame=@{level="0",addr="0x0001076c",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="11", ++ arch="i386:x86_64"@}, ++frame=@{level="1",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="2",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="3",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="4",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="5",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="6",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="7",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="8",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="9",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="10",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="11",addr="0x00010738",func="main", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="4", ++ arch="i386:x86_64"@}] ++(gdb) ++@end smallexample ++ ++Show frames between @var{low_frame} and @var{high_frame}: ++ ++@smallexample ++(gdb) ++-stack-list-frames 3 5 ++^done,stack= ++[frame=@{level="3",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="4",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}, ++frame=@{level="5",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}] ++(gdb) ++@end smallexample ++ ++Show a single frame: ++ ++@smallexample ++(gdb) ++-stack-list-frames 3 3 ++^done,stack= ++[frame=@{level="3",addr="0x000107a4",func="foo", ++ file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="14", ++ arch="i386:x86_64"@}] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-stack-list-locals} Command ++@findex -stack-list-locals ++@anchor{-stack-list-locals} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-list-locals [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} ++@end smallexample ++ ++Display the local variable names for the selected frame. If ++@var{print-values} is 0 or @code{--no-values}, print only the names of ++the variables; if it is 1 or @code{--all-values}, print also their ++values; and if it is 2 or @code{--simple-values}, print the name, ++type and value for simple data types, and the name and type for arrays, ++structures and unions. In this last case, a frontend can immediately ++display the value of simple data types and create variable objects for ++other data types when the user wishes to explore their values in ++more detail. If the option @code{--no-frame-filters} is supplied, then ++Python frame filters will not be executed. ++ ++If the @code{--skip-unavailable} option is specified, local variables ++that are not available are not listed. Partially available local ++variables are still displayed, however. ++ ++This command is deprecated in favor of the ++@samp{-stack-list-variables} command. ++ ++@subsubheading @value{GDBN} Command ++ ++@samp{info locals} in @value{GDBN}, @samp{gdb_get_locals} in @code{gdbtk}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-stack-list-locals 0 ++^done,locals=[name="A",name="B",name="C"] ++(gdb) ++-stack-list-locals --all-values ++^done,locals=[@{name="A",value="1"@},@{name="B",value="2"@}, ++ @{name="C",value="@{1, 2, 3@}"@}] ++-stack-list-locals --simple-values ++^done,locals=[@{name="A",type="int",value="1"@}, ++ @{name="B",type="int",value="2"@},@{name="C",type="int [3]"@}] ++(gdb) ++@end smallexample ++ ++@anchor{-stack-list-variables} ++@subheading The @code{-stack-list-variables} Command ++@findex -stack-list-variables ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-list-variables [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} ++@end smallexample ++ ++Display the names of local variables and function arguments for the selected frame. If ++@var{print-values} is 0 or @code{--no-values}, print only the names of ++the variables; if it is 1 or @code{--all-values}, print also their ++values; and if it is 2 or @code{--simple-values}, print the name, ++type and value for simple data types, and the name and type for arrays, ++structures and unions. If the option @code{--no-frame-filters} is ++supplied, then Python frame filters will not be executed. ++ ++If the @code{--skip-unavailable} option is specified, local variables ++and arguments that are not available are not listed. Partially ++available arguments and local variables are still displayed, however. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-stack-list-variables --thread 1 --frame 0 --all-values ++^done,variables=[@{name="x",value="11"@},@{name="s",value="@{a = 1, b = 2@}"@}] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-stack-select-frame} Command ++@findex -stack-select-frame ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -stack-select-frame @var{framenum} ++@end smallexample ++ ++Change the selected frame. Select a different frame @var{framenum} on ++the stack. ++ ++This command in deprecated in favor of passing the @samp{--frame} ++option to every command. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{frame}, @samp{up}, ++@samp{down}, @samp{select-frame}, @samp{up-silent}, and @samp{down-silent}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-stack-select-frame 2 ++^done ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Variable Objects ++@section @sc{gdb/mi} Variable Objects ++ ++@ignore ++ ++@subheading Motivation for Variable Objects in @sc{gdb/mi} ++ ++For the implementation of a variable debugger window (locals, watched ++expressions, etc.), we are proposing the adaptation of the existing code ++used by @code{Insight}. ++ ++The two main reasons for that are: ++ ++@enumerate 1 ++@item ++It has been proven in practice (it is already on its second generation). ++ ++@item ++It will shorten development time (needless to say how important it is ++now). ++@end enumerate ++ ++The original interface was designed to be used by Tcl code, so it was ++slightly changed so it could be used through @sc{gdb/mi}. This section ++describes the @sc{gdb/mi} operations that will be available and gives some ++hints about their use. ++ ++@emph{Note}: In addition to the set of operations described here, we ++expect the @sc{gui} implementation of a variable window to require, at ++least, the following operations: ++ ++@itemize @bullet ++@item @code{-gdb-show} @code{output-radix} ++@item @code{-stack-list-arguments} ++@item @code{-stack-list-locals} ++@item @code{-stack-select-frame} ++@end itemize ++ ++@end ignore ++ ++@subheading Introduction to Variable Objects ++ ++@cindex variable objects in @sc{gdb/mi} ++ ++Variable objects are "object-oriented" MI interface for examining and ++changing values of expressions. Unlike some other MI interfaces that ++work with expressions, variable objects are specifically designed for ++simple and efficient presentation in the frontend. A variable object ++is identified by string name. When a variable object is created, the ++frontend specifies the expression for that variable object. The ++expression can be a simple variable, or it can be an arbitrary complex ++expression, and can even involve CPU registers. After creating a ++variable object, the frontend can invoke other variable object ++operations---for example to obtain or change the value of a variable ++object, or to change display format. ++ ++Variable objects have hierarchical tree structure. Any variable object ++that corresponds to a composite type, such as structure in C, has ++a number of child variable objects, for example corresponding to each ++element of a structure. A child variable object can itself have ++children, recursively. Recursion ends when we reach ++leaf variable objects, which always have built-in types. Child variable ++objects are created only by explicit request, so if a frontend ++is not interested in the children of a particular variable object, no ++child will be created. ++ ++For a leaf variable object it is possible to obtain its value as a ++string, or set the value from a string. String value can be also ++obtained for a non-leaf variable object, but it's generally a string ++that only indicates the type of the object, and does not list its ++contents. Assignment to a non-leaf variable object is not allowed. ++ ++A frontend does not need to read the values of all variable objects each time ++the program stops. Instead, MI provides an update command that lists all ++variable objects whose values has changed since the last update ++operation. This considerably reduces the amount of data that must ++be transferred to the frontend. As noted above, children variable ++objects are created on demand, and only leaf variable objects have a ++real value. As result, gdb will read target memory only for leaf ++variables that frontend has created. ++ ++The automatic update is not always desirable. For example, a frontend ++might want to keep a value of some expression for future reference, ++and never update it. For another example, fetching memory is ++relatively slow for embedded targets, so a frontend might want ++to disable automatic update for the variables that are either not ++visible on the screen, or ``closed''. This is possible using so ++called ``frozen variable objects''. Such variable objects are never ++implicitly updated. ++ ++Variable objects can be either @dfn{fixed} or @dfn{floating}. For the ++fixed variable object, the expression is parsed when the variable ++object is created, including associating identifiers to specific ++variables. The meaning of expression never changes. For a floating ++variable object the values of variables whose names appear in the ++expressions are re-evaluated every time in the context of the current ++frame. Consider this example: ++ ++@smallexample ++void do_work(...) ++@{ ++ struct work_state state; ++ ++ if (...) ++ do_work(...); ++@} ++@end smallexample ++ ++If a fixed variable object for the @code{state} variable is created in ++this function, and we enter the recursive call, the variable ++object will report the value of @code{state} in the top-level ++@code{do_work} invocation. On the other hand, a floating variable ++object will report the value of @code{state} in the current frame. ++ ++If an expression specified when creating a fixed variable object ++refers to a local variable, the variable object becomes bound to the ++thread and frame in which the variable object is created. When such ++variable object is updated, @value{GDBN} makes sure that the ++thread/frame combination the variable object is bound to still exists, ++and re-evaluates the variable object in context of that thread/frame. ++ ++The following is the complete set of @sc{gdb/mi} operations defined to ++access this functionality: ++ ++@multitable @columnfractions .4 .6 ++@item @strong{Operation} ++@tab @strong{Description} ++ ++@item @code{-enable-pretty-printing} ++@tab enable Python-based pretty-printing ++@item @code{-var-create} ++@tab create a variable object ++@item @code{-var-delete} ++@tab delete the variable object and/or its children ++@item @code{-var-set-format} ++@tab set the display format of this variable ++@item @code{-var-show-format} ++@tab show the display format of this variable ++@item @code{-var-info-num-children} ++@tab tells how many children this object has ++@item @code{-var-list-children} ++@tab return a list of the object's children ++@item @code{-var-info-type} ++@tab show the type of this variable object ++@item @code{-var-info-expression} ++@tab print parent-relative expression that this variable object represents ++@item @code{-var-info-path-expression} ++@tab print full expression that this variable object represents ++@item @code{-var-show-attributes} ++@tab is this variable editable? does it exist here? ++@item @code{-var-evaluate-expression} ++@tab get the value of this variable ++@item @code{-var-assign} ++@tab set the value of this variable ++@item @code{-var-update} ++@tab update the variable and its children ++@item @code{-var-set-frozen} ++@tab set frozenness attribute ++@item @code{-var-set-update-range} ++@tab set range of children to display on update ++@end multitable ++ ++In the next subsection we describe each operation in detail and suggest ++how it can be used. ++ ++@subheading Description And Use of Operations on Variable Objects ++ ++@subheading The @code{-enable-pretty-printing} Command ++@findex -enable-pretty-printing ++ ++@smallexample ++-enable-pretty-printing ++@end smallexample ++ ++@value{GDBN} allows Python-based visualizers to affect the output of the ++MI variable object commands. However, because there was no way to ++implement this in a fully backward-compatible way, a front end must ++request that this functionality be enabled. ++ ++Once enabled, this feature cannot be disabled. ++ ++Note that if Python support has not been compiled into @value{GDBN}, ++this command will still succeed (and do nothing). ++ ++This feature is currently (as of @value{GDBN} 7.0) experimental, and ++may work differently in future versions of @value{GDBN}. ++ ++@subheading The @code{-var-create} Command ++@findex -var-create ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-create @{@var{name} | "-"@} ++ @{@var{frame-addr} | "*" | "@@"@} @var{expression} ++@end smallexample ++ ++This operation creates a variable object, which allows the monitoring of ++a variable, the result of an expression, a memory cell or a CPU ++register. ++ ++The @var{name} parameter is the string by which the object can be ++referenced. It must be unique. If @samp{-} is specified, the varobj ++system will generate a string ``varNNNNNN'' automatically. It will be ++unique provided that one does not specify @var{name} of that format. ++The command fails if a duplicate name is found. ++ ++The frame under which the expression should be evaluated can be ++specified by @var{frame-addr}. A @samp{*} indicates that the current ++frame should be used. A @samp{@@} indicates that a floating variable ++object must be created. ++ ++@var{expression} is any expression valid on the current language set (must not ++begin with a @samp{*}), or one of the following: ++ ++@itemize @bullet ++@item ++@samp{*@var{addr}}, where @var{addr} is the address of a memory cell ++ ++@item ++@samp{*@var{addr}-@var{addr}} --- a memory address range (TBD) ++ ++@item ++@samp{$@var{regname}} --- a CPU register name ++@end itemize ++ ++@cindex dynamic varobj ++A varobj's contents may be provided by a Python-based pretty-printer. In this ++case the varobj is known as a @dfn{dynamic varobj}. Dynamic varobjs ++have slightly different semantics in some cases. If the ++@code{-enable-pretty-printing} command is not sent, then @value{GDBN} ++will never create a dynamic varobj. This ensures backward ++compatibility for existing clients. ++ ++@subsubheading Result ++ ++This operation returns attributes of the newly-created varobj. These ++are: ++ ++@table @samp ++@item name ++The name of the varobj. ++ ++@item numchild ++The number of children of the varobj. This number is not necessarily ++reliable for a dynamic varobj. Instead, you must examine the ++@samp{has_more} attribute. ++ ++@item value ++The varobj's scalar value. For a varobj whose type is some sort of ++aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value ++will not be interesting. ++ ++@item type ++The varobj's type. This is a string representation of the type, as ++would be printed by the @value{GDBN} CLI. If @samp{print object} ++(@pxref{Print Settings, set print object}) is set to @code{on}, the ++@emph{actual} (derived) type of the object is shown rather than the ++@emph{declared} one. ++ ++@item thread-id ++If a variable object is bound to a specific thread, then this is the ++thread's global identifier. ++ ++@item has_more ++For a dynamic varobj, this indicates whether there appear to be any ++children available. For a non-dynamic varobj, this will be 0. ++ ++@item dynamic ++This attribute will be present and have the value @samp{1} if the ++varobj is a dynamic varobj. If the varobj is not a dynamic varobj, ++then this attribute will not be present. ++ ++@item displayhint ++A dynamic varobj can supply a display hint to the front end. The ++value comes directly from the Python pretty-printer object's ++@code{display_hint} method. @xref{Pretty Printing API}. ++@end table ++ ++Typical output will look like this: ++ ++@smallexample ++ name="@var{name}",numchild="@var{N}",type="@var{type}",thread-id="@var{M}", ++ has_more="@var{has_more}" ++@end smallexample ++ ++ ++@subheading The @code{-var-delete} Command ++@findex -var-delete ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-delete [ -c ] @var{name} ++@end smallexample ++ ++Deletes a previously created variable object and all of its children. ++With the @samp{-c} option, just deletes the children. ++ ++Returns an error if the object @var{name} is not found. ++ ++ ++@subheading The @code{-var-set-format} Command ++@findex -var-set-format ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-set-format @var{name} @var{format-spec} ++@end smallexample ++ ++Sets the output format for the value of the object @var{name} to be ++@var{format-spec}. ++ ++@anchor{-var-set-format} ++The syntax for the @var{format-spec} is as follows: ++ ++@smallexample ++ @var{format-spec} @expansion{} ++ @{binary | decimal | hexadecimal | octal | natural | zero-hexadecimal@} ++@end smallexample ++ ++The natural format is the default format choosen automatically ++based on the variable type (like decimal for an @code{int}, hex ++for pointers, etc.). ++ ++The zero-hexadecimal format has a representation similar to hexadecimal ++but with padding zeroes to the left of the value. For example, a 32-bit ++hexadecimal value of 0x1234 would be represented as 0x00001234 in the ++zero-hexadecimal format. ++ ++For a variable with children, the format is set only on the ++variable itself, and the children are not affected. ++ ++@subheading The @code{-var-show-format} Command ++@findex -var-show-format ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-show-format @var{name} ++@end smallexample ++ ++Returns the format used to display the value of the object @var{name}. ++ ++@smallexample ++ @var{format} @expansion{} ++ @var{format-spec} ++@end smallexample ++ ++ ++@subheading The @code{-var-info-num-children} Command ++@findex -var-info-num-children ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-info-num-children @var{name} ++@end smallexample ++ ++Returns the number of children of a variable object @var{name}: ++ ++@smallexample ++ numchild=@var{n} ++@end smallexample ++ ++Note that this number is not completely reliable for a dynamic varobj. ++It will return the current number of children, but more children may ++be available. ++ ++ ++@subheading The @code{-var-list-children} Command ++@findex -var-list-children ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-list-children [@var{print-values}] @var{name} [@var{from} @var{to}] ++@end smallexample ++@anchor{-var-list-children} ++ ++Return a list of the children of the specified variable object and ++create variable objects for them, if they do not already exist. With ++a single argument or if @var{print-values} has a value of 0 or ++@code{--no-values}, print only the names of the variables; if ++@var{print-values} is 1 or @code{--all-values}, also print their ++values; and if it is 2 or @code{--simple-values} print the name and ++value for simple data types and just the name for arrays, structures ++and unions. ++ ++@var{from} and @var{to}, if specified, indicate the range of children ++to report. If @var{from} or @var{to} is less than zero, the range is ++reset and all children will be reported. Otherwise, children starting ++at @var{from} (zero-based) and up to and excluding @var{to} will be ++reported. ++ ++If a child range is requested, it will only affect the current call to ++@code{-var-list-children}, but not future calls to @code{-var-update}. ++For this, you must instead use @code{-var-set-update-range}. The ++intent of this approach is to enable a front end to implement any ++update approach it likes; for example, scrolling a view may cause the ++front end to request more children with @code{-var-list-children}, and ++then the front end could call @code{-var-set-update-range} with a ++different range to ensure that future updates are restricted to just ++the visible items. ++ ++For each child the following results are returned: ++ ++@table @var ++ ++@item name ++Name of the variable object created for this child. ++ ++@item exp ++The expression to be shown to the user by the front end to designate this child. ++For example this may be the name of a structure member. ++ ++For a dynamic varobj, this value cannot be used to form an ++expression. There is no way to do this at all with a dynamic varobj. ++ ++For C/C@t{++} structures there are several pseudo children returned to ++designate access qualifiers. For these pseudo children @var{exp} is ++@samp{public}, @samp{private}, or @samp{protected}. In this case the ++type and value are not present. ++ ++A dynamic varobj will not report the access qualifying ++pseudo-children, regardless of the language. This information is not ++available at all with a dynamic varobj. ++ ++@item numchild ++Number of children this child has. For a dynamic varobj, this will be ++0. ++ ++@item type ++The type of the child. If @samp{print object} ++(@pxref{Print Settings, set print object}) is set to @code{on}, the ++@emph{actual} (derived) type of the object is shown rather than the ++@emph{declared} one. ++ ++@item value ++If values were requested, this is the value. ++ ++@item thread-id ++If this variable object is associated with a thread, this is the ++thread's global thread id. Otherwise this result is not present. ++ ++@item frozen ++If the variable object is frozen, this variable will be present with a value of 1. ++ ++@item displayhint ++A dynamic varobj can supply a display hint to the front end. The ++value comes directly from the Python pretty-printer object's ++@code{display_hint} method. @xref{Pretty Printing API}. ++ ++@item dynamic ++This attribute will be present and have the value @samp{1} if the ++varobj is a dynamic varobj. If the varobj is not a dynamic varobj, ++then this attribute will not be present. ++ ++@end table ++ ++The result may have its own attributes: ++ ++@table @samp ++@item displayhint ++A dynamic varobj can supply a display hint to the front end. The ++value comes directly from the Python pretty-printer object's ++@code{display_hint} method. @xref{Pretty Printing API}. ++ ++@item has_more ++This is an integer attribute which is nonzero if there are children ++remaining after the end of the selected range. ++@end table ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++ -var-list-children n ++ ^done,numchild=@var{n},children=[child=@{name=@var{name},exp=@var{exp}, ++ numchild=@var{n},type=@var{type}@},@r{(repeats N times)}] ++(gdb) ++ -var-list-children --all-values n ++ ^done,numchild=@var{n},children=[child=@{name=@var{name},exp=@var{exp}, ++ numchild=@var{n},value=@var{value},type=@var{type}@},@r{(repeats N times)}] ++@end smallexample ++ ++ ++@subheading The @code{-var-info-type} Command ++@findex -var-info-type ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-info-type @var{name} ++@end smallexample ++ ++Returns the type of the specified variable @var{name}. The type is ++returned as a string in the same format as it is output by the ++@value{GDBN} CLI: ++ ++@smallexample ++ type=@var{typename} ++@end smallexample ++ ++ ++@subheading The @code{-var-info-expression} Command ++@findex -var-info-expression ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-info-expression @var{name} ++@end smallexample ++ ++Returns a string that is suitable for presenting this ++variable object in user interface. The string is generally ++not valid expression in the current language, and cannot be evaluated. ++ ++For example, if @code{a} is an array, and variable object ++@code{A} was created for @code{a}, then we'll get this output: ++ ++@smallexample ++(gdb) -var-info-expression A.1 ++^done,lang="C",exp="1" ++@end smallexample ++ ++@noindent ++Here, the value of @code{lang} is the language name, which can be ++found in @ref{Supported Languages}. ++ ++Note that the output of the @code{-var-list-children} command also ++includes those expressions, so the @code{-var-info-expression} command ++is of limited use. ++ ++@subheading The @code{-var-info-path-expression} Command ++@findex -var-info-path-expression ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-info-path-expression @var{name} ++@end smallexample ++ ++Returns an expression that can be evaluated in the current ++context and will yield the same value that a variable object has. ++Compare this with the @code{-var-info-expression} command, which ++result can be used only for UI presentation. Typical use of ++the @code{-var-info-path-expression} command is creating a ++watchpoint from a variable object. ++ ++This command is currently not valid for children of a dynamic varobj, ++and will give an error when invoked on one. ++ ++For example, suppose @code{C} is a C@t{++} class, derived from class ++@code{Base}, and that the @code{Base} class has a member called ++@code{m_size}. Assume a variable @code{c} is has the type of ++@code{C} and a variable object @code{C} was created for variable ++@code{c}. Then, we'll get this output: ++@smallexample ++(gdb) -var-info-path-expression C.Base.public.m_size ++^done,path_expr=((Base)c).m_size) ++@end smallexample ++ ++@subheading The @code{-var-show-attributes} Command ++@findex -var-show-attributes ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-show-attributes @var{name} ++@end smallexample ++ ++List attributes of the specified variable object @var{name}: ++ ++@smallexample ++ status=@var{attr} [ ( ,@var{attr} )* ] ++@end smallexample ++ ++@noindent ++where @var{attr} is @code{@{ @{ editable | noneditable @} | TBD @}}. ++ ++@subheading The @code{-var-evaluate-expression} Command ++@findex -var-evaluate-expression ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-evaluate-expression [-f @var{format-spec}] @var{name} ++@end smallexample ++ ++Evaluates the expression that is represented by the specified variable ++object and returns its value as a string. The format of the string ++can be specified with the @samp{-f} option. The possible values of ++this option are the same as for @code{-var-set-format} ++(@pxref{-var-set-format}). If the @samp{-f} option is not specified, ++the current display format will be used. The current display format ++can be changed using the @code{-var-set-format} command. ++ ++@smallexample ++ value=@var{value} ++@end smallexample ++ ++Note that one must invoke @code{-var-list-children} for a variable ++before the value of a child variable can be evaluated. ++ ++@subheading The @code{-var-assign} Command ++@findex -var-assign ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-assign @var{name} @var{expression} ++@end smallexample ++ ++Assigns the value of @var{expression} to the variable object specified ++by @var{name}. The object must be @samp{editable}. If the variable's ++value is altered by the assign, the variable will show up in any ++subsequent @code{-var-update} list. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-var-assign var1 3 ++^done,value="3" ++(gdb) ++-var-update * ++^done,changelist=[@{name="var1",in_scope="true",type_changed="false"@}] ++(gdb) ++@end smallexample ++ ++@subheading The @code{-var-update} Command ++@findex -var-update ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-update [@var{print-values}] @{@var{name} | "*"@} ++@end smallexample ++ ++Reevaluate the expressions corresponding to the variable object ++@var{name} and all its direct and indirect children, and return the ++list of variable objects whose values have changed; @var{name} must ++be a root variable object. Here, ``changed'' means that the result of ++@code{-var-evaluate-expression} before and after the ++@code{-var-update} is different. If @samp{*} is used as the variable ++object names, all existing variable objects are updated, except ++for frozen ones (@pxref{-var-set-frozen}). The option ++@var{print-values} determines whether both names and values, or just ++names are printed. The possible values of this option are the same ++as for @code{-var-list-children} (@pxref{-var-list-children}). It is ++recommended to use the @samp{--all-values} option, to reduce the ++number of MI commands needed on each program stop. ++ ++With the @samp{*} parameter, if a variable object is bound to a ++currently running thread, it will not be updated, without any ++diagnostic. ++ ++If @code{-var-set-update-range} was previously used on a varobj, then ++only the selected range of children will be reported. ++ ++@code{-var-update} reports all the changed varobjs in a tuple named ++@samp{changelist}. ++ ++Each item in the change list is itself a tuple holding: ++ ++@table @samp ++@item name ++The name of the varobj. ++ ++@item value ++If values were requested for this update, then this field will be ++present and will hold the value of the varobj. ++ ++@item in_scope ++@anchor{-var-update} ++This field is a string which may take one of three values: ++ ++@table @code ++@item "true" ++The variable object's current value is valid. ++ ++@item "false" ++The variable object does not currently hold a valid value but it may ++hold one in the future if its associated expression comes back into ++scope. ++ ++@item "invalid" ++The variable object no longer holds a valid value. ++This can occur when the executable file being debugged has changed, ++either through recompilation or by using the @value{GDBN} @code{file} ++command. The front end should normally choose to delete these variable ++objects. ++@end table ++ ++In the future new values may be added to this list so the front should ++be prepared for this possibility. @xref{GDB/MI Development and Front Ends, ,@sc{GDB/MI} Development and Front Ends}. ++ ++@item type_changed ++This is only present if the varobj is still valid. If the type ++changed, then this will be the string @samp{true}; otherwise it will ++be @samp{false}. ++ ++When a varobj's type changes, its children are also likely to have ++become incorrect. Therefore, the varobj's children are automatically ++deleted when this attribute is @samp{true}. Also, the varobj's update ++range, when set using the @code{-var-set-update-range} command, is ++unset. ++ ++@item new_type ++If the varobj's type changed, then this field will be present and will ++hold the new type. ++ ++@item new_num_children ++For a dynamic varobj, if the number of children changed, or if the ++type changed, this will be the new number of children. ++ ++The @samp{numchild} field in other varobj responses is generally not ++valid for a dynamic varobj -- it will show the number of children that ++@value{GDBN} knows about, but because dynamic varobjs lazily ++instantiate their children, this will not reflect the number of ++children which may be available. ++ ++The @samp{new_num_children} attribute only reports changes to the ++number of children known by @value{GDBN}. This is the only way to ++detect whether an update has removed children (which necessarily can ++only happen at the end of the update range). ++ ++@item displayhint ++The display hint, if any. ++ ++@item has_more ++This is an integer value, which will be 1 if there are more children ++available outside the varobj's update range. ++ ++@item dynamic ++This attribute will be present and have the value @samp{1} if the ++varobj is a dynamic varobj. If the varobj is not a dynamic varobj, ++then this attribute will not be present. ++ ++@item new_children ++If new children were added to a dynamic varobj within the selected ++update range (as set by @code{-var-set-update-range}), then they will ++be listed in this attribute. ++@end table ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-var-assign var1 3 ++^done,value="3" ++(gdb) ++-var-update --all-values var1 ++^done,changelist=[@{name="var1",value="3",in_scope="true", ++type_changed="false"@}] ++(gdb) ++@end smallexample ++ ++@subheading The @code{-var-set-frozen} Command ++@findex -var-set-frozen ++@anchor{-var-set-frozen} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-set-frozen @var{name} @var{flag} ++@end smallexample ++ ++Set the frozenness flag on the variable object @var{name}. The ++@var{flag} parameter should be either @samp{1} to make the variable ++frozen or @samp{0} to make it unfrozen. If a variable object is ++frozen, then neither itself, nor any of its children, are ++implicitly updated by @code{-var-update} of ++a parent variable or by @code{-var-update *}. Only ++@code{-var-update} of the variable itself will update its value and ++values of its children. After a variable object is unfrozen, it is ++implicitly updated by all subsequent @code{-var-update} operations. ++Unfreezing a variable does not update it, only subsequent ++@code{-var-update} does. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-var-set-frozen V 1 ++^done ++(gdb) ++@end smallexample ++ ++@subheading The @code{-var-set-update-range} command ++@findex -var-set-update-range ++@anchor{-var-set-update-range} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-set-update-range @var{name} @var{from} @var{to} ++@end smallexample ++ ++Set the range of children to be returned by future invocations of ++@code{-var-update}. ++ ++@var{from} and @var{to} indicate the range of children to report. If ++@var{from} or @var{to} is less than zero, the range is reset and all ++children will be reported. Otherwise, children starting at @var{from} ++(zero-based) and up to and excluding @var{to} will be reported. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-var-set-update-range V 1 2 ++^done ++@end smallexample ++ ++@subheading The @code{-var-set-visualizer} command ++@findex -var-set-visualizer ++@anchor{-var-set-visualizer} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -var-set-visualizer @var{name} @var{visualizer} ++@end smallexample ++ ++Set a visualizer for the variable object @var{name}. ++ ++@var{visualizer} is the visualizer to use. The special value ++@samp{None} means to disable any visualizer in use. ++ ++If not @samp{None}, @var{visualizer} must be a Python expression. ++This expression must evaluate to a callable object which accepts a ++single argument. @value{GDBN} will call this object with the value of ++the varobj @var{name} as an argument (this is done so that the same ++Python pretty-printing code can be used for both the CLI and MI). ++When called, this object must return an object which conforms to the ++pretty-printing interface (@pxref{Pretty Printing API}). ++ ++The pre-defined function @code{gdb.default_visualizer} may be used to ++select a visualizer by following the built-in process ++(@pxref{Selecting Pretty-Printers}). This is done automatically when ++a varobj is created, and so ordinarily is not needed. ++ ++This feature is only available if Python support is enabled. The MI ++command @code{-list-features} (@pxref{GDB/MI Support Commands}) ++can be used to check this. ++ ++@subsubheading Example ++ ++Resetting the visualizer: ++ ++@smallexample ++(gdb) ++-var-set-visualizer V None ++^done ++@end smallexample ++ ++Reselecting the default (type-based) visualizer: ++ ++@smallexample ++(gdb) ++-var-set-visualizer V gdb.default_visualizer ++^done ++@end smallexample ++ ++Suppose @code{SomeClass} is a visualizer class. A lambda expression ++can be used to instantiate this class for a varobj: ++ ++@smallexample ++(gdb) ++-var-set-visualizer V "lambda val: SomeClass()" ++^done ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Data Manipulation ++@section @sc{gdb/mi} Data Manipulation ++ ++@cindex data manipulation, in @sc{gdb/mi} ++@cindex @sc{gdb/mi}, data manipulation ++This section describes the @sc{gdb/mi} commands that manipulate data: ++examine memory and registers, evaluate expressions, etc. ++ ++For details about what an addressable memory unit is, ++@pxref{addressable memory unit}. ++ ++@c REMOVED FROM THE INTERFACE. ++@c @subheading -data-assign ++@c Change the value of a program variable. Plenty of side effects. ++@c @subsubheading GDB Command ++@c set variable ++@c @subsubheading Example ++@c N.A. ++ ++@subheading The @code{-data-disassemble} Command ++@findex -data-disassemble ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-disassemble ++ [ -s @var{start-addr} -e @var{end-addr} ] ++ | [ -a @var{addr} ] ++ | [ -f @var{filename} -l @var{linenum} [ -n @var{lines} ] ] ++ -- @var{mode} ++@end smallexample ++ ++@noindent ++Where: ++ ++@table @samp ++@item @var{start-addr} ++is the beginning address (or @code{$pc}) ++@item @var{end-addr} ++is the end address ++@item @var{addr} ++is an address anywhere within (or the name of) the function to ++disassemble. If an address is specified, the whole function ++surrounding that address will be disassembled. If a name is ++specified, the whole function with that name will be disassembled. ++@item @var{filename} ++is the name of the file to disassemble ++@item @var{linenum} ++is the line number to disassemble around ++@item @var{lines} ++is the number of disassembly lines to be produced. If it is -1, ++the whole function will be disassembled, in case no @var{end-addr} is ++specified. If @var{end-addr} is specified as a non-zero value, and ++@var{lines} is lower than the number of disassembly lines between ++@var{start-addr} and @var{end-addr}, only @var{lines} lines are ++displayed; if @var{lines} is higher than the number of lines between ++@var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr} ++are displayed. ++@item @var{mode} ++is one of: ++@itemize @bullet ++@item 0 disassembly only ++@item 1 mixed source and disassembly (deprecated) ++@item 2 disassembly with raw opcodes ++@item 3 mixed source and disassembly with raw opcodes (deprecated) ++@item 4 mixed source and disassembly ++@item 5 mixed source and disassembly with raw opcodes ++@end itemize ++ ++Modes 1 and 3 are deprecated. The output is ``source centric'' ++which hasn't proved useful in practice. ++@xref{Machine Code}, for a discussion of the difference between ++@code{/m} and @code{/s} output of the @code{disassemble} command. ++@end table ++ ++@subsubheading Result ++ ++The result of the @code{-data-disassemble} command will be a list named ++@samp{asm_insns}, the contents of this list depend on the @var{mode} ++used with the @code{-data-disassemble} command. ++ ++For modes 0 and 2 the @samp{asm_insns} list contains tuples with the ++following fields: ++ ++@table @code ++@item address ++The address at which this instruction was disassembled. ++ ++@item func-name ++The name of the function this instruction is within. ++ ++@item offset ++The decimal offset in bytes from the start of @samp{func-name}. ++ ++@item inst ++The text disassembly for this @samp{address}. ++ ++@item opcodes ++This field is only present for modes 2, 3 and 5. This contains the raw opcode ++bytes for the @samp{inst} field. ++ ++@end table ++ ++For modes 1, 3, 4 and 5 the @samp{asm_insns} list contains tuples named ++@samp{src_and_asm_line}, each of which has the following fields: ++ ++@table @code ++@item line ++The line number within @samp{file}. ++ ++@item file ++The file name from the compilation unit. This might be an absolute ++file name or a relative file name depending on the compile command ++used. ++ ++@item fullname ++Absolute file name of @samp{file}. It is converted to a canonical form ++using the source file search path ++(@pxref{Source Path, ,Specifying Source Directories}) ++and after resolving all the symbolic links. ++ ++If the source file is not found this field will contain the path as ++present in the debug information. ++ ++@item line_asm_insn ++This is a list of tuples containing the disassembly for @samp{line} in ++@samp{file}. The fields of each tuple are the same as for ++@code{-data-disassemble} in @var{mode} 0 and 2, so @samp{address}, ++@samp{func-name}, @samp{offset}, @samp{inst}, and optionally ++@samp{opcodes}. ++ ++@end table ++ ++Note that whatever included in the @samp{inst} field, is not ++manipulated directly by @sc{gdb/mi}, i.e., it is not possible to ++adjust its format. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{disassemble}. ++ ++@subsubheading Example ++ ++Disassemble from the current value of @code{$pc} to @code{$pc + 20}: ++ ++@smallexample ++(gdb) ++-data-disassemble -s $pc -e "$pc + 20" -- 0 ++^done, ++asm_insns=[ ++@{address="0x000107c0",func-name="main",offset="4", ++inst="mov 2, %o0"@}, ++@{address="0x000107c4",func-name="main",offset="8", ++inst="sethi %hi(0x11800), %o2"@}, ++@{address="0x000107c8",func-name="main",offset="12", ++inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"@}, ++@{address="0x000107cc",func-name="main",offset="16", ++inst="sethi %hi(0x11800), %o2"@}, ++@{address="0x000107d0",func-name="main",offset="20", ++inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"@}] ++(gdb) ++@end smallexample ++ ++Disassemble the whole @code{main} function. Line 32 is part of ++@code{main}. ++ ++@smallexample ++-data-disassemble -f basics.c -l 32 -- 0 ++^done,asm_insns=[ ++@{address="0x000107bc",func-name="main",offset="0", ++inst="save %sp, -112, %sp"@}, ++@{address="0x000107c0",func-name="main",offset="4", ++inst="mov 2, %o0"@}, ++@{address="0x000107c4",func-name="main",offset="8", ++inst="sethi %hi(0x11800), %o2"@}, ++[@dots{}] ++@{address="0x0001081c",func-name="main",offset="96",inst="ret "@}, ++@{address="0x00010820",func-name="main",offset="100",inst="restore "@}] ++(gdb) ++@end smallexample ++ ++Disassemble 3 instructions from the start of @code{main}: ++ ++@smallexample ++(gdb) ++-data-disassemble -f basics.c -l 32 -n 3 -- 0 ++^done,asm_insns=[ ++@{address="0x000107bc",func-name="main",offset="0", ++inst="save %sp, -112, %sp"@}, ++@{address="0x000107c0",func-name="main",offset="4", ++inst="mov 2, %o0"@}, ++@{address="0x000107c4",func-name="main",offset="8", ++inst="sethi %hi(0x11800), %o2"@}] ++(gdb) ++@end smallexample ++ ++Disassemble 3 instructions from the start of @code{main} in mixed mode: ++ ++@smallexample ++(gdb) ++-data-disassemble -f basics.c -l 32 -n 3 -- 1 ++^done,asm_insns=[ ++src_and_asm_line=@{line="31", ++file="../../../src/gdb/testsuite/gdb.mi/basics.c", ++fullname="/absolute/path/to/src/gdb/testsuite/gdb.mi/basics.c", ++line_asm_insn=[@{address="0x000107bc", ++func-name="main",offset="0",inst="save %sp, -112, %sp"@}]@}, ++src_and_asm_line=@{line="32", ++file="../../../src/gdb/testsuite/gdb.mi/basics.c", ++fullname="/absolute/path/to/src/gdb/testsuite/gdb.mi/basics.c", ++line_asm_insn=[@{address="0x000107c0", ++func-name="main",offset="4",inst="mov 2, %o0"@}, ++@{address="0x000107c4",func-name="main",offset="8", ++inst="sethi %hi(0x11800), %o2"@}]@}] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-data-evaluate-expression} Command ++@findex -data-evaluate-expression ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-evaluate-expression @var{expr} ++@end smallexample ++ ++Evaluate @var{expr} as an expression. The expression could contain an ++inferior function call. The function call will execute synchronously. ++If the expression contains spaces, it must be enclosed in double quotes. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{print}, @samp{output}, and ++@samp{call}. In @code{gdbtk} only, there's a corresponding ++@samp{gdb_eval} command. ++ ++@subsubheading Example ++ ++In the following example, the numbers that precede the commands are the ++@dfn{tokens} described in @ref{GDB/MI Command Syntax, ,@sc{gdb/mi} ++Command Syntax}. Notice how @sc{gdb/mi} returns the same tokens in its ++output. ++ ++@smallexample ++211-data-evaluate-expression A ++211^done,value="1" ++(gdb) ++311-data-evaluate-expression &A ++311^done,value="0xefffeb7c" ++(gdb) ++411-data-evaluate-expression A+3 ++411^done,value="4" ++(gdb) ++511-data-evaluate-expression "A + 3" ++511^done,value="4" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-data-list-changed-registers} Command ++@findex -data-list-changed-registers ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-list-changed-registers ++@end smallexample ++ ++Display a list of the registers that have changed. ++ ++@subsubheading @value{GDBN} Command ++ ++@value{GDBN} doesn't have a direct analog for this command; @code{gdbtk} ++has the corresponding command @samp{gdb_changed_register_list}. ++ ++@subsubheading Example ++ ++On a PPC MBX board: ++ ++@smallexample ++(gdb) ++-exec-continue ++^running ++ ++(gdb) ++*stopped,reason="breakpoint-hit",disp="keep",bkptno="1",frame=@{ ++func="main",args=[],file="try.c",fullname="/home/foo/bar/try.c", ++line="5",arch="powerpc"@} ++(gdb) ++-data-list-changed-registers ++^done,changed-registers=["0","1","2","4","5","6","7","8","9", ++"10","11","13","14","15","16","17","18","19","20","21","22","23", ++"24","25","26","27","28","30","31","64","65","66","67","69"] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-data-list-register-names} Command ++@findex -data-list-register-names ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-list-register-names [ ( @var{regno} )+ ] ++@end smallexample ++ ++Show a list of register names for the current target. If no arguments ++are given, it shows a list of the names of all the registers. If ++integer numbers are given as arguments, it will print a list of the ++names of the registers corresponding to the arguments. To ensure ++consistency between a register name and its number, the output list may ++include empty register names. ++ ++@subsubheading @value{GDBN} Command ++ ++@value{GDBN} does not have a command which corresponds to ++@samp{-data-list-register-names}. In @code{gdbtk} there is a ++corresponding command @samp{gdb_regnames}. ++ ++@subsubheading Example ++ ++For the PPC MBX board: ++@smallexample ++(gdb) ++-data-list-register-names ++^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7", ++"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", ++"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", ++"r30","r31","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","f31", ++"", "pc","ps","cr","lr","ctr","xer"] ++(gdb) ++-data-list-register-names 1 2 3 ++^done,register-names=["r1","r2","r3"] ++(gdb) ++@end smallexample ++ ++@subheading The @code{-data-list-register-values} Command ++@findex -data-list-register-values ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-list-register-values ++ [ @code{--skip-unavailable} ] @var{fmt} [ ( @var{regno} )*] ++@end smallexample ++ ++Display the registers' contents. The format according to which the ++registers' contents are to be returned is given by @var{fmt}, followed ++by an optional list of numbers specifying the registers to display. A ++missing list of numbers indicates that the contents of all the ++registers must be returned. The @code{--skip-unavailable} option ++indicates that only the available registers are to be returned. ++ ++Allowed formats for @var{fmt} are: ++ ++@table @code ++@item x ++Hexadecimal ++@item o ++Octal ++@item t ++Binary ++@item d ++Decimal ++@item r ++Raw ++@item N ++Natural ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} commands are @samp{info reg}, @samp{info ++all-reg}, and (in @code{gdbtk}) @samp{gdb_fetch_registers}. ++ ++@subsubheading Example ++ ++For a PPC MBX board (note: line breaks are for readability only, they ++don't appear in the actual output): ++ ++@smallexample ++(gdb) ++-data-list-register-values r 64 65 ++^done,register-values=[@{number="64",value="0xfe00a300"@}, ++@{number="65",value="0x00029002"@}] ++(gdb) ++-data-list-register-values x ++^done,register-values=[@{number="0",value="0xfe0043c8"@}, ++@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@}, ++@{number="3",value="0x0"@},@{number="4",value="0xa"@}, ++@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@}, ++@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@}, ++@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@}, ++@{number="11",value="0x1"@},@{number="12",value="0x0"@}, ++@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@}, ++@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@}, ++@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@}, ++@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@}, ++@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@}, ++@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@}, ++@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@}, ++@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@}, ++@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@}, ++@{number="31",value="0x0"@},@{number="32",value="0x0"@}, ++@{number="33",value="0x0"@},@{number="34",value="0x0"@}, ++@{number="35",value="0x0"@},@{number="36",value="0x0"@}, ++@{number="37",value="0x0"@},@{number="38",value="0x0"@}, ++@{number="39",value="0x0"@},@{number="40",value="0x0"@}, ++@{number="41",value="0x0"@},@{number="42",value="0x0"@}, ++@{number="43",value="0x0"@},@{number="44",value="0x0"@}, ++@{number="45",value="0x0"@},@{number="46",value="0x0"@}, ++@{number="47",value="0x0"@},@{number="48",value="0x0"@}, ++@{number="49",value="0x0"@},@{number="50",value="0x0"@}, ++@{number="51",value="0x0"@},@{number="52",value="0x0"@}, ++@{number="53",value="0x0"@},@{number="54",value="0x0"@}, ++@{number="55",value="0x0"@},@{number="56",value="0x0"@}, ++@{number="57",value="0x0"@},@{number="58",value="0x0"@}, ++@{number="59",value="0x0"@},@{number="60",value="0x0"@}, ++@{number="61",value="0x0"@},@{number="62",value="0x0"@}, ++@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@}, ++@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@}, ++@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@}, ++@{number="69",value="0x20002b03"@}] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-data-read-memory} Command ++@findex -data-read-memory ++ ++This command is deprecated, use @code{-data-read-memory-bytes} instead. ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-read-memory [ -o @var{byte-offset} ] ++ @var{address} @var{word-format} @var{word-size} ++ @var{nr-rows} @var{nr-cols} [ @var{aschar} ] ++@end smallexample ++ ++@noindent ++where: ++ ++@table @samp ++@item @var{address} ++An expression specifying the address of the first memory word to be ++read. Complex expressions containing embedded white space should be ++quoted using the C convention. ++ ++@item @var{word-format} ++The format to be used to print the memory words. The notation is the ++same as for @value{GDBN}'s @code{print} command (@pxref{Output Formats, ++,Output Formats}). ++ ++@item @var{word-size} ++The size of each memory word in bytes. ++ ++@item @var{nr-rows} ++The number of rows in the output table. ++ ++@item @var{nr-cols} ++The number of columns in the output table. ++ ++@item @var{aschar} ++If present, indicates that each row should include an @sc{ascii} dump. The ++value of @var{aschar} is used as a padding character when a byte is not a ++member of the printable @sc{ascii} character set (printable @sc{ascii} ++characters are those whose code is between 32 and 126, inclusively). ++ ++@item @var{byte-offset} ++An offset to add to the @var{address} before fetching memory. ++@end table ++ ++This command displays memory contents as a table of @var{nr-rows} by ++@var{nr-cols} words, each word being @var{word-size} bytes. In total, ++@code{@var{nr-rows} * @var{nr-cols} * @var{word-size}} bytes are read ++(returned as @samp{total-bytes}). Should less than the requested number ++of bytes be returned by the target, the missing words are identified ++using @samp{N/A}. The number of bytes read from the target is returned ++in @samp{nr-bytes} and the starting address used to read memory in ++@samp{addr}. ++ ++The address of the next/previous row or page is available in ++@samp{next-row} and @samp{prev-row}, @samp{next-page} and ++@samp{prev-page}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{x}. @code{gdbtk} has ++@samp{gdb_get_mem} memory read command. ++ ++@subsubheading Example ++ ++Read six bytes of memory starting at @code{bytes+6} but then offset by ++@code{-6} bytes. Format as three rows of two columns. One byte per ++word. Display each word in hex. ++ ++@smallexample ++(gdb) ++9-data-read-memory -o -6 -- bytes+6 x 1 3 2 ++9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", ++next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", ++prev-page="0x0000138a",memory=[ ++@{addr="0x00001390",data=["0x00","0x01"]@}, ++@{addr="0x00001392",data=["0x02","0x03"]@}, ++@{addr="0x00001394",data=["0x04","0x05"]@}] ++(gdb) ++@end smallexample ++ ++Read two bytes of memory starting at address @code{shorts + 64} and ++display as a single word formatted in decimal. ++ ++@smallexample ++(gdb) ++5-data-read-memory shorts+64 d 2 1 1 ++5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", ++next-row="0x00001512",prev-row="0x0000150e", ++next-page="0x00001512",prev-page="0x0000150e",memory=[ ++@{addr="0x00001510",data=["128"]@}] ++(gdb) ++@end smallexample ++ ++Read thirty two bytes of memory starting at @code{bytes+16} and format ++as eight rows of four columns. Include a string encoding with @samp{x} ++used as the non-printable character. ++ ++@smallexample ++(gdb) ++4-data-read-memory bytes+16 x 1 8 4 x ++4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", ++next-row="0x000013c0",prev-row="0x0000139c", ++next-page="0x000013c0",prev-page="0x00001380",memory=[ ++@{addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"@}, ++@{addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"@}, ++@{addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"@}, ++@{addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"@}, ++@{addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"@}, ++@{addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"@}, ++@{addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"@}, ++@{addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"@}] ++(gdb) ++@end smallexample ++ ++@subheading The @code{-data-read-memory-bytes} Command ++@findex -data-read-memory-bytes ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-read-memory-bytes [ -o @var{offset} ] ++ @var{address} @var{count} ++@end smallexample ++ ++@noindent ++where: ++ ++@table @samp ++@item @var{address} ++An expression specifying the address of the first addressable memory unit ++to be read. Complex expressions containing embedded white space should be ++quoted using the C convention. ++ ++@item @var{count} ++The number of addressable memory units to read. This should be an integer ++literal. ++ ++@item @var{offset} ++The offset relative to @var{address} at which to start reading. This ++should be an integer literal. This option is provided so that a frontend ++is not required to first evaluate address and then perform address ++arithmetics itself. ++ ++@end table ++ ++This command attempts to read all accessible memory regions in the ++specified range. First, all regions marked as unreadable in the memory ++map (if one is defined) will be skipped. @xref{Memory Region ++Attributes}. Second, @value{GDBN} will attempt to read the remaining ++regions. For each one, if reading full region results in an errors, ++@value{GDBN} will try to read a subset of the region. ++ ++In general, every single memory unit in the region may be readable or not, ++and the only way to read every readable unit is to try a read at ++every address, which is not practical. Therefore, @value{GDBN} will ++attempt to read all accessible memory units at either beginning or the end ++of the region, using a binary division scheme. This heuristic works ++well for reading across a memory map boundary. Note that if a region ++has a readable range that is neither at the beginning or the end, ++@value{GDBN} will not read it. ++ ++The result record (@pxref{GDB/MI Result Records}) that is output of ++the command includes a field named @samp{memory} whose content is a ++list of tuples. Each tuple represent a successfully read memory block ++and has the following fields: ++ ++@table @code ++@item begin ++The start address of the memory block, as hexadecimal literal. ++ ++@item end ++The end address of the memory block, as hexadecimal literal. ++ ++@item offset ++The offset of the memory block, as hexadecimal literal, relative to ++the start address passed to @code{-data-read-memory-bytes}. ++ ++@item contents ++The contents of the memory block, in hex. ++ ++@end table ++ ++ ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{x}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-data-read-memory-bytes &a 10 ++^done,memory=[@{begin="0xbffff154",offset="0x00000000", ++ end="0xbffff15e", ++ contents="01000000020000000300"@}] ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-data-write-memory-bytes} Command ++@findex -data-write-memory-bytes ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -data-write-memory-bytes @var{address} @var{contents} ++ -data-write-memory-bytes @var{address} @var{contents} @r{[}@var{count}@r{]} ++@end smallexample ++ ++@noindent ++where: ++ ++@table @samp ++@item @var{address} ++An expression specifying the address of the first addressable memory unit ++to be written. Complex expressions containing embedded white space should ++be quoted using the C convention. ++ ++@item @var{contents} ++The hex-encoded data to write. It is an error if @var{contents} does ++not represent an integral number of addressable memory units. ++ ++@item @var{count} ++Optional argument indicating the number of addressable memory units to be ++written. If @var{count} is greater than @var{contents}' length, ++@value{GDBN} will repeatedly write @var{contents} until it fills ++@var{count} memory units. ++ ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++There's no corresponding @value{GDBN} command. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-data-write-memory-bytes &a "aabbccdd" ++^done ++(gdb) ++@end smallexample ++ ++@smallexample ++(gdb) ++-data-write-memory-bytes &a "aabbccdd" 16e ++^done ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Tracepoint Commands ++@section @sc{gdb/mi} Tracepoint Commands ++ ++The commands defined in this section implement MI support for ++tracepoints. For detailed introduction, see @ref{Tracepoints}. ++ ++@subheading The @code{-trace-find} Command ++@findex -trace-find ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-find @var{mode} [@var{parameters}@dots{}] ++@end smallexample ++ ++Find a trace frame using criteria defined by @var{mode} and ++@var{parameters}. The following table lists permissible ++modes and their parameters. For details of operation, see @ref{tfind}. ++ ++@table @samp ++ ++@item none ++No parameters are required. Stops examining trace frames. ++ ++@item frame-number ++An integer is required as parameter. Selects tracepoint frame with ++that index. ++ ++@item tracepoint-number ++An integer is required as parameter. Finds next ++trace frame that corresponds to tracepoint with the specified number. ++ ++@item pc ++An address is required as parameter. Finds ++next trace frame that corresponds to any tracepoint at the specified ++address. ++ ++@item pc-inside-range ++Two addresses are required as parameters. Finds next trace ++frame that corresponds to a tracepoint at an address inside the ++specified range. Both bounds are considered to be inside the range. ++ ++@item pc-outside-range ++Two addresses are required as parameters. Finds ++next trace frame that corresponds to a tracepoint at an address outside ++the specified range. Both bounds are considered to be inside the range. ++ ++@item line ++Line specification is required as parameter. @xref{Specify Location}. ++Finds next trace frame that corresponds to a tracepoint at ++the specified location. ++ ++@end table ++ ++If @samp{none} was passed as @var{mode}, the response does not ++have fields. Otherwise, the response may have the following fields: ++ ++@table @samp ++@item found ++This field has either @samp{0} or @samp{1} as the value, depending ++on whether a matching tracepoint was found. ++ ++@item traceframe ++The index of the found traceframe. This field is present iff ++the @samp{found} field has value of @samp{1}. ++ ++@item tracepoint ++The index of the found tracepoint. This field is present iff ++the @samp{found} field has value of @samp{1}. ++ ++@item frame ++The information about the frame corresponding to the found trace ++frame. This field is present only if a trace frame was found. ++@xref{GDB/MI Frame Information}, for description of this field. ++ ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tfind}. ++ ++@subheading -trace-define-variable ++@findex -trace-define-variable ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-define-variable @var{name} [ @var{value} ] ++@end smallexample ++ ++Create trace variable @var{name} if it does not exist. If ++@var{value} is specified, sets the initial value of the specified ++trace variable to that value. Note that the @var{name} should start ++with the @samp{$} character. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tvariable}. ++ ++@subheading The @code{-trace-frame-collected} Command ++@findex -trace-frame-collected ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-frame-collected ++ [--var-print-values @var{var_pval}] ++ [--comp-print-values @var{comp_pval}] ++ [--registers-format @var{regformat}] ++ [--memory-contents] ++@end smallexample ++ ++This command returns the set of collected objects, register names, ++trace state variable names, memory ranges and computed expressions ++that have been collected at a particular trace frame. The optional ++parameters to the command affect the output format in different ways. ++See the output description table below for more details. ++ ++The reported names can be used in the normal manner to create ++varobjs and inspect the objects themselves. The items returned by ++this command are categorized so that it is clear which is a variable, ++which is a register, which is a trace state variable, which is a ++memory range and which is a computed expression. ++ ++For instance, if the actions were ++@smallexample ++collect myVar, myArray[myIndex], myObj.field, myPtr->field, myCount + 2 ++collect *(int*)0xaf02bef0@@40 ++@end smallexample ++ ++@noindent ++the object collected in its entirety would be @code{myVar}. The ++object @code{myArray} would be partially collected, because only the ++element at index @code{myIndex} would be collected. The remaining ++objects would be computed expressions. ++ ++An example output would be: ++ ++@smallexample ++(gdb) ++-trace-frame-collected ++^done, ++ explicit-variables=[@{name="myVar",value="1"@}], ++ computed-expressions=[@{name="myArray[myIndex]",value="0"@}, ++ @{name="myObj.field",value="0"@}, ++ @{name="myPtr->field",value="1"@}, ++ @{name="myCount + 2",value="3"@}, ++ @{name="$tvar1 + 1",value="43970027"@}], ++ registers=[@{number="0",value="0x7fe2c6e79ec8"@}, ++ @{number="1",value="0x0"@}, ++ @{number="2",value="0x4"@}, ++ ... ++ @{number="125",value="0x0"@}], ++ tvars=[@{name="$tvar1",current="43970026"@}], ++ memory=[@{address="0x0000000000602264",length="4"@}, ++ @{address="0x0000000000615bc0",length="4"@}] ++(gdb) ++@end smallexample ++ ++Where: ++ ++@table @code ++@item explicit-variables ++The set of objects that have been collected in their entirety (as ++opposed to collecting just a few elements of an array or a few struct ++members). For each object, its name and value are printed. ++The @code{--var-print-values} option affects how or whether the value ++field is output. If @var{var_pval} is 0, then print only the names; ++if it is 1, print also their values; and if it is 2, print the name, ++type and value for simple data types, and the name and type for ++arrays, structures and unions. ++ ++@item computed-expressions ++The set of computed expressions that have been collected at the ++current trace frame. The @code{--comp-print-values} option affects ++this set like the @code{--var-print-values} option affects the ++@code{explicit-variables} set. See above. ++ ++@item registers ++The registers that have been collected at the current trace frame. ++For each register collected, the name and current value are returned. ++The value is formatted according to the @code{--registers-format} ++option. See the @command{-data-list-register-values} command for a ++list of the allowed formats. The default is @samp{x}. ++ ++@item tvars ++The trace state variables that have been collected at the current ++trace frame. For each trace state variable collected, the name and ++current value are returned. ++ ++@item memory ++The set of memory ranges that have been collected at the current trace ++frame. Its content is a list of tuples. Each tuple represents a ++collected memory range and has the following fields: ++ ++@table @code ++@item address ++The start address of the memory range, as hexadecimal literal. ++ ++@item length ++The length of the memory range, as decimal literal. ++ ++@item contents ++The contents of the memory block, in hex. This field is only present ++if the @code{--memory-contents} option is specified. ++ ++@end table ++ ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++There is no corresponding @value{GDBN} command. ++ ++@subsubheading Example ++ ++@subheading -trace-list-variables ++@findex -trace-list-variables ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-list-variables ++@end smallexample ++ ++Return a table of all defined trace variables. Each element of the ++table has the following fields: ++ ++@table @samp ++@item name ++The name of the trace variable. This field is always present. ++ ++@item initial ++The initial value. This is a 64-bit signed integer. This ++field is always present. ++ ++@item current ++The value the trace variable has at the moment. This is a 64-bit ++signed integer. This field is absent iff current value is ++not defined, for example if the trace was never run, or is ++presently running. ++ ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tvariables}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-trace-list-variables ++^done,trace-variables=@{nr_rows="1",nr_cols="3", ++hdr=[@{width="15",alignment="-1",col_name="name",colhdr="Name"@}, ++ @{width="11",alignment="-1",col_name="initial",colhdr="Initial"@}, ++ @{width="11",alignment="-1",col_name="current",colhdr="Current"@}], ++body=[variable=@{name="$trace_timestamp",initial="0"@} ++ variable=@{name="$foo",initial="10",current="15"@}]@} ++(gdb) ++@end smallexample ++ ++@subheading -trace-save ++@findex -trace-save ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-save [ -r ] [ -ctf ] @var{filename} ++@end smallexample ++ ++Saves the collected trace data to @var{filename}. Without the ++@samp{-r} option, the data is downloaded from the target and saved ++in a local file. With the @samp{-r} option the target is asked ++to perform the save. ++ ++By default, this command will save the trace in the tfile format. You can ++supply the optional @samp{-ctf} argument to save it the CTF format. See ++@ref{Trace Files} for more information about CTF. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tsave}. ++ ++ ++@subheading -trace-start ++@findex -trace-start ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-start ++@end smallexample ++ ++Starts a tracing experiment. The result of this command does not ++have any fields. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tstart}. ++ ++@subheading -trace-status ++@findex -trace-status ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-status ++@end smallexample ++ ++Obtains the status of a tracing experiment. The result may include ++the following fields: ++ ++@table @samp ++ ++@item supported ++May have a value of either @samp{0}, when no tracing operations are ++supported, @samp{1}, when all tracing operations are supported, or ++@samp{file} when examining trace file. In the latter case, examining ++of trace frame is possible but new tracing experiement cannot be ++started. This field is always present. ++ ++@item running ++May have a value of either @samp{0} or @samp{1} depending on whether ++tracing experiement is in progress on target. This field is present ++if @samp{supported} field is not @samp{0}. ++ ++@item stop-reason ++Report the reason why the tracing was stopped last time. This field ++may be absent iff tracing was never stopped on target yet. The ++value of @samp{request} means the tracing was stopped as result of ++the @code{-trace-stop} command. The value of @samp{overflow} means ++the tracing buffer is full. The value of @samp{disconnection} means ++tracing was automatically stopped when @value{GDBN} has disconnected. ++The value of @samp{passcount} means tracing was stopped when a ++tracepoint was passed a maximal number of times for that tracepoint. ++This field is present if @samp{supported} field is not @samp{0}. ++ ++@item stopping-tracepoint ++The number of tracepoint whose passcount as exceeded. This field is ++present iff the @samp{stop-reason} field has the value of ++@samp{passcount}. ++ ++@item frames ++@itemx frames-created ++The @samp{frames} field is a count of the total number of trace frames ++in the trace buffer, while @samp{frames-created} is the total created ++during the run, including ones that were discarded, such as when a ++circular trace buffer filled up. Both fields are optional. ++ ++@item buffer-size ++@itemx buffer-free ++These fields tell the current size of the tracing buffer and the ++remaining space. These fields are optional. ++ ++@item circular ++The value of the circular trace buffer flag. @code{1} means that the ++trace buffer is circular and old trace frames will be discarded if ++necessary to make room, @code{0} means that the trace buffer is linear ++and may fill up. ++ ++@item disconnected ++The value of the disconnected tracing flag. @code{1} means that ++tracing will continue after @value{GDBN} disconnects, @code{0} means ++that the trace run will stop. ++ ++@item trace-file ++The filename of the trace file being examined. This field is ++optional, and only present when examining a trace file. ++ ++@end table ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tstatus}. ++ ++@subheading -trace-stop ++@findex -trace-stop ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -trace-stop ++@end smallexample ++ ++Stops a tracing experiment. The result of this command has the same ++fields as @code{-trace-status}, except that the @samp{supported} and ++@samp{running} fields are not output. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{tstop}. ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Symbol Query ++@section @sc{gdb/mi} Symbol Query Commands ++ ++ ++@ignore ++@subheading The @code{-symbol-info-address} Command ++@findex -symbol-info-address ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-address @var{symbol} ++@end smallexample ++ ++Describe where @var{symbol} is stored. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info address}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-info-file} Command ++@findex -symbol-info-file ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-file ++@end smallexample ++ ++Show the file for the symbol. ++ ++@subsubheading @value{GDBN} Command ++ ++There's no equivalent @value{GDBN} command. @code{gdbtk} has ++@samp{gdb_find_file}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++@subheading The @code{-symbol-info-functions} Command ++@findex -symbol-info-functions ++@anchor{-symbol-info-functions} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-functions [--include-nondebug] ++ [--type @var{type_regexp}] ++ [--name @var{name_regexp}] ++ [--max-results @var{limit}] ++@end smallexample ++ ++@noindent ++Return a list containing the names and types for all global functions ++taken from the debug information. The functions are grouped by source ++file, and shown with the line number on which each function is ++defined. ++ ++The @code{--include-nondebug} option causes the output to include ++code symbols from the symbol table. ++ ++The options @code{--type} and @code{--name} allow the symbols returned ++to be filtered based on either the name of the function, or the type ++signature of the function. ++ ++The option @code{--max-results} restricts the command to return no ++more than @var{limit} results. If exactly @var{limit} results are ++returned then there might be additional results available if a higher ++limit is used. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info functions}. ++ ++@subsubheading Example ++@smallexample ++@group ++(gdb) ++-symbol-info-functions ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"@}, ++ @{line="42", name="main", type="int ()", ++ description="int main();"@}, ++ @{line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="33", name="f2", type="float (another_float_t)", ++ description="float f2(another_float_t);"@}, ++ @{line="39", name="f3", type="int (another_int_t)", ++ description="int f3(another_int_t);"@}, ++ @{line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-functions --name f1 ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-functions --type void ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-functions --include-nondebug ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="36", name="f4", type="void (int *)", ++ description="void f4(int *);"@}, ++ @{line="42", name="main", type="int ()", ++ description="int main();"@}, ++ @{line="30", name="f1", type="my_int_t (int, int)", ++ description="static my_int_t f1(int, int);"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="33", name="f2", type="float (another_float_t)", ++ description="float f2(another_float_t);"@}, ++ @{line="39", name="f3", type="int (another_int_t)", ++ description="int f3(another_int_t);"@}, ++ @{line="27", name="f1", type="another_float_t (int)", ++ description="static another_float_t f1(int);"@}]@}], ++ nondebug= ++ [@{address="0x0000000000400398",name="_init"@}, ++ @{address="0x00000000004003b0",name="_start"@}, ++ ... ++ ]@} ++@end group ++@end smallexample ++ ++@subheading The @code{-symbol-info-module-functions} Command ++@findex -symbol-info-module-functions ++@anchor{-symbol-info-module-functions} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-module-functions [--module @var{module_regexp}] ++ [--name @var{name_regexp}] ++ [--type @var{type_regexp}] ++@end smallexample ++ ++@noindent ++Return a list containing the names of all known functions within all ++know Fortran modules. The functions are grouped by source file and ++containing module, and shown with the line number on which each ++function is defined. ++ ++The option @code{--module} only returns results for modules matching ++@var{module_regexp}. The option @code{--name} only returns functions ++whose name matches @var{name_regexp}, and @code{--type} only returns ++functions whose type matches @var{type_regexp}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info module functions}. ++ ++@subsubheading Example ++ ++@smallexample ++@group ++(gdb) ++-symbol-info-module-functions ++^done,symbols= ++ [@{module="mod1", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="21",name="mod1::check_all",type="void (void)", ++ description="void mod1::check_all(void);"@}]@}]@}, ++ @{module="mod2", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="30",name="mod2::check_var_i",type="void (void)", ++ description="void mod2::check_var_i(void);"@}]@}]@}, ++ @{module="mod3", ++ files=[@{filename="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/projec/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="21",name="mod3::check_all",type="void (void)", ++ description="void mod3::check_all(void);"@}, ++ @{line="27",name="mod3::check_mod2",type="void (void)", ++ description="void mod3::check_mod2(void);"@}]@}]@}, ++ @{module="modmany", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="35",name="modmany::check_some",type="void (void)", ++ description="void modmany::check_some(void);"@}]@}]@}, ++ @{module="moduse", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="44",name="moduse::check_all",type="void (void)", ++ description="void moduse::check_all(void);"@}, ++ @{line="49",name="moduse::check_var_x",type="void (void)", ++ description="void moduse::check_var_x(void);"@}]@}]@}] ++@end group ++@end smallexample ++ ++@subheading The @code{-symbol-info-module-variables} Command ++@findex -symbol-info-module-variables ++@anchor{-symbol-info-module-variables} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-module-variables [--module @var{module_regexp}] ++ [--name @var{name_regexp}] ++ [--type @var{type_regexp}] ++@end smallexample ++ ++@noindent ++Return a list containing the names of all known variables within all ++know Fortran modules. The variables are grouped by source file and ++containing module, and shown with the line number on which each ++variable is defined. ++ ++The option @code{--module} only returns results for modules matching ++@var{module_regexp}. The option @code{--name} only returns variables ++whose name matches @var{name_regexp}, and @code{--type} only returns ++variables whose type matches @var{type_regexp}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info module variables}. ++ ++@subsubheading Example ++ ++@smallexample ++@group ++(gdb) ++-symbol-info-module-variables ++^done,symbols= ++ [@{module="mod1", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="18",name="mod1::var_const",type="integer(kind=4)", ++ description="integer(kind=4) mod1::var_const;"@}, ++ @{line="17",name="mod1::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod1::var_i;"@}]@}]@}, ++ @{module="mod2", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="28",name="mod2::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod2::var_i;"@}]@}]@}, ++ @{module="mod3", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="18",name="mod3::mod1",type="integer(kind=4)", ++ description="integer(kind=4) mod3::mod1;"@}, ++ @{line="17",name="mod3::mod2",type="integer(kind=4)", ++ description="integer(kind=4) mod3::mod2;"@}, ++ @{line="19",name="mod3::var_i",type="integer(kind=4)", ++ description="integer(kind=4) mod3::var_i;"@}]@}]@}, ++ @{module="modmany", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="33",name="modmany::var_a",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_a;"@}, ++ @{line="33",name="modmany::var_b",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_b;"@}, ++ @{line="33",name="modmany::var_c",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_c;"@}, ++ @{line="33",name="modmany::var_i",type="integer(kind=4)", ++ description="integer(kind=4) modmany::var_i;"@}]@}]@}, ++ @{module="moduse", ++ files=[@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="42",name="moduse::var_x",type="integer(kind=4)", ++ description="integer(kind=4) moduse::var_x;"@}, ++ @{line="42",name="moduse::var_y",type="integer(kind=4)", ++ description="integer(kind=4) moduse::var_y;"@}]@}]@}] ++@end group ++@end smallexample ++ ++@subheading The @code{-symbol-info-modules} Command ++@findex -symbol-info-modules ++@anchor{-symbol-info-modules} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-modules [--name @var{name_regexp}] ++ [--max-results @var{limit}] ++ ++@end smallexample ++ ++@noindent ++Return a list containing the names of all known Fortran modules. The ++modules are grouped by source file, and shown with the line number on ++which each modules is defined. ++ ++The option @code{--name} allows the modules returned to be filtered ++based the name of the module. ++ ++The option @code{--max-results} restricts the command to return no ++more than @var{limit} results. If exactly @var{limit} results are ++returned then there might be additional results available if a higher ++limit is used. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info modules}. ++ ++@subsubheading Example ++@smallexample ++@group ++(gdb) ++-symbol-info-modules ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="16",name="mod1"@}, ++ @{line="22",name="mod2"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="16",name="mod3"@}, ++ @{line="22",name="modmany"@}, ++ @{line="26",name="moduse"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-modules --name mod[123] ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules-2.f90", ++ symbols=[@{line="16",name="mod1"@}, ++ @{line="22",name="mod2"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-fortran-modules.f90", ++ symbols=[@{line="16",name="mod3"@}]@}]@} ++@end group ++@end smallexample ++ ++@subheading The @code{-symbol-info-types} Command ++@findex -symbol-info-types ++@anchor{-symbol-info-types} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-types [--name @var{name_regexp}] ++ [--max-results @var{limit}] ++ ++@end smallexample ++ ++@noindent ++Return a list of all defined types. The types are grouped by source ++file, and shown with the line number on which each user defined type ++is defined. Some base types are not defined in the source code but ++are added to the debug information by the compiler, for example ++@code{int}, @code{float}, etc.; these types do not have an associated ++line number. ++ ++The option @code{--name} allows the list of types returned to be ++filtered by name. ++ ++The option @code{--max-results} restricts the command to return no ++more than @var{limit} results. If exactly @var{limit} results are ++returned then there might be additional results available if a higher ++limit is used. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info types}. ++ ++@subsubheading Example ++@smallexample ++@group ++(gdb) ++-symbol-info-types ++^done,symbols= ++ @{debug= ++ [@{filename="gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{name="float"@}, ++ @{name="int"@}, ++ @{line="27",name="typedef int my_int_t;"@}]@}, ++ @{filename="gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="24",name="typedef float another_float_t;"@}, ++ @{line="23",name="typedef int another_int_t;"@}, ++ @{name="float"@}, ++ @{name="int"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-types --name _int_ ++^done,symbols= ++ @{debug= ++ [@{filename="gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="27",name="typedef int my_int_t;"@}]@}, ++ @{filename="gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="23",name="typedef int another_int_t;"@}]@}]@} ++@end group ++@end smallexample ++ ++@subheading The @code{-symbol-info-variables} Command ++@findex -symbol-info-variables ++@anchor{-symbol-info-variables} ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-variables [--include-nondebug] ++ [--type @var{type_regexp}] ++ [--name @var{name_regexp}] ++ [--max-results @var{limit}] ++ ++@end smallexample ++ ++@noindent ++Return a list containing the names and types for all global variables ++taken from the debug information. The variables are grouped by source ++file, and shown with the line number on which each variable is ++defined. ++ ++The @code{--include-nondebug} option causes the output to include ++data symbols from the symbol table. ++ ++The options @code{--type} and @code{--name} allow the symbols returned ++to be filtered based on either the name of the variable, or the type ++of the variable. ++ ++The option @code{--max-results} restricts the command to return no ++more than @var{limit} results. If exactly @var{limit} results are ++returned then there might be additional results available if a higher ++limit is used. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info variables}. ++ ++@subsubheading Example ++@smallexample ++@group ++(gdb) ++-symbol-info-variables ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="25",name="global_f1",type="float", ++ description="static float global_f1;"@}, ++ @{line="24",name="global_i1",type="int", ++ description="static int global_i1;"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="21",name="global_f2",type="int", ++ description="int global_f2;"@}, ++ @{line="20",name="global_i2",type="int", ++ description="int global_i2;"@}, ++ @{line="19",name="global_f1",type="float", ++ description="static float global_f1;"@}, ++ @{line="18",name="global_i1",type="int", ++ description="static int global_i1;"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-variables --name f1 ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="25",name="global_f1",type="float", ++ description="static float global_f1;"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="19",name="global_f1",type="float", ++ description="static float global_f1;"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-variables --type float ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="25",name="global_f1",type="float", ++ description="static float global_f1;"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="19",name="global_f1",type="float", ++ description="static float global_f1;"@}]@}]@} ++@end group ++@group ++(gdb) ++-symbol-info-variables --include-nondebug ++^done,symbols= ++ @{debug= ++ [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", ++ symbols=[@{line="25",name="global_f1",type="float", ++ description="static float global_f1;"@}, ++ @{line="24",name="global_i1",type="int", ++ description="static int global_i1;"@}]@}, ++ @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", ++ symbols=[@{line="21",name="global_f2",type="int", ++ description="int global_f2;"@}, ++ @{line="20",name="global_i2",type="int", ++ description="int global_i2;"@}, ++ @{line="19",name="global_f1",type="float", ++ description="static float global_f1;"@}, ++ @{line="18",name="global_i1",type="int", ++ description="static int global_i1;"@}]@}], ++ nondebug= ++ [@{address="0x00000000004005d0",name="_IO_stdin_used"@}, ++ @{address="0x00000000004005d8",name="__dso_handle"@} ++ ... ++ ]@} ++@end group ++@end smallexample ++ ++@ignore ++@subheading The @code{-symbol-info-line} Command ++@findex -symbol-info-line ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-line ++@end smallexample ++ ++Show the core addresses of the code for a source line. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info line}. ++@code{gdbtk} has the @samp{gdb_get_line} and @samp{gdb_get_file} commands. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-info-symbol} Command ++@findex -symbol-info-symbol ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-info-symbol @var{addr} ++@end smallexample ++ ++Describe what symbol is at location @var{addr}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info symbol}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-list-functions} Command ++@findex -symbol-list-functions ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-list-functions ++@end smallexample ++ ++List the functions in the executable. ++ ++@subsubheading @value{GDBN} Command ++ ++@samp{info functions} in @value{GDBN}, @samp{gdb_listfunc} and ++@samp{gdb_search} in @code{gdbtk}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-symbol-list-lines} Command ++@findex -symbol-list-lines ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-list-lines @var{filename} ++@end smallexample ++ ++Print the list of lines that contain code and their associated program ++addresses for the given source filename. The entries are sorted in ++ascending PC order. ++ ++@subsubheading @value{GDBN} Command ++ ++There is no corresponding @value{GDBN} command. ++ ++@subsubheading Example ++@smallexample ++(gdb) ++-symbol-list-lines basics.c ++^done,lines=[@{pc="0x08048554",line="7"@},@{pc="0x0804855a",line="8"@}] ++(gdb) ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-symbol-list-types} Command ++@findex -symbol-list-types ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-list-types ++@end smallexample ++ ++List all the type names. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding commands are @samp{info types} in @value{GDBN}, ++@samp{gdb_search} in @code{gdbtk}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-list-variables} Command ++@findex -symbol-list-variables ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-list-variables ++@end smallexample ++ ++List all the global and static variable names. ++ ++@subsubheading @value{GDBN} Command ++ ++@samp{info variables} in @value{GDBN}, @samp{gdb_search} in @code{gdbtk}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-locate} Command ++@findex -symbol-locate ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-locate ++@end smallexample ++ ++@subsubheading @value{GDBN} Command ++ ++@samp{gdb_loc} in @code{gdbtk}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-symbol-type} Command ++@findex -symbol-type ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -symbol-type @var{variable} ++@end smallexample ++ ++Show type of @var{variable}. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{ptype}, @code{gdbtk} has ++@samp{gdb_obj_variable}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI File Commands ++@section @sc{gdb/mi} File Commands ++ ++This section describes the GDB/MI commands to specify executable file names ++and to read in and obtain symbol table information. ++ ++@subheading The @code{-file-exec-and-symbols} Command ++@findex -file-exec-and-symbols ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-exec-and-symbols @var{file} ++@end smallexample ++ ++Specify the executable file to be debugged. This file is the one from ++which the symbol table is also read. If no file is specified, the ++command clears the executable and symbol information. If breakpoints ++are set when using this command with no arguments, @value{GDBN} will produce ++error messages. Otherwise, no output is produced, except a completion ++notification. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{file}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-file-exec-file} Command ++@findex -file-exec-file ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-exec-file @var{file} ++@end smallexample ++ ++Specify the executable file to be debugged. Unlike ++@samp{-file-exec-and-symbols}, the symbol table is @emph{not} read ++from this file. If used without argument, @value{GDBN} clears the information ++about the executable file. No output is produced, except a completion ++notification. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{exec-file}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++^done ++(gdb) ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-file-list-exec-sections} Command ++@findex -file-list-exec-sections ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-list-exec-sections ++@end smallexample ++ ++List the sections of the current executable file. ++ ++@subsubheading @value{GDBN} Command ++ ++The @value{GDBN} command @samp{info file} shows, among the rest, the same ++information as this command. @code{gdbtk} has a corresponding command ++@samp{gdb_load_info}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-file-list-exec-source-file} Command ++@findex -file-list-exec-source-file ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-list-exec-source-file ++@end smallexample ++ ++List the line number, the current source file, and the absolute path ++to the current source file for the current executable. The macro ++information field has a value of @samp{1} or @samp{0} depending on ++whether or not the file includes preprocessor macro information. ++ ++@subsubheading @value{GDBN} Command ++ ++The @value{GDBN} equivalent is @samp{info source} ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++123-file-list-exec-source-file ++123^done,line="1",file="foo.c",fullname="/home/bar/foo.c,macro-info="1" ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-file-list-exec-source-files} Command ++@findex -file-list-exec-source-files ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-list-exec-source-files ++@end smallexample ++ ++List the source files for the current executable. ++ ++It will always output both the filename and fullname (absolute file ++name) of a source file. ++ ++@subsubheading @value{GDBN} Command ++ ++The @value{GDBN} equivalent is @samp{info sources}. ++@code{gdbtk} has an analogous command @samp{gdb_listfiles}. ++ ++@subsubheading Example ++@smallexample ++(gdb) ++-file-list-exec-source-files ++^done,files=[ ++@{file=foo.c,fullname=/home/foo.c@}, ++@{file=/home/bar.c,fullname=/home/bar.c@}, ++@{file=gdb_could_not_find_fullpath.c@}] ++(gdb) ++@end smallexample ++ ++@subheading The @code{-file-list-shared-libraries} Command ++@findex -file-list-shared-libraries ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-list-shared-libraries [ @var{regexp} ] ++@end smallexample ++ ++List the shared libraries in the program. ++With a regular expression @var{regexp}, only those libraries whose ++names match @var{regexp} are listed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info shared}. The fields ++have a similar meaning to the @code{=library-loaded} notification. ++The @code{ranges} field specifies the multiple segments belonging to this ++library. Each range has the following fields: ++ ++@table @samp ++@item from ++The address defining the inclusive lower bound of the segment. ++@item to ++The address defining the exclusive upper bound of the segment. ++@end table ++ ++@subsubheading Example ++@smallexample ++(gdb) ++-file-list-exec-source-files ++^done,shared-libraries=[ ++@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@}, ++@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}] ++(gdb) ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-file-list-symbol-files} Command ++@findex -file-list-symbol-files ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-list-symbol-files ++@end smallexample ++ ++List symbol files. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info file} (part of it). ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-file-symbol-file} Command ++@findex -file-symbol-file ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -file-symbol-file @var{file} ++@end smallexample ++ ++Read symbol table info from the specified @var{file} argument. When ++used without arguments, clears @value{GDBN}'s symbol table info. No output is ++produced, except for a completion notification. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{symbol-file}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ++^done ++(gdb) ++@end smallexample ++ ++@ignore ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Memory Overlay Commands ++@section @sc{gdb/mi} Memory Overlay Commands ++ ++The memory overlay commands are not implemented. ++ ++@c @subheading -overlay-auto ++ ++@c @subheading -overlay-list-mapping-state ++ ++@c @subheading -overlay-list-overlays ++ ++@c @subheading -overlay-map ++ ++@c @subheading -overlay-off ++ ++@c @subheading -overlay-on ++ ++@c @subheading -overlay-unmap ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Signal Handling Commands ++@section @sc{gdb/mi} Signal Handling Commands ++ ++Signal handling commands are not implemented. ++ ++@c @subheading -signal-handle ++ ++@c @subheading -signal-list-handle-actions ++ ++@c @subheading -signal-list-signal-types ++@end ignore ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Target Manipulation ++@section @sc{gdb/mi} Target Manipulation Commands ++ ++ ++@subheading The @code{-target-attach} Command ++@findex -target-attach ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-attach @var{pid} | @var{gid} | @var{file} ++@end smallexample ++ ++Attach to a process @var{pid} or a file @var{file} outside of ++@value{GDBN}, or a thread group @var{gid}. If attaching to a thread ++group, the id previously returned by ++@samp{-list-thread-groups --available} must be used. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{attach}. ++ ++@subsubheading Example ++@smallexample ++(gdb) ++-target-attach 34 ++=thread-created,id="1" ++*stopped,thread-id="1",frame=@{addr="0xb7f7e410",func="bar",args=[]@} ++^done ++(gdb) ++@end smallexample ++ ++@ignore ++@subheading The @code{-target-compare-sections} Command ++@findex -target-compare-sections ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-compare-sections [ @var{section} ] ++@end smallexample ++ ++Compare data of section @var{section} on target to the exec file. ++Without the argument, all sections are compared. ++ ++@subsubheading @value{GDBN} Command ++ ++The @value{GDBN} equivalent is @samp{compare-sections}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-target-detach} Command ++@findex -target-detach ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-detach [ @var{pid} | @var{gid} ] ++@end smallexample ++ ++Detach from the remote target which normally resumes its execution. ++If either @var{pid} or @var{gid} is specified, detaches from either ++the specified process, or specified thread group. There's no output. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{detach}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-detach ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-target-disconnect} Command ++@findex -target-disconnect ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-disconnect ++@end smallexample ++ ++Disconnect from the remote target. There's no output and the target is ++generally not resumed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{disconnect}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-disconnect ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-target-download} Command ++@findex -target-download ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-download ++@end smallexample ++ ++Loads the executable onto the remote target. ++It prints out an update message every half second, which includes the fields: ++ ++@table @samp ++@item section ++The name of the section. ++@item section-sent ++The size of what has been sent so far for that section. ++@item section-size ++The size of the section. ++@item total-sent ++The total size of what was sent so far (the current and the previous sections). ++@item total-size ++The size of the overall executable to download. ++@end table ++ ++@noindent ++Each message is sent as status record (@pxref{GDB/MI Output Syntax, , ++@sc{gdb/mi} Output Syntax}). ++ ++In addition, it prints the name and size of the sections, as they are ++downloaded. These messages include the following fields: ++ ++@table @samp ++@item section ++The name of the section. ++@item section-size ++The size of the section. ++@item total-size ++The size of the overall executable to download. ++@end table ++ ++@noindent ++At the end, a summary is printed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{load}. ++ ++@subsubheading Example ++ ++Note: each status message appears on a single line. Here the messages ++have been broken down so that they can fit onto a page. ++ ++@smallexample ++(gdb) ++-target-download +++download,@{section=".text",section-size="6668",total-size="9880"@} +++download,@{section=".text",section-sent="512",section-size="6668", ++total-sent="512",total-size="9880"@} +++download,@{section=".text",section-sent="1024",section-size="6668", ++total-sent="1024",total-size="9880"@} +++download,@{section=".text",section-sent="1536",section-size="6668", ++total-sent="1536",total-size="9880"@} +++download,@{section=".text",section-sent="2048",section-size="6668", ++total-sent="2048",total-size="9880"@} +++download,@{section=".text",section-sent="2560",section-size="6668", ++total-sent="2560",total-size="9880"@} +++download,@{section=".text",section-sent="3072",section-size="6668", ++total-sent="3072",total-size="9880"@} +++download,@{section=".text",section-sent="3584",section-size="6668", ++total-sent="3584",total-size="9880"@} +++download,@{section=".text",section-sent="4096",section-size="6668", ++total-sent="4096",total-size="9880"@} +++download,@{section=".text",section-sent="4608",section-size="6668", ++total-sent="4608",total-size="9880"@} +++download,@{section=".text",section-sent="5120",section-size="6668", ++total-sent="5120",total-size="9880"@} +++download,@{section=".text",section-sent="5632",section-size="6668", ++total-sent="5632",total-size="9880"@} +++download,@{section=".text",section-sent="6144",section-size="6668", ++total-sent="6144",total-size="9880"@} +++download,@{section=".text",section-sent="6656",section-size="6668", ++total-sent="6656",total-size="9880"@} +++download,@{section=".init",section-size="28",total-size="9880"@} +++download,@{section=".fini",section-size="28",total-size="9880"@} +++download,@{section=".data",section-size="3156",total-size="9880"@} +++download,@{section=".data",section-sent="512",section-size="3156", ++total-sent="7236",total-size="9880"@} +++download,@{section=".data",section-sent="1024",section-size="3156", ++total-sent="7748",total-size="9880"@} +++download,@{section=".data",section-sent="1536",section-size="3156", ++total-sent="8260",total-size="9880"@} +++download,@{section=".data",section-sent="2048",section-size="3156", ++total-sent="8772",total-size="9880"@} +++download,@{section=".data",section-sent="2560",section-size="3156", ++total-sent="9284",total-size="9880"@} +++download,@{section=".data",section-sent="3072",section-size="3156", ++total-sent="9796",total-size="9880"@} ++^done,address="0x10004",load-size="9880",transfer-rate="6586", ++write-rate="429" ++(gdb) ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-target-exec-status} Command ++@findex -target-exec-status ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-exec-status ++@end smallexample ++ ++Provide information on the state of the target (whether it is running or ++not, for instance). ++ ++@subsubheading @value{GDBN} Command ++ ++There's no equivalent @value{GDBN} command. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-target-list-available-targets} Command ++@findex -target-list-available-targets ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-list-available-targets ++@end smallexample ++ ++List the possible targets to connect to. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{help target}. ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-target-list-current-targets} Command ++@findex -target-list-current-targets ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-list-current-targets ++@end smallexample ++ ++Describe the current target. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding information is printed by @samp{info file} (among ++other things). ++ ++@subsubheading Example ++N.A. ++ ++ ++@subheading The @code{-target-list-parameters} Command ++@findex -target-list-parameters ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-list-parameters ++@end smallexample ++ ++@c ???? ++@end ignore ++ ++@subsubheading @value{GDBN} Command ++ ++No equivalent. ++ ++@subsubheading Example ++N.A. ++ ++@subheading The @code{-target-flash-erase} Command ++@findex -target-flash-erase ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-flash-erase ++@end smallexample ++ ++Erases all known flash memory regions on the target. ++ ++The corresponding @value{GDBN} command is @samp{flash-erase}. ++ ++The output is a list of flash regions that have been erased, with starting ++addresses and memory region sizes. ++ ++@smallexample ++(gdb) ++-target-flash-erase ++^done,erased-regions=@{address="0x0",size="0x40000"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-target-select} Command ++@findex -target-select ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-select @var{type} @var{parameters @dots{}} ++@end smallexample ++ ++Connect @value{GDBN} to the remote target. This command takes two args: ++ ++@table @samp ++@item @var{type} ++The type of target, for instance @samp{remote}, etc. ++@item @var{parameters} ++Device names, host names and the like. @xref{Target Commands, , ++Commands for Managing Targets}, for more details. ++@end table ++ ++The output is a connection notification, followed by the address at ++which the target program is, in the following form: ++ ++@smallexample ++^connected,addr="@var{address}",func="@var{function name}", ++ args=[@var{arg list}] ++@end smallexample ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{target}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-select remote /dev/ttya ++^connected,addr="0xfe00a300",func="??",args=[] ++(gdb) ++@end smallexample ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI File Transfer Commands ++@section @sc{gdb/mi} File Transfer Commands ++ ++ ++@subheading The @code{-target-file-put} Command ++@findex -target-file-put ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-file-put @var{hostfile} @var{targetfile} ++@end smallexample ++ ++Copy file @var{hostfile} from the host system (the machine running ++@value{GDBN}) to @var{targetfile} on the target system. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{remote put}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-file-put localfile remotefile ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-target-file-get} Command ++@findex -target-file-get ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-file-get @var{targetfile} @var{hostfile} ++@end smallexample ++ ++Copy file @var{targetfile} from the target system to @var{hostfile} ++on the host system. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{remote get}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-file-get remotefile localfile ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-target-file-delete} Command ++@findex -target-file-delete ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -target-file-delete @var{targetfile} ++@end smallexample ++ ++Delete @var{targetfile} from the target system. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{remote delete}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-target-file-delete remotefile ++^done ++(gdb) ++@end smallexample ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Ada Exceptions Commands ++@section Ada Exceptions @sc{gdb/mi} Commands ++ ++@subheading The @code{-info-ada-exceptions} Command ++@findex -info-ada-exceptions ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -info-ada-exceptions [ @var{regexp}] ++@end smallexample ++ ++List all Ada exceptions defined within the program being debugged. ++With a regular expression @var{regexp}, only those exceptions whose ++names match @var{regexp} are listed. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info exceptions}. ++ ++@subsubheading Result ++ ++The result is a table of Ada exceptions. The following columns are ++defined for each exception: ++ ++@table @samp ++@item name ++The name of the exception. ++ ++@item address ++The address of the exception. ++ ++@end table ++ ++@subsubheading Example ++ ++@smallexample ++-info-ada-exceptions aint ++^done,ada-exceptions=@{nr_rows="2",nr_cols="2", ++hdr=[@{width="1",alignment="-1",col_name="name",colhdr="Name"@}, ++@{width="1",alignment="-1",col_name="address",colhdr="Address"@}], ++body=[@{name="constraint_error",address="0x0000000000613da0"@}, ++@{name="const.aint_global_e",address="0x0000000000613b00"@}]@} ++@end smallexample ++ ++@subheading Catching Ada Exceptions ++ ++The commands describing how to ask @value{GDBN} to stop when a program ++raises an exception are described at @ref{Ada Exception GDB/MI ++Catchpoint Commands}. ++ ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Support Commands ++@section @sc{gdb/mi} Support Commands ++ ++Since new commands and features get regularly added to @sc{gdb/mi}, ++some commands are available to help front-ends query the debugger ++about support for these capabilities. Similarly, it is also possible ++to query @value{GDBN} about target support of certain features. ++ ++@subheading The @code{-info-gdb-mi-command} Command ++@cindex @code{-info-gdb-mi-command} ++@findex -info-gdb-mi-command ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -info-gdb-mi-command @var{cmd_name} ++@end smallexample ++ ++Query support for the @sc{gdb/mi} command named @var{cmd_name}. ++ ++Note that the dash (@code{-}) starting all @sc{gdb/mi} commands ++is technically not part of the command name (@pxref{GDB/MI Input ++Syntax}), and thus should be omitted in @var{cmd_name}. However, ++for ease of use, this command also accepts the form with the leading ++dash. ++ ++@subsubheading @value{GDBN} Command ++ ++There is no corresponding @value{GDBN} command. ++ ++@subsubheading Result ++ ++The result is a tuple. There is currently only one field: ++ ++@table @samp ++@item exists ++This field is equal to @code{"true"} if the @sc{gdb/mi} command exists, ++@code{"false"} otherwise. ++ ++@end table ++ ++@subsubheading Example ++ ++Here is an example where the @sc{gdb/mi} command does not exist: ++ ++@smallexample ++-info-gdb-mi-command unsupported-command ++^done,command=@{exists="false"@} ++@end smallexample ++ ++@noindent ++And here is an example where the @sc{gdb/mi} command is known ++to the debugger: ++ ++@smallexample ++-info-gdb-mi-command symbol-list-lines ++^done,command=@{exists="true"@} ++@end smallexample ++ ++@subheading The @code{-list-features} Command ++@findex -list-features ++@cindex supported @sc{gdb/mi} features, list ++ ++Returns a list of particular features of the MI protocol that ++this version of gdb implements. A feature can be a command, ++or a new field in an output of some command, or even an ++important bugfix. While a frontend can sometimes detect presence ++of a feature at runtime, it is easier to perform detection at debugger ++startup. ++ ++The command returns a list of strings, with each string naming an ++available feature. Each returned string is just a name, it does not ++have any internal structure. The list of possible feature names ++is given below. ++ ++Example output: ++ ++@smallexample ++(gdb) -list-features ++^done,result=["feature1","feature2"] ++@end smallexample ++ ++The current list of features is: ++ ++@ftable @samp ++@item frozen-varobjs ++Indicates support for the @code{-var-set-frozen} command, as well ++as possible presence of the @code{frozen} field in the output ++of @code{-varobj-create}. ++@item pending-breakpoints ++Indicates support for the @option{-f} option to the @code{-break-insert} ++command. ++@item python ++Indicates Python scripting support, Python-based ++pretty-printing commands, and possible presence of the ++@samp{display_hint} field in the output of @code{-var-list-children} ++@item thread-info ++Indicates support for the @code{-thread-info} command. ++@item data-read-memory-bytes ++Indicates support for the @code{-data-read-memory-bytes} and the ++@code{-data-write-memory-bytes} commands. ++@item breakpoint-notifications ++Indicates that changes to breakpoints and breakpoints created via the ++CLI will be announced via async records. ++@item ada-task-info ++Indicates support for the @code{-ada-task-info} command. ++@item language-option ++Indicates that all @sc{gdb/mi} commands accept the @option{--language} ++option (@pxref{Context management}). ++@item info-gdb-mi-command ++Indicates support for the @code{-info-gdb-mi-command} command. ++@item undefined-command-error-code ++Indicates support for the "undefined-command" error code in error result ++records, produced when trying to execute an undefined @sc{gdb/mi} command ++(@pxref{GDB/MI Result Records}). ++@item exec-run-start-option ++Indicates that the @code{-exec-run} command supports the @option{--start} ++option (@pxref{GDB/MI Program Execution}). ++@item data-disassemble-a-option ++Indicates that the @code{-data-disassemble} command supports the @option{-a} ++option (@pxref{GDB/MI Data Manipulation}). ++@end ftable ++ ++@subheading The @code{-list-target-features} Command ++@findex -list-target-features ++ ++Returns a list of particular features that are supported by the ++target. Those features affect the permitted MI commands, but ++unlike the features reported by the @code{-list-features} command, the ++features depend on which target GDB is using at the moment. Whenever ++a target can change, due to commands such as @code{-target-select}, ++@code{-target-attach} or @code{-exec-run}, the list of target features ++may change, and the frontend should obtain it again. ++Example output: ++ ++@smallexample ++(gdb) -list-target-features ++^done,result=["async"] ++@end smallexample ++ ++The current list of features is: ++ ++@table @samp ++@item async ++Indicates that the target is capable of asynchronous command ++execution, which means that @value{GDBN} will accept further commands ++while the target is running. ++ ++@item reverse ++Indicates that the target is capable of reverse execution. ++@xref{Reverse Execution}, for more information. ++ ++@end table ++ ++@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ++@node GDB/MI Miscellaneous Commands ++@section Miscellaneous @sc{gdb/mi} Commands ++ ++@c @subheading -gdb-complete ++ ++@subheading The @code{-gdb-exit} Command ++@findex -gdb-exit ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -gdb-exit ++@end smallexample ++ ++Exit @value{GDBN} immediately. ++ ++@subsubheading @value{GDBN} Command ++ ++Approximately corresponds to @samp{quit}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-gdb-exit ++^exit ++@end smallexample ++ ++ ++@ignore ++@subheading The @code{-exec-abort} Command ++@findex -exec-abort ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -exec-abort ++@end smallexample ++ ++Kill the inferior running program. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{kill}. ++ ++@subsubheading Example ++N.A. ++@end ignore ++ ++ ++@subheading The @code{-gdb-set} Command ++@findex -gdb-set ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -gdb-set ++@end smallexample ++ ++Set an internal @value{GDBN} variable. ++@c IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ????? ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{set}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-gdb-set $foo=3 ++^done ++(gdb) ++@end smallexample ++ ++ ++@subheading The @code{-gdb-show} Command ++@findex -gdb-show ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -gdb-show ++@end smallexample ++ ++Show the current value of a @value{GDBN} variable. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{show}. ++ ++@subsubheading Example ++ ++@smallexample ++(gdb) ++-gdb-show annotate ++^done,value="0" ++(gdb) ++@end smallexample ++ ++@c @subheading -gdb-source ++ ++ ++@subheading The @code{-gdb-version} Command ++@findex -gdb-version ++ ++@subsubheading Synopsis ++ ++@smallexample ++ -gdb-version ++@end smallexample ++ ++Show version information for @value{GDBN}. Used mostly in testing. ++ ++@subsubheading @value{GDBN} Command ++ ++The @value{GDBN} equivalent is @samp{show version}. @value{GDBN} by ++default shows this information when you start an interactive session. ++ ++@subsubheading Example ++ ++@c This example modifies the actual output from GDB to avoid overfull ++@c box in TeX. ++@smallexample ++(gdb) ++-gdb-version ++~GNU gdb 5.2.1 ++~Copyright 2000 Free Software Foundation, Inc. ++~GDB is free software, covered by the GNU General Public License, and ++~you are welcome to change it and/or distribute copies of it under ++~ certain conditions. ++~Type "show copying" to see the conditions. ++~There is absolutely no warranty for GDB. Type "show warranty" for ++~ details. ++~This GDB was configured as ++ "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". ++^done ++(gdb) ++@end smallexample ++ ++@subheading The @code{-list-thread-groups} Command ++@findex -list-thread-groups ++ ++@subheading Synopsis ++ ++@smallexample ++-list-thread-groups [ --available ] [ --recurse 1 ] [ @var{group} ... ] ++@end smallexample ++ ++Lists thread groups (@pxref{Thread groups}). When a single thread ++group is passed as the argument, lists the children of that group. ++When several thread group are passed, lists information about those ++thread groups. Without any parameters, lists information about all ++top-level thread groups. ++ ++Normally, thread groups that are being debugged are reported. ++With the @samp{--available} option, @value{GDBN} reports thread groups ++available on the target. ++ ++The output of this command may have either a @samp{threads} result or ++a @samp{groups} result. The @samp{thread} result has a list of tuples ++as value, with each tuple describing a thread (@pxref{GDB/MI Thread ++Information}). The @samp{groups} result has a list of tuples as value, ++each tuple describing a thread group. If top-level groups are ++requested (that is, no parameter is passed), or when several groups ++are passed, the output always has a @samp{groups} result. The format ++of the @samp{group} result is described below. ++ ++To reduce the number of roundtrips it's possible to list thread groups ++together with their children, by passing the @samp{--recurse} option ++and the recursion depth. Presently, only recursion depth of 1 is ++permitted. If this option is present, then every reported thread group ++will also include its children, either as @samp{group} or ++@samp{threads} field. ++ ++In general, any combination of option and parameters is permitted, with ++the following caveats: ++ ++@itemize @bullet ++@item ++When a single thread group is passed, the output will typically ++be the @samp{threads} result. Because threads may not contain ++anything, the @samp{recurse} option will be ignored. ++ ++@item ++When the @samp{--available} option is passed, limited information may ++be available. In particular, the list of threads of a process might ++be inaccessible. Further, specifying specific thread groups might ++not give any performance advantage over listing all thread groups. ++The frontend should assume that @samp{-list-thread-groups --available} ++is always an expensive operation and cache the results. ++ ++@end itemize ++ ++The @samp{groups} result is a list of tuples, where each tuple may ++have the following fields: ++ ++@table @code ++@item id ++Identifier of the thread group. This field is always present. ++The identifier is an opaque string; frontends should not try to ++convert it to an integer, even though it might look like one. ++ ++@item type ++The type of the thread group. At present, only @samp{process} is a ++valid type. ++ ++@item pid ++The target-specific process identifier. This field is only present ++for thread groups of type @samp{process} and only if the process exists. ++ ++@item exit-code ++The exit code of this group's last exited thread, formatted in octal. ++This field is only present for thread groups of type @samp{process} and ++only if the process is not running. ++ ++@item num_children ++The number of children this thread group has. This field may be ++absent for an available thread group. ++ ++@item threads ++This field has a list of tuples as value, each tuple describing a ++thread. It may be present if the @samp{--recurse} option is ++specified, and it's actually possible to obtain the threads. ++ ++@item cores ++This field is a list of integers, each identifying a core that one ++thread of the group is running on. This field may be absent if ++such information is not available. ++ ++@item executable ++The name of the executable file that corresponds to this thread group. ++The field is only present for thread groups of type @samp{process}, ++and only if there is a corresponding executable file. ++ ++@end table ++ ++@subheading Example ++ ++@smallexample ++@value{GDBP} ++-list-thread-groups ++^done,groups=[@{id="17",type="process",pid="yyy",num_children="2"@}] ++-list-thread-groups 17 ++^done,threads=[@{id="2",target-id="Thread 0xb7e14b90 (LWP 21257)", ++ frame=@{level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]@},state="running"@}, ++@{id="1",target-id="Thread 0xb7e156b0 (LWP 21254)", ++ frame=@{level="0",addr="0x0804891f",func="foo",args=[@{name="i",value="10"@}], ++ file="/tmp/a.c",fullname="/tmp/a.c",line="158",arch="i386:x86_64"@},state="running"@}]] ++-list-thread-groups --available ++^done,groups=[@{id="17",type="process",pid="yyy",num_children="2",cores=[1,2]@}] ++-list-thread-groups --available --recurse 1 ++ ^done,groups=[@{id="17", types="process",pid="yyy",num_children="2",cores=[1,2], ++ threads=[@{id="1",target-id="Thread 0xb7e14b90",cores=[1]@}, ++ @{id="2",target-id="Thread 0xb7e14b90",cores=[2]@}]@},..] ++-list-thread-groups --available --recurse 1 17 18 ++^done,groups=[@{id="17", types="process",pid="yyy",num_children="2",cores=[1,2], ++ threads=[@{id="1",target-id="Thread 0xb7e14b90",cores=[1]@}, ++ @{id="2",target-id="Thread 0xb7e14b90",cores=[2]@}]@},...] ++@end smallexample ++ ++@subheading The @code{-info-os} Command ++@findex -info-os ++ ++@subsubheading Synopsis ++ ++@smallexample ++-info-os [ @var{type} ] ++@end smallexample ++ ++If no argument is supplied, the command returns a table of available ++operating-system-specific information types. If one of these types is ++supplied as an argument @var{type}, then the command returns a table ++of data of that type. ++ ++The types of information available depend on the target operating ++system. ++ ++@subsubheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{info os}. ++ ++@subsubheading Example ++ ++When run on a @sc{gnu}/Linux system, the output will look something ++like this: ++ ++@smallexample ++@value{GDBP} ++-info-os ++^done,OSDataTable=@{nr_rows="10",nr_cols="3", ++hdr=[@{width="10",alignment="-1",col_name="col0",colhdr="Type"@}, ++ @{width="10",alignment="-1",col_name="col1",colhdr="Description"@}, ++ @{width="10",alignment="-1",col_name="col2",colhdr="Title"@}], ++body=[item=@{col0="cpus",col1="Listing of all cpus/cores on the system", ++ col2="CPUs"@}, ++ item=@{col0="files",col1="Listing of all file descriptors", ++ col2="File descriptors"@}, ++ item=@{col0="modules",col1="Listing of all loaded kernel modules", ++ col2="Kernel modules"@}, ++ item=@{col0="msg",col1="Listing of all message queues", ++ col2="Message queues"@}, ++ item=@{col0="processes",col1="Listing of all processes", ++ col2="Processes"@}, ++ item=@{col0="procgroups",col1="Listing of all process groups", ++ col2="Process groups"@}, ++ item=@{col0="semaphores",col1="Listing of all semaphores", ++ col2="Semaphores"@}, ++ item=@{col0="shm",col1="Listing of all shared-memory regions", ++ col2="Shared-memory regions"@}, ++ item=@{col0="sockets",col1="Listing of all internet-domain sockets", ++ col2="Sockets"@}, ++ item=@{col0="threads",col1="Listing of all threads", ++ col2="Threads"@}] ++@value{GDBP} ++-info-os processes ++^done,OSDataTable=@{nr_rows="190",nr_cols="4", ++hdr=[@{width="10",alignment="-1",col_name="col0",colhdr="pid"@}, ++ @{width="10",alignment="-1",col_name="col1",colhdr="user"@}, ++ @{width="10",alignment="-1",col_name="col2",colhdr="command"@}, ++ @{width="10",alignment="-1",col_name="col3",colhdr="cores"@}], ++body=[item=@{col0="1",col1="root",col2="/sbin/init",col3="0"@}, ++ item=@{col0="2",col1="root",col2="[kthreadd]",col3="1"@}, ++ item=@{col0="3",col1="root",col2="[ksoftirqd/0]",col3="0"@}, ++ ... ++ item=@{col0="26446",col1="stan",col2="bash",col3="0"@}, ++ item=@{col0="28152",col1="stan",col2="bash",col3="1"@}]@} ++(gdb) ++@end smallexample ++ ++(Note that the MI output here includes a @code{"Title"} column that ++does not appear in command-line @code{info os}; this column is useful ++for MI clients that want to enumerate the types of data, such as in a ++popup menu, but is needless clutter on the command line, and ++@code{info os} omits it.) ++ ++@subheading The @code{-add-inferior} Command ++@findex -add-inferior ++ ++@subheading Synopsis ++ ++@smallexample ++-add-inferior ++@end smallexample ++ ++Creates a new inferior (@pxref{Inferiors Connections and Programs}). The created ++inferior is not associated with any executable. Such association may ++be established with the @samp{-file-exec-and-symbols} command ++(@pxref{GDB/MI File Commands}). The command response has a single ++field, @samp{inferior}, whose value is the identifier of the ++thread group corresponding to the new inferior. ++ ++@subheading Example ++ ++@smallexample ++@value{GDBP} ++-add-inferior ++^done,inferior="i3" ++@end smallexample ++ ++@subheading The @code{-interpreter-exec} Command ++@findex -interpreter-exec ++ ++@subheading Synopsis ++ ++@smallexample ++-interpreter-exec @var{interpreter} @var{command} ++@end smallexample ++@anchor{-interpreter-exec} ++ ++Execute the specified @var{command} in the given @var{interpreter}. ++ ++@subheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{interpreter-exec}. ++ ++@subheading Example ++ ++@smallexample ++(gdb) ++-interpreter-exec console "break main" ++&"During symbol reading, couldn't parse type; debugger out of date?.\n" ++&"During symbol reading, bad structure-type format.\n" ++~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" ++^done ++(gdb) ++@end smallexample ++ ++@subheading The @code{-inferior-tty-set} Command ++@findex -inferior-tty-set ++ ++@subheading Synopsis ++ ++@smallexample ++-inferior-tty-set /dev/pts/1 ++@end smallexample ++ ++Set terminal for future runs of the program being debugged. ++ ++@subheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{set inferior-tty} /dev/pts/1. ++ ++@subheading Example ++ ++@smallexample ++(gdb) ++-inferior-tty-set /dev/pts/1 ++^done ++(gdb) ++@end smallexample ++ ++@subheading The @code{-inferior-tty-show} Command ++@findex -inferior-tty-show ++ ++@subheading Synopsis ++ ++@smallexample ++-inferior-tty-show ++@end smallexample ++ ++Show terminal for future runs of program being debugged. ++ ++@subheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{show inferior-tty}. ++ ++@subheading Example ++ ++@smallexample ++(gdb) ++-inferior-tty-set /dev/pts/1 ++^done ++(gdb) ++-inferior-tty-show ++^done,inferior_tty_terminal="/dev/pts/1" ++(gdb) ++@end smallexample ++ ++@subheading The @code{-enable-timings} Command ++@findex -enable-timings ++ ++@subheading Synopsis ++ ++@smallexample ++-enable-timings [yes | no] ++@end smallexample ++ ++Toggle the printing of the wallclock, user and system times for an MI ++command as a field in its output. This command is to help frontend ++developers optimize the performance of their code. No argument is ++equivalent to @samp{yes}. ++ ++@subheading @value{GDBN} Command ++ ++No equivalent. ++ ++@subheading Example ++ ++@smallexample ++(gdb) ++-enable-timings ++^done ++(gdb) ++-break-insert main ++^done,bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ++addr="0x080484ed",func="main",file="myprog.c", ++fullname="/home/nickrob/myprog.c",line="73",thread-groups=["i1"], ++times="0"@}, ++time=@{wallclock="0.05185",user="0.00800",system="0.00000"@} ++(gdb) ++-enable-timings no ++^done ++(gdb) ++-exec-run ++^running ++(gdb) ++*stopped,reason="breakpoint-hit",disp="keep",bkptno="1",thread-id="0", ++frame=@{addr="0x080484ed",func="main",args=[@{name="argc",value="1"@}, ++@{name="argv",value="0xbfb60364"@}],file="myprog.c", ++fullname="/home/nickrob/myprog.c",line="73",arch="i386:x86_64"@} ++(gdb) ++@end smallexample ++ ++@subheading The @code{-complete} Command ++@findex -complete ++ ++@subheading Synopsis ++ ++@smallexample ++-complete @var{command} ++@end smallexample ++ ++Show a list of completions for partially typed CLI @var{command}. ++ ++This command is intended for @sc{gdb/mi} frontends that cannot use two separate ++CLI and MI channels --- for example: because of lack of PTYs like on Windows or ++because @value{GDBN} is used remotely via a SSH connection. ++ ++@subheading Result ++ ++The result consists of two or three fields: ++ ++@table @samp ++@item completion ++This field contains the completed @var{command}. If @var{command} ++has no known completions, this field is omitted. ++ ++@item matches ++This field contains a (possibly empty) array of matches. It is always present. ++ ++@item max_completions_reached ++This field contains @code{1} if number of known completions is above ++@code{max-completions} limit (@pxref{Completion}), otherwise it contains ++@code{0}. It is always present. ++ ++@end table ++ ++@subheading @value{GDBN} Command ++ ++The corresponding @value{GDBN} command is @samp{complete}. ++ ++@subheading Example ++ ++@smallexample ++(gdb) ++-complete br ++^done,completion="break", ++ matches=["break","break-range"], ++ max_completions_reached="0" ++(gdb) ++-complete "b ma" ++^done,completion="b ma", ++ matches=["b madvise","b main"],max_completions_reached="0" ++(gdb) ++-complete "b push_b" ++^done,completion="b push_back(", ++ matches=[ ++ "b A::push_back(void*)", ++ "b std::string::push_back(char)", ++ "b std::vector >::push_back(int&&)"], ++ max_completions_reached="0" ++(gdb) ++-complete "nonexist" ++^done,matches=[],max_completions_reached="0" ++(gdb) ++ ++@end smallexample ++ ++@node Annotations ++@chapter @value{GDBN} Annotations ++ ++This chapter describes annotations in @value{GDBN}. Annotations were ++designed to interface @value{GDBN} to graphical user interfaces or other ++similar programs which want to interact with @value{GDBN} at a ++relatively high level. ++ ++The annotation mechanism has largely been superseded by @sc{gdb/mi} ++(@pxref{GDB/MI}). ++ ++@ignore ++This is Edition @value{EDITION}, @value{DATE}. ++@end ignore ++ ++@menu ++* Annotations Overview:: What annotations are; the general syntax. ++* Server Prefix:: Issuing a command without affecting user state. ++* Prompting:: Annotations marking @value{GDBN}'s need for input. ++* Errors:: Annotations for error messages. ++* Invalidation:: Some annotations describe things now invalid. ++* Annotations for Running:: ++ Whether the program is running, how it stopped, etc. ++* Source Annotations:: Annotations describing source code. ++@end menu ++ ++@node Annotations Overview ++@section What is an Annotation? ++@cindex annotations ++ ++Annotations start with a newline character, two @samp{control-z} ++characters, and the name of the annotation. If there is no additional ++information associated with this annotation, the name of the annotation ++is followed immediately by a newline. If there is additional ++information, the name of the annotation is followed by a space, the ++additional information, and a newline. The additional information ++cannot contain newline characters. ++ ++Any output not beginning with a newline and two @samp{control-z} ++characters denotes literal output from @value{GDBN}. Currently there is ++no need for @value{GDBN} to output a newline followed by two ++@samp{control-z} characters, but if there was such a need, the ++annotations could be extended with an @samp{escape} annotation which ++means those three characters as output. ++ ++The annotation @var{level}, which is specified using the ++@option{--annotate} command line option (@pxref{Mode Options}), controls ++how much information @value{GDBN} prints together with its prompt, ++values of expressions, source lines, and other types of output. Level 0 ++is for no annotations, level 1 is for use when @value{GDBN} is run as a ++subprocess of @sc{gnu} Emacs, level 3 is the maximum annotation suitable ++for programs that control @value{GDBN}, and level 2 annotations have ++been made obsolete (@pxref{Limitations, , Limitations of the Annotation ++Interface, annotate, GDB's Obsolete Annotations}). ++ ++@table @code ++@kindex set annotate ++@item set annotate @var{level} ++The @value{GDBN} command @code{set annotate} sets the level of ++annotations to the specified @var{level}. ++ ++@item show annotate ++@kindex show annotate ++Show the current annotation level. ++@end table ++ ++This chapter describes level 3 annotations. ++ ++A simple example of starting up @value{GDBN} with annotations is: ++ ++@smallexample ++$ @kbd{gdb --annotate=3} ++GNU gdb 6.0 ++Copyright 2003 Free Software Foundation, Inc. ++GDB is free software, covered by the GNU General Public License, ++and you are welcome to change it and/or distribute copies of it ++under certain conditions. ++Type "show copying" to see the conditions. ++There is absolutely no warranty for GDB. Type "show warranty" ++for details. ++This GDB was configured as "i386-pc-linux-gnu" ++ ++^Z^Zpre-prompt ++(@value{GDBP}) ++^Z^Zprompt ++@kbd{quit} ++ ++^Z^Zpost-prompt ++$ ++@end smallexample ++ ++Here @samp{quit} is input to @value{GDBN}; the rest is output from ++@value{GDBN}. The three lines beginning @samp{^Z^Z} (where @samp{^Z} ++denotes a @samp{control-z} character) are annotations; the rest is ++output from @value{GDBN}. ++ ++@node Server Prefix ++@section The Server Prefix ++@cindex server prefix ++ ++If you prefix a command with @samp{server } then it will not affect ++the command history, nor will it affect @value{GDBN}'s notion of which ++command to repeat if @key{RET} is pressed on a line by itself. This ++means that commands can be run behind a user's back by a front-end in ++a transparent manner. ++ ++The @code{server } prefix does not affect the recording of values into ++the value history; to print a value without recording it into the ++value history, use the @code{output} command instead of the ++@code{print} command. ++ ++Using this prefix also disables confirmation requests ++(@pxref{confirmation requests}). ++ ++@node Prompting ++@section Annotation for @value{GDBN} Input ++ ++@cindex annotations for prompts ++When @value{GDBN} prompts for input, it annotates this fact so it is possible ++to know when to send output, when the output from a given command is ++over, etc. ++ ++Different kinds of input each have a different @dfn{input type}. Each ++input type has three annotations: a @code{pre-} annotation, which ++denotes the beginning of any prompt which is being output, a plain ++annotation, which denotes the end of the prompt, and then a @code{post-} ++annotation which denotes the end of any echo which may (or may not) be ++associated with the input. For example, the @code{prompt} input type ++features the following annotations: ++ ++@smallexample ++^Z^Zpre-prompt ++^Z^Zprompt ++^Z^Zpost-prompt ++@end smallexample ++ ++The input types are ++ ++@table @code ++@findex pre-prompt annotation ++@findex prompt annotation ++@findex post-prompt annotation ++@item prompt ++When @value{GDBN} is prompting for a command (the main @value{GDBN} prompt). ++ ++@findex pre-commands annotation ++@findex commands annotation ++@findex post-commands annotation ++@item commands ++When @value{GDBN} prompts for a set of commands, like in the @code{commands} ++command. The annotations are repeated for each command which is input. ++ ++@findex pre-overload-choice annotation ++@findex overload-choice annotation ++@findex post-overload-choice annotation ++@item overload-choice ++When @value{GDBN} wants the user to select between various overloaded functions. ++ ++@findex pre-query annotation ++@findex query annotation ++@findex post-query annotation ++@item query ++When @value{GDBN} wants the user to confirm a potentially dangerous operation. ++ ++@findex pre-prompt-for-continue annotation ++@findex prompt-for-continue annotation ++@findex post-prompt-for-continue annotation ++@item prompt-for-continue ++When @value{GDBN} is asking the user to press return to continue. Note: Don't ++expect this to work well; instead use @code{set height 0} to disable ++prompting. This is because the counting of lines is buggy in the ++presence of annotations. ++@end table ++ ++@node Errors ++@section Errors ++@cindex annotations for errors, warnings and interrupts ++ ++@findex quit annotation ++@smallexample ++^Z^Zquit ++@end smallexample ++ ++This annotation occurs right before @value{GDBN} responds to an interrupt. ++ ++@findex error annotation ++@smallexample ++^Z^Zerror ++@end smallexample ++ ++This annotation occurs right before @value{GDBN} responds to an error. ++ ++Quit and error annotations indicate that any annotations which @value{GDBN} was ++in the middle of may end abruptly. For example, if a ++@code{value-history-begin} annotation is followed by a @code{error}, one ++cannot expect to receive the matching @code{value-history-end}. One ++cannot expect not to receive it either, however; an error annotation ++does not necessarily mean that @value{GDBN} is immediately returning all the way ++to the top level. ++ ++@findex error-begin annotation ++A quit or error annotation may be preceded by ++ ++@smallexample ++^Z^Zerror-begin ++@end smallexample ++ ++Any output between that and the quit or error annotation is the error ++message. ++ ++Warning messages are not yet annotated. ++@c If we want to change that, need to fix warning(), type_error(), ++@c range_error(), and possibly other places. ++ ++@node Invalidation ++@section Invalidation Notices ++ ++@cindex annotations for invalidation messages ++The following annotations say that certain pieces of state may have ++changed. ++ ++@table @code ++@findex frames-invalid annotation ++@item ^Z^Zframes-invalid ++ ++The frames (for example, output from the @code{backtrace} command) may ++have changed. ++ ++@findex breakpoints-invalid annotation ++@item ^Z^Zbreakpoints-invalid ++ ++The breakpoints may have changed. For example, the user just added or ++deleted a breakpoint. ++@end table ++ ++@node Annotations for Running ++@section Running the Program ++@cindex annotations for running programs ++ ++@findex starting annotation ++@findex stopping annotation ++When the program starts executing due to a @value{GDBN} command such as ++@code{step} or @code{continue}, ++ ++@smallexample ++^Z^Zstarting ++@end smallexample ++ ++is output. When the program stops, ++ ++@smallexample ++^Z^Zstopped ++@end smallexample ++ ++is output. Before the @code{stopped} annotation, a variety of ++annotations describe how the program stopped. ++ ++@table @code ++@findex exited annotation ++@item ^Z^Zexited @var{exit-status} ++The program exited, and @var{exit-status} is the exit status (zero for ++successful exit, otherwise nonzero). ++ ++@findex signalled annotation ++@findex signal-name annotation ++@findex signal-name-end annotation ++@findex signal-string annotation ++@findex signal-string-end annotation ++@item ^Z^Zsignalled ++The program exited with a signal. After the @code{^Z^Zsignalled}, the ++annotation continues: ++ ++@smallexample ++@var{intro-text} ++^Z^Zsignal-name ++@var{name} ++^Z^Zsignal-name-end ++@var{middle-text} ++^Z^Zsignal-string ++@var{string} ++^Z^Zsignal-string-end ++@var{end-text} ++@end smallexample ++ ++@noindent ++where @var{name} is the name of the signal, such as @code{SIGILL} or ++@code{SIGSEGV}, and @var{string} is the explanation of the signal, such ++as @code{Illegal Instruction} or @code{Segmentation fault}. The arguments ++@var{intro-text}, @var{middle-text}, and @var{end-text} are for the ++user's benefit and have no particular format. ++ ++@findex signal annotation ++@item ^Z^Zsignal ++The syntax of this annotation is just like @code{signalled}, but @value{GDBN} is ++just saying that the program received the signal, not that it was ++terminated with it. ++ ++@findex breakpoint annotation ++@item ^Z^Zbreakpoint @var{number} ++The program hit breakpoint number @var{number}. ++ ++@findex watchpoint annotation ++@item ^Z^Zwatchpoint @var{number} ++The program hit watchpoint number @var{number}. ++@end table ++ ++@node Source Annotations ++@section Displaying Source ++@cindex annotations for source display ++ ++@findex source annotation ++The following annotation is used instead of displaying source code: ++ ++@smallexample ++^Z^Zsource @var{filename}:@var{line}:@var{character}:@var{middle}:@var{addr} ++@end smallexample ++ ++where @var{filename} is an absolute file name indicating which source ++file, @var{line} is the line number within that file (where 1 is the ++first line in the file), @var{character} is the character position ++within the file (where 0 is the first character in the file) (for most ++debug formats this will necessarily point to the beginning of a line), ++@var{middle} is @samp{middle} if @var{addr} is in the middle of the ++line, or @samp{beg} if @var{addr} is at the beginning of the line, and ++@var{addr} is the address in the target program associated with the ++source which is being displayed. The @var{addr} is in the form @samp{0x} ++followed by one or more lowercase hex digits (note that this does not ++depend on the language). ++ ++@node JIT Interface ++@chapter JIT Compilation Interface ++@cindex just-in-time compilation ++@cindex JIT compilation interface ++ ++This chapter documents @value{GDBN}'s @dfn{just-in-time} (JIT) compilation ++interface. A JIT compiler is a program or library that generates native ++executable code at runtime and executes it, usually in order to achieve good ++performance while maintaining platform independence. ++ ++Programs that use JIT compilation are normally difficult to debug because ++portions of their code are generated at runtime, instead of being loaded from ++object files, which is where @value{GDBN} normally finds the program's symbols ++and debug information. In order to debug programs that use JIT compilation, ++@value{GDBN} has an interface that allows the program to register in-memory ++symbol files with @value{GDBN} at runtime. ++ ++If you are using @value{GDBN} to debug a program that uses this interface, then ++it should work transparently so long as you have not stripped the binary. If ++you are developing a JIT compiler, then the interface is documented in the rest ++of this chapter. At this time, the only known client of this interface is the ++LLVM JIT. ++ ++Broadly speaking, the JIT interface mirrors the dynamic loader interface. The ++JIT compiler communicates with @value{GDBN} by writing data into a global ++variable and calling a function at a well-known symbol. When @value{GDBN} ++attaches, it reads a linked list of symbol files from the global variable to ++find existing code, and puts a breakpoint in the function so that it can find ++out about additional code. ++ ++@menu ++* Declarations:: Relevant C struct declarations ++* Registering Code:: Steps to register code ++* Unregistering Code:: Steps to unregister code ++* Custom Debug Info:: Emit debug information in a custom format ++@end menu ++ ++@node Declarations ++@section JIT Declarations ++ ++These are the relevant struct declarations that a C program should include to ++implement the interface: ++ ++@smallexample ++typedef enum ++@{ ++ JIT_NOACTION = 0, ++ JIT_REGISTER_FN, ++ JIT_UNREGISTER_FN ++@} jit_actions_t; ++ ++struct jit_code_entry ++@{ ++ struct jit_code_entry *next_entry; ++ struct jit_code_entry *prev_entry; ++ const char *symfile_addr; ++ uint64_t symfile_size; ++@}; ++ ++struct jit_descriptor ++@{ ++ uint32_t version; ++ /* This type should be jit_actions_t, but we use uint32_t ++ to be explicit about the bitwidth. */ ++ uint32_t action_flag; ++ struct jit_code_entry *relevant_entry; ++ struct jit_code_entry *first_entry; ++@}; ++ ++/* GDB puts a breakpoint in this function. */ ++void __attribute__((noinline)) __jit_debug_register_code() @{ @}; ++ ++/* Make sure to specify the version statically, because the ++ debugger may check the version before we can set it. */ ++struct jit_descriptor __jit_debug_descriptor = @{ 1, 0, 0, 0 @}; ++@end smallexample ++ ++If the JIT is multi-threaded, then it is important that the JIT synchronize any ++modifications to this global data properly, which can easily be done by putting ++a global mutex around modifications to these structures. ++ ++@node Registering Code ++@section Registering Code ++ ++To register code with @value{GDBN}, the JIT should follow this protocol: ++ ++@itemize @bullet ++@item ++Generate an object file in memory with symbols and other desired debug ++information. The file must include the virtual addresses of the sections. ++ ++@item ++Create a code entry for the file, which gives the start and size of the symbol ++file. ++ ++@item ++Add it to the linked list in the JIT descriptor. ++ ++@item ++Point the relevant_entry field of the descriptor at the entry. ++ ++@item ++Set @code{action_flag} to @code{JIT_REGISTER} and call ++@code{__jit_debug_register_code}. ++@end itemize ++ ++When @value{GDBN} is attached and the breakpoint fires, @value{GDBN} uses the ++@code{relevant_entry} pointer so it doesn't have to walk the list looking for ++new code. However, the linked list must still be maintained in order to allow ++@value{GDBN} to attach to a running process and still find the symbol files. ++ ++@node Unregistering Code ++@section Unregistering Code ++ ++If code is freed, then the JIT should use the following protocol: ++ ++@itemize @bullet ++@item ++Remove the code entry corresponding to the code from the linked list. ++ ++@item ++Point the @code{relevant_entry} field of the descriptor at the code entry. ++ ++@item ++Set @code{action_flag} to @code{JIT_UNREGISTER} and call ++@code{__jit_debug_register_code}. ++@end itemize ++ ++If the JIT frees or recompiles code without unregistering it, then @value{GDBN} ++and the JIT will leak the memory used for the associated symbol files. ++ ++@node Custom Debug Info ++@section Custom Debug Info ++@cindex custom JIT debug info ++@cindex JIT debug info reader ++ ++Generating debug information in platform-native file formats (like ELF ++or COFF) may be an overkill for JIT compilers; especially if all the ++debug info is used for is displaying a meaningful backtrace. The ++issue can be resolved by having the JIT writers decide on a debug info ++format and also provide a reader that parses the debug info generated ++by the JIT compiler. This section gives a brief overview on writing ++such a parser. More specific details can be found in the source file ++@file{gdb/jit-reader.in}, which is also installed as a header at ++@file{@var{includedir}/gdb/jit-reader.h} for easy inclusion. ++ ++The reader is implemented as a shared object (so this functionality is ++not available on platforms which don't allow loading shared objects at ++runtime). Two @value{GDBN} commands, @code{jit-reader-load} and ++@code{jit-reader-unload} are provided, to be used to load and unload ++the readers from a preconfigured directory. Once loaded, the shared ++object is used the parse the debug information emitted by the JIT ++compiler. ++ ++@menu ++* Using JIT Debug Info Readers:: How to use supplied readers correctly ++* Writing JIT Debug Info Readers:: Creating a debug-info reader ++@end menu ++ ++@node Using JIT Debug Info Readers ++@subsection Using JIT Debug Info Readers ++@kindex jit-reader-load ++@kindex jit-reader-unload ++ ++Readers can be loaded and unloaded using the @code{jit-reader-load} ++and @code{jit-reader-unload} commands. ++ ++@table @code ++@item jit-reader-load @var{reader} ++Load the JIT reader named @var{reader}, which is a shared ++object specified as either an absolute or a relative file name. In ++the latter case, @value{GDBN} will try to load the reader from a ++pre-configured directory, usually @file{@var{libdir}/gdb/} on a UNIX ++system (here @var{libdir} is the system library directory, often ++@file{/usr/local/lib}). ++ ++Only one reader can be active at a time; trying to load a second ++reader when one is already loaded will result in @value{GDBN} ++reporting an error. A new JIT reader can be loaded by first unloading ++the current one using @code{jit-reader-unload} and then invoking ++@code{jit-reader-load}. ++ ++@item jit-reader-unload ++Unload the currently loaded JIT reader. ++ ++@end table ++ ++@node Writing JIT Debug Info Readers ++@subsection Writing JIT Debug Info Readers ++@cindex writing JIT debug info readers ++ ++As mentioned, a reader is essentially a shared object conforming to a ++certain ABI. This ABI is described in @file{jit-reader.h}. ++ ++@file{jit-reader.h} defines the structures, macros and functions ++required to write a reader. It is installed (along with ++@value{GDBN}), in @file{@var{includedir}/gdb} where @var{includedir} is ++the system include directory. ++ ++Readers need to be released under a GPL compatible license. A reader ++can be declared as released under such a license by placing the macro ++@code{GDB_DECLARE_GPL_COMPATIBLE_READER} in a source file. ++ ++The entry point for readers is the symbol @code{gdb_init_reader}, ++which is expected to be a function with the prototype ++ ++@findex gdb_init_reader ++@smallexample ++extern struct gdb_reader_funcs *gdb_init_reader (void); ++@end smallexample ++ ++@cindex @code{struct gdb_reader_funcs} ++ ++@code{struct gdb_reader_funcs} contains a set of pointers to callback ++functions. These functions are executed to read the debug info ++generated by the JIT compiler (@code{read}), to unwind stack frames ++(@code{unwind}) and to create canonical frame IDs ++(@code{get_frame_id}). It also has a callback that is called when the ++reader is being unloaded (@code{destroy}). The struct looks like this ++ ++@smallexample ++struct gdb_reader_funcs ++@{ ++ /* Must be set to GDB_READER_INTERFACE_VERSION. */ ++ int reader_version; ++ ++ /* For use by the reader. */ ++ void *priv_data; ++ ++ gdb_read_debug_info *read; ++ gdb_unwind_frame *unwind; ++ gdb_get_frame_id *get_frame_id; ++ gdb_destroy_reader *destroy; ++@}; ++@end smallexample ++ ++@cindex @code{struct gdb_symbol_callbacks} ++@cindex @code{struct gdb_unwind_callbacks} ++ ++The callbacks are provided with another set of callbacks by ++@value{GDBN} to do their job. For @code{read}, these callbacks are ++passed in a @code{struct gdb_symbol_callbacks} and for @code{unwind} ++and @code{get_frame_id}, in a @code{struct gdb_unwind_callbacks}. ++@code{struct gdb_symbol_callbacks} has callbacks to create new object ++files and new symbol tables inside those object files. @code{struct ++gdb_unwind_callbacks} has callbacks to read registers off the current ++frame and to write out the values of the registers in the previous ++frame. Both have a callback (@code{target_read}) to read bytes off the ++target's address space. ++ ++@node In-Process Agent ++@chapter In-Process Agent ++@cindex debugging agent ++The traditional debugging model is conceptually low-speed, but works fine, ++because most bugs can be reproduced in debugging-mode execution. However, ++as multi-core or many-core processors are becoming mainstream, and ++multi-threaded programs become more and more popular, there should be more ++and more bugs that only manifest themselves at normal-mode execution, for ++example, thread races, because debugger's interference with the program's ++timing may conceal the bugs. On the other hand, in some applications, ++it is not feasible for the debugger to interrupt the program's execution ++long enough for the developer to learn anything helpful about its behavior. ++If the program's correctness depends on its real-time behavior, delays ++introduced by a debugger might cause the program to fail, even when the ++code itself is correct. It is useful to be able to observe the program's ++behavior without interrupting it. ++ ++Therefore, traditional debugging model is too intrusive to reproduce ++some bugs. In order to reduce the interference with the program, we can ++reduce the number of operations performed by debugger. The ++@dfn{In-Process Agent}, a shared library, is running within the same ++process with inferior, and is able to perform some debugging operations ++itself. As a result, debugger is only involved when necessary, and ++performance of debugging can be improved accordingly. Note that ++interference with program can be reduced but can't be removed completely, ++because the in-process agent will still stop or slow down the program. ++ ++The in-process agent can interpret and execute Agent Expressions ++(@pxref{Agent Expressions}) during performing debugging operations. The ++agent expressions can be used for different purposes, such as collecting ++data in tracepoints, and condition evaluation in breakpoints. ++ ++@anchor{Control Agent} ++You can control whether the in-process agent is used as an aid for ++debugging with the following commands: ++ ++@table @code ++@kindex set agent on ++@item set agent on ++Causes the in-process agent to perform some operations on behalf of the ++debugger. Just which operations requested by the user will be done ++by the in-process agent depends on the its capabilities. For example, ++if you request to evaluate breakpoint conditions in the in-process agent, ++and the in-process agent has such capability as well, then breakpoint ++conditions will be evaluated in the in-process agent. ++ ++@kindex set agent off ++@item set agent off ++Disables execution of debugging operations by the in-process agent. All ++of the operations will be performed by @value{GDBN}. ++ ++@kindex show agent ++@item show agent ++Display the current setting of execution of debugging operations by ++the in-process agent. ++@end table ++ ++@menu ++* In-Process Agent Protocol:: ++@end menu ++ ++@node In-Process Agent Protocol ++@section In-Process Agent Protocol ++@cindex in-process agent protocol ++ ++The in-process agent is able to communicate with both @value{GDBN} and ++GDBserver (@pxref{In-Process Agent}). This section documents the protocol ++used for communications between @value{GDBN} or GDBserver and the IPA. ++In general, @value{GDBN} or GDBserver sends commands ++(@pxref{IPA Protocol Commands}) and data to in-process agent, and then ++in-process agent replies back with the return result of the command, or ++some other information. The data sent to in-process agent is composed ++of primitive data types, such as 4-byte or 8-byte type, and composite ++types, which are called objects (@pxref{IPA Protocol Objects}). ++ ++@menu ++* IPA Protocol Objects:: ++* IPA Protocol Commands:: ++@end menu ++ ++@node IPA Protocol Objects ++@subsection IPA Protocol Objects ++@cindex ipa protocol objects ++ ++The commands sent to and results received from agent may contain some ++complex data types called @dfn{objects}. ++ ++The in-process agent is running on the same machine with @value{GDBN} ++or GDBserver, so it doesn't have to handle as much differences between ++two ends as remote protocol (@pxref{Remote Protocol}) tries to handle. ++However, there are still some differences of two ends in two processes: ++ ++@enumerate ++@item ++word size. On some 64-bit machines, @value{GDBN} or GDBserver can be ++compiled as a 64-bit executable, while in-process agent is a 32-bit one. ++@item ++ABI. Some machines may have multiple types of ABI, @value{GDBN} or ++GDBserver is compiled with one, and in-process agent is compiled with ++the other one. ++@end enumerate ++ ++Here are the IPA Protocol Objects: ++ ++@enumerate ++@item ++agent expression object. It represents an agent expression ++(@pxref{Agent Expressions}). ++@anchor{agent expression object} ++@item ++tracepoint action object. It represents a tracepoint action ++(@pxref{Tracepoint Actions,,Tracepoint Action Lists}) to collect registers, ++memory, static trace data and to evaluate expression. ++@anchor{tracepoint action object} ++@item ++tracepoint object. It represents a tracepoint (@pxref{Tracepoints}). ++@anchor{tracepoint object} ++ ++@end enumerate ++ ++The following table describes important attributes of each IPA protocol ++object: ++ ++@multitable @columnfractions .30 .20 .50 ++@headitem Name @tab Size @tab Description ++@item @emph{agent expression object} @tab @tab ++@item length @tab 4 @tab length of bytes code ++@item byte code @tab @var{length} @tab contents of byte code ++@item @emph{tracepoint action for collecting memory} @tab @tab ++@item 'M' @tab 1 @tab type of tracepoint action ++@item addr @tab 8 @tab if @var{basereg} is @samp{-1}, @var{addr} is the ++address of the lowest byte to collect, otherwise @var{addr} is the offset ++of @var{basereg} for memory collecting. ++@item len @tab 8 @tab length of memory for collecting ++@item basereg @tab 4 @tab the register number containing the starting ++memory address for collecting. ++@item @emph{tracepoint action for collecting registers} @tab @tab ++@item 'R' @tab 1 @tab type of tracepoint action ++@item @emph{tracepoint action for collecting static trace data} @tab @tab ++@item 'L' @tab 1 @tab type of tracepoint action ++@item @emph{tracepoint action for expression evaluation} @tab @tab ++@item 'X' @tab 1 @tab type of tracepoint action ++@item agent expression @tab length of @tab @ref{agent expression object} ++@item @emph{tracepoint object} @tab @tab ++@item number @tab 4 @tab number of tracepoint ++@item address @tab 8 @tab address of tracepoint inserted on ++@item type @tab 4 @tab type of tracepoint ++@item enabled @tab 1 @tab enable or disable of tracepoint ++@item step_count @tab 8 @tab step ++@item pass_count @tab 8 @tab pass ++@item numactions @tab 4 @tab number of tracepoint actions ++@item hit count @tab 8 @tab hit count ++@item trace frame usage @tab 8 @tab trace frame usage ++@item compiled_cond @tab 8 @tab compiled condition ++@item orig_size @tab 8 @tab orig size ++@item condition @tab 4 if condition is NULL otherwise length of ++@ref{agent expression object} ++@tab zero if condition is NULL, otherwise is ++@ref{agent expression object} ++@item actions @tab variable ++@tab numactions number of @ref{tracepoint action object} ++@end multitable ++ ++@node IPA Protocol Commands ++@subsection IPA Protocol Commands ++@cindex ipa protocol commands ++ ++The spaces in each command are delimiters to ease reading this commands ++specification. They don't exist in real commands. ++ ++@table @samp ++ ++@item FastTrace:@var{tracepoint_object} @var{gdb_jump_pad_head} ++Installs a new fast tracepoint described by @var{tracepoint_object} ++(@pxref{tracepoint object}). The @var{gdb_jump_pad_head}, 8-byte long, is the ++head of @dfn{jumppad}, which is used to jump to data collection routine ++in IPA finally. ++ ++Replies: ++@table @samp ++@item OK @var{target_address} @var{gdb_jump_pad_head} @var{fjump_size} @var{fjump} ++@var{target_address} is address of tracepoint in the inferior. ++The @var{gdb_jump_pad_head} is updated head of jumppad. Both of ++@var{target_address} and @var{gdb_jump_pad_head} are 8-byte long. ++The @var{fjump} contains a sequence of instructions jump to jumppad entry. ++The @var{fjump_size}, 4-byte long, is the size of @var{fjump}. ++@item E @var{NN} ++for an error ++ ++@end table ++ ++@item close ++Closes the in-process agent. This command is sent when @value{GDBN} or GDBserver ++is about to kill inferiors. ++ ++@item qTfSTM ++@xref{qTfSTM}. ++@item qTsSTM ++@xref{qTsSTM}. ++@item qTSTMat ++@xref{qTSTMat}. ++@item probe_marker_at:@var{address} ++Asks in-process agent to probe the marker at @var{address}. ++ ++Replies: ++@table @samp ++@item E @var{NN} ++for an error ++@end table ++@item unprobe_marker_at:@var{address} ++Asks in-process agent to unprobe the marker at @var{address}. ++@end table ++ ++@node GDB Bugs ++@chapter Reporting Bugs in @value{GDBN} ++@cindex bugs in @value{GDBN} ++@cindex reporting bugs in @value{GDBN} ++ ++Your bug reports play an essential role in making @value{GDBN} reliable. ++ ++Reporting a bug may help you by bringing a solution to your problem, or it ++may not. But in any case the principal function of a bug report is to help ++the entire community by making the next version of @value{GDBN} work better. Bug ++reports are your contribution to the maintenance of @value{GDBN}. ++ ++In order for a bug report to serve its purpose, you must include the ++information that enables us to fix the bug. ++ ++@menu ++* Bug Criteria:: Have you found a bug? ++* Bug Reporting:: How to report bugs ++@end menu ++ ++@node Bug Criteria ++@section Have You Found a Bug? ++@cindex bug criteria ++ ++If you are not sure whether you have found a bug, here are some guidelines: ++ ++@itemize @bullet ++@cindex fatal signal ++@cindex debugger crash ++@cindex crash of debugger ++@item ++If the debugger gets a fatal signal, for any input whatever, that is a ++@value{GDBN} bug. Reliable debuggers never crash. ++ ++@cindex error on valid input ++@item ++If @value{GDBN} produces an error message for valid input, that is a ++bug. (Note that if you're cross debugging, the problem may also be ++somewhere in the connection to the target.) ++ ++@cindex invalid input ++@item ++If @value{GDBN} does not produce an error message for invalid input, ++that is a bug. However, you should note that your idea of ++``invalid input'' might be our idea of ``an extension'' or ``support ++for traditional practice''. ++ ++@item ++If you are an experienced user of debugging tools, your suggestions ++for improvement of @value{GDBN} are welcome in any case. ++@end itemize ++ ++@node Bug Reporting ++@section How to Report Bugs ++@cindex bug reports ++@cindex @value{GDBN} bugs, reporting ++ ++A number of companies and individuals offer support for @sc{gnu} products. ++If you obtained @value{GDBN} from a support organization, we recommend you ++contact that organization first. ++ ++You can find contact information for many support companies and ++individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs ++distribution. ++@c should add a web page ref... ++ ++@ifset BUGURL ++@ifset BUGURL_DEFAULT ++In any event, we also recommend that you submit bug reports for ++@value{GDBN}. The preferred method is to submit them directly using ++@uref{http://www.gnu.org/software/gdb/bugs/, @value{GDBN}'s Bugs web ++page}. Alternatively, the @email{bug-gdb@@gnu.org, e-mail gateway} can ++be used. ++ ++@strong{Do not send bug reports to @samp{info-gdb}, or to ++@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do ++not want to receive bug reports. Those that do have arranged to receive ++@samp{bug-gdb}. ++ ++The mailing list @samp{bug-gdb} has a newsgroup @samp{gnu.gdb.bug} which ++serves as a repeater. The mailing list and the newsgroup carry exactly ++the same messages. Often people think of posting bug reports to the ++newsgroup instead of mailing them. This appears to work, but it has one ++problem which can be crucial: a newsgroup posting often lacks a mail ++path back to the sender. Thus, if we need to ask for more information, ++we may be unable to reach you. For this reason, it is better to send ++bug reports to the mailing list. ++@end ifset ++@ifclear BUGURL_DEFAULT ++In any event, we also recommend that you submit bug reports for ++@value{GDBN} to @value{BUGURL}. ++@end ifclear ++@end ifset ++ ++The fundamental principle of reporting bugs usefully is this: ++@strong{report all the facts}. If you are not sure whether to state a ++fact or leave it out, state it! ++ ++Often people omit facts because they think they know what causes the ++problem and assume that some details do not matter. Thus, you might ++assume that the name of the variable you use in an example does not matter. ++Well, probably it does not, but one cannot be sure. Perhaps the bug is a ++stray memory reference which happens to fetch from the location where that ++name is stored in memory; perhaps, if the name were different, the contents ++of that location would fool the debugger into doing the right thing despite ++the bug. Play it safe and give a specific, complete example. That is the ++easiest thing for you to do, and the most helpful. ++ ++Keep in mind that the purpose of a bug report is to enable us to fix the ++bug. It may be that the bug has been reported previously, but neither ++you nor we can know that unless your bug report is complete and ++self-contained. ++ ++Sometimes people give a few sketchy facts and ask, ``Does this ring a ++bell?'' Those bug reports are useless, and we urge everyone to ++@emph{refuse to respond to them} except to chide the sender to report ++bugs properly. ++ ++To enable us to fix the bug, you should include all these things: ++ ++@itemize @bullet ++@item ++The version of @value{GDBN}. @value{GDBN} announces it if you start ++with no arguments; you can also print it at any time using @code{show ++version}. ++ ++Without this, we will not know whether there is any point in looking for ++the bug in the current version of @value{GDBN}. ++ ++@item ++The type of machine you are using, and the operating system name and ++version number. ++ ++@item ++The details of the @value{GDBN} build-time configuration. ++@value{GDBN} shows these details if you invoke it with the ++@option{--configuration} command-line option, or if you type ++@code{show configuration} at @value{GDBN}'s prompt. ++ ++@item ++What compiler (and its version) was used to compile @value{GDBN}---e.g.@: ++``@value{GCC}--2.8.1''. ++ ++@item ++What compiler (and its version) was used to compile the program you are ++debugging---e.g.@: ``@value{GCC}--2.8.1'', or ``HP92453-01 A.10.32.03 HP ++C Compiler''. For @value{NGCC}, you can say @kbd{@value{GCC} --version} ++to get this information; for other compilers, see the documentation for ++those compilers. ++ ++@item ++The command arguments you gave the compiler to compile your example and ++observe the bug. For example, did you use @samp{-O}? To guarantee ++you will not omit something important, list them all. A copy of the ++Makefile (or the output from make) is sufficient. ++ ++If we were to try to guess the arguments, we would probably guess wrong ++and then we might not encounter the bug. ++ ++@item ++A complete input script, and all necessary source files, that will ++reproduce the bug. ++ ++@item ++A description of what behavior you observe that you believe is ++incorrect. For example, ``It gets a fatal signal.'' ++ ++Of course, if the bug is that @value{GDBN} gets a fatal signal, then we ++will certainly notice it. But if the bug is incorrect output, we might ++not notice unless it is glaringly wrong. You might as well not give us ++a chance to make a mistake. ++ ++Even if the problem you experience is a fatal signal, you should still ++say so explicitly. Suppose something strange is going on, such as, your ++copy of @value{GDBN} is out of synch, or you have encountered a bug in ++the C library on your system. (This has happened!) Your copy might ++crash and ours would not. If you told us to expect a crash, then when ++ours fails to crash, we would know that the bug was not happening for ++us. If you had not told us to expect a crash, then we would not be able ++to draw any conclusion from our observations. ++ ++@pindex script ++@cindex recording a session script ++To collect all this information, you can use a session recording program ++such as @command{script}, which is available on many Unix systems. ++Just run your @value{GDBN} session inside @command{script} and then ++include the @file{typescript} file with your bug report. ++ ++Another way to record a @value{GDBN} session is to run @value{GDBN} ++inside Emacs and then save the entire buffer to a file. ++ ++@item ++If you wish to suggest changes to the @value{GDBN} source, send us context ++diffs. If you even discuss something in the @value{GDBN} source, refer to ++it by context, not by line number. ++ ++The line numbers in our development sources will not match those in your ++sources. Your line numbers would convey no useful information to us. ++ ++@end itemize ++ ++Here are some things that are not necessary: ++ ++@itemize @bullet ++@item ++A description of the envelope of the bug. ++ ++Often people who encounter a bug spend a lot of time investigating ++which changes to the input file will make the bug go away and which ++changes will not affect it. ++ ++This is often time consuming and not very useful, because the way we ++will find the bug is by running a single example under the debugger ++with breakpoints, not by pure deduction from a series of examples. ++We recommend that you save your time for something else. ++ ++Of course, if you can find a simpler example to report @emph{instead} ++of the original one, that is a convenience for us. Errors in the ++output will be easier to spot, running under the debugger will take ++less time, and so on. ++ ++However, simplification is not vital; if you do not want to do this, ++report the bug anyway and send us the entire test case you used. ++ ++@item ++A patch for the bug. ++ ++A patch for the bug does help us if it is a good one. But do not omit ++the necessary information, such as the test case, on the assumption that ++a patch is all we need. We might see problems with your patch and decide ++to fix the problem another way, or we might not understand it at all. ++ ++Sometimes with a program as complicated as @value{GDBN} it is very hard to ++construct an example that will make the program follow a certain path ++through the code. If you do not send us the example, we will not be able ++to construct one, so we will not be able to verify that the bug is fixed. ++ ++And if we cannot understand what bug you are trying to fix, or why your ++patch should be an improvement, we will not install it. A test case will ++help us to understand. ++ ++@item ++A guess about what the bug is or what it depends on. ++ ++Such guesses are usually wrong. Even we cannot guess right about such ++things without first using the debugger to find the facts. ++@end itemize ++ ++@c The readline documentation is distributed with the readline code ++@c and consists of the two following files: ++@c rluser.texi ++@c hsuser.texi ++@c Use -I with makeinfo to point to the appropriate directory, ++@c environment var TEXINPUTS with TeX. ++@ifclear SYSTEM_READLINE ++@include rluser.texi ++@include hsuser.texi ++@end ifclear ++ ++@node In Memoriam ++@appendix In Memoriam ++ ++The @value{GDBN} project mourns the loss of the following long-time ++contributors: ++ ++@table @code ++@item Fred Fish ++Fred was a long-standing contributor to @value{GDBN} (1991-2006), and ++to Free Software in general. Outside of @value{GDBN}, he was known in ++the Amiga world for his series of Fish Disks, and the GeekGadget project. ++ ++@item Michael Snyder ++Michael was one of the Global Maintainers of the @value{GDBN} project, ++with contributions recorded as early as 1996, until 2011. In addition ++to his day to day participation, he was a large driving force behind ++adding Reverse Debugging to @value{GDBN}. ++@end table ++ ++Beyond their technical contributions to the project, they were also ++enjoyable members of the Free Software Community. We will miss them. ++ ++@node Formatting Documentation ++@appendix Formatting Documentation ++ ++@cindex @value{GDBN} reference card ++@cindex reference card ++The @value{GDBN} 4 release includes an already-formatted reference card, ready ++for printing with PostScript or Ghostscript, in the @file{gdb} ++subdirectory of the main source directory@footnote{In ++@file{gdb-@value{GDBVN}/gdb/refcard.ps} of the version @value{GDBVN} ++release.}. If you can use PostScript or Ghostscript with your printer, ++you can print the reference card immediately with @file{refcard.ps}. ++ ++The release also includes the source for the reference card. You ++can format it, using @TeX{}, by typing: ++ ++@smallexample ++make refcard.dvi ++@end smallexample ++ ++The @value{GDBN} reference card is designed to print in @dfn{landscape} ++mode on US ``letter'' size paper; ++that is, on a sheet 11 inches wide by 8.5 inches ++high. You will need to specify this form of printing as an option to ++your @sc{dvi} output program. ++ ++@cindex documentation ++ ++All the documentation for @value{GDBN} comes as part of the machine-readable ++distribution. The documentation is written in Texinfo format, which is ++a documentation system that uses a single source file to produce both ++on-line information and a printed manual. You can use one of the Info ++formatting commands to create the on-line version of the documentation ++and @TeX{} (or @code{texi2roff}) to typeset the printed version. ++ ++@value{GDBN} includes an already formatted copy of the on-line Info ++version of this manual in the @file{gdb} subdirectory. The main Info ++file is @file{gdb-@value{GDBVN}/gdb/gdb.info}, and it refers to ++subordinate files matching @samp{gdb.info*} in the same directory. If ++necessary, you can print out these files, or read them with any editor; ++but they are easier to read using the @code{info} subsystem in @sc{gnu} ++Emacs or the standalone @code{info} program, available as part of the ++@sc{gnu} Texinfo distribution. ++ ++If you want to format these Info files yourself, you need one of the ++Info formatting programs, such as @code{texinfo-format-buffer} or ++@code{makeinfo}. ++ ++If you have @code{makeinfo} installed, and are in the top level ++@value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of ++version @value{GDBVN}), you can make the Info file by typing: ++ ++@smallexample ++cd gdb ++make gdb.info ++@end smallexample ++ ++If you want to typeset and print copies of this manual, you need @TeX{}, ++a program to print its @sc{dvi} output files, and @file{texinfo.tex}, the ++Texinfo definitions file. ++ ++@TeX{} is a typesetting program; it does not print files directly, but ++produces output files called @sc{dvi} files. To print a typeset ++document, you need a program to print @sc{dvi} files. If your system ++has @TeX{} installed, chances are it has such a program. The precise ++command to use depends on your system; @kbd{lpr -d} is common; another ++(for PostScript devices) is @kbd{dvips}. The @sc{dvi} print command may ++require a file name without any extension or a @samp{.dvi} extension. ++ ++@TeX{} also requires a macro definitions file called ++@file{texinfo.tex}. This file tells @TeX{} how to typeset a document ++written in Texinfo format. On its own, @TeX{} cannot either read or ++typeset a Texinfo file. @file{texinfo.tex} is distributed with GDB ++and is located in the @file{gdb-@var{version-number}/texinfo} ++directory. ++ ++If you have @TeX{} and a @sc{dvi} printer program installed, you can ++typeset and print this manual. First switch to the @file{gdb} ++subdirectory of the main source directory (for example, to ++@file{gdb-@value{GDBVN}/gdb}) and type: ++ ++@smallexample ++make gdb.dvi ++@end smallexample ++ ++Then give @file{gdb.dvi} to your @sc{dvi} printing program. ++ ++@node Installing GDB ++@appendix Installing @value{GDBN} ++@cindex installation ++ ++@menu ++* Requirements:: Requirements for building @value{GDBN} ++* Running Configure:: Invoking the @value{GDBN} @file{configure} script ++* Separate Objdir:: Compiling @value{GDBN} in another directory ++* Config Names:: Specifying names for hosts and targets ++* Configure Options:: Summary of options for configure ++* System-wide configuration:: Having a system-wide init file ++@end menu ++ ++@node Requirements ++@section Requirements for Building @value{GDBN} ++@cindex building @value{GDBN}, requirements for ++ ++Building @value{GDBN} requires various tools and packages to be available. ++Other packages will be used only if they are found. ++ ++@heading Tools/Packages Necessary for Building @value{GDBN} ++@table @asis ++@item C@t{++}11 compiler ++@value{GDBN} is written in C@t{++}11. It should be buildable with any ++recent C@t{++}11 compiler, e.g.@: GCC. ++ ++@item GNU make ++@value{GDBN}'s build system relies on features only found in the GNU ++make program. Other variants of @code{make} will not work. ++@end table ++ ++@heading Tools/Packages Optional for Building @value{GDBN} ++@table @asis ++@item Expat ++@anchor{Expat} ++@value{GDBN} can use the Expat XML parsing library. This library may be ++included with your operating system distribution; if it is not, you ++can get the latest version from @url{http://expat.sourceforge.net}. ++The @file{configure} script will search for this library in several ++standard locations; if it is installed in an unusual path, you can ++use the @option{--with-libexpat-prefix} option to specify its location. ++ ++Expat is used for: ++ ++@itemize @bullet ++@item ++Remote protocol memory maps (@pxref{Memory Map Format}) ++@item ++Target descriptions (@pxref{Target Descriptions}) ++@item ++Remote shared library lists (@xref{Library List Format}, ++or alternatively @pxref{Library List Format for SVR4 Targets}) ++@item ++MS-Windows shared libraries (@pxref{Shared Libraries}) ++@item ++Traceframe info (@pxref{Traceframe Info Format}) ++@item ++Branch trace (@pxref{Branch Trace Format}, ++@pxref{Branch Trace Configuration Format}) ++@end itemize ++ ++@item Guile ++@value{GDBN} can be scripted using GNU Guile. @xref{Guile}. By ++default, @value{GDBN} will be compiled if the Guile libraries are ++installed and are found by @file{configure}. You can use the ++@code{--with-guile} option to request Guile, and pass either the Guile ++version number or the file name of the relevant @code{pkg-config} ++program to choose a particular version of Guile. ++ ++@item iconv ++@value{GDBN}'s features related to character sets (@pxref{Character ++Sets}) require a functioning @code{iconv} implementation. If you are ++on a GNU system, then this is provided by the GNU C Library. Some ++other systems also provide a working @code{iconv}. ++ ++If @value{GDBN} is using the @code{iconv} program which is installed ++in a non-standard place, you will need to tell @value{GDBN} where to ++find it. This is done with @option{--with-iconv-bin} which specifies ++the directory that contains the @code{iconv} program. This program is ++run in order to make a list of the available character sets. ++ ++On systems without @code{iconv}, you can install GNU Libiconv. If ++Libiconv is installed in a standard place, @value{GDBN} will ++automatically use it if it is needed. If you have previously ++installed Libiconv in a non-standard place, you can use the ++@option{--with-libiconv-prefix} option to @file{configure}. ++ ++@value{GDBN}'s top-level @file{configure} and @file{Makefile} will ++arrange to build Libiconv if a directory named @file{libiconv} appears ++in the top-most source directory. If Libiconv is built this way, and ++if the operating system does not provide a suitable @code{iconv} ++implementation, then the just-built library will automatically be used ++by @value{GDBN}. One easy way to set this up is to download GNU ++Libiconv, unpack it inside the top-level directory of the @value{GDBN} ++source tree, and then rename the directory holding the Libiconv source ++code to @samp{libiconv}. ++ ++@item lzma ++@value{GDBN} can support debugging sections that are compressed with ++the LZMA library. @xref{MiniDebugInfo}. If this library is not ++included with your operating system, you can find it in the xz package ++at @url{http://tukaani.org/xz/}. If the LZMA library is available in ++the usual place, then the @file{configure} script will use it ++automatically. If it is installed in an unusual path, you can use the ++@option{--with-lzma-prefix} option to specify its location. ++ ++@item MPFR ++@anchor{MPFR} ++@value{GDBN} can use the GNU MPFR multiple-precision floating-point ++library. This library may be included with your operating system ++distribution; if it is not, you can get the latest version from ++@url{http://www.mpfr.org}. The @file{configure} script will search ++for this library in several standard locations; if it is installed ++in an unusual path, you can use the @option{--with-libmpfr-prefix} ++option to specify its location. ++ ++GNU MPFR is used to emulate target floating-point arithmetic during ++expression evaluation when the target uses different floating-point ++formats than the host. If GNU MPFR it is not available, @value{GDBN} ++will fall back to using host floating-point arithmetic. ++ ++@item Python ++@value{GDBN} can be scripted using Python language. @xref{Python}. ++By default, @value{GDBN} will be compiled if the Python libraries are ++installed and are found by @file{configure}. You can use the ++@code{--with-python} option to request Python, and pass either the ++file name of the relevant @code{python} executable, or the name of the ++directory in which Python is installed, to choose a particular ++installation of Python. ++ ++@item zlib ++@cindex compressed debug sections ++@value{GDBN} will use the @samp{zlib} library, if available, to read ++compressed debug sections. Some linkers, such as GNU gold, are capable ++of producing binaries with compressed debug sections. If @value{GDBN} ++is compiled with @samp{zlib}, it will be able to read the debug ++information in such binaries. ++ ++The @samp{zlib} library is likely included with your operating system ++distribution; if it is not, you can get the latest version from ++@url{http://zlib.net}. ++@end table ++ ++@node Running Configure ++@section Invoking the @value{GDBN} @file{configure} Script ++@cindex configuring @value{GDBN} ++@value{GDBN} comes with a @file{configure} script that automates the process ++of preparing @value{GDBN} for installation; you can then use @code{make} to ++build the @code{gdb} program. ++@iftex ++@c irrelevant in info file; it's as current as the code it lives with. ++@footnote{If you have a more recent version of @value{GDBN} than @value{GDBVN}, ++look at the @file{README} file in the sources; we may have improved the ++installation procedures since publishing this manual.} ++@end iftex ++ ++The @value{GDBN} distribution includes all the source code you need for ++@value{GDBN} in a single directory, whose name is usually composed by ++appending the version number to @samp{gdb}. ++ ++For example, the @value{GDBN} version @value{GDBVN} distribution is in the ++@file{gdb-@value{GDBVN}} directory. That directory contains: ++ ++@table @code ++@item gdb-@value{GDBVN}/configure @r{(and supporting files)} ++script for configuring @value{GDBN} and all its supporting libraries ++ ++@item gdb-@value{GDBVN}/gdb ++the source specific to @value{GDBN} itself ++ ++@item gdb-@value{GDBVN}/bfd ++source for the Binary File Descriptor library ++ ++@item gdb-@value{GDBVN}/include ++@sc{gnu} include files ++ ++@item gdb-@value{GDBVN}/libiberty ++source for the @samp{-liberty} free software library ++ ++@item gdb-@value{GDBVN}/opcodes ++source for the library of opcode tables and disassemblers ++ ++@item gdb-@value{GDBVN}/readline ++source for the @sc{gnu} command-line interface ++@end table ++ ++There may be other subdirectories as well. ++ ++The simplest way to configure and build @value{GDBN} is to run @file{configure} ++from the @file{gdb-@var{version-number}} source directory, which in ++this example is the @file{gdb-@value{GDBVN}} directory. ++ ++First switch to the @file{gdb-@var{version-number}} source directory ++if you are not already in it; then run @file{configure}. Pass the ++identifier for the platform on which @value{GDBN} will run as an ++argument. ++ ++For example: ++ ++@smallexample ++cd gdb-@value{GDBVN} ++./configure ++make ++@end smallexample ++ ++Running @samp{configure} and then running @code{make} builds the ++included supporting libraries, then @code{gdb} itself. The configured ++source files, and the binaries, are left in the corresponding source ++directories. ++ ++@need 750 ++@file{configure} is a Bourne-shell (@code{/bin/sh}) script; if your ++system does not recognize this automatically when you run a different ++shell, you may need to run @code{sh} on it explicitly: ++ ++@smallexample ++sh configure ++@end smallexample ++ ++You should run the @file{configure} script from the top directory in the ++source tree, the @file{gdb-@var{version-number}} directory. If you run ++@file{configure} from one of the subdirectories, you will configure only ++that subdirectory. That is usually not what you want. In particular, ++if you run the first @file{configure} from the @file{gdb} subdirectory ++of the @file{gdb-@var{version-number}} directory, you will omit the ++configuration of @file{bfd}, @file{readline}, and other sibling ++directories of the @file{gdb} subdirectory. This leads to build errors ++about missing include files such as @file{bfd/bfd.h}. ++ ++You can install @code{@value{GDBN}} anywhere. The best way to do this ++is to pass the @code{--prefix} option to @code{configure}, and then ++install it with @code{make install}. ++ ++@node Separate Objdir ++@section Compiling @value{GDBN} in Another Directory ++ ++If you want to run @value{GDBN} versions for several host or target machines, ++you need a different @code{gdb} compiled for each combination of ++host and target. @file{configure} is designed to make this easy by ++allowing you to generate each configuration in a separate subdirectory, ++rather than in the source directory. If your @code{make} program ++handles the @samp{VPATH} feature (@sc{gnu} @code{make} does), running ++@code{make} in each of these directories builds the @code{gdb} ++program specified there. ++ ++To build @code{gdb} in a separate directory, run @file{configure} ++with the @samp{--srcdir} option to specify where to find the source. ++(You also need to specify a path to find @file{configure} ++itself from your working directory. If the path to @file{configure} ++would be the same as the argument to @samp{--srcdir}, you can leave out ++the @samp{--srcdir} option; it is assumed.) ++ ++For example, with version @value{GDBVN}, you can build @value{GDBN} in a ++separate directory for a Sun 4 like this: ++ ++@smallexample ++@group ++cd gdb-@value{GDBVN} ++mkdir ../gdb-sun4 ++cd ../gdb-sun4 ++../gdb-@value{GDBVN}/configure ++make ++@end group ++@end smallexample ++ ++When @file{configure} builds a configuration using a remote source ++directory, it creates a tree for the binaries with the same structure ++(and using the same names) as the tree under the source directory. In ++the example, you'd find the Sun 4 library @file{libiberty.a} in the ++directory @file{gdb-sun4/libiberty}, and @value{GDBN} itself in ++@file{gdb-sun4/gdb}. ++ ++Make sure that your path to the @file{configure} script has just one ++instance of @file{gdb} in it. If your path to @file{configure} looks ++like @file{../gdb-@value{GDBVN}/gdb/configure}, you are configuring only ++one subdirectory of @value{GDBN}, not the whole package. This leads to ++build errors about missing include files such as @file{bfd/bfd.h}. ++ ++One popular reason to build several @value{GDBN} configurations in separate ++directories is to configure @value{GDBN} for cross-compiling (where ++@value{GDBN} runs on one machine---the @dfn{host}---while debugging ++programs that run on another machine---the @dfn{target}). ++You specify a cross-debugging target by ++giving the @samp{--target=@var{target}} option to @file{configure}. ++ ++When you run @code{make} to build a program or library, you must run ++it in a configured directory---whatever directory you were in when you ++called @file{configure} (or one of its subdirectories). ++ ++The @code{Makefile} that @file{configure} generates in each source ++directory also runs recursively. If you type @code{make} in a source ++directory such as @file{gdb-@value{GDBVN}} (or in a separate configured ++directory configured with @samp{--srcdir=@var{dirname}/gdb-@value{GDBVN}}), you ++will build all the required libraries, and then build GDB. ++ ++When you have multiple hosts or targets configured in separate ++directories, you can run @code{make} on them in parallel (for example, ++if they are NFS-mounted on each of the hosts); they will not interfere ++with each other. ++ ++@node Config Names ++@section Specifying Names for Hosts and Targets ++ ++The specifications used for hosts and targets in the @file{configure} ++script are based on a three-part naming scheme, but some short predefined ++aliases are also supported. The full naming scheme encodes three pieces ++of information in the following pattern: ++ ++@smallexample ++@var{architecture}-@var{vendor}-@var{os} ++@end smallexample ++ ++For example, you can use the alias @code{sun4} as a @var{host} argument, ++or as the value for @var{target} in a @code{--target=@var{target}} ++option. The equivalent full name is @samp{sparc-sun-sunos4}. ++ ++The @file{configure} script accompanying @value{GDBN} does not provide ++any query facility to list all supported host and target names or ++aliases. @file{configure} calls the Bourne shell script ++@code{config.sub} to map abbreviations to full names; you can read the ++script, if you wish, or you can use it to test your guesses on ++abbreviations---for example: ++ ++@smallexample ++% sh config.sub i386-linux ++i386-pc-linux-gnu ++% sh config.sub alpha-linux ++alpha-unknown-linux-gnu ++% sh config.sub sw_64-linux ++sw_64-unknown-linux-gnu ++% sh config.sub hp9k700 ++hppa1.1-hp-hpux ++% sh config.sub sun4 ++sparc-sun-sunos4.1.1 ++% sh config.sub sun3 ++m68k-sun-sunos4.1.1 ++% sh config.sub i986v ++Invalid configuration `i986v': machine `i986v' not recognized ++@end smallexample ++ ++@noindent ++@code{config.sub} is also distributed in the @value{GDBN} source ++directory (@file{gdb-@value{GDBVN}}, for version @value{GDBVN}). ++ ++@node Configure Options ++@section @file{configure} Options ++ ++Here is a summary of the @file{configure} options and arguments that ++are most often useful for building @value{GDBN}. @file{configure} ++also has several other options not listed here. @inforef{Running ++configure scripts,,autoconf.info}, for a full ++explanation of @file{configure}. ++ ++@smallexample ++configure @r{[}--help@r{]} ++ @r{[}--prefix=@var{dir}@r{]} ++ @r{[}--exec-prefix=@var{dir}@r{]} ++ @r{[}--srcdir=@var{dirname}@r{]} ++ @r{[}--target=@var{target}@r{]} ++@end smallexample ++ ++@noindent ++You may introduce options with a single @samp{-} rather than ++@samp{--} if you prefer; but you may abbreviate option names if you use ++@samp{--}. ++ ++@table @code ++@item --help ++Display a quick summary of how to invoke @file{configure}. ++ ++@item --prefix=@var{dir} ++Configure the source to install programs and files under directory ++@file{@var{dir}}. ++ ++@item --exec-prefix=@var{dir} ++Configure the source to install programs under directory ++@file{@var{dir}}. ++ ++@c avoid splitting the warning from the explanation: ++@need 2000 ++@item --srcdir=@var{dirname} ++Use this option to make configurations in directories separate from the ++@value{GDBN} source directories. Among other things, you can use this to ++build (or maintain) several configurations simultaneously, in separate ++directories. @file{configure} writes configuration-specific files in ++the current directory, but arranges for them to use the source in the ++directory @var{dirname}. @file{configure} creates directories under ++the working directory in parallel to the source directories below ++@var{dirname}. ++ ++@item --target=@var{target} ++Configure @value{GDBN} for cross-debugging programs running on the specified ++@var{target}. Without this option, @value{GDBN} is configured to debug ++programs that run on the same machine (@var{host}) as @value{GDBN} itself. ++ ++There is no convenient way to generate a list of all available ++targets. Also see the @code{--enable-targets} option, below. ++@end table ++ ++There are many other options that are specific to @value{GDBN}. This ++lists just the most common ones; there are some very specialized ++options not described here. ++ ++@table @code ++@item --enable-targets=@r{[}@var{target}@r{]}@dots{} ++@itemx --enable-targets=all ++Configure @value{GDBN} for cross-debugging programs running on the ++specified list of targets. The special value @samp{all} configures ++@value{GDBN} for debugging programs running on any target it supports. ++ ++@item --with-gdb-datadir=@var{path} ++Set the @value{GDBN}-specific data directory. @value{GDBN} will look ++here for certain supporting files or scripts. This defaults to the ++@file{gdb} subdirectory of @samp{datadir} (which can be set using ++@code{--datadir}). ++ ++@item --with-relocated-sources=@var{dir} ++Sets up the default source path substitution rule so that directory ++names recorded in debug information will be automatically adjusted for ++any directory under @var{dir}. @var{dir} should be a subdirectory of ++@value{GDBN}'s configured prefix, the one mentioned in the ++@code{--prefix} or @code{--exec-prefix} options to configure. This ++option is useful if GDB is supposed to be moved to a different place ++after it is built. ++ ++@item --enable-64-bit-bfd ++Enable 64-bit support in BFD on 32-bit hosts. ++ ++@item --disable-gdbmi ++Build @value{GDBN} without the GDB/MI machine interface ++(@pxref{GDB/MI}). ++ ++@item --enable-tui ++Build @value{GDBN} with the text-mode full-screen user interface ++(TUI). Requires a curses library (ncurses and cursesX are also ++supported). ++ ++@item --with-curses ++Use the curses library instead of the termcap library, for text-mode ++terminal operations. ++ ++@item --with-debuginfod ++Build @value{GDBN} with libdebuginfod, the debuginfod client library. ++Used to automatically fetch source files and separate debug files from ++debuginfod servers using the associated executable's build ID. Enabled ++by default if libdebuginfod is installed and found at configure time. ++debuginfod is packaged with elfutils, starting with version 0.178. You ++can get the latest version from `https://sourceware.org/elfutils/'. ++ ++@item --with-libunwind-ia64 ++Use the libunwind library for unwinding function call stack on ia64 ++target platforms. See http://www.nongnu.org/libunwind/index.html for ++details. ++ ++@item --with-system-readline ++Use the readline library installed on the host, rather than the ++library supplied as part of @value{GDBN}. Readline 7 or newer is ++required; this is enforced by the build system. ++ ++@item --with-system-zlib ++Use the zlib library installed on the host, rather than the library ++supplied as part of @value{GDBN}. ++ ++@item --with-expat ++Build @value{GDBN} with Expat, a library for XML parsing. (Done by ++default if libexpat is installed and found at configure time.) This ++library is used to read XML files supplied with @value{GDBN}. If it ++is unavailable, some features, such as remote protocol memory maps, ++target descriptions, and shared library lists, that are based on XML ++files, will not be available in @value{GDBN}. If your host does not ++have libexpat installed, you can get the latest version from ++`http://expat.sourceforge.net'. ++ ++@item --with-libiconv-prefix@r{[}=@var{dir}@r{]} ++ ++Build @value{GDBN} with GNU libiconv, a character set encoding ++conversion library. This is not done by default, as on GNU systems ++the @code{iconv} that is built in to the C library is sufficient. If ++your host does not have a working @code{iconv}, you can get the latest ++version of GNU iconv from `https://www.gnu.org/software/libiconv/'. ++ ++@value{GDBN}'s build system also supports building GNU libiconv as ++part of the overall build. @xref{Requirements}. ++ ++@item --with-lzma ++Build @value{GDBN} with LZMA, a compression library. (Done by default ++if liblzma is installed and found at configure time.) LZMA is used by ++@value{GDBN}'s "mini debuginfo" feature, which is only useful on ++platforms using the ELF object file format. If your host does not ++have liblzma installed, you can get the latest version from ++`https://tukaani.org/xz/'. ++ ++@item --with-mpfr ++Build @value{GDBN} with GNU MPFR, a library for multiple-precision ++floating-point computation with correct rounding. (Done by default if ++GNU MPFR is installed and found at configure time.) This library is ++used to emulate target floating-point arithmetic during expression ++evaluation when the target uses different floating-point formats than ++the host. If GNU MPFR is not available, @value{GDBN} will fall back ++to using host floating-point arithmetic. If your host does not have ++GNU MPFR installed, you can get the latest version from ++`http://www.mpfr.org'. ++ ++@item --with-python@r{[}=@var{python}@r{]} ++Build @value{GDBN} with Python scripting support. (Done by default if ++libpython is present and found at configure time.) Python makes ++@value{GDBN} scripting much more powerful than the restricted CLI ++scripting language. If your host does not have Python installed, you ++can find it on `http://www.python.org/download/'. The oldest version ++of Python supported by GDB is 2.6. The optional argument @var{python} ++is used to find the Python headers and libraries. It can be either ++the name of a Python executable, or the name of the directory in which ++Python is installed. ++ ++@item --with-guile[=GUILE]' ++Build @value{GDBN} with GNU Guile scripting support. (Done by default ++if libguile is present and found at configure time.) If your host ++does not have Guile installed, you can find it at ++`https://www.gnu.org/software/guile/'. The optional argument GUILE ++can be a version number, which will cause @code{configure} to try to ++use that version of Guile; or the file name of a @code{pkg-config} ++executable, which will be queried to find the information needed to ++compile and link against Guile. ++ ++@item --without-included-regex ++Don't use the regex library included with @value{GDBN} (as part of the ++libiberty library). This is the default on hosts with version 2 of ++the GNU C library. ++ ++@item --with-sysroot=@var{dir} ++Use @var{dir} as the default system root directory for libraries whose ++file names begin with @file{/lib}' or @file{/usr/lib'}. (The value of ++@var{dir} can be modified at run time by using the @command{set ++sysroot} command.) If @var{dir} is under the @value{GDBN} configured ++prefix (set with @code{--prefix} or @code{--exec-prefix options}, the ++default system root will be automatically adjusted if and when ++@value{GDBN} is moved to a different location. ++ ++@item --with-system-gdbinit=@var{file} ++Configure @value{GDBN} to automatically load a system-wide init file. ++@var{file} should be an absolute file name. If @var{file} is in a ++directory under the configured prefix, and @value{GDBN} is moved to ++another location after being built, the location of the system-wide ++init file will be adjusted accordingly. ++ ++@item --with-system-gdbinit-dir=@var{directory} ++Configure @value{GDBN} to automatically load init files from a ++system-wide directory. @var{directory} should be an absolute directory ++name. If @var{directory} is in a directory under the configured ++prefix, and @value{GDBN} is moved to another location after being ++built, the location of the system-wide init directory will be ++adjusted accordingly. ++ ++@item --enable-build-warnings ++When building the @value{GDBN} sources, ask the compiler to warn about ++any code which looks even vaguely suspicious. It passes many ++different warning flags, depending on the exact version of the ++compiler you are using. ++ ++@item --enable-werror ++Treat compiler warnings as werrors. It adds the @code{-Werror} flag ++to the compiler, which will fail the compilation if the compiler ++outputs any warning messages. ++ ++@item --enable-ubsan ++Enable the GCC undefined behavior sanitizer. This is disabled by ++default, but passing @code{--enable-ubsan=yes} or ++@code{--enable-ubsan=auto} to @code{configure} will enable it. The ++undefined behavior sanitizer checks for C@t{++} undefined behavior. ++It has a performance cost, so if you are looking at @value{GDBN}'s ++performance, you should disable it. The undefined behavior sanitizer ++was first introduced in GCC 4.9. ++@end table ++ ++@node System-wide configuration ++@section System-wide configuration and settings ++@cindex system-wide init file ++ ++@value{GDBN} can be configured to have a system-wide init file and a ++system-wide init file directory; this file and files in that directory ++(if they have a recognized file extension) will be read and executed at ++startup (@pxref{Startup, , What @value{GDBN} does during startup}). ++ ++Here are the corresponding configure options: ++ ++@table @code ++@item --with-system-gdbinit=@var{file} ++Specify that the default location of the system-wide init file is ++@var{file}. ++@item --with-system-gdbinit-dir=@var{directory} ++Specify that the default location of the system-wide init file directory ++is @var{directory}. ++@end table ++ ++If @value{GDBN} has been configured with the option @option{--prefix=$prefix}, ++they may be subject to relocation. Two possible cases: ++ ++@itemize @bullet ++@item ++If the default location of this init file/directory contains @file{$prefix}, ++it will be subject to relocation. Suppose that the configure options ++are @option{--prefix=$prefix --with-system-gdbinit=$prefix/etc/gdbinit}; ++if @value{GDBN} is moved from @file{$prefix} to @file{$install}, the system ++init file is looked for as @file{$install/etc/gdbinit} instead of ++@file{$prefix/etc/gdbinit}. ++ ++@item ++By contrast, if the default location does not contain the prefix, ++it will not be relocated. E.g.@: if @value{GDBN} has been configured with ++@option{--prefix=/usr/local --with-system-gdbinit=/usr/share/gdb/gdbinit}, ++then @value{GDBN} will always look for @file{/usr/share/gdb/gdbinit}, ++wherever @value{GDBN} is installed. ++@end itemize ++ ++If the configured location of the system-wide init file (as given by the ++@option{--with-system-gdbinit} option at configure time) is in the ++data-directory (as specified by @option{--with-gdb-datadir} at configure ++time) or in one of its subdirectories, then @value{GDBN} will look for the ++system-wide init file in the directory specified by the ++@option{--data-directory} command-line option. ++Note that the system-wide init file is only read once, during @value{GDBN} ++initialization. If the data-directory is changed after @value{GDBN} has ++started with the @code{set data-directory} command, the file will not be ++reread. ++ ++This applies similarly to the system-wide directory specified in ++@option{--with-system-gdbinit-dir}. ++ ++Any supported scripting language can be used for these init files, as long ++as the file extension matches the scripting language. To be interpreted ++as regular @value{GDBN} commands, the files needs to have a @file{.gdb} ++extension. ++ ++@menu ++* System-wide Configuration Scripts:: Installed System-wide Configuration Scripts ++@end menu ++ ++@node System-wide Configuration Scripts ++@subsection Installed System-wide Configuration Scripts ++@cindex system-wide configuration scripts ++ ++The @file{system-gdbinit} directory, located inside the data-directory ++(as specified by @option{--with-gdb-datadir} at configure time) contains ++a number of scripts which can be used as system-wide init files. To ++automatically source those scripts at startup, @value{GDBN} should be ++configured with @option{--with-system-gdbinit}. Otherwise, any user ++should be able to source them by hand as needed. ++ ++The following scripts are currently available: ++@itemize @bullet ++ ++@item @file{elinos.py} ++@pindex elinos.py ++@cindex ELinOS system-wide configuration script ++This script is useful when debugging a program on an ELinOS target. ++It takes advantage of the environment variables defined in a standard ++ELinOS environment in order to determine the location of the system ++shared libraries, and then sets the @samp{solib-absolute-prefix} ++and @samp{solib-search-path} variables appropriately. ++ ++@item @file{wrs-linux.py} ++@pindex wrs-linux.py ++@cindex Wind River Linux system-wide configuration script ++This script is useful when debugging a program on a target running ++Wind River Linux. It expects the @env{ENV_PREFIX} to be set to ++the host-side sysroot used by the target system. ++ ++@end itemize ++ ++@node Maintenance Commands ++@appendix Maintenance Commands ++@cindex maintenance commands ++@cindex internal commands ++ ++In addition to commands intended for @value{GDBN} users, @value{GDBN} ++includes a number of commands intended for @value{GDBN} developers, ++that are not documented elsewhere in this manual. These commands are ++provided here for reference. (For commands that turn on debugging ++messages, see @ref{Debugging Output}.) ++ ++@table @code ++@kindex maint agent ++@kindex maint agent-eval ++@item maint agent @r{[}-at @var{location}@r{,}@r{]} @var{expression} ++@itemx maint agent-eval @r{[}-at @var{location}@r{,}@r{]} @var{expression} ++Translate the given @var{expression} into remote agent bytecodes. ++This command is useful for debugging the Agent Expression mechanism ++(@pxref{Agent Expressions}). The @samp{agent} version produces an ++expression useful for data collection, such as by tracepoints, while ++@samp{maint agent-eval} produces an expression that evaluates directly ++to a result. For instance, a collection expression for @code{globa + ++globb} will include bytecodes to record four bytes of memory at each ++of the addresses of @code{globa} and @code{globb}, while discarding ++the result of the addition, while an evaluation expression will do the ++addition and return the sum. ++If @code{-at} is given, generate remote agent bytecode for @var{location}. ++If not, generate remote agent bytecode for current frame PC address. ++ ++@kindex maint agent-printf ++@item maint agent-printf @var{format},@var{expr},... ++Translate the given format string and list of argument expressions ++into remote agent bytecodes and display them as a disassembled list. ++This command is useful for debugging the agent version of dynamic ++printf (@pxref{Dynamic Printf}). ++ ++@kindex maint info breakpoints ++@item @anchor{maint info breakpoints}maint info breakpoints ++Using the same format as @samp{info breakpoints}, display both the ++breakpoints you've set explicitly, and those @value{GDBN} is using for ++internal purposes. Internal breakpoints are shown with negative ++breakpoint numbers. The type column identifies what kind of breakpoint ++is shown: ++ ++@table @code ++@item breakpoint ++Normal, explicitly set breakpoint. ++ ++@item watchpoint ++Normal, explicitly set watchpoint. ++ ++@item longjmp ++Internal breakpoint, used to handle correctly stepping through ++@code{longjmp} calls. ++ ++@item longjmp resume ++Internal breakpoint at the target of a @code{longjmp}. ++ ++@item until ++Temporary internal breakpoint used by the @value{GDBN} @code{until} command. ++ ++@item finish ++Temporary internal breakpoint used by the @value{GDBN} @code{finish} command. ++ ++@item shlib events ++Shared library events. ++ ++@end table ++ ++@kindex maint info btrace ++@item maint info btrace ++Pint information about raw branch tracing data. ++ ++@kindex maint btrace packet-history ++@item maint btrace packet-history ++Print the raw branch trace packets that are used to compute the ++execution history for the @samp{record btrace} command. Both the ++information and the format in which it is printed depend on the btrace ++recording format. ++ ++@table @code ++@item bts ++For the BTS recording format, print a list of blocks of sequential ++code. For each block, the following information is printed: ++ ++@table @asis ++@item Block number ++Newer blocks have higher numbers. The oldest block has number zero. ++@item Lowest @samp{PC} ++@item Highest @samp{PC} ++@end table ++ ++@item pt ++For the Intel Processor Trace recording format, print a list of ++Intel Processor Trace packets. For each packet, the following ++information is printed: ++ ++@table @asis ++@item Packet number ++Newer packets have higher numbers. The oldest packet has number zero. ++@item Trace offset ++The packet's offset in the trace stream. ++@item Packet opcode and payload ++@end table ++@end table ++ ++@kindex maint btrace clear-packet-history ++@item maint btrace clear-packet-history ++Discards the cached packet history printed by the @samp{maint btrace ++packet-history} command. The history will be computed again when ++needed. ++ ++@kindex maint btrace clear ++@item maint btrace clear ++Discard the branch trace data. The data will be fetched anew and the ++branch trace will be recomputed when needed. ++ ++This implicitly truncates the branch trace to a single branch trace ++buffer. When updating branch trace incrementally, the branch trace ++available to @value{GDBN} may be bigger than a single branch trace ++buffer. ++ ++@kindex maint set btrace pt skip-pad ++@item maint set btrace pt skip-pad ++@kindex maint show btrace pt skip-pad ++@item maint show btrace pt skip-pad ++Control whether @value{GDBN} will skip PAD packets when computing the ++packet history. ++ ++@kindex set displaced-stepping ++@kindex show displaced-stepping ++@cindex displaced stepping support ++@cindex out-of-line single-stepping ++@item set displaced-stepping ++@itemx show displaced-stepping ++Control whether or not @value{GDBN} will do @dfn{displaced stepping} ++if the target supports it. Displaced stepping is a way to single-step ++over breakpoints without removing them from the inferior, by executing ++an out-of-line copy of the instruction that was originally at the ++breakpoint location. It is also known as out-of-line single-stepping. ++ ++@table @code ++@item set displaced-stepping on ++If the target architecture supports it, @value{GDBN} will use ++displaced stepping to step over breakpoints. ++ ++@item set displaced-stepping off ++@value{GDBN} will not use displaced stepping to step over breakpoints, ++even if such is supported by the target architecture. ++ ++@cindex non-stop mode, and @samp{set displaced-stepping} ++@item set displaced-stepping auto ++This is the default mode. @value{GDBN} will use displaced stepping ++only if non-stop mode is active (@pxref{Non-Stop Mode}) and the target ++architecture supports displaced stepping. ++@end table ++ ++@kindex maint check-psymtabs ++@item maint check-psymtabs ++Check the consistency of currently expanded psymtabs versus symtabs. ++Use this to check, for example, whether a symbol is in one but not the other. ++ ++@kindex maint check-symtabs ++@item maint check-symtabs ++Check the consistency of currently expanded symtabs. ++ ++@kindex maint expand-symtabs ++@item maint expand-symtabs [@var{regexp}] ++Expand symbol tables. ++If @var{regexp} is specified, only expand symbol tables for file ++names matching @var{regexp}. ++ ++@kindex maint set catch-demangler-crashes ++@kindex maint show catch-demangler-crashes ++@cindex demangler crashes ++@item maint set catch-demangler-crashes [on|off] ++@itemx maint show catch-demangler-crashes ++Control whether @value{GDBN} should attempt to catch crashes in the ++symbol name demangler. The default is to attempt to catch crashes. ++If enabled, the first time a crash is caught, a core file is created, ++the offending symbol is displayed and the user is presented with the ++option to terminate the current session. ++ ++@kindex maint cplus first_component ++@item maint cplus first_component @var{name} ++Print the first C@t{++} class/namespace component of @var{name}. ++ ++@kindex maint cplus namespace ++@item maint cplus namespace ++Print the list of possible C@t{++} namespaces. ++ ++@kindex maint deprecate ++@kindex maint undeprecate ++@cindex deprecated commands ++@item maint deprecate @var{command} @r{[}@var{replacement}@r{]} ++@itemx maint undeprecate @var{command} ++Deprecate or undeprecate the named @var{command}. Deprecated commands ++cause @value{GDBN} to issue a warning when you use them. The optional ++argument @var{replacement} says which newer command should be used in ++favor of the deprecated one; if it is given, @value{GDBN} will mention ++the replacement as part of the warning. ++ ++@kindex maint dump-me ++@item maint dump-me ++@cindex @code{SIGQUIT} signal, dump core of @value{GDBN} ++Cause a fatal signal in the debugger and force it to dump its core. ++This is supported only on systems which support aborting a program ++with the @code{SIGQUIT} signal. ++ ++@kindex maint internal-error ++@kindex maint internal-warning ++@kindex maint demangler-warning ++@cindex demangler crashes ++@item maint internal-error @r{[}@var{message-text}@r{]} ++@itemx maint internal-warning @r{[}@var{message-text}@r{]} ++@itemx maint demangler-warning @r{[}@var{message-text}@r{]} ++ ++Cause @value{GDBN} to call the internal function @code{internal_error}, ++@code{internal_warning} or @code{demangler_warning} and hence behave ++as though an internal problem has been detected. In addition to ++reporting the internal problem, these functions give the user the ++opportunity to either quit @value{GDBN} or (for @code{internal_error} ++and @code{internal_warning}) create a core file of the current ++@value{GDBN} session. ++ ++These commands take an optional parameter @var{message-text} that is ++used as the text of the error or warning message. ++ ++Here's an example of using @code{internal-error}: ++ ++@smallexample ++(@value{GDBP}) @kbd{maint internal-error testing, 1, 2} ++@dots{}/maint.c:121: internal-error: testing, 1, 2 ++A problem internal to GDB has been detected. Further ++debugging may prove unreliable. ++Quit this debugging session? (y or n) @kbd{n} ++Create a core file? (y or n) @kbd{n} ++(@value{GDBP}) ++@end smallexample ++ ++@cindex @value{GDBN} internal error ++@cindex internal errors, control of @value{GDBN} behavior ++@cindex demangler crashes ++ ++@kindex maint set internal-error ++@kindex maint show internal-error ++@kindex maint set internal-warning ++@kindex maint show internal-warning ++@kindex maint set demangler-warning ++@kindex maint show demangler-warning ++@item maint set internal-error @var{action} [ask|yes|no] ++@itemx maint show internal-error @var{action} ++@itemx maint set internal-warning @var{action} [ask|yes|no] ++@itemx maint show internal-warning @var{action} ++@itemx maint set demangler-warning @var{action} [ask|yes|no] ++@itemx maint show demangler-warning @var{action} ++When @value{GDBN} reports an internal problem (error or warning) it ++gives the user the opportunity to both quit @value{GDBN} and create a ++core file of the current @value{GDBN} session. These commands let you ++override the default behaviour for each particular @var{action}, ++described in the table below. ++ ++@table @samp ++@item quit ++You can specify that @value{GDBN} should always (yes) or never (no) ++quit. The default is to ask the user what to do. ++ ++@item corefile ++You can specify that @value{GDBN} should always (yes) or never (no) ++create a core file. The default is to ask the user what to do. Note ++that there is no @code{corefile} option for @code{demangler-warning}: ++demangler warnings always create a core file and this cannot be ++disabled. ++@end table ++ ++@kindex maint packet ++@item maint packet @var{text} ++If @value{GDBN} is talking to an inferior via the serial protocol, ++then this command sends the string @var{text} to the inferior, and ++displays the response packet. @value{GDBN} supplies the initial ++@samp{$} character, the terminating @samp{#} character, and the ++checksum. ++ ++@kindex maint print architecture ++@item maint print architecture @r{[}@var{file}@r{]} ++Print the entire architecture configuration. The optional argument ++@var{file} names the file where the output goes. ++ ++@kindex maint print c-tdesc @r{[}@var{file}@r{]} ++@item maint print c-tdesc ++Print the target description (@pxref{Target Descriptions}) as ++a C source file. By default, the target description is for the current ++target, but if the optional argument @var{file} is provided, that file ++is used to produce the description. The @var{file} should be an XML ++document, of the form described in @ref{Target Description Format}. ++The created source file is built into @value{GDBN} when @value{GDBN} is ++built again. This command is used by developers after they add or ++modify XML target descriptions. ++ ++@kindex maint print xml-tdesc ++@item maint print xml-tdesc @r{[}@var{file}@r{]} ++Print the target description (@pxref{Target Descriptions}) as an XML ++file. By default print the target description for the current target, ++but if the optional argument @var{file} is provided, then that file is ++read in by GDB and then used to produce the description. The ++@var{file} should be an XML document, of the form described in ++@ref{Target Description Format}. ++ ++@kindex maint check xml-descriptions ++@item maint check xml-descriptions @var{dir} ++Check that the target descriptions dynamically created by @value{GDBN} ++equal the descriptions created from XML files found in @var{dir}. ++ ++@anchor{maint check libthread-db} ++@kindex maint check libthread-db ++@item maint check libthread-db ++Run integrity checks on the current inferior's thread debugging ++library. This exercises all @code{libthread_db} functionality used by ++@value{GDBN} on GNU/Linux systems, and by extension also exercises the ++@code{proc_service} functions provided by @value{GDBN} that ++@code{libthread_db} uses. Note that parts of the test may be skipped ++on some platforms when debugging core files. ++ ++@kindex maint print core-file-backed-mappings ++@cindex memory address space mappings ++@item maint print core-file-backed-mappings ++Print the file-backed mappings which were loaded from a core file note. ++This output represents state internal to @value{GDBN} and should be ++similar to the mappings displayed by the @code{info proc mappings} ++command. ++ ++@kindex maint print dummy-frames ++@item maint print dummy-frames ++Prints the contents of @value{GDBN}'s internal dummy-frame stack. ++ ++@smallexample ++(@value{GDBP}) @kbd{b add} ++@dots{} ++(@value{GDBP}) @kbd{print add(2,3)} ++Breakpoint 2, add (a=2, b=3) at @dots{} ++58 return (a + b); ++The program being debugged stopped while in a function called from GDB. ++@dots{} ++(@value{GDBP}) @kbd{maint print dummy-frames} ++0xa8206d8: id=@{stack=0xbfffe734,code=0xbfffe73f,!special@}, ptid=process 9353 ++(@value{GDBP}) ++@end smallexample ++ ++Takes an optional file parameter. ++ ++@kindex maint print registers ++@kindex maint print raw-registers ++@kindex maint print cooked-registers ++@kindex maint print register-groups ++@kindex maint print remote-registers ++@item maint print registers @r{[}@var{file}@r{]} ++@itemx maint print raw-registers @r{[}@var{file}@r{]} ++@itemx maint print cooked-registers @r{[}@var{file}@r{]} ++@itemx maint print register-groups @r{[}@var{file}@r{]} ++@itemx maint print remote-registers @r{[}@var{file}@r{]} ++Print @value{GDBN}'s internal register data structures. ++ ++The command @code{maint print raw-registers} includes the contents of ++the raw register cache; the command @code{maint print ++cooked-registers} includes the (cooked) value of all registers, ++including registers which aren't available on the target nor visible ++to user; the command @code{maint print register-groups} includes the ++groups that each register is a member of; and the command @code{maint ++print remote-registers} includes the remote target's register numbers ++and offsets in the `G' packets. ++ ++These commands take an optional parameter, a file name to which to ++write the information. ++ ++@kindex maint print reggroups ++@item maint print reggroups @r{[}@var{file}@r{]} ++Print @value{GDBN}'s internal register group data structures. The ++optional argument @var{file} tells to what file to write the ++information. ++ ++The register groups info looks like this: ++ ++@smallexample ++(@value{GDBP}) @kbd{maint print reggroups} ++ Group Type ++ general user ++ float user ++ all user ++ vector user ++ system user ++ save internal ++ restore internal ++@end smallexample ++ ++@kindex flushregs ++@item flushregs ++This command forces @value{GDBN} to flush its internal register cache. ++ ++@kindex maint print objfiles ++@cindex info for known object files ++@item maint print objfiles @r{[}@var{regexp}@r{]} ++Print a dump of all known object files. ++If @var{regexp} is specified, only print object files whose names ++match @var{regexp}. For each object file, this command prints its name, ++address in memory, and all of its psymtabs and symtabs. ++ ++@kindex maint print user-registers ++@cindex user registers ++@item maint print user-registers ++List all currently available @dfn{user registers}. User registers ++typically provide alternate names for actual hardware registers. They ++include the four ``standard'' registers @code{$fp}, @code{$pc}, ++@code{$sp}, and @code{$ps}. @xref{standard registers}. User ++registers can be used in expressions in the same way as the canonical ++register names, but only the latter are listed by the @code{info ++registers} and @code{maint print registers} commands. ++ ++@kindex maint print section-scripts ++@cindex info for known .debug_gdb_scripts-loaded scripts ++@item maint print section-scripts [@var{regexp}] ++Print a dump of scripts specified in the @code{.debug_gdb_section} section. ++If @var{regexp} is specified, only print scripts loaded by object files ++matching @var{regexp}. ++For each script, this command prints its name as specified in the objfile, ++and the full path if known. ++@xref{dotdebug_gdb_scripts section}. ++ ++@kindex maint print statistics ++@cindex bcache statistics ++@item maint print statistics ++This command prints, for each object file in the program, various data ++about that object file followed by the byte cache (@dfn{bcache}) ++statistics for the object file. The objfile data includes the number ++of minimal, partial, full, and stabs symbols, the number of types ++defined by the objfile, the number of as yet unexpanded psym tables, ++the number of line tables and string tables, and the amount of memory ++used by the various tables. The bcache statistics include the counts, ++sizes, and counts of duplicates of all and unique objects, max, ++average, and median entry size, total memory used and its overhead and ++savings, and various measures of the hash table size and chain ++lengths. ++ ++@kindex maint print target-stack ++@cindex target stack description ++@item maint print target-stack ++A @dfn{target} is an interface between the debugger and a particular ++kind of file or process. Targets can be stacked in @dfn{strata}, ++so that more than one target can potentially respond to a request. ++In particular, memory accesses will walk down the stack of targets ++until they find a target that is interested in handling that particular ++address. ++ ++This command prints a short description of each layer that was pushed on ++the @dfn{target stack}, starting from the top layer down to the bottom one. ++ ++@kindex maint print type ++@cindex type chain of a data type ++@item maint print type @var{expr} ++Print the type chain for a type specified by @var{expr}. The argument ++can be either a type name or a symbol. If it is a symbol, the type of ++that symbol is described. The type chain produced by this command is ++a recursive definition of the data type as stored in @value{GDBN}'s ++data structures, including its flags and contained types. ++ ++@kindex maint selftest ++@cindex self tests ++@item maint selftest @r{[}@var{filter}@r{]} ++Run any self tests that were compiled in to @value{GDBN}. This will ++print a message showing how many tests were run, and how many failed. ++If a @var{filter} is passed, only the tests with @var{filter} in their ++name will by ran. ++ ++@kindex maint info selftests ++@cindex self tests ++@item maint info selftests ++List the selftests compiled in to @value{GDBN}. ++ ++@kindex maint set dwarf always-disassemble ++@kindex maint show dwarf always-disassemble ++@item maint set dwarf always-disassemble ++@item maint show dwarf always-disassemble ++Control the behavior of @code{info address} when using DWARF debugging ++information. ++ ++The default is @code{off}, which means that @value{GDBN} should try to ++describe a variable's location in an easily readable format. When ++@code{on}, @value{GDBN} will instead display the DWARF location ++expression in an assembly-like format. Note that some locations are ++too complex for @value{GDBN} to describe simply; in this case you will ++always see the disassembly form. ++ ++Here is an example of the resulting disassembly: ++ ++@smallexample ++(gdb) info addr argc ++Symbol "argc" is a complex DWARF expression: ++ 1: DW_OP_fbreg 0 ++@end smallexample ++ ++For more information on these expressions, see ++@uref{http://www.dwarfstd.org/, the DWARF standard}. ++ ++@kindex maint set dwarf max-cache-age ++@kindex maint show dwarf max-cache-age ++@item maint set dwarf max-cache-age ++@itemx maint show dwarf max-cache-age ++Control the DWARF compilation unit cache. ++ ++@cindex DWARF compilation units cache ++In object files with inter-compilation-unit references, such as those ++produced by the GCC option @samp{-feliminate-dwarf2-dups}, the DWARF ++reader needs to frequently refer to previously read compilation units. ++This setting controls how long a compilation unit will remain in the ++cache if it is not referenced. A higher limit means that cached ++compilation units will be stored in memory longer, and more total ++memory will be used. Setting it to zero disables caching, which will ++slow down @value{GDBN} startup, but reduce memory consumption. ++ ++@kindex maint set dwarf unwinders ++@kindex maint show dwarf unwinders ++@item maint set dwarf unwinders ++@itemx maint show dwarf unwinders ++Control use of the DWARF frame unwinders. ++ ++@cindex DWARF frame unwinders ++Many targets that support DWARF debugging use @value{GDBN}'s DWARF ++frame unwinders to build the backtrace. Many of these targets will ++also have a second mechanism for building the backtrace for use in ++cases where DWARF information is not available, this second mechanism ++is often an analysis of a function's prologue. ++ ++In order to extend testing coverage of the second level stack ++unwinding mechanisms it is helpful to be able to disable the DWARF ++stack unwinders, this can be done with this switch. ++ ++In normal use of @value{GDBN} disabling the DWARF unwinders is not ++advisable, there are cases that are better handled through DWARF than ++prologue analysis, and the debug experience is likely to be better ++with the DWARF frame unwinders enabled. ++ ++If DWARF frame unwinders are not supported for a particular target ++architecture, then enabling this flag does not cause them to be used. ++ ++@kindex maint set worker-threads ++@kindex maint show worker-threads ++@item maint set worker-threads ++@item maint show worker-threads ++Control the number of worker threads that may be used by @value{GDBN}. ++On capable hosts, @value{GDBN} may use multiple threads to speed up ++certain CPU-intensive operations, such as demangling symbol names. ++While the number of threads used by @value{GDBN} may vary, this ++command can be used to set an upper bound on this number. The default ++is @code{unlimited}, which lets @value{GDBN} choose a reasonable ++number. Note that this only controls worker threads started by ++@value{GDBN} itself; libraries used by @value{GDBN} may start threads ++of their own. ++ ++@kindex maint set profile ++@kindex maint show profile ++@cindex profiling GDB ++@item maint set profile ++@itemx maint show profile ++Control profiling of @value{GDBN}. ++ ++Profiling will be disabled until you use the @samp{maint set profile} ++command to enable it. When you enable profiling, the system will begin ++collecting timing and execution count data; when you disable profiling or ++exit @value{GDBN}, the results will be written to a log file. Remember that ++if you use profiling, @value{GDBN} will overwrite the profiling log file ++(often called @file{gmon.out}). If you have a record of important profiling ++data in a @file{gmon.out} file, be sure to move it to a safe location. ++ ++Configuring with @samp{--enable-profiling} arranges for @value{GDBN} to be ++compiled with the @samp{-pg} compiler option. ++ ++@kindex maint set show-debug-regs ++@kindex maint show show-debug-regs ++@cindex hardware debug registers ++@item maint set show-debug-regs ++@itemx maint show show-debug-regs ++Control whether to show variables that mirror the hardware debug ++registers. Use @code{on} to enable, @code{off} to disable. If ++enabled, the debug registers values are shown when @value{GDBN} inserts or ++removes a hardware breakpoint or watchpoint, and when the inferior ++triggers a hardware-assisted breakpoint or watchpoint. ++ ++@kindex maint set show-all-tib ++@kindex maint show show-all-tib ++@item maint set show-all-tib ++@itemx maint show show-all-tib ++Control whether to show all non zero areas within a 1k block starting ++at thread local base, when using the @samp{info w32 thread-information-block} ++command. ++ ++@kindex maint set target-async ++@kindex maint show target-async ++@item maint set target-async ++@itemx maint show target-async ++This controls whether @value{GDBN} targets operate in synchronous or ++asynchronous mode (@pxref{Background Execution}). Normally the ++default is asynchronous, if it is available; but this can be changed ++to more easily debug problems occurring only in synchronous mode. ++ ++@kindex maint set target-non-stop @var{mode} [on|off|auto] ++@kindex maint show target-non-stop ++@item maint set target-non-stop ++@itemx maint show target-non-stop ++ ++This controls whether @value{GDBN} targets always operate in non-stop ++mode even if @code{set non-stop} is @code{off} (@pxref{Non-Stop ++Mode}). The default is @code{auto}, meaning non-stop mode is enabled ++if supported by the target. ++ ++@table @code ++@item maint set target-non-stop auto ++This is the default mode. @value{GDBN} controls the target in ++non-stop mode if the target supports it. ++ ++@item maint set target-non-stop on ++@value{GDBN} controls the target in non-stop mode even if the target ++does not indicate support. ++ ++@item maint set target-non-stop off ++@value{GDBN} does not control the target in non-stop mode even if the ++target supports it. ++@end table ++ ++@kindex maint set tui-resize-message ++@kindex maint show tui-resize-message ++@item maint set tui-resize-message ++@item maint show tui-resize-message ++Control whether @value{GDBN} displays a message each time the terminal ++is resized when in TUI mode. The default is @code{off}, which means ++that @value{GDBN} is silent during resizes. When @code{on}, ++@value{GDBN} will display a message after a resize is completed; the ++message will include a number indicating how many times the terminal ++has been resized. This setting is intended for use by the test suite, ++where it would otherwise be difficult to determine when a resize and ++refresh has been completed. ++ ++@kindex maint set per-command ++@kindex maint show per-command ++@item maint set per-command ++@itemx maint show per-command ++@cindex resources used by commands ++ ++@value{GDBN} can display the resources used by each command. ++This is useful in debugging performance problems. ++ ++@table @code ++@item maint set per-command space [on|off] ++@itemx maint show per-command space ++Enable or disable the printing of the memory used by GDB for each command. ++If enabled, @value{GDBN} will display how much memory each command ++took, following the command's own output. ++This can also be requested by invoking @value{GDBN} with the ++@option{--statistics} command-line switch (@pxref{Mode Options}). ++ ++@item maint set per-command time [on|off] ++@itemx maint show per-command time ++Enable or disable the printing of the execution time of @value{GDBN} ++for each command. ++If enabled, @value{GDBN} will display how much time it ++took to execute each command, following the command's own output. ++Both CPU time and wallclock time are printed. ++Printing both is useful when trying to determine whether the cost is ++CPU or, e.g., disk/network latency. ++Note that the CPU time printed is for @value{GDBN} only, it does not include ++the execution time of the inferior because there's no mechanism currently ++to compute how much time was spent by @value{GDBN} and how much time was ++spent by the program been debugged. ++This can also be requested by invoking @value{GDBN} with the ++@option{--statistics} command-line switch (@pxref{Mode Options}). ++ ++@item maint set per-command symtab [on|off] ++@itemx maint show per-command symtab ++Enable or disable the printing of basic symbol table statistics ++for each command. ++If enabled, @value{GDBN} will display the following information: ++ ++@enumerate a ++@item ++number of symbol tables ++@item ++number of primary symbol tables ++@item ++number of blocks in the blockvector ++@end enumerate ++@end table ++ ++@kindex maint set check-libthread-db ++@kindex maint show check-libthread-db ++@item maint set check-libthread-db [on|off] ++@itemx maint show check-libthread-db ++Control whether @value{GDBN} should run integrity checks on inferior ++specific thread debugging libraries as they are loaded. The default ++is not to perform such checks. If any check fails @value{GDBN} will ++unload the library and continue searching for a suitable candidate as ++described in @ref{set libthread-db-search-path}. For more information ++about the tests, see @ref{maint check libthread-db}. ++ ++@kindex maint space ++@cindex memory used by commands ++@item maint space @var{value} ++An alias for @code{maint set per-command space}. ++A non-zero value enables it, zero disables it. ++ ++@kindex maint time ++@cindex time of command execution ++@item maint time @var{value} ++An alias for @code{maint set per-command time}. ++A non-zero value enables it, zero disables it. ++ ++@kindex maint translate-address ++@item maint translate-address @r{[}@var{section}@r{]} @var{addr} ++Find the symbol stored at the location specified by the address ++@var{addr} and an optional section name @var{section}. If found, ++@value{GDBN} prints the name of the closest symbol and an offset from ++the symbol's location to the specified address. This is similar to ++the @code{info address} command (@pxref{Symbols}), except that this ++command also allows to find symbols in other sections. ++ ++If section was not specified, the section in which the symbol was found ++is also printed. For dynamically linked executables, the name of ++executable or shared library containing the symbol is printed as well. ++ ++@kindex maint test-options ++@item maint test-options require-delimiter ++@itemx maint test-options unknown-is-error ++@itemx maint test-options unknown-is-operand ++These commands are used by the testsuite to validate the command ++options framework. The @code{require-delimiter} variant requires a ++double-dash delimiter to indicate end of options. The ++@code{unknown-is-error} and @code{unknown-is-operand} do not. The ++@code{unknown-is-error} variant throws an error on unknown option, ++while @code{unknown-is-operand} treats unknown options as the start of ++the command's operands. When run, the commands output the result of ++the processed options. When completed, the commands store the ++internal result of completion in a variable exposed by the @code{maint ++show test-options-completion-result} command. ++ ++@kindex maint show test-options-completion-result ++@item maint show test-options-completion-result ++Shows the result of completing the @code{maint test-options} ++subcommands. This is used by the testsuite to validate completion ++support in the command options framework. ++ ++@kindex maint set test-settings ++@kindex maint show test-settings ++@item maint set test-settings @var{kind} ++@itemx maint show test-settings @var{kind} ++These are representative commands for each @var{kind} of setting type ++@value{GDBN} supports. They are used by the testsuite for exercising ++the settings infrastructure. ++ ++@kindex maint with ++@item maint with @var{setting} [@var{value}] [-- @var{command}] ++Like the @code{with} command, but works with @code{maintenance set} ++variables. This is used by the testsuite to exercise the @code{with} ++command's infrastructure. ++ ++@end table ++ ++The following command is useful for non-interactive invocations of ++@value{GDBN}, such as in the test suite. ++ ++@table @code ++@item set watchdog @var{nsec} ++@kindex set watchdog ++@cindex watchdog timer ++@cindex timeout for commands ++Set the maximum number of seconds @value{GDBN} will wait for the ++target operation to finish. If this time expires, @value{GDBN} ++reports and error and the command is aborted. ++ ++@item show watchdog ++Show the current setting of the target wait timeout. ++@end table ++ ++@node Remote Protocol ++@appendix @value{GDBN} Remote Serial Protocol ++ ++@menu ++* Overview:: ++* Packets:: ++* Stop Reply Packets:: ++* General Query Packets:: ++* Architecture-Specific Protocol Details:: ++* Tracepoint Packets:: ++* Host I/O Packets:: ++* Interrupts:: ++* Notification Packets:: ++* Remote Non-Stop:: ++* Packet Acknowledgment:: ++* Examples:: ++* File-I/O Remote Protocol Extension:: ++* Library List Format:: ++* Library List Format for SVR4 Targets:: ++* Memory Map Format:: ++* Thread List Format:: ++* Traceframe Info Format:: ++* Branch Trace Format:: ++* Branch Trace Configuration Format:: ++@end menu ++ ++@node Overview ++@section Overview ++ ++There may be occasions when you need to know something about the ++protocol---for example, if there is only one serial port to your target ++machine, you might want your program to do something special if it ++recognizes a packet meant for @value{GDBN}. ++ ++In the examples below, @samp{->} and @samp{<-} are used to indicate ++transmitted and received data, respectively. ++ ++@cindex protocol, @value{GDBN} remote serial ++@cindex serial protocol, @value{GDBN} remote ++@cindex remote serial protocol ++All @value{GDBN} commands and responses (other than acknowledgments ++and notifications, see @ref{Notification Packets}) are sent as a ++@var{packet}. A @var{packet} is introduced with the character ++@samp{$}, the actual @var{packet-data}, and the terminating character ++@samp{#} followed by a two-digit @var{checksum}: ++ ++@smallexample ++@code{$}@var{packet-data}@code{#}@var{checksum} ++@end smallexample ++@noindent ++ ++@cindex checksum, for @value{GDBN} remote ++@noindent ++The two-digit @var{checksum} is computed as the modulo 256 sum of all ++characters between the leading @samp{$} and the trailing @samp{#} (an ++eight bit unsigned checksum). ++ ++Implementors should note that prior to @value{GDBN} 5.0 the protocol ++specification also included an optional two-digit @var{sequence-id}: ++ ++@smallexample ++@code{$}@var{sequence-id}@code{:}@var{packet-data}@code{#}@var{checksum} ++@end smallexample ++ ++@cindex sequence-id, for @value{GDBN} remote ++@noindent ++That @var{sequence-id} was appended to the acknowledgment. @value{GDBN} ++has never output @var{sequence-id}s. Stubs that handle packets added ++since @value{GDBN} 5.0 must not accept @var{sequence-id}. ++ ++When either the host or the target machine receives a packet, the first ++response expected is an acknowledgment: either @samp{+} (to indicate ++the package was received correctly) or @samp{-} (to request ++retransmission): ++ ++@smallexample ++-> @code{$}@var{packet-data}@code{#}@var{checksum} ++<- @code{+} ++@end smallexample ++@noindent ++ ++The @samp{+}/@samp{-} acknowledgments can be disabled ++once a connection is established. ++@xref{Packet Acknowledgment}, for details. ++ ++The host (@value{GDBN}) sends @var{command}s, and the target (the ++debugging stub incorporated in your program) sends a @var{response}. In ++the case of step and continue @var{command}s, the response is only sent ++when the operation has completed, and the target has again stopped all ++threads in all attached processes. This is the default all-stop mode ++behavior, but the remote protocol also supports @value{GDBN}'s non-stop ++execution mode; see @ref{Remote Non-Stop}, for details. ++ ++@var{packet-data} consists of a sequence of characters with the ++exception of @samp{#} and @samp{$} (see @samp{X} packet for additional ++exceptions). ++ ++@cindex remote protocol, field separator ++Fields within the packet should be separated using @samp{,} @samp{;} or ++@samp{:}. Except where otherwise noted all numbers are represented in ++@sc{hex} with leading zeros suppressed. ++ ++Implementors should note that prior to @value{GDBN} 5.0, the character ++@samp{:} could not appear as the third character in a packet (as it ++would potentially conflict with the @var{sequence-id}). ++ ++@cindex remote protocol, binary data ++@anchor{Binary Data} ++Binary data in most packets is encoded either as two hexadecimal ++digits per byte of binary data. This allowed the traditional remote ++protocol to work over connections which were only seven-bit clean. ++Some packets designed more recently assume an eight-bit clean ++connection, and use a more efficient encoding to send and receive ++binary data. ++ ++The binary data representation uses @code{7d} (@sc{ascii} @samp{@}}) ++as an escape character. Any escaped byte is transmitted as the escape ++character followed by the original character XORed with @code{0x20}. ++For example, the byte @code{0x7d} would be transmitted as the two ++bytes @code{0x7d 0x5d}. The bytes @code{0x23} (@sc{ascii} @samp{#}), ++@code{0x24} (@sc{ascii} @samp{$}), and @code{0x7d} (@sc{ascii} ++@samp{@}}) must always be escaped. Responses sent by the stub ++must also escape @code{0x2a} (@sc{ascii} @samp{*}), so that it ++is not interpreted as the start of a run-length encoded sequence ++(described next). ++ ++Response @var{data} can be run-length encoded to save space. ++Run-length encoding replaces runs of identical characters with one ++instance of the repeated character, followed by a @samp{*} and a ++repeat count. The repeat count is itself sent encoded, to avoid ++binary characters in @var{data}: a value of @var{n} is sent as ++@code{@var{n}+29}. For a repeat count greater or equal to 3, this ++produces a printable @sc{ascii} character, e.g.@: a space (@sc{ascii} ++code 32) for a repeat count of 3. (This is because run-length ++encoding starts to win for counts 3 or more.) Thus, for example, ++@samp{0* } is a run-length encoding of ``0000'': the space character ++after @samp{*} means repeat the leading @code{0} @w{@code{32 - 29 = ++3}} more times. ++ ++The printable characters @samp{#} and @samp{$} or with a numeric value ++greater than 126 must not be used. Runs of six repeats (@samp{#}) or ++seven repeats (@samp{$}) can be expanded using a repeat count of only ++five (@samp{"}). For example, @samp{00000000} can be encoded as ++@samp{0*"00}. ++ ++The error response returned for some packets includes a two character ++error number. That number is not well defined. ++ ++@cindex empty response, for unsupported packets ++For any @var{command} not supported by the stub, an empty response ++(@samp{$#00}) should be returned. That way it is possible to extend the ++protocol. A newer @value{GDBN} can tell if a packet is supported based ++on that response. ++ ++At a minimum, a stub is required to support the @samp{?} command to ++tell @value{GDBN} the reason for halting, @samp{g} and @samp{G} ++commands for register access, and the @samp{m} and @samp{M} commands ++for memory access. Stubs that only control single-threaded targets ++can implement run control with the @samp{c} (continue) command, and if ++the target architecture supports hardware-assisted single-stepping, ++the @samp{s} (step) command. Stubs that support multi-threading ++targets should support the @samp{vCont} command. All other commands ++are optional. ++ ++@node Packets ++@section Packets ++ ++The following table provides a complete list of all currently defined ++@var{command}s and their corresponding response @var{data}. ++@xref{File-I/O Remote Protocol Extension}, for details about the File ++I/O extension of the remote protocol. ++ ++Each packet's description has a template showing the packet's overall ++syntax, followed by an explanation of the packet's meaning. We ++include spaces in some of the templates for clarity; these are not ++part of the packet's syntax. No @value{GDBN} packet uses spaces to ++separate its components. For example, a template like @samp{foo ++@var{bar} @var{baz}} describes a packet beginning with the three ASCII ++bytes @samp{foo}, followed by a @var{bar}, followed directly by a ++@var{baz}. @value{GDBN} does not transmit a space character between the ++@samp{foo} and the @var{bar}, or between the @var{bar} and the ++@var{baz}. ++ ++@cindex @var{thread-id}, in remote protocol ++@anchor{thread-id syntax} ++Several packets and replies include a @var{thread-id} field to identify ++a thread. Normally these are positive numbers with a target-specific ++interpretation, formatted as big-endian hex strings. A @var{thread-id} ++can also be a literal @samp{-1} to indicate all threads, or @samp{0} to ++pick any thread. ++ ++In addition, the remote protocol supports a multiprocess feature in ++which the @var{thread-id} syntax is extended to optionally include both ++process and thread ID fields, as @samp{p@var{pid}.@var{tid}}. ++The @var{pid} (process) and @var{tid} (thread) components each have the ++format described above: a positive number with target-specific ++interpretation formatted as a big-endian hex string, literal @samp{-1} ++to indicate all processes or threads (respectively), or @samp{0} to ++indicate an arbitrary process or thread. Specifying just a process, as ++@samp{p@var{pid}}, is equivalent to @samp{p@var{pid}.-1}. It is an ++error to specify all processes but a specific thread, such as ++@samp{p-1.@var{tid}}. Note that the @samp{p} prefix is @emph{not} used ++for those packets and replies explicitly documented to include a process ++ID, rather than a @var{thread-id}. ++ ++The multiprocess @var{thread-id} syntax extensions are only used if both ++@value{GDBN} and the stub report support for the @samp{multiprocess} ++feature using @samp{qSupported}. @xref{multiprocess extensions}, for ++more information. ++ ++Note that all packet forms beginning with an upper- or lower-case ++letter, other than those described here, are reserved for future use. ++ ++Here are the packet descriptions. ++ ++@table @samp ++ ++@item ! ++@cindex @samp{!} packet ++@anchor{extended mode} ++Enable extended mode. In extended mode, the remote server is made ++persistent. The @samp{R} packet is used to restart the program being ++debugged. ++ ++Reply: ++@table @samp ++@item OK ++The remote target both supports and has enabled extended mode. ++@end table ++ ++@item ? ++@cindex @samp{?} packet ++@anchor{? packet} ++Indicate the reason the target halted. The reply is the same as for ++step and continue. This packet has a special interpretation when the ++target is in non-stop mode; see @ref{Remote Non-Stop}. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item A @var{arglen},@var{argnum},@var{arg},@dots{} ++@cindex @samp{A} packet ++Initialized @code{argv[]} array passed into program. @var{arglen} ++specifies the number of bytes in the hex encoded byte stream ++@var{arg}. See @code{gdbserver} for more details. ++ ++Reply: ++@table @samp ++@item OK ++The arguments were set. ++@item E @var{NN} ++An error occurred. ++@end table ++ ++@item b @var{baud} ++@cindex @samp{b} packet ++(Don't use this packet; its behavior is not well-defined.) ++Change the serial line speed to @var{baud}. ++ ++JTC: @emph{When does the transport layer state change? When it's ++received, or after the ACK is transmitted. In either case, there are ++problems if the command or the acknowledgment packet is dropped.} ++ ++Stan: @emph{If people really wanted to add something like this, and get ++it working for the first time, they ought to modify ser-unix.c to send ++some kind of out-of-band message to a specially-setup stub and have the ++switch happen "in between" packets, so that from remote protocol's point ++of view, nothing actually happened.} ++ ++@item B @var{addr},@var{mode} ++@cindex @samp{B} packet ++Set (@var{mode} is @samp{S}) or clear (@var{mode} is @samp{C}) a ++breakpoint at @var{addr}. ++ ++Don't use this packet. Use the @samp{Z} and @samp{z} packets instead ++(@pxref{insert breakpoint or watchpoint packet}). ++ ++@cindex @samp{bc} packet ++@anchor{bc} ++@item bc ++Backward continue. Execute the target system in reverse. No parameter. ++@xref{Reverse Execution}, for more information. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@cindex @samp{bs} packet ++@anchor{bs} ++@item bs ++Backward single step. Execute one instruction in reverse. No parameter. ++@xref{Reverse Execution}, for more information. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item c @r{[}@var{addr}@r{]} ++@cindex @samp{c} packet ++Continue at @var{addr}, which is the address to resume. If @var{addr} ++is omitted, resume at current address. ++ ++This packet is deprecated for multi-threading support. @xref{vCont ++packet}. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item C @var{sig}@r{[};@var{addr}@r{]} ++@cindex @samp{C} packet ++Continue with signal @var{sig} (hex signal number). If ++@samp{;@var{addr}} is omitted, resume at same address. ++ ++This packet is deprecated for multi-threading support. @xref{vCont ++packet}. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item d ++@cindex @samp{d} packet ++Toggle debug flag. ++ ++Don't use this packet; instead, define a general set packet ++(@pxref{General Query Packets}). ++ ++@item D ++@itemx D;@var{pid} ++@cindex @samp{D} packet ++The first form of the packet is used to detach @value{GDBN} from the ++remote system. It is sent to the remote target ++before @value{GDBN} disconnects via the @code{detach} command. ++ ++The second form, including a process ID, is used when multiprocess ++protocol extensions are enabled (@pxref{multiprocess extensions}), to ++detach only a specific process. The @var{pid} is specified as a ++big-endian hex string. ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@item F @var{RC},@var{EE},@var{CF};@var{XX} ++@cindex @samp{F} packet ++A reply from @value{GDBN} to an @samp{F} packet sent by the target. ++This is part of the File-I/O protocol extension. @xref{File-I/O ++Remote Protocol Extension}, for the specification. ++ ++@item g ++@anchor{read registers packet} ++@cindex @samp{g} packet ++Read general registers. ++ ++Reply: ++@table @samp ++@item @var{XX@dots{}} ++Each byte of register data is described by two hex digits. The bytes ++with the register are transmitted in target byte order. The size of ++each register and their position within the @samp{g} packet are ++determined by the @value{GDBN} internal gdbarch functions ++@code{DEPRECATED_REGISTER_RAW_SIZE} and @code{gdbarch_register_name}. ++ ++When reading registers from a trace frame (@pxref{Analyze Collected ++Data,,Using the Collected Data}), the stub may also return a string of ++literal @samp{x}'s in place of the register data digits, to indicate ++that the corresponding register has not been collected, thus its value ++is unavailable. For example, for an architecture with 4 registers of ++4 bytes each, the following reply indicates to @value{GDBN} that ++registers 0 and 2 have not been collected, while registers 1 and 3 ++have been collected, and both have zero value: ++ ++@smallexample ++-> @code{g} ++<- @code{xxxxxxxx00000000xxxxxxxx00000000} ++@end smallexample ++ ++@item E @var{NN} ++for an error. ++@end table ++ ++@item G @var{XX@dots{}} ++@cindex @samp{G} packet ++Write general registers. @xref{read registers packet}, for a ++description of the @var{XX@dots{}} data. ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@item H @var{op} @var{thread-id} ++@cindex @samp{H} packet ++Set thread for subsequent operations (@samp{m}, @samp{M}, @samp{g}, ++@samp{G}, et.al.). Depending on the operation to be performed, @var{op} ++should be @samp{c} for step and continue operations (note that this ++is deprecated, supporting the @samp{vCont} command is a better ++option), and @samp{g} for other operations. The thread designator ++@var{thread-id} has the format and interpretation described in ++@ref{thread-id syntax}. ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@c FIXME: JTC: ++@c 'H': How restrictive (or permissive) is the thread model. If a ++@c thread is selected and stopped, are other threads allowed ++@c to continue to execute? As I mentioned above, I think the ++@c semantics of each command when a thread is selected must be ++@c described. For example: ++@c ++@c 'g': If the stub supports threads and a specific thread is ++@c selected, returns the register block from that thread; ++@c otherwise returns current registers. ++@c ++@c 'G' If the stub supports threads and a specific thread is ++@c selected, sets the registers of the register block of ++@c that thread; otherwise sets current registers. ++ ++@item i @r{[}@var{addr}@r{[},@var{nnn}@r{]]} ++@anchor{cycle step packet} ++@cindex @samp{i} packet ++Step the remote target by a single clock cycle. If @samp{,@var{nnn}} is ++present, cycle step @var{nnn} cycles. If @var{addr} is present, cycle ++step starting at that address. ++ ++@item I ++@cindex @samp{I} packet ++Signal, then cycle step. @xref{step with signal packet}. @xref{cycle ++step packet}. ++ ++@item k ++@cindex @samp{k} packet ++Kill request. ++ ++The exact effect of this packet is not specified. ++ ++For a bare-metal target, it may power cycle or reset the target ++system. For that reason, the @samp{k} packet has no reply. ++ ++For a single-process target, it may kill that process if possible. ++ ++A multiple-process target may choose to kill just one process, or all ++that are under @value{GDBN}'s control. For more precise control, use ++the vKill packet (@pxref{vKill packet}). ++ ++If the target system immediately closes the connection in response to ++@samp{k}, @value{GDBN} does not consider the lack of packet ++acknowledgment to be an error, and assumes the kill was successful. ++ ++If connected using @kbd{target extended-remote}, and the target does ++not close the connection in response to a kill request, @value{GDBN} ++probes the target state as if a new connection was opened ++(@pxref{? packet}). ++ ++@item m @var{addr},@var{length} ++@cindex @samp{m} packet ++Read @var{length} addressable memory units starting at address @var{addr} ++(@pxref{addressable memory unit}). Note that @var{addr} may not be aligned to ++any particular boundary. ++ ++The stub need not use any particular size or alignment when gathering ++data from memory for the response; even if @var{addr} is word-aligned ++and @var{length} is a multiple of the word size, the stub is free to ++use byte accesses, or not. For this reason, this packet may not be ++suitable for accessing memory-mapped I/O devices. ++@cindex alignment of remote memory accesses ++@cindex size of remote memory accesses ++@cindex memory, alignment and size of remote accesses ++ ++Reply: ++@table @samp ++@item @var{XX@dots{}} ++Memory contents; each byte is transmitted as a two-digit hexadecimal number. ++The reply may contain fewer addressable memory units than requested if the ++server was able to read only part of the region of memory. ++@item E @var{NN} ++@var{NN} is errno ++@end table ++ ++@item M @var{addr},@var{length}:@var{XX@dots{}} ++@cindex @samp{M} packet ++Write @var{length} addressable memory units starting at address @var{addr} ++(@pxref{addressable memory unit}). The data is given by @var{XX@dots{}}; each ++byte is transmitted as a two-digit hexadecimal number. ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error (this includes the case where only part of the data was ++written). ++@end table ++ ++@item p @var{n} ++@cindex @samp{p} packet ++Read the value of register @var{n}; @var{n} is in hex. ++@xref{read registers packet}, for a description of how the returned ++register value is encoded. ++ ++Reply: ++@table @samp ++@item @var{XX@dots{}} ++the register's value ++@item E @var{NN} ++for an error ++@item @w{} ++Indicating an unrecognized @var{query}. ++@end table ++ ++@item P @var{n@dots{}}=@var{r@dots{}} ++@anchor{write register packet} ++@cindex @samp{P} packet ++Write register @var{n@dots{}} with value @var{r@dots{}}. The register ++number @var{n} is in hexadecimal, and @var{r@dots{}} contains two hex ++digits for each byte in the register (target byte order). ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@item q @var{name} @var{params}@dots{} ++@itemx Q @var{name} @var{params}@dots{} ++@cindex @samp{q} packet ++@cindex @samp{Q} packet ++General query (@samp{q}) and set (@samp{Q}). These packets are ++described fully in @ref{General Query Packets}. ++ ++@item r ++@cindex @samp{r} packet ++Reset the entire system. ++ ++Don't use this packet; use the @samp{R} packet instead. ++ ++@item R @var{XX} ++@cindex @samp{R} packet ++Restart the program being debugged. The @var{XX}, while needed, is ignored. ++This packet is only available in extended mode (@pxref{extended mode}). ++ ++The @samp{R} packet has no reply. ++ ++@item s @r{[}@var{addr}@r{]} ++@cindex @samp{s} packet ++Single step, resuming at @var{addr}. If ++@var{addr} is omitted, resume at same address. ++ ++This packet is deprecated for multi-threading support. @xref{vCont ++packet}. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item S @var{sig}@r{[};@var{addr}@r{]} ++@anchor{step with signal packet} ++@cindex @samp{S} packet ++Step with signal. This is analogous to the @samp{C} packet, but ++requests a single-step, rather than a normal resumption of execution. ++ ++This packet is deprecated for multi-threading support. @xref{vCont ++packet}. ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item t @var{addr}:@var{PP},@var{MM} ++@cindex @samp{t} packet ++Search backwards starting at address @var{addr} for a match with pattern ++@var{PP} and mask @var{MM}, both of which are are 4 byte long. ++There must be at least 3 digits in @var{addr}. ++ ++@item T @var{thread-id} ++@cindex @samp{T} packet ++Find out if the thread @var{thread-id} is alive. @xref{thread-id syntax}. ++ ++Reply: ++@table @samp ++@item OK ++thread is still alive ++@item E @var{NN} ++thread is dead ++@end table ++ ++@item v ++Packets starting with @samp{v} are identified by a multi-letter name, ++up to the first @samp{;} or @samp{?} (or the end of the packet). ++ ++@item vAttach;@var{pid} ++@cindex @samp{vAttach} packet ++Attach to a new process with the specified process ID @var{pid}. ++The process ID is a ++hexadecimal integer identifying the process. In all-stop mode, all ++threads in the attached process are stopped; in non-stop mode, it may be ++attached without being stopped if that is supported by the target. ++ ++@c In non-stop mode, on a successful vAttach, the stub should set the ++@c current thread to a thread of the newly-attached process. After ++@c attaching, GDB queries for the attached process's thread ID with qC. ++@c Also note that, from a user perspective, whether or not the ++@c target is stopped on attach in non-stop mode depends on whether you ++@c use the foreground or background version of the attach command, not ++@c on what vAttach does; GDB does the right thing with respect to either ++@c stopping or restarting threads. ++ ++This packet is only available in extended mode (@pxref{extended mode}). ++ ++Reply: ++@table @samp ++@item E @var{nn} ++for an error ++@item @r{Any stop packet} ++for success in all-stop mode (@pxref{Stop Reply Packets}) ++@item OK ++for success in non-stop mode (@pxref{Remote Non-Stop}) ++@end table ++ ++@item vCont@r{[};@var{action}@r{[}:@var{thread-id}@r{]]}@dots{} ++@cindex @samp{vCont} packet ++@anchor{vCont packet} ++Resume the inferior, specifying different actions for each thread. ++ ++For each inferior thread, the leftmost action with a matching ++@var{thread-id} is applied. Threads that don't match any action ++remain in their current state. Thread IDs are specified using the ++syntax described in @ref{thread-id syntax}. If multiprocess ++extensions (@pxref{multiprocess extensions}) are supported, actions ++can be specified to match all threads in a process by using the ++@samp{p@var{pid}.-1} form of the @var{thread-id}. An action with no ++@var{thread-id} matches all threads. Specifying no actions is an ++error. ++ ++Currently supported actions are: ++ ++@table @samp ++@item c ++Continue. ++@item C @var{sig} ++Continue with signal @var{sig}. The signal @var{sig} should be two hex digits. ++@item s ++Step. ++@item S @var{sig} ++Step with signal @var{sig}. The signal @var{sig} should be two hex digits. ++@item t ++Stop. ++@item r @var{start},@var{end} ++Step once, and then keep stepping as long as the thread stops at ++addresses between @var{start} (inclusive) and @var{end} (exclusive). ++The remote stub reports a stop reply when either the thread goes out ++of the range or is stopped due to an unrelated reason, such as hitting ++a breakpoint. @xref{range stepping}. ++ ++If the range is empty (@var{start} == @var{end}), then the action ++becomes equivalent to the @samp{s} action. In other words, ++single-step once, and report the stop (even if the stepped instruction ++jumps to @var{start}). ++ ++(A stop reply may be sent at any point even if the PC is still within ++the stepping range; for example, it is valid to implement this packet ++in a degenerate way as a single instruction step operation.) ++ ++@end table ++ ++The optional argument @var{addr} normally associated with the ++@samp{c}, @samp{C}, @samp{s}, and @samp{S} packets is ++not supported in @samp{vCont}. ++ ++The @samp{t} action is only relevant in non-stop mode ++(@pxref{Remote Non-Stop}) and may be ignored by the stub otherwise. ++A stop reply should be generated for any affected thread not already stopped. ++When a thread is stopped by means of a @samp{t} action, ++the corresponding stop reply should indicate that the thread has stopped with ++signal @samp{0}, regardless of whether the target uses some other signal ++as an implementation detail. ++ ++The server must ignore @samp{c}, @samp{C}, @samp{s}, @samp{S}, and ++@samp{r} actions for threads that are already running. Conversely, ++the server must ignore @samp{t} actions for threads that are already ++stopped. ++ ++@emph{Note:} In non-stop mode, a thread is considered running until ++@value{GDBN} acknowledges an asynchronous stop notification for it with ++the @samp{vStopped} packet (@pxref{Remote Non-Stop}). ++ ++The stub must support @samp{vCont} if it reports support for ++multiprocess extensions (@pxref{multiprocess extensions}). ++ ++Reply: ++@xref{Stop Reply Packets}, for the reply specifications. ++ ++@item vCont? ++@cindex @samp{vCont?} packet ++Request a list of actions supported by the @samp{vCont} packet. ++ ++Reply: ++@table @samp ++@item vCont@r{[};@var{action}@dots{}@r{]} ++The @samp{vCont} packet is supported. Each @var{action} is a supported ++command in the @samp{vCont} packet. ++@item @w{} ++The @samp{vCont} packet is not supported. ++@end table ++ ++@anchor{vCtrlC packet} ++@item vCtrlC ++@cindex @samp{vCtrlC} packet ++Interrupt remote target as if a control-C was pressed on the remote ++terminal. This is the equivalent to reacting to the @code{^C} ++(@samp{\003}, the control-C character) character in all-stop mode ++while the target is running, except this works in non-stop mode. ++@xref{interrupting remote targets}, for more info on the all-stop ++variant. ++ ++Reply: ++@table @samp ++@item E @var{nn} ++for an error ++@item OK ++for success ++@end table ++ ++@item vFile:@var{operation}:@var{parameter}@dots{} ++@cindex @samp{vFile} packet ++Perform a file operation on the target system. For details, ++see @ref{Host I/O Packets}. ++ ++@item vFlashErase:@var{addr},@var{length} ++@cindex @samp{vFlashErase} packet ++Direct the stub to erase @var{length} bytes of flash starting at ++@var{addr}. The region may enclose any number of flash blocks, but ++its start and end must fall on block boundaries, as indicated by the ++flash block size appearing in the memory map (@pxref{Memory Map ++Format}). @value{GDBN} groups flash memory programming operations ++together, and sends a @samp{vFlashDone} request after each group; the ++stub is allowed to delay erase operation until the @samp{vFlashDone} ++packet is received. ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@item vFlashWrite:@var{addr}:@var{XX@dots{}} ++@cindex @samp{vFlashWrite} packet ++Direct the stub to write data to flash address @var{addr}. The data ++is passed in binary form using the same encoding as for the @samp{X} ++packet (@pxref{Binary Data}). The memory ranges specified by ++@samp{vFlashWrite} packets preceding a @samp{vFlashDone} packet must ++not overlap, and must appear in order of increasing addresses ++(although @samp{vFlashErase} packets for higher addresses may already ++have been received; the ordering is guaranteed only between ++@samp{vFlashWrite} packets). If a packet writes to an address that was ++neither erased by a preceding @samp{vFlashErase} packet nor by some other ++target-specific method, the results are unpredictable. ++ ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E.memtype ++for vFlashWrite addressing non-flash memory ++@item E @var{NN} ++for an error ++@end table ++ ++@item vFlashDone ++@cindex @samp{vFlashDone} packet ++Indicate to the stub that flash programming operation is finished. ++The stub is permitted to delay or batch the effects of a group of ++@samp{vFlashErase} and @samp{vFlashWrite} packets until a ++@samp{vFlashDone} packet is received. The contents of the affected ++regions of flash memory are unpredictable until the @samp{vFlashDone} ++request is completed. ++ ++@item vKill;@var{pid} ++@cindex @samp{vKill} packet ++@anchor{vKill packet} ++Kill the process with the specified process ID @var{pid}, which is a ++hexadecimal integer identifying the process. This packet is used in ++preference to @samp{k} when multiprocess protocol extensions are ++supported; see @ref{multiprocess extensions}. ++ ++Reply: ++@table @samp ++@item E @var{nn} ++for an error ++@item OK ++for success ++@end table ++ ++@item vMustReplyEmpty ++@cindex @samp{vMustReplyEmpty} packet ++The correct reply to an unknown @samp{v} packet is to return the empty ++string, however, some older versions of @command{gdbserver} would ++incorrectly return @samp{OK} for unknown @samp{v} packets. ++ ++The @samp{vMustReplyEmpty} is used as a feature test to check how ++@command{gdbserver} handles unknown packets, it is important that this ++packet be handled in the same way as other unknown @samp{v} packets. ++If this packet is handled differently to other unknown @samp{v} ++packets then it is possible that @value{GDBN} may run into problems in ++other areas, specifically around use of @samp{vFile:setfs:}. ++ ++@item vRun;@var{filename}@r{[};@var{argument}@r{]}@dots{} ++@cindex @samp{vRun} packet ++Run the program @var{filename}, passing it each @var{argument} on its ++command line. The file and arguments are hex-encoded strings. If ++@var{filename} is an empty string, the stub may use a default program ++(e.g.@: the last program run). The program is created in the stopped ++state. ++ ++@c FIXME: What about non-stop mode? ++ ++This packet is only available in extended mode (@pxref{extended mode}). ++ ++Reply: ++@table @samp ++@item E @var{nn} ++for an error ++@item @r{Any stop packet} ++for success (@pxref{Stop Reply Packets}) ++@end table ++ ++@item vStopped ++@cindex @samp{vStopped} packet ++@xref{Notification Packets}. ++ ++@item X @var{addr},@var{length}:@var{XX@dots{}} ++@anchor{X packet} ++@cindex @samp{X} packet ++Write data to memory, where the data is transmitted in binary. ++Memory is specified by its address @var{addr} and number of addressable memory ++units @var{length} (@pxref{addressable memory unit}); ++@samp{@var{XX}@dots{}} is binary data (@pxref{Binary Data}). ++ ++Reply: ++@table @samp ++@item OK ++for success ++@item E @var{NN} ++for an error ++@end table ++ ++@item z @var{type},@var{addr},@var{kind} ++@itemx Z @var{type},@var{addr},@var{kind} ++@anchor{insert breakpoint or watchpoint packet} ++@cindex @samp{z} packet ++@cindex @samp{Z} packets ++Insert (@samp{Z}) or remove (@samp{z}) a @var{type} breakpoint or ++watchpoint starting at address @var{address} of kind @var{kind}. ++ ++Each breakpoint and watchpoint packet @var{type} is documented ++separately. ++ ++@emph{Implementation notes: A remote target shall return an empty string ++for an unrecognized breakpoint or watchpoint packet @var{type}. A ++remote target shall support either both or neither of a given ++@samp{Z@var{type}@dots{}} and @samp{z@var{type}@dots{}} packet pair. To ++avoid potential problems with duplicate packets, the operations should ++be implemented in an idempotent way.} ++ ++@item z0,@var{addr},@var{kind} ++@itemx Z0,@var{addr},@var{kind}@r{[};@var{cond_list}@dots{}@r{]}@r{[};cmds:@var{persist},@var{cmd_list}@dots{}@r{]} ++@cindex @samp{z0} packet ++@cindex @samp{Z0} packet ++Insert (@samp{Z0}) or remove (@samp{z0}) a software breakpoint at address ++@var{addr} of type @var{kind}. ++ ++A software breakpoint is implemented by replacing the instruction at ++@var{addr} with a software breakpoint or trap instruction. The ++@var{kind} is target-specific and typically indicates the size of the ++breakpoint in bytes that should be inserted. E.g., the @sc{arm} and ++@sc{mips} can insert either a 2 or 4 byte breakpoint. Some ++architectures have additional meanings for @var{kind} ++(@pxref{Architecture-Specific Protocol Details}); if no ++architecture-specific value is being used, it should be @samp{0}. ++@var{kind} is hex-encoded. @var{cond_list} is an optional list of ++conditional expressions in bytecode form that should be evaluated on ++the target's side. These are the conditions that should be taken into ++consideration when deciding if the breakpoint trigger should be ++reported back to @value{GDBN}. ++ ++See also the @samp{swbreak} stop reason (@pxref{swbreak stop reason}) ++for how to best report a software breakpoint event to @value{GDBN}. ++ ++The @var{cond_list} parameter is comprised of a series of expressions, ++concatenated without separators. Each expression has the following form: ++ ++@table @samp ++ ++@item X @var{len},@var{expr} ++@var{len} is the length of the bytecode expression and @var{expr} is the ++actual conditional expression in bytecode form. ++ ++@end table ++ ++The optional @var{cmd_list} parameter introduces commands that may be ++run on the target, rather than being reported back to @value{GDBN}. ++The parameter starts with a numeric flag @var{persist}; if the flag is ++nonzero, then the breakpoint may remain active and the commands ++continue to be run even when @value{GDBN} disconnects from the target. ++Following this flag is a series of expressions concatenated with no ++separators. Each expression has the following form: ++ ++@table @samp ++ ++@item X @var{len},@var{expr} ++@var{len} is the length of the bytecode expression and @var{expr} is the ++actual commands expression in bytecode form. ++ ++@end table ++ ++@emph{Implementation note: It is possible for a target to copy or move ++code that contains software breakpoints (e.g., when implementing ++overlays). The behavior of this packet, in the presence of such a ++target, is not defined.} ++ ++Reply: ++@table @samp ++@item OK ++success ++@item @w{} ++not supported ++@item E @var{NN} ++for an error ++@end table ++ ++@item z1,@var{addr},@var{kind} ++@itemx Z1,@var{addr},@var{kind}@r{[};@var{cond_list}@dots{}@r{]}@r{[};cmds:@var{persist},@var{cmd_list}@dots{}@r{]} ++@cindex @samp{z1} packet ++@cindex @samp{Z1} packet ++Insert (@samp{Z1}) or remove (@samp{z1}) a hardware breakpoint at ++address @var{addr}. ++ ++A hardware breakpoint is implemented using a mechanism that is not ++dependent on being able to modify the target's memory. The ++@var{kind}, @var{cond_list}, and @var{cmd_list} arguments have the ++same meaning as in @samp{Z0} packets. ++ ++@emph{Implementation note: A hardware breakpoint is not affected by code ++movement.} ++ ++Reply: ++@table @samp ++@item OK ++success ++@item @w{} ++not supported ++@item E @var{NN} ++for an error ++@end table ++ ++@item z2,@var{addr},@var{kind} ++@itemx Z2,@var{addr},@var{kind} ++@cindex @samp{z2} packet ++@cindex @samp{Z2} packet ++Insert (@samp{Z2}) or remove (@samp{z2}) a write watchpoint at @var{addr}. ++The number of bytes to watch is specified by @var{kind}. ++ ++Reply: ++@table @samp ++@item OK ++success ++@item @w{} ++not supported ++@item E @var{NN} ++for an error ++@end table ++ ++@item z3,@var{addr},@var{kind} ++@itemx Z3,@var{addr},@var{kind} ++@cindex @samp{z3} packet ++@cindex @samp{Z3} packet ++Insert (@samp{Z3}) or remove (@samp{z3}) a read watchpoint at @var{addr}. ++The number of bytes to watch is specified by @var{kind}. ++ ++Reply: ++@table @samp ++@item OK ++success ++@item @w{} ++not supported ++@item E @var{NN} ++for an error ++@end table ++ ++@item z4,@var{addr},@var{kind} ++@itemx Z4,@var{addr},@var{kind} ++@cindex @samp{z4} packet ++@cindex @samp{Z4} packet ++Insert (@samp{Z4}) or remove (@samp{z4}) an access watchpoint at @var{addr}. ++The number of bytes to watch is specified by @var{kind}. ++ ++Reply: ++@table @samp ++@item OK ++success ++@item @w{} ++not supported ++@item E @var{NN} ++for an error ++@end table ++ ++@end table ++ ++@node Stop Reply Packets ++@section Stop Reply Packets ++@cindex stop reply packets ++ ++The @samp{C}, @samp{c}, @samp{S}, @samp{s}, @samp{vCont}, ++@samp{vAttach}, @samp{vRun}, @samp{vStopped}, and @samp{?} packets can ++receive any of the below as a reply. Except for @samp{?} ++and @samp{vStopped}, that reply is only returned ++when the target halts. In the below the exact meaning of @dfn{signal ++number} is defined by the header @file{include/gdb/signals.h} in the ++@value{GDBN} source code. ++ ++In non-stop mode, the server will simply reply @samp{OK} to commands ++such as @samp{vCont}; any stop will be the subject of a future ++notification. @xref{Remote Non-Stop}. ++ ++As in the description of request packets, we include spaces in the ++reply templates for clarity; these are not part of the reply packet's ++syntax. No @value{GDBN} stop reply packet uses spaces to separate its ++components. ++ ++@table @samp ++ ++@item S @var{AA} ++The program received signal number @var{AA} (a two-digit hexadecimal ++number). This is equivalent to a @samp{T} response with no ++@var{n}:@var{r} pairs. ++ ++@item T @var{AA} @var{n1}:@var{r1};@var{n2}:@var{r2};@dots{} ++@cindex @samp{T} packet reply ++The program received signal number @var{AA} (a two-digit hexadecimal ++number). This is equivalent to an @samp{S} response, except that the ++@samp{@var{n}:@var{r}} pairs can carry values of important registers ++and other information directly in the stop reply packet, reducing ++round-trip latency. Single-step and breakpoint traps are reported ++this way. Each @samp{@var{n}:@var{r}} pair is interpreted as follows: ++ ++@itemize @bullet ++@item ++If @var{n} is a hexadecimal number, it is a register number, and the ++corresponding @var{r} gives that register's value. The data @var{r} is a ++series of bytes in target byte order, with each byte given by a ++two-digit hex number. ++ ++@item ++If @var{n} is @samp{thread}, then @var{r} is the @var{thread-id} of ++the stopped thread, as specified in @ref{thread-id syntax}. ++ ++@item ++If @var{n} is @samp{core}, then @var{r} is the hexadecimal number of ++the core on which the stop event was detected. ++ ++@item ++If @var{n} is a recognized @dfn{stop reason}, it describes a more ++specific event that stopped the target. The currently defined stop ++reasons are listed below. The @var{aa} should be @samp{05}, the trap ++signal. At most one stop reason should be present. ++ ++@item ++Otherwise, @value{GDBN} should ignore this @samp{@var{n}:@var{r}} pair ++and go on to the next; this allows us to extend the protocol in the ++future. ++@end itemize ++ ++The currently defined stop reasons are: ++ ++@table @samp ++@item watch ++@itemx rwatch ++@itemx awatch ++The packet indicates a watchpoint hit, and @var{r} is the data address, in ++hex. ++ ++@item syscall_entry ++@itemx syscall_return ++The packet indicates a syscall entry or return, and @var{r} is the ++syscall number, in hex. ++ ++@cindex shared library events, remote reply ++@item library ++The packet indicates that the loaded libraries have changed. ++@value{GDBN} should use @samp{qXfer:libraries:read} to fetch a new ++list of loaded libraries. The @var{r} part is ignored. ++ ++@cindex replay log events, remote reply ++@item replaylog ++The packet indicates that the target cannot continue replaying ++logged execution events, because it has reached the end (or the ++beginning when executing backward) of the log. The value of @var{r} ++will be either @samp{begin} or @samp{end}. @xref{Reverse Execution}, ++for more information. ++ ++@item swbreak ++@anchor{swbreak stop reason} ++The packet indicates a software breakpoint instruction was executed, ++irrespective of whether it was @value{GDBN} that planted the ++breakpoint or the breakpoint is hardcoded in the program. The @var{r} ++part must be left empty. ++ ++On some architectures, such as x86, at the architecture level, when a ++breakpoint instruction executes the program counter points at the ++breakpoint address plus an offset. On such targets, the stub is ++responsible for adjusting the PC to point back at the breakpoint ++address. ++ ++This packet should not be sent by default; older @value{GDBN} versions ++did not support it. @value{GDBN} requests it, by supplying an ++appropriate @samp{qSupported} feature (@pxref{qSupported}). The ++remote stub must also supply the appropriate @samp{qSupported} feature ++indicating support. ++ ++This packet is required for correct non-stop mode operation. ++ ++@item hwbreak ++The packet indicates the target stopped for a hardware breakpoint. ++The @var{r} part must be left empty. ++ ++The same remarks about @samp{qSupported} and non-stop mode above ++apply. ++ ++@cindex fork events, remote reply ++@item fork ++The packet indicates that @code{fork} was called, and @var{r} ++is the thread ID of the new child process. Refer to ++@ref{thread-id syntax} for the format of the @var{thread-id} ++field. This packet is only applicable to targets that support ++fork events. ++ ++This packet should not be sent by default; older @value{GDBN} versions ++did not support it. @value{GDBN} requests it, by supplying an ++appropriate @samp{qSupported} feature (@pxref{qSupported}). The ++remote stub must also supply the appropriate @samp{qSupported} feature ++indicating support. ++ ++@cindex vfork events, remote reply ++@item vfork ++The packet indicates that @code{vfork} was called, and @var{r} ++is the thread ID of the new child process. Refer to ++@ref{thread-id syntax} for the format of the @var{thread-id} ++field. This packet is only applicable to targets that support ++vfork events. ++ ++This packet should not be sent by default; older @value{GDBN} versions ++did not support it. @value{GDBN} requests it, by supplying an ++appropriate @samp{qSupported} feature (@pxref{qSupported}). The ++remote stub must also supply the appropriate @samp{qSupported} feature ++indicating support. ++ ++@cindex vforkdone events, remote reply ++@item vforkdone ++The packet indicates that a child process created by a vfork ++has either called @code{exec} or terminated, so that the ++address spaces of the parent and child process are no longer ++shared. The @var{r} part is ignored. This packet is only ++applicable to targets that support vforkdone events. ++ ++This packet should not be sent by default; older @value{GDBN} versions ++did not support it. @value{GDBN} requests it, by supplying an ++appropriate @samp{qSupported} feature (@pxref{qSupported}). The ++remote stub must also supply the appropriate @samp{qSupported} feature ++indicating support. ++ ++@cindex exec events, remote reply ++@item exec ++The packet indicates that @code{execve} was called, and @var{r} ++is the absolute pathname of the file that was executed, in hex. ++This packet is only applicable to targets that support exec events. ++ ++This packet should not be sent by default; older @value{GDBN} versions ++did not support it. @value{GDBN} requests it, by supplying an ++appropriate @samp{qSupported} feature (@pxref{qSupported}). The ++remote stub must also supply the appropriate @samp{qSupported} feature ++indicating support. ++ ++@cindex thread create event, remote reply ++@anchor{thread create event} ++@item create ++The packet indicates that the thread was just created. The new thread ++is stopped until @value{GDBN} sets it running with a resumption packet ++(@pxref{vCont packet}). This packet should not be sent by default; ++@value{GDBN} requests it with the @ref{QThreadEvents} packet. See ++also the @samp{w} (@pxref{thread exit event}) remote reply below. The ++@var{r} part is ignored. ++ ++@end table ++ ++@item W @var{AA} ++@itemx W @var{AA} ; process:@var{pid} ++The process exited, and @var{AA} is the exit status. This is only ++applicable to certain targets. ++ ++The second form of the response, including the process ID of the ++exited process, can be used only when @value{GDBN} has reported ++support for multiprocess protocol extensions; see @ref{multiprocess ++extensions}. Both @var{AA} and @var{pid} are formatted as big-endian ++hex strings. ++ ++@item X @var{AA} ++@itemx X @var{AA} ; process:@var{pid} ++The process terminated with signal @var{AA}. ++ ++The second form of the response, including the process ID of the ++terminated process, can be used only when @value{GDBN} has reported ++support for multiprocess protocol extensions; see @ref{multiprocess ++extensions}. Both @var{AA} and @var{pid} are formatted as big-endian ++hex strings. ++ ++@anchor{thread exit event} ++@cindex thread exit event, remote reply ++@item w @var{AA} ; @var{tid} ++ ++The thread exited, and @var{AA} is the exit status. This response ++should not be sent by default; @value{GDBN} requests it with the ++@ref{QThreadEvents} packet. See also @ref{thread create event} above. ++@var{AA} is formatted as a big-endian hex string. ++ ++@item N ++There are no resumed threads left in the target. In other words, even ++though the process is alive, the last resumed thread has exited. For ++example, say the target process has two threads: thread 1 and thread ++2. The client leaves thread 1 stopped, and resumes thread 2, which ++subsequently exits. At this point, even though the process is still ++alive, and thus no @samp{W} stop reply is sent, no thread is actually ++executing either. The @samp{N} stop reply thus informs the client ++that it can stop waiting for stop replies. This packet should not be ++sent by default; older @value{GDBN} versions did not support it. ++@value{GDBN} requests it, by supplying an appropriate ++@samp{qSupported} feature (@pxref{qSupported}). The remote stub must ++also supply the appropriate @samp{qSupported} feature indicating ++support. ++ ++@item O @var{XX}@dots{} ++@samp{@var{XX}@dots{}} is hex encoding of @sc{ascii} data, to be ++written as the program's console output. This can happen at any time ++while the program is running and the debugger should continue to wait ++for @samp{W}, @samp{T}, etc. This reply is not permitted in non-stop mode. ++ ++@item F @var{call-id},@var{parameter}@dots{} ++@var{call-id} is the identifier which says which host system call should ++be called. This is just the name of the function. Translation into the ++correct system call is only applicable as it's defined in @value{GDBN}. ++@xref{File-I/O Remote Protocol Extension}, for a list of implemented ++system calls. ++ ++@samp{@var{parameter}@dots{}} is a list of parameters as defined for ++this very system call. ++ ++The target replies with this packet when it expects @value{GDBN} to ++call a host system call on behalf of the target. @value{GDBN} replies ++with an appropriate @samp{F} packet and keeps up waiting for the next ++reply packet from the target. The latest @samp{C}, @samp{c}, @samp{S} ++or @samp{s} action is expected to be continued. @xref{File-I/O Remote ++Protocol Extension}, for more details. ++ ++@end table ++ ++@node General Query Packets ++@section General Query Packets ++@cindex remote query requests ++ ++Packets starting with @samp{q} are @dfn{general query packets}; ++packets starting with @samp{Q} are @dfn{general set packets}. General ++query and set packets are a semi-unified form for retrieving and ++sending information to and from the stub. ++ ++The initial letter of a query or set packet is followed by a name ++indicating what sort of thing the packet applies to. For example, ++@value{GDBN} may use a @samp{qSymbol} packet to exchange symbol ++definitions with the stub. These packet names follow some ++conventions: ++ ++@itemize @bullet ++@item ++The name must not contain commas, colons or semicolons. ++@item ++Most @value{GDBN} query and set packets have a leading upper case ++letter. ++@item ++The names of custom vendor packets should use a company prefix, in ++lower case, followed by a period. For example, packets designed at ++the Acme Corporation might begin with @samp{qacme.foo} (for querying ++foos) or @samp{Qacme.bar} (for setting bars). ++@end itemize ++ ++The name of a query or set packet should be separated from any ++parameters by a @samp{:}; the parameters themselves should be ++separated by @samp{,} or @samp{;}. Stubs must be careful to match the ++full packet name, and check for a separator or the end of the packet, ++in case two packet names share a common prefix. New packets should not begin ++with @samp{qC}, @samp{qP}, or @samp{qL}@footnote{The @samp{qP} and @samp{qL} ++packets predate these conventions, and have arguments without any terminator ++for the packet name; we suspect they are in widespread use in places that ++are difficult to upgrade. The @samp{qC} packet has no arguments, but some ++existing stubs (e.g.@: RedBoot) are known to not check for the end of the ++packet.}. ++ ++Like the descriptions of the other packets, each description here ++has a template showing the packet's overall syntax, followed by an ++explanation of the packet's meaning. We include spaces in some of the ++templates for clarity; these are not part of the packet's syntax. No ++@value{GDBN} packet uses spaces to separate its components. ++ ++Here are the currently defined query and set packets: ++ ++@table @samp ++ ++@item QAgent:1 ++@itemx QAgent:0 ++Turn on or off the agent as a helper to perform some debugging operations ++delegated from @value{GDBN} (@pxref{Control Agent}). ++ ++@item QAllow:@var{op}:@var{val}@dots{} ++@cindex @samp{QAllow} packet ++Specify which operations @value{GDBN} expects to request of the ++target, as a semicolon-separated list of operation name and value ++pairs. Possible values for @var{op} include @samp{WriteReg}, ++@samp{WriteMem}, @samp{InsertBreak}, @samp{InsertTrace}, ++@samp{InsertFastTrace}, and @samp{Stop}. @var{val} is either 0, ++indicating that @value{GDBN} will not request the operation, or 1, ++indicating that it may. (The target can then use this to set up its ++own internals optimally, for instance if the debugger never expects to ++insert breakpoints, it may not need to install its own trap handler.) ++ ++@item qC ++@cindex current thread, remote request ++@cindex @samp{qC} packet ++Return the current thread ID. ++ ++Reply: ++@table @samp ++@item QC @var{thread-id} ++Where @var{thread-id} is a thread ID as documented in ++@ref{thread-id syntax}. ++@item @r{(anything else)} ++Any other reply implies the old thread ID. ++@end table ++ ++@item qCRC:@var{addr},@var{length} ++@cindex CRC of memory block, remote request ++@cindex @samp{qCRC} packet ++@anchor{qCRC packet} ++Compute the CRC checksum of a block of memory using CRC-32 defined in ++IEEE 802.3. The CRC is computed byte at a time, taking the most ++significant bit of each byte first. The initial pattern code ++@code{0xffffffff} is used to ensure leading zeros affect the CRC. ++ ++@emph{Note:} This is the same CRC used in validating separate debug ++files (@pxref{Separate Debug Files, , Debugging Information in Separate ++Files}). However the algorithm is slightly different. When validating ++separate debug files, the CRC is computed taking the @emph{least} ++significant bit of each byte first, and the final result is inverted to ++detect trailing zeros. ++ ++Reply: ++@table @samp ++@item E @var{NN} ++An error (such as memory fault) ++@item C @var{crc32} ++The specified memory region's checksum is @var{crc32}. ++@end table ++ ++@item QDisableRandomization:@var{value} ++@cindex disable address space randomization, remote request ++@cindex @samp{QDisableRandomization} packet ++Some target operating systems will randomize the virtual address space ++of the inferior process as a security feature, but provide a feature ++to disable such randomization, e.g.@: to allow for a more deterministic ++debugging experience. On such systems, this packet with a @var{value} ++of 1 directs the target to disable address space randomization for ++processes subsequently started via @samp{vRun} packets, while a packet ++with a @var{value} of 0 tells the target to enable address space ++randomization. ++ ++This packet is only available in extended mode (@pxref{extended mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QDisableRandomization} is not supported ++by the stub. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++This should only be done on targets that actually support disabling ++address space randomization. ++ ++@item QStartupWithShell:@var{value} ++@cindex startup with shell, remote request ++@cindex @samp{QStartupWithShell} packet ++On UNIX-like targets, it is possible to start the inferior using a ++shell program. This is the default behavior on both @value{GDBN} and ++@command{gdbserver} (@pxref{set startup-with-shell}). This packet is ++used to inform @command{gdbserver} whether it should start the ++inferior using a shell or not. ++ ++If @var{value} is @samp{0}, @command{gdbserver} will not use a shell ++to start the inferior. If @var{value} is @samp{1}, ++@command{gdbserver} will use a shell to start the inferior. All other ++values are considered an error. ++ ++This packet is only available in extended mode (@pxref{extended ++mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). This should only be done on targets that ++actually support starting the inferior using a shell. ++ ++Use of this packet is controlled by the @code{set startup-with-shell} ++command; @pxref{set startup-with-shell}. ++ ++@item QEnvironmentHexEncoded:@var{hex-value} ++@anchor{QEnvironmentHexEncoded} ++@cindex set environment variable, remote request ++@cindex @samp{QEnvironmentHexEncoded} packet ++On UNIX-like targets, it is possible to set environment variables that ++will be passed to the inferior during the startup process. This ++packet is used to inform @command{gdbserver} of an environment ++variable that has been defined by the user on @value{GDBN} (@pxref{set ++environment}). ++ ++The packet is composed by @var{hex-value}, an hex encoded ++representation of the @var{name=value} format representing an ++environment variable. The name of the environment variable is ++represented by @var{name}, and the value to be assigned to the ++environment variable is represented by @var{value}. If the variable ++has no value (i.e., the value is @code{null}), then @var{value} will ++not be present. ++ ++This packet is only available in extended mode (@pxref{extended ++mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). This should only be done on targets that ++actually support passing environment variables to the starting ++inferior. ++ ++This packet is related to the @code{set environment} command; ++@pxref{set environment}. ++ ++@item QEnvironmentUnset:@var{hex-value} ++@anchor{QEnvironmentUnset} ++@cindex unset environment variable, remote request ++@cindex @samp{QEnvironmentUnset} packet ++On UNIX-like targets, it is possible to unset environment variables ++before starting the inferior in the remote target. This packet is ++used to inform @command{gdbserver} of an environment variable that has ++been unset by the user on @value{GDBN} (@pxref{unset environment}). ++ ++The packet is composed by @var{hex-value}, an hex encoded ++representation of the name of the environment variable to be unset. ++ ++This packet is only available in extended mode (@pxref{extended ++mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). This should only be done on targets that ++actually support passing environment variables to the starting ++inferior. ++ ++This packet is related to the @code{unset environment} command; ++@pxref{unset environment}. ++ ++@item QEnvironmentReset ++@anchor{QEnvironmentReset} ++@cindex reset environment, remote request ++@cindex @samp{QEnvironmentReset} packet ++On UNIX-like targets, this packet is used to reset the state of ++environment variables in the remote target before starting the ++inferior. In this context, reset means unsetting all environment ++variables that were previously set by the user (i.e., were not ++initially present in the environment). It is sent to ++@command{gdbserver} before the @samp{QEnvironmentHexEncoded} ++(@pxref{QEnvironmentHexEncoded}) and the @samp{QEnvironmentUnset} ++(@pxref{QEnvironmentUnset}) packets. ++ ++This packet is only available in extended mode (@pxref{extended ++mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). This should only be done on targets that ++actually support passing environment variables to the starting ++inferior. ++ ++@item QSetWorkingDir:@r{[}@var{directory}@r{]} ++@anchor{QSetWorkingDir packet} ++@cindex set working directory, remote request ++@cindex @samp{QSetWorkingDir} packet ++This packet is used to inform the remote server of the intended ++current working directory for programs that are going to be executed. ++ ++The packet is composed by @var{directory}, an hex encoded ++representation of the directory that the remote inferior will use as ++its current working directory. If @var{directory} is an empty string, ++the remote server should reset the inferior's current working ++directory to its original, empty value. ++ ++This packet is only available in extended mode (@pxref{extended ++mode}). ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++@end table ++ ++@item qfThreadInfo ++@itemx qsThreadInfo ++@cindex list active threads, remote request ++@cindex @samp{qfThreadInfo} packet ++@cindex @samp{qsThreadInfo} packet ++Obtain a list of all active thread IDs from the target (OS). Since there ++may be too many active threads to fit into one reply packet, this query ++works iteratively: it may require more than one query/reply sequence to ++obtain the entire list of threads. The first query of the sequence will ++be the @samp{qfThreadInfo} query; subsequent queries in the ++sequence will be the @samp{qsThreadInfo} query. ++ ++NOTE: This packet replaces the @samp{qL} query (see below). ++ ++Reply: ++@table @samp ++@item m @var{thread-id} ++A single thread ID ++@item m @var{thread-id},@var{thread-id}@dots{} ++a comma-separated list of thread IDs ++@item l ++(lower case letter @samp{L}) denotes end of list. ++@end table ++ ++In response to each query, the target will reply with a list of one or ++more thread IDs, separated by commas. ++@value{GDBN} will respond to each reply with a request for more thread ++ids (using the @samp{qs} form of the query), until the target responds ++with @samp{l} (lower-case ell, for @dfn{last}). ++Refer to @ref{thread-id syntax}, for the format of the @var{thread-id} ++fields. ++ ++@emph{Note: @value{GDBN} will send the @code{qfThreadInfo} query during the ++initial connection with the remote target, and the very first thread ID ++mentioned in the reply will be stopped by @value{GDBN} in a subsequent ++message. Therefore, the stub should ensure that the first thread ID in ++the @code{qfThreadInfo} reply is suitable for being stopped by @value{GDBN}.} ++ ++@item qGetTLSAddr:@var{thread-id},@var{offset},@var{lm} ++@cindex get thread-local storage address, remote request ++@cindex @samp{qGetTLSAddr} packet ++Fetch the address associated with thread local storage specified ++by @var{thread-id}, @var{offset}, and @var{lm}. ++ ++@var{thread-id} is the thread ID associated with the ++thread for which to fetch the TLS address. @xref{thread-id syntax}. ++ ++@var{offset} is the (big endian, hex encoded) offset associated with the ++thread local variable. (This offset is obtained from the debug ++information associated with the variable.) ++ ++@var{lm} is the (big endian, hex encoded) OS/ABI-specific encoding of the ++load module associated with the thread local storage. For example, ++a @sc{gnu}/Linux system will pass the link map address of the shared ++object associated with the thread local storage under consideration. ++Other operating environments may choose to represent the load module ++differently, so the precise meaning of this parameter will vary. ++ ++Reply: ++@table @samp ++@item @var{XX}@dots{} ++Hex encoded (big endian) bytes representing the address of the thread ++local storage requested. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{qGetTLSAddr} is not supported by the stub. ++@end table ++ ++@item qGetTIBAddr:@var{thread-id} ++@cindex get thread information block address ++@cindex @samp{qGetTIBAddr} packet ++Fetch address of the Windows OS specific Thread Information Block. ++ ++@var{thread-id} is the thread ID associated with the thread. ++ ++Reply: ++@table @samp ++@item @var{XX}@dots{} ++Hex encoded (big endian) bytes representing the linear address of the ++thread information block. ++ ++@item E @var{nn} ++An error occured. This means that either the thread was not found, or the ++address could not be retrieved. ++ ++@item @w{} ++An empty reply indicates that @samp{qGetTIBAddr} is not supported by the stub. ++@end table ++ ++@item qL @var{startflag} @var{threadcount} @var{nextthread} ++Obtain thread information from RTOS. Where: @var{startflag} (one hex ++digit) is one to indicate the first query and zero to indicate a ++subsequent query; @var{threadcount} (two hex digits) is the maximum ++number of threads the response packet can contain; and @var{nextthread} ++(eight hex digits), for subsequent queries (@var{startflag} is zero), is ++returned in the response as @var{argthread}. ++ ++Don't use this packet; use the @samp{qfThreadInfo} query instead (see above). ++ ++Reply: ++@table @samp ++@item qM @var{count} @var{done} @var{argthread} @var{thread}@dots{} ++Where: @var{count} (two hex digits) is the number of threads being ++returned; @var{done} (one hex digit) is zero to indicate more threads ++and one indicates no further threads; @var{argthreadid} (eight hex ++digits) is @var{nextthread} from the request packet; @var{thread}@dots{} ++is a sequence of thread IDs, @var{threadid} (eight hex ++digits), from the target. See @code{remote.c:parse_threadlist_response()}. ++@end table ++ ++@item qOffsets ++@cindex section offsets, remote request ++@cindex @samp{qOffsets} packet ++Get section offsets that the target used when relocating the downloaded ++image. ++ ++Reply: ++@table @samp ++@item Text=@var{xxx};Data=@var{yyy}@r{[};Bss=@var{zzz}@r{]} ++Relocate the @code{Text} section by @var{xxx} from its original address. ++Relocate the @code{Data} section by @var{yyy} from its original address. ++If the object file format provides segment information (e.g.@: @sc{elf} ++@samp{PT_LOAD} program headers), @value{GDBN} will relocate entire ++segments by the supplied offsets. ++ ++@emph{Note: while a @code{Bss} offset may be included in the response, ++@value{GDBN} ignores this and instead applies the @code{Data} offset ++to the @code{Bss} section.} ++ ++@item TextSeg=@var{xxx}@r{[};DataSeg=@var{yyy}@r{]} ++Relocate the first segment of the object file, which conventionally ++contains program code, to a starting address of @var{xxx}. If ++@samp{DataSeg} is specified, relocate the second segment, which ++conventionally contains modifiable data, to a starting address of ++@var{yyy}. @value{GDBN} will report an error if the object file ++does not contain segment information, or does not contain at least ++as many segments as mentioned in the reply. Extra segments are ++kept at fixed offsets relative to the last relocated segment. ++@end table ++ ++@item qP @var{mode} @var{thread-id} ++@cindex thread information, remote request ++@cindex @samp{qP} packet ++Returns information on @var{thread-id}. Where: @var{mode} is a hex ++encoded 32 bit mode; @var{thread-id} is a thread ID ++(@pxref{thread-id syntax}). ++ ++Don't use this packet; use the @samp{qThreadExtraInfo} query instead ++(see below). ++ ++Reply: see @code{remote.c:remote_unpack_thread_info_response()}. ++ ++@item QNonStop:1 ++@itemx QNonStop:0 ++@cindex non-stop mode, remote request ++@cindex @samp{QNonStop} packet ++@anchor{QNonStop} ++Enter non-stop (@samp{QNonStop:1}) or all-stop (@samp{QNonStop:0}) mode. ++@xref{Remote Non-Stop}, for more information. ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QNonStop} is not supported by ++the stub. ++@end table ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++Use of this packet is controlled by the @code{set non-stop} command; ++@pxref{Non-Stop Mode}. ++ ++@item QCatchSyscalls:1 @r{[};@var{sysno}@r{]}@dots{} ++@itemx QCatchSyscalls:0 ++@cindex catch syscalls from inferior, remote request ++@cindex @samp{QCatchSyscalls} packet ++@anchor{QCatchSyscalls} ++Enable (@samp{QCatchSyscalls:1}) or disable (@samp{QCatchSyscalls:0}) ++catching syscalls from the inferior process. ++ ++For @samp{QCatchSyscalls:1}, each listed syscall @var{sysno} (encoded ++in hex) should be reported to @value{GDBN}. If no syscall @var{sysno} ++is listed, every system call should be reported. ++ ++Note that if a syscall not in the list is reported, @value{GDBN} will ++still filter the event according to its own list from all corresponding ++@code{catch syscall} commands. However, it is more efficient to only ++report the requested syscalls. ++ ++Multiple @samp{QCatchSyscalls:1} packets do not combine; any earlier ++@samp{QCatchSyscalls:1} list is completely replaced by the new list. ++ ++If the inferior process execs, the state of @samp{QCatchSyscalls} is ++kept for the new process too. On targets where exec may affect syscall ++numbers, for example with exec between 32 and 64-bit processes, the ++client should send a new packet with the new syscall list. ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. @var{nn} are hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QCatchSyscalls} is not supported by ++the stub. ++@end table ++ ++Use of this packet is controlled by the @code{set remote catch-syscalls} ++command (@pxref{Remote Configuration, set remote catch-syscalls}). ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item QPassSignals: @var{signal} @r{[};@var{signal}@r{]}@dots{} ++@cindex pass signals to inferior, remote request ++@cindex @samp{QPassSignals} packet ++@anchor{QPassSignals} ++Each listed @var{signal} should be passed directly to the inferior process. ++Signals are numbered identically to continue packets and stop replies ++(@pxref{Stop Reply Packets}). Each @var{signal} list item should be ++strictly greater than the previous item. These signals do not need to stop ++the inferior, or be reported to @value{GDBN}. All other signals should be ++reported to @value{GDBN}. Multiple @samp{QPassSignals} packets do not ++combine; any earlier @samp{QPassSignals} list is completely replaced by the ++new list. This packet improves performance when using @samp{handle ++@var{signal} nostop noprint pass}. ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QPassSignals} is not supported by ++the stub. ++@end table ++ ++Use of this packet is controlled by the @code{set remote pass-signals} ++command (@pxref{Remote Configuration, set remote pass-signals}). ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item QProgramSignals: @var{signal} @r{[};@var{signal}@r{]}@dots{} ++@cindex signals the inferior may see, remote request ++@cindex @samp{QProgramSignals} packet ++@anchor{QProgramSignals} ++Each listed @var{signal} may be delivered to the inferior process. ++Others should be silently discarded. ++ ++In some cases, the remote stub may need to decide whether to deliver a ++signal to the program or not without @value{GDBN} involvement. One ++example of that is while detaching --- the program's threads may have ++stopped for signals that haven't yet had a chance of being reported to ++@value{GDBN}, and so the remote stub can use the signal list specified ++by this packet to know whether to deliver or ignore those pending ++signals. ++ ++This does not influence whether to deliver a signal as requested by a ++resumption packet (@pxref{vCont packet}). ++ ++Signals are numbered identically to continue packets and stop replies ++(@pxref{Stop Reply Packets}). Each @var{signal} list item should be ++strictly greater than the previous item. Multiple ++@samp{QProgramSignals} packets do not combine; any earlier ++@samp{QProgramSignals} list is completely replaced by the new list. ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QProgramSignals} is not supported ++by the stub. ++@end table ++ ++Use of this packet is controlled by the @code{set remote program-signals} ++command (@pxref{Remote Configuration, set remote program-signals}). ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@anchor{QThreadEvents} ++@item QThreadEvents:1 ++@itemx QThreadEvents:0 ++@cindex thread create/exit events, remote request ++@cindex @samp{QThreadEvents} packet ++ ++Enable (@samp{QThreadEvents:1}) or disable (@samp{QThreadEvents:0}) ++reporting of thread create and exit events. @xref{thread create ++event}, for the reply specifications. For example, this is used in ++non-stop mode when @value{GDBN} stops a set of threads and ++synchronously waits for the their corresponding stop replies. Without ++exit events, if one of the threads exits, @value{GDBN} would hang ++forever not knowing that it should no longer expect a stop for that ++same thread. @value{GDBN} does not enable this feature unless the ++stub reports that it supports it by including @samp{QThreadEvents+} in ++its @samp{qSupported} reply. ++ ++Reply: ++@table @samp ++@item OK ++The request succeeded. ++ ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++ ++@item @w{} ++An empty reply indicates that @samp{QThreadEvents} is not supported by ++the stub. ++@end table ++ ++Use of this packet is controlled by the @code{set remote thread-events} ++command (@pxref{Remote Configuration, set remote thread-events}). ++ ++@item qRcmd,@var{command} ++@cindex execute remote command, remote request ++@cindex @samp{qRcmd} packet ++@var{command} (hex encoded) is passed to the local interpreter for ++execution. Invalid commands should be reported using the output ++string. Before the final result packet, the target may also respond ++with a number of intermediate @samp{O@var{output}} console output ++packets. @emph{Implementors should note that providing access to a ++stubs's interpreter may have security implications}. ++ ++Reply: ++@table @samp ++@item OK ++A command response with no output. ++@item @var{OUTPUT} ++A command response with the hex encoded output string @var{OUTPUT}. ++@item E @var{NN} ++Indicate a badly formed request. ++@item @w{} ++An empty reply indicates that @samp{qRcmd} is not recognized. ++@end table ++ ++(Note that the @code{qRcmd} packet's name is separated from the ++command by a @samp{,}, not a @samp{:}, contrary to the naming ++conventions above. Please don't use this packet as a model for new ++packets.) ++ ++@item qSearch:memory:@var{address};@var{length};@var{search-pattern} ++@cindex searching memory, in remote debugging ++@ifnotinfo ++@cindex @samp{qSearch:memory} packet ++@end ifnotinfo ++@cindex @samp{qSearch memory} packet ++@anchor{qSearch memory} ++Search @var{length} bytes at @var{address} for @var{search-pattern}. ++Both @var{address} and @var{length} are encoded in hex; ++@var{search-pattern} is a sequence of bytes, also hex encoded. ++ ++Reply: ++@table @samp ++@item 0 ++The pattern was not found. ++@item 1,address ++The pattern was found at @var{address}. ++@item E @var{NN} ++A badly formed request or an error was encountered while searching memory. ++@item @w{} ++An empty reply indicates that @samp{qSearch:memory} is not recognized. ++@end table ++ ++@item QStartNoAckMode ++@cindex @samp{QStartNoAckMode} packet ++@anchor{QStartNoAckMode} ++Request that the remote stub disable the normal @samp{+}/@samp{-} ++protocol acknowledgments (@pxref{Packet Acknowledgment}). ++ ++Reply: ++@table @samp ++@item OK ++The stub has switched to no-acknowledgment mode. ++@value{GDBN} acknowledges this response, ++but neither the stub nor @value{GDBN} shall send or expect further ++@samp{+}/@samp{-} acknowledgments in the current connection. ++@item @w{} ++An empty reply indicates that the stub does not support no-acknowledgment mode. ++@end table ++ ++@item qSupported @r{[}:@var{gdbfeature} @r{[};@var{gdbfeature}@r{]}@dots{} @r{]} ++@cindex supported packets, remote query ++@cindex features of the remote protocol ++@cindex @samp{qSupported} packet ++@anchor{qSupported} ++Tell the remote stub about features supported by @value{GDBN}, and ++query the stub for features it supports. This packet allows ++@value{GDBN} and the remote stub to take advantage of each others' ++features. @samp{qSupported} also consolidates multiple feature probes ++at startup, to improve @value{GDBN} performance---a single larger ++packet performs better than multiple smaller probe packets on ++high-latency links. Some features may enable behavior which must not ++be on by default, e.g.@: because it would confuse older clients or ++stubs. Other features may describe packets which could be ++automatically probed for, but are not. These features must be ++reported before @value{GDBN} will use them. This ``default ++unsupported'' behavior is not appropriate for all packets, but it ++helps to keep the initial connection time under control with new ++versions of @value{GDBN} which support increasing numbers of packets. ++ ++Reply: ++@table @samp ++@item @var{stubfeature} @r{[};@var{stubfeature}@r{]}@dots{} ++The stub supports or does not support each returned @var{stubfeature}, ++depending on the form of each @var{stubfeature} (see below for the ++possible forms). ++@item @w{} ++An empty reply indicates that @samp{qSupported} is not recognized, ++or that no features needed to be reported to @value{GDBN}. ++@end table ++ ++The allowed forms for each feature (either a @var{gdbfeature} in the ++@samp{qSupported} packet, or a @var{stubfeature} in the response) ++are: ++ ++@table @samp ++@item @var{name}=@var{value} ++The remote protocol feature @var{name} is supported, and associated ++with the specified @var{value}. The format of @var{value} depends ++on the feature, but it must not include a semicolon. ++@item @var{name}+ ++The remote protocol feature @var{name} is supported, and does not ++need an associated value. ++@item @var{name}- ++The remote protocol feature @var{name} is not supported. ++@item @var{name}? ++The remote protocol feature @var{name} may be supported, and ++@value{GDBN} should auto-detect support in some other way when it is ++needed. This form will not be used for @var{gdbfeature} notifications, ++but may be used for @var{stubfeature} responses. ++@end table ++ ++Whenever the stub receives a @samp{qSupported} request, the ++supplied set of @value{GDBN} features should override any previous ++request. This allows @value{GDBN} to put the stub in a known ++state, even if the stub had previously been communicating with ++a different version of @value{GDBN}. ++ ++The following values of @var{gdbfeature} (for the packet sent by @value{GDBN}) ++are defined: ++ ++@table @samp ++@item multiprocess ++This feature indicates whether @value{GDBN} supports multiprocess ++extensions to the remote protocol. @value{GDBN} does not use such ++extensions unless the stub also reports that it supports them by ++including @samp{multiprocess+} in its @samp{qSupported} reply. ++@xref{multiprocess extensions}, for details. ++ ++@item xmlRegisters ++This feature indicates that @value{GDBN} supports the XML target ++description. If the stub sees @samp{xmlRegisters=} with target ++specific strings separated by a comma, it will report register ++description. ++ ++@item qRelocInsn ++This feature indicates whether @value{GDBN} supports the ++@samp{qRelocInsn} packet (@pxref{Tracepoint Packets,,Relocate ++instruction reply packet}). ++ ++@item swbreak ++This feature indicates whether @value{GDBN} supports the swbreak stop ++reason in stop replies. @xref{swbreak stop reason}, for details. ++ ++@item hwbreak ++This feature indicates whether @value{GDBN} supports the hwbreak stop ++reason in stop replies. @xref{swbreak stop reason}, for details. ++ ++@item fork-events ++This feature indicates whether @value{GDBN} supports fork event ++extensions to the remote protocol. @value{GDBN} does not use such ++extensions unless the stub also reports that it supports them by ++including @samp{fork-events+} in its @samp{qSupported} reply. ++ ++@item vfork-events ++This feature indicates whether @value{GDBN} supports vfork event ++extensions to the remote protocol. @value{GDBN} does not use such ++extensions unless the stub also reports that it supports them by ++including @samp{vfork-events+} in its @samp{qSupported} reply. ++ ++@item exec-events ++This feature indicates whether @value{GDBN} supports exec event ++extensions to the remote protocol. @value{GDBN} does not use such ++extensions unless the stub also reports that it supports them by ++including @samp{exec-events+} in its @samp{qSupported} reply. ++ ++@item vContSupported ++This feature indicates whether @value{GDBN} wants to know the ++supported actions in the reply to @samp{vCont?} packet. ++@end table ++ ++Stubs should ignore any unknown values for ++@var{gdbfeature}. Any @value{GDBN} which sends a @samp{qSupported} ++packet supports receiving packets of unlimited length (earlier ++versions of @value{GDBN} may reject overly long responses). Additional values ++for @var{gdbfeature} may be defined in the future to let the stub take ++advantage of new features in @value{GDBN}, e.g.@: incompatible ++improvements in the remote protocol---the @samp{multiprocess} feature is ++an example of such a feature. The stub's reply should be independent ++of the @var{gdbfeature} entries sent by @value{GDBN}; first @value{GDBN} ++describes all the features it supports, and then the stub replies with ++all the features it supports. ++ ++Similarly, @value{GDBN} will silently ignore unrecognized stub feature ++responses, as long as each response uses one of the standard forms. ++ ++Some features are flags. A stub which supports a flag feature ++should respond with a @samp{+} form response. Other features ++require values, and the stub should respond with an @samp{=} ++form response. ++ ++Each feature has a default value, which @value{GDBN} will use if ++@samp{qSupported} is not available or if the feature is not mentioned ++in the @samp{qSupported} response. The default values are fixed; a ++stub is free to omit any feature responses that match the defaults. ++ ++Not all features can be probed, but for those which can, the probing ++mechanism is useful: in some cases, a stub's internal ++architecture may not allow the protocol layer to know some information ++about the underlying target in advance. This is especially common in ++stubs which may be configured for multiple targets. ++ ++These are the currently defined stub features and their properties: ++ ++@multitable @columnfractions 0.35 0.2 0.12 0.2 ++@c NOTE: The first row should be @headitem, but we do not yet require ++@c a new enough version of Texinfo (4.7) to use @headitem. ++@item Feature Name ++@tab Value Required ++@tab Default ++@tab Probe Allowed ++ ++@item @samp{PacketSize} ++@tab Yes ++@tab @samp{-} ++@tab No ++ ++@item @samp{qXfer:auxv:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:btrace:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:btrace-conf:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:exec-file:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:features:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:libraries:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:libraries-svr4:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{augmented-libraries-svr4-read} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{qXfer:memory-map:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:sdata:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:siginfo:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:siginfo:write} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:threads:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:traceframe-info:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:uib:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{qXfer:fdpic:read} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{Qbtrace:off} ++@tab Yes ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{Qbtrace:bts} ++@tab Yes ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{Qbtrace:pt} ++@tab Yes ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{Qbtrace-conf:bts:size} ++@tab Yes ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{Qbtrace-conf:pt:size} ++@tab Yes ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{QNonStop} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{QCatchSyscalls} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{QPassSignals} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{QStartNoAckMode} ++@tab No ++@tab @samp{-} ++@tab Yes ++ ++@item @samp{multiprocess} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{ConditionalBreakpoints} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{ConditionalTracepoints} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{ReverseContinue} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{ReverseStep} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{TracepointSource} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{QAgent} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{QAllow} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{QDisableRandomization} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{EnableDisableTracepoints} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{QTBuffer:size} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{tracenz} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{BreakpointCommands} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{swbreak} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{hwbreak} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{fork-events} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{vfork-events} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{exec-events} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{QThreadEvents} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@item @samp{no-resumed} ++@tab No ++@tab @samp{-} ++@tab No ++ ++@end multitable ++ ++These are the currently defined stub features, in more detail: ++ ++@table @samp ++@cindex packet size, remote protocol ++@item PacketSize=@var{bytes} ++The remote stub can accept packets up to at least @var{bytes} in ++length. @value{GDBN} will send packets up to this size for bulk ++transfers, and will never send larger packets. This is a limit on the ++data characters in the packet, including the frame and checksum. ++There is no trailing NUL byte in a remote protocol packet; if the stub ++stores packets in a NUL-terminated format, it should allow an extra ++byte in its buffer for the NUL. If this stub feature is not supported, ++@value{GDBN} guesses based on the size of the @samp{g} packet response. ++ ++@item qXfer:auxv:read ++The remote stub understands the @samp{qXfer:auxv:read} packet ++(@pxref{qXfer auxiliary vector read}). ++ ++@item qXfer:btrace:read ++The remote stub understands the @samp{qXfer:btrace:read} ++packet (@pxref{qXfer btrace read}). ++ ++@item qXfer:btrace-conf:read ++The remote stub understands the @samp{qXfer:btrace-conf:read} ++packet (@pxref{qXfer btrace-conf read}). ++ ++@item qXfer:exec-file:read ++The remote stub understands the @samp{qXfer:exec-file:read} packet ++(@pxref{qXfer executable filename read}). ++ ++@item qXfer:features:read ++The remote stub understands the @samp{qXfer:features:read} packet ++(@pxref{qXfer target description read}). ++ ++@item qXfer:libraries:read ++The remote stub understands the @samp{qXfer:libraries:read} packet ++(@pxref{qXfer library list read}). ++ ++@item qXfer:libraries-svr4:read ++The remote stub understands the @samp{qXfer:libraries-svr4:read} packet ++(@pxref{qXfer svr4 library list read}). ++ ++@item augmented-libraries-svr4-read ++The remote stub understands the augmented form of the ++@samp{qXfer:libraries-svr4:read} packet ++(@pxref{qXfer svr4 library list read}). ++ ++@item qXfer:memory-map:read ++The remote stub understands the @samp{qXfer:memory-map:read} packet ++(@pxref{qXfer memory map read}). ++ ++@item qXfer:sdata:read ++The remote stub understands the @samp{qXfer:sdata:read} packet ++(@pxref{qXfer sdata read}). ++ ++@item qXfer:siginfo:read ++The remote stub understands the @samp{qXfer:siginfo:read} packet ++(@pxref{qXfer siginfo read}). ++ ++@item qXfer:siginfo:write ++The remote stub understands the @samp{qXfer:siginfo:write} packet ++(@pxref{qXfer siginfo write}). ++ ++@item qXfer:threads:read ++The remote stub understands the @samp{qXfer:threads:read} packet ++(@pxref{qXfer threads read}). ++ ++@item qXfer:traceframe-info:read ++The remote stub understands the @samp{qXfer:traceframe-info:read} ++packet (@pxref{qXfer traceframe info read}). ++ ++@item qXfer:uib:read ++The remote stub understands the @samp{qXfer:uib:read} ++packet (@pxref{qXfer unwind info block}). ++ ++@item qXfer:fdpic:read ++The remote stub understands the @samp{qXfer:fdpic:read} ++packet (@pxref{qXfer fdpic loadmap read}). ++ ++@item QNonStop ++The remote stub understands the @samp{QNonStop} packet ++(@pxref{QNonStop}). ++ ++@item QCatchSyscalls ++The remote stub understands the @samp{QCatchSyscalls} packet ++(@pxref{QCatchSyscalls}). ++ ++@item QPassSignals ++The remote stub understands the @samp{QPassSignals} packet ++(@pxref{QPassSignals}). ++ ++@item QStartNoAckMode ++The remote stub understands the @samp{QStartNoAckMode} packet and ++prefers to operate in no-acknowledgment mode. @xref{Packet Acknowledgment}. ++ ++@item multiprocess ++@anchor{multiprocess extensions} ++@cindex multiprocess extensions, in remote protocol ++The remote stub understands the multiprocess extensions to the remote ++protocol syntax. The multiprocess extensions affect the syntax of ++thread IDs in both packets and replies (@pxref{thread-id syntax}), and ++add process IDs to the @samp{D} packet and @samp{W} and @samp{X} ++replies. Note that reporting this feature indicates support for the ++syntactic extensions only, not that the stub necessarily supports ++debugging of more than one process at a time. The stub must not use ++multiprocess extensions in packet replies unless @value{GDBN} has also ++indicated it supports them in its @samp{qSupported} request. ++ ++@item qXfer:osdata:read ++The remote stub understands the @samp{qXfer:osdata:read} packet ++((@pxref{qXfer osdata read}). ++ ++@item ConditionalBreakpoints ++The target accepts and implements evaluation of conditional expressions ++defined for breakpoints. The target will only report breakpoint triggers ++when such conditions are true (@pxref{Conditions, ,Break Conditions}). ++ ++@item ConditionalTracepoints ++The remote stub accepts and implements conditional expressions defined ++for tracepoints (@pxref{Tracepoint Conditions}). ++ ++@item ReverseContinue ++The remote stub accepts and implements the reverse continue packet ++(@pxref{bc}). ++ ++@item ReverseStep ++The remote stub accepts and implements the reverse step packet ++(@pxref{bs}). ++ ++@item TracepointSource ++The remote stub understands the @samp{QTDPsrc} packet that supplies ++the source form of tracepoint definitions. ++ ++@item QAgent ++The remote stub understands the @samp{QAgent} packet. ++ ++@item QAllow ++The remote stub understands the @samp{QAllow} packet. ++ ++@item QDisableRandomization ++The remote stub understands the @samp{QDisableRandomization} packet. ++ ++@item StaticTracepoint ++@cindex static tracepoints, in remote protocol ++The remote stub supports static tracepoints. ++ ++@item InstallInTrace ++@anchor{install tracepoint in tracing} ++The remote stub supports installing tracepoint in tracing. ++ ++@item EnableDisableTracepoints ++The remote stub supports the @samp{QTEnable} (@pxref{QTEnable}) and ++@samp{QTDisable} (@pxref{QTDisable}) packets that allow tracepoints ++to be enabled and disabled while a trace experiment is running. ++ ++@item QTBuffer:size ++The remote stub supports the @samp{QTBuffer:size} (@pxref{QTBuffer-size}) ++packet that allows to change the size of the trace buffer. ++ ++@item tracenz ++@cindex string tracing, in remote protocol ++The remote stub supports the @samp{tracenz} bytecode for collecting strings. ++See @ref{Bytecode Descriptions} for details about the bytecode. ++ ++@item BreakpointCommands ++@cindex breakpoint commands, in remote protocol ++The remote stub supports running a breakpoint's command list itself, ++rather than reporting the hit to @value{GDBN}. ++ ++@item Qbtrace:off ++The remote stub understands the @samp{Qbtrace:off} packet. ++ ++@item Qbtrace:bts ++The remote stub understands the @samp{Qbtrace:bts} packet. ++ ++@item Qbtrace:pt ++The remote stub understands the @samp{Qbtrace:pt} packet. ++ ++@item Qbtrace-conf:bts:size ++The remote stub understands the @samp{Qbtrace-conf:bts:size} packet. ++ ++@item Qbtrace-conf:pt:size ++The remote stub understands the @samp{Qbtrace-conf:pt:size} packet. ++ ++@item swbreak ++The remote stub reports the @samp{swbreak} stop reason for memory ++breakpoints. ++ ++@item hwbreak ++The remote stub reports the @samp{hwbreak} stop reason for hardware ++breakpoints. ++ ++@item fork-events ++The remote stub reports the @samp{fork} stop reason for fork events. ++ ++@item vfork-events ++The remote stub reports the @samp{vfork} stop reason for vfork events ++and vforkdone events. ++ ++@item exec-events ++The remote stub reports the @samp{exec} stop reason for exec events. ++ ++@item vContSupported ++The remote stub reports the supported actions in the reply to ++@samp{vCont?} packet. ++ ++@item QThreadEvents ++The remote stub understands the @samp{QThreadEvents} packet. ++ ++@item no-resumed ++The remote stub reports the @samp{N} stop reply. ++ ++@end table ++ ++@item qSymbol:: ++@cindex symbol lookup, remote request ++@cindex @samp{qSymbol} packet ++Notify the target that @value{GDBN} is prepared to serve symbol lookup ++requests. Accept requests from the target for the values of symbols. ++ ++Reply: ++@table @samp ++@item OK ++The target does not need to look up any (more) symbols. ++@item qSymbol:@var{sym_name} ++The target requests the value of symbol @var{sym_name} (hex encoded). ++@value{GDBN} may provide the value by using the ++@samp{qSymbol:@var{sym_value}:@var{sym_name}} message, described ++below. ++@end table ++ ++@item qSymbol:@var{sym_value}:@var{sym_name} ++Set the value of @var{sym_name} to @var{sym_value}. ++ ++@var{sym_name} (hex encoded) is the name of a symbol whose value the ++target has previously requested. ++ ++@var{sym_value} (hex) is the value for symbol @var{sym_name}. If ++@value{GDBN} cannot supply a value for @var{sym_name}, then this field ++will be empty. ++ ++Reply: ++@table @samp ++@item OK ++The target does not need to look up any (more) symbols. ++@item qSymbol:@var{sym_name} ++The target requests the value of a new symbol @var{sym_name} (hex ++encoded). @value{GDBN} will continue to supply the values of symbols ++(if available), until the target ceases to request them. ++@end table ++ ++@item qTBuffer ++@itemx QTBuffer ++@itemx QTDisconnected ++@itemx QTDP ++@itemx QTDPsrc ++@itemx QTDV ++@itemx qTfP ++@itemx qTfV ++@itemx QTFrame ++@itemx qTMinFTPILen ++ ++@xref{Tracepoint Packets}. ++ ++@item qThreadExtraInfo,@var{thread-id} ++@cindex thread attributes info, remote request ++@cindex @samp{qThreadExtraInfo} packet ++Obtain from the target OS a printable string description of thread ++attributes for the thread @var{thread-id}; see @ref{thread-id syntax}, ++for the forms of @var{thread-id}. This ++string may contain anything that the target OS thinks is interesting ++for @value{GDBN} to tell the user about the thread. The string is ++displayed in @value{GDBN}'s @code{info threads} display. Some ++examples of possible thread extra info strings are @samp{Runnable}, or ++@samp{Blocked on Mutex}. ++ ++Reply: ++@table @samp ++@item @var{XX}@dots{} ++Where @samp{@var{XX}@dots{}} is a hex encoding of @sc{ascii} data, ++comprising the printable string containing the extra information about ++the thread's attributes. ++@end table ++ ++(Note that the @code{qThreadExtraInfo} packet's name is separated from ++the command by a @samp{,}, not a @samp{:}, contrary to the naming ++conventions above. Please don't use this packet as a model for new ++packets.) ++ ++@item QTNotes ++@itemx qTP ++@itemx QTSave ++@itemx qTsP ++@itemx qTsV ++@itemx QTStart ++@itemx QTStop ++@itemx QTEnable ++@itemx QTDisable ++@itemx QTinit ++@itemx QTro ++@itemx qTStatus ++@itemx qTV ++@itemx qTfSTM ++@itemx qTsSTM ++@itemx qTSTMat ++@xref{Tracepoint Packets}. ++ ++@item qXfer:@var{object}:read:@var{annex}:@var{offset},@var{length} ++@cindex read special object, remote request ++@cindex @samp{qXfer} packet ++@anchor{qXfer read} ++Read uninterpreted bytes from the target's special data area ++identified by the keyword @var{object}. Request @var{length} bytes ++starting at @var{offset} bytes into the data. The content and ++encoding of @var{annex} is specific to @var{object}; it can supply ++additional details about what data to access. ++ ++Reply: ++@table @samp ++@item m @var{data} ++Data @var{data} (@pxref{Binary Data}) has been read from the ++target. There may be more data at a higher address (although ++it is permitted to return @samp{m} even for the last valid ++block of data, as long as at least one byte of data was read). ++It is possible for @var{data} to have fewer bytes than the @var{length} in the ++request. ++ ++@item l @var{data} ++Data @var{data} (@pxref{Binary Data}) has been read from the target. ++There is no more data to be read. It is possible for @var{data} to ++have fewer bytes than the @var{length} in the request. ++ ++@item l ++The @var{offset} in the request is at the end of the data. ++There is no more data to be read. ++ ++@item E00 ++The request was malformed, or @var{annex} was invalid. ++ ++@item E @var{nn} ++The offset was invalid, or there was an error encountered reading the data. ++The @var{nn} part is a hex-encoded @code{errno} value. ++ ++@item @w{} ++An empty reply indicates the @var{object} string was not recognized by ++the stub, or that the object does not support reading. ++@end table ++ ++Here are the specific requests of this form defined so far. All the ++@samp{qXfer:@var{object}:read:@dots{}} requests use the same reply ++formats, listed above. ++ ++@table @samp ++@item qXfer:auxv:read::@var{offset},@var{length} ++@anchor{qXfer auxiliary vector read} ++Access the target's @dfn{auxiliary vector}. @xref{OS Information, ++auxiliary vector}. Note @var{annex} must be empty. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:btrace:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer btrace read} ++ ++Return a description of the current branch trace. ++@xref{Branch Trace Format}. The annex part of the generic @samp{qXfer} ++packet may have one of the following values: ++ ++@table @code ++@item all ++Returns all available branch trace. ++ ++@item new ++Returns all available branch trace if the branch trace changed since ++the last read request. ++ ++@item delta ++Returns the new branch trace since the last read request. Adds a new ++block to the end of the trace that begins at zero and ends at the source ++location of the first branch in the trace buffer. This extra block is ++used to stitch traces together. ++ ++If the trace buffer overflowed, returns an error indicating the overflow. ++@end table ++ ++This packet is not probed by default; the remote stub must request it ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:btrace-conf:read::@var{offset},@var{length} ++@anchor{qXfer btrace-conf read} ++ ++Return a description of the current branch trace configuration. ++@xref{Branch Trace Configuration Format}. ++ ++This packet is not probed by default; the remote stub must request it ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:exec-file:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer executable filename read} ++Return the full absolute name of the file that was executed to create ++a process running on the remote system. The annex specifies the ++numeric process ID of the process to query, encoded as a hexadecimal ++number. If the annex part is empty the remote stub should return the ++filename corresponding to the currently executing process. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:features:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer target description read} ++Access the @dfn{target description}. @xref{Target Descriptions}. The ++annex specifies which XML document to access. The main description is ++always loaded from the @samp{target.xml} annex. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:libraries:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer library list read} ++Access the target's list of loaded libraries. @xref{Library List Format}. ++The annex part of the generic @samp{qXfer} packet must be empty ++(@pxref{qXfer read}). ++ ++Targets which maintain a list of libraries in the program's memory do ++not need to implement this packet; it is designed for platforms where ++the operating system manages the list of loaded libraries. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:libraries-svr4:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer svr4 library list read} ++Access the target's list of loaded libraries when the target is an SVR4 ++platform. @xref{Library List Format for SVR4 Targets}. The annex part ++of the generic @samp{qXfer} packet must be empty unless the remote ++stub indicated it supports the augmented form of this packet ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qXfer read}, @ref{qSupported}). ++ ++This packet is optional for better performance on SVR4 targets. ++@value{GDBN} uses memory read packets to read the SVR4 library list otherwise. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++If the remote stub indicates it supports the augmented form of this ++packet then the annex part of the generic @samp{qXfer} packet may ++contain a semicolon-separated list of @samp{@var{name}=@var{value}} ++arguments. The currently supported arguments are: ++ ++@table @code ++@item start=@var{address} ++A hexadecimal number specifying the address of the @samp{struct ++link_map} to start reading the library list from. If unset or zero ++then the first @samp{struct link_map} in the library list will be ++chosen as the starting point. ++ ++@item prev=@var{address} ++A hexadecimal number specifying the address of the @samp{struct ++link_map} immediately preceding the @samp{struct link_map} ++specified by the @samp{start} argument. If unset or zero then ++the remote stub will expect that no @samp{struct link_map} ++exists prior to the starting point. ++ ++@end table ++ ++Arguments that are not understood by the remote stub will be silently ++ignored. ++ ++@item qXfer:memory-map:read::@var{offset},@var{length} ++@anchor{qXfer memory map read} ++Access the target's @dfn{memory-map}. @xref{Memory Map Format}. The ++annex part of the generic @samp{qXfer} packet must be empty ++(@pxref{qXfer read}). ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:sdata:read::@var{offset},@var{length} ++@anchor{qXfer sdata read} ++ ++Read contents of the extra collected static tracepoint marker ++information. The annex part of the generic @samp{qXfer} packet must ++be empty (@pxref{qXfer read}). @xref{Tracepoint Actions,,Tracepoint ++Action Lists}. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). ++ ++@item qXfer:siginfo:read::@var{offset},@var{length} ++@anchor{qXfer siginfo read} ++Read contents of the extra signal information on the target ++system. The annex part of the generic @samp{qXfer} packet must be ++empty (@pxref{qXfer read}). ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). ++ ++@item qXfer:threads:read::@var{offset},@var{length} ++@anchor{qXfer threads read} ++Access the list of threads on target. @xref{Thread List Format}. The ++annex part of the generic @samp{qXfer} packet must be empty ++(@pxref{qXfer read}). ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:traceframe-info:read::@var{offset},@var{length} ++@anchor{qXfer traceframe info read} ++ ++Return a description of the current traceframe's contents. ++@xref{Traceframe Info Format}. The annex part of the generic ++@samp{qXfer} packet must be empty (@pxref{qXfer read}). ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:uib:read:@var{pc}:@var{offset},@var{length} ++@anchor{qXfer unwind info block} ++ ++Return the unwind information block for @var{pc}. This packet is used ++on OpenVMS/ia64 to ask the kernel unwind information. ++ ++This packet is not probed by default. ++ ++@item qXfer:fdpic:read:@var{annex}:@var{offset},@var{length} ++@anchor{qXfer fdpic loadmap read} ++Read contents of @code{loadmap}s on the target system. The ++annex, either @samp{exec} or @samp{interp}, specifies which @code{loadmap}, ++executable @code{loadmap} or interpreter @code{loadmap} to read. ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}). ++ ++@item qXfer:osdata:read::@var{offset},@var{length} ++@anchor{qXfer osdata read} ++Access the target's @dfn{operating system information}. ++@xref{Operating System Information}. ++ ++@end table ++ ++@item qXfer:@var{object}:write:@var{annex}:@var{offset}:@var{data}@dots{} ++@cindex write data into object, remote request ++@anchor{qXfer write} ++Write uninterpreted bytes into the target's special data area ++identified by the keyword @var{object}, starting at @var{offset} bytes ++into the data. The binary-encoded data (@pxref{Binary Data}) to be ++written is given by @var{data}@dots{}. The content and encoding of @var{annex} ++is specific to @var{object}; it can supply additional details about what data ++to access. ++ ++Reply: ++@table @samp ++@item @var{nn} ++@var{nn} (hex encoded) is the number of bytes written. ++This may be fewer bytes than supplied in the request. ++ ++@item E00 ++The request was malformed, or @var{annex} was invalid. ++ ++@item E @var{nn} ++The offset was invalid, or there was an error encountered writing the data. ++The @var{nn} part is a hex-encoded @code{errno} value. ++ ++@item @w{} ++An empty reply indicates the @var{object} string was not ++recognized by the stub, or that the object does not support writing. ++@end table ++ ++Here are the specific requests of this form defined so far. All the ++@samp{qXfer:@var{object}:write:@dots{}} requests use the same reply ++formats, listed above. ++ ++@table @samp ++@item qXfer:siginfo:write::@var{offset}:@var{data}@dots{} ++@anchor{qXfer siginfo write} ++Write @var{data} to the extra signal information on the target system. ++The annex part of the generic @samp{qXfer} packet must be ++empty (@pxref{qXfer write}). ++ ++This packet is not probed by default; the remote stub must request it, ++by supplying an appropriate @samp{qSupported} response ++(@pxref{qSupported}). ++@end table ++ ++@item qXfer:@var{object}:@var{operation}:@dots{} ++Requests of this form may be added in the future. When a stub does ++not recognize the @var{object} keyword, or its support for ++@var{object} does not recognize the @var{operation} keyword, the stub ++must respond with an empty packet. ++ ++@item qAttached:@var{pid} ++@cindex query attached, remote request ++@cindex @samp{qAttached} packet ++Return an indication of whether the remote server attached to an ++existing process or created a new process. When the multiprocess ++protocol extensions are supported (@pxref{multiprocess extensions}), ++@var{pid} is an integer in hexadecimal format identifying the target ++process. Otherwise, @value{GDBN} will omit the @var{pid} field and ++the query packet will be simplified as @samp{qAttached}. ++ ++This query is used, for example, to know whether the remote process ++should be detached or killed when a @value{GDBN} session is ended with ++the @code{quit} command. ++ ++Reply: ++@table @samp ++@item 1 ++The remote server attached to an existing process. ++@item 0 ++The remote server created a new process. ++@item E @var{NN} ++A badly formed request or an error was encountered. ++@end table ++ ++@item Qbtrace:bts ++Enable branch tracing for the current thread using Branch Trace Store. ++ ++Reply: ++@table @samp ++@item OK ++Branch tracing has been enabled. ++@item E.errtext ++A badly formed request or an error was encountered. ++@end table ++ ++@item Qbtrace:pt ++Enable branch tracing for the current thread using Intel Processor Trace. ++ ++Reply: ++@table @samp ++@item OK ++Branch tracing has been enabled. ++@item E.errtext ++A badly formed request or an error was encountered. ++@end table ++ ++@item Qbtrace:off ++Disable branch tracing for the current thread. ++ ++Reply: ++@table @samp ++@item OK ++Branch tracing has been disabled. ++@item E.errtext ++A badly formed request or an error was encountered. ++@end table ++ ++@item Qbtrace-conf:bts:size=@var{value} ++Set the requested ring buffer size for new threads that use the ++btrace recording method in bts format. ++ ++Reply: ++@table @samp ++@item OK ++The ring buffer size has been set. ++@item E.errtext ++A badly formed request or an error was encountered. ++@end table ++ ++@item Qbtrace-conf:pt:size=@var{value} ++Set the requested ring buffer size for new threads that use the ++btrace recording method in pt format. ++ ++Reply: ++@table @samp ++@item OK ++The ring buffer size has been set. ++@item E.errtext ++A badly formed request or an error was encountered. ++@end table ++ ++@end table ++ ++@node Architecture-Specific Protocol Details ++@section Architecture-Specific Protocol Details ++ ++This section describes how the remote protocol is applied to specific ++target architectures. Also see @ref{Standard Target Features}, for ++details of XML target descriptions for each architecture. ++ ++@menu ++* ARM-Specific Protocol Details:: ++* MIPS-Specific Protocol Details:: ++@end menu ++ ++@node ARM-Specific Protocol Details ++@subsection @acronym{ARM}-specific Protocol Details ++ ++@menu ++* ARM Breakpoint Kinds:: ++@end menu ++ ++@node ARM Breakpoint Kinds ++@subsubsection @acronym{ARM} Breakpoint Kinds ++@cindex breakpoint kinds, @acronym{ARM} ++ ++These breakpoint kinds are defined for the @samp{Z0} and @samp{Z1} packets. ++ ++@table @r ++ ++@item 2 ++16-bit Thumb mode breakpoint. ++ ++@item 3 ++32-bit Thumb mode (Thumb-2) breakpoint. ++ ++@item 4 ++32-bit @acronym{ARM} mode breakpoint. ++ ++@end table ++ ++@node MIPS-Specific Protocol Details ++@subsection @acronym{MIPS}-specific Protocol Details ++ ++@menu ++* MIPS Register packet Format:: ++* MIPS Breakpoint Kinds:: ++@end menu ++ ++@node MIPS Register packet Format ++@subsubsection @acronym{MIPS} Register Packet Format ++@cindex register packet format, @acronym{MIPS} ++ ++The following @code{g}/@code{G} packets have previously been defined. ++In the below, some thirty-two bit registers are transferred as ++sixty-four bits. Those registers should be zero/sign extended (which?) ++to fill the space allocated. Register bytes are transferred in target ++byte order. The two nibbles within a register byte are transferred ++most-significant -- least-significant. ++ ++@table @r ++ ++@item MIPS32 ++All registers are transferred as thirty-two bit quantities in the order: ++32 general-purpose; sr; lo; hi; bad; cause; pc; 32 floating-point ++registers; fsr; fir; fp. ++ ++@item MIPS64 ++All registers are transferred as sixty-four bit quantities (including ++thirty-two bit registers such as @code{sr}). The ordering is the same ++as @code{MIPS32}. ++ ++@end table ++ ++@node MIPS Breakpoint Kinds ++@subsubsection @acronym{MIPS} Breakpoint Kinds ++@cindex breakpoint kinds, @acronym{MIPS} ++ ++These breakpoint kinds are defined for the @samp{Z0} and @samp{Z1} packets. ++ ++@table @r ++ ++@item 2 ++16-bit @acronym{MIPS16} mode breakpoint. ++ ++@item 3 ++16-bit @acronym{microMIPS} mode breakpoint. ++ ++@item 4 ++32-bit standard @acronym{MIPS} mode breakpoint. ++ ++@item 5 ++32-bit @acronym{microMIPS} mode breakpoint. ++ ++@end table ++ ++@node Tracepoint Packets ++@section Tracepoint Packets ++@cindex tracepoint packets ++@cindex packets, tracepoint ++ ++Here we describe the packets @value{GDBN} uses to implement ++tracepoints (@pxref{Tracepoints}). ++ ++@table @samp ++ ++@item QTDP:@var{n}:@var{addr}:@var{ena}:@var{step}:@var{pass}[:F@var{flen}][:X@var{len},@var{bytes}]@r{[}-@r{]} ++@cindex @samp{QTDP} packet ++Create a new tracepoint, number @var{n}, at @var{addr}. If @var{ena} ++is @samp{E}, then the tracepoint is enabled; if it is @samp{D}, then ++the tracepoint is disabled. The @var{step} gives the tracepoint's step ++count, and @var{pass} gives its pass count. If an @samp{F} is present, ++then the tracepoint is to be a fast tracepoint, and the @var{flen} is ++the number of bytes that the target should copy elsewhere to make room ++for the tracepoint. If an @samp{X} is present, it introduces a ++tracepoint condition, which consists of a hexadecimal length, followed ++by a comma and hex-encoded bytes, in a manner similar to action ++encodings as described below. If the trailing @samp{-} is present, ++further @samp{QTDP} packets will follow to specify this tracepoint's ++actions. ++ ++Replies: ++@table @samp ++@item OK ++The packet was understood and carried out. ++@item qRelocInsn ++@xref{Tracepoint Packets,,Relocate instruction reply packet}. ++@item @w{} ++The packet was not recognized. ++@end table ++ ++@item QTDP:-@var{n}:@var{addr}:@r{[}S@r{]}@var{action}@dots{}@r{[}-@r{]} ++Define actions to be taken when a tracepoint is hit. The @var{n} and ++@var{addr} must be the same as in the initial @samp{QTDP} packet for ++this tracepoint. This packet may only be sent immediately after ++another @samp{QTDP} packet that ended with a @samp{-}. If the ++trailing @samp{-} is present, further @samp{QTDP} packets will follow, ++specifying more actions for this tracepoint. ++ ++In the series of action packets for a given tracepoint, at most one ++can have an @samp{S} before its first @var{action}. If such a packet ++is sent, it and the following packets define ``while-stepping'' ++actions. Any prior packets define ordinary actions --- that is, those ++taken when the tracepoint is first hit. If no action packet has an ++@samp{S}, then all the packets in the series specify ordinary ++tracepoint actions. ++ ++The @samp{@var{action}@dots{}} portion of the packet is a series of ++actions, concatenated without separators. Each action has one of the ++following forms: ++ ++@table @samp ++ ++@item R @var{mask} ++Collect the registers whose bits are set in @var{mask}, ++a hexadecimal number whose @var{i}'th bit is set if register number ++@var{i} should be collected. (The least significant bit is numbered ++zero.) Note that @var{mask} may be any number of digits long; it may ++not fit in a 32-bit word. ++ ++@item M @var{basereg},@var{offset},@var{len} ++Collect @var{len} bytes of memory starting at the address in register ++number @var{basereg}, plus @var{offset}. If @var{basereg} is ++@samp{-1}, then the range has a fixed address: @var{offset} is the ++address of the lowest byte to collect. The @var{basereg}, ++@var{offset}, and @var{len} parameters are all unsigned hexadecimal ++values (the @samp{-1} value for @var{basereg} is a special case). ++ ++@item X @var{len},@var{expr} ++Evaluate @var{expr}, whose length is @var{len}, and collect memory as ++it directs. The agent expression @var{expr} is as described in ++@ref{Agent Expressions}. Each byte of the expression is encoded as a ++two-digit hex number in the packet; @var{len} is the number of bytes ++in the expression (and thus one-half the number of hex digits in the ++packet). ++ ++@end table ++ ++Any number of actions may be packed together in a single @samp{QTDP} ++packet, as long as the packet does not exceed the maximum packet ++length (400 bytes, for many stubs). There may be only one @samp{R} ++action per tracepoint, and it must precede any @samp{M} or @samp{X} ++actions. Any registers referred to by @samp{M} and @samp{X} actions ++must be collected by a preceding @samp{R} action. (The ++``while-stepping'' actions are treated as if they were attached to a ++separate tracepoint, as far as these restrictions are concerned.) ++ ++Replies: ++@table @samp ++@item OK ++The packet was understood and carried out. ++@item qRelocInsn ++@xref{Tracepoint Packets,,Relocate instruction reply packet}. ++@item @w{} ++The packet was not recognized. ++@end table ++ ++@item QTDPsrc:@var{n}:@var{addr}:@var{type}:@var{start}:@var{slen}:@var{bytes} ++@cindex @samp{QTDPsrc} packet ++Specify a source string of tracepoint @var{n} at address @var{addr}. ++This is useful to get accurate reproduction of the tracepoints ++originally downloaded at the beginning of the trace run. The @var{type} ++is the name of the tracepoint part, such as @samp{cond} for the ++tracepoint's conditional expression (see below for a list of types), while ++@var{bytes} is the string, encoded in hexadecimal. ++ ++@var{start} is the offset of the @var{bytes} within the overall source ++string, while @var{slen} is the total length of the source string. ++This is intended for handling source strings that are longer than will ++fit in a single packet. ++@c Add detailed example when this info is moved into a dedicated ++@c tracepoint descriptions section. ++ ++The available string types are @samp{at} for the location, ++@samp{cond} for the conditional, and @samp{cmd} for an action command. ++@value{GDBN} sends a separate packet for each command in the action ++list, in the same order in which the commands are stored in the list. ++ ++The target does not need to do anything with source strings except ++report them back as part of the replies to the @samp{qTfP}/@samp{qTsP} ++query packets. ++ ++Although this packet is optional, and @value{GDBN} will only send it ++if the target replies with @samp{TracepointSource} @xref{General ++Query Packets}, it makes both disconnected tracing and trace files ++much easier to use. Otherwise the user must be careful that the ++tracepoints in effect while looking at trace frames are identical to ++the ones in effect during the trace run; even a small discrepancy ++could cause @samp{tdump} not to work, or a particular trace frame not ++be found. ++ ++@item QTDV:@var{n}:@var{value}:@var{builtin}:@var{name} ++@cindex define trace state variable, remote request ++@cindex @samp{QTDV} packet ++Create a new trace state variable, number @var{n}, with an initial ++value of @var{value}, which is a 64-bit signed integer. Both @var{n} ++and @var{value} are encoded as hexadecimal values. @value{GDBN} has ++the option of not using this packet for initial values of zero; the ++target should simply create the trace state variables as they are ++mentioned in expressions. The value @var{builtin} should be 1 (one) ++if the trace state variable is builtin and 0 (zero) if it is not builtin. ++@value{GDBN} only sets @var{builtin} to 1 if a previous @samp{qTfV} or ++@samp{qTsV} packet had it set. The contents of @var{name} is the ++hex-encoded name (without the leading @samp{$}) of the trace state ++variable. ++ ++@item QTFrame:@var{n} ++@cindex @samp{QTFrame} packet ++Select the @var{n}'th tracepoint frame from the buffer, and use the ++register and memory contents recorded there to answer subsequent ++request packets from @value{GDBN}. ++ ++A successful reply from the stub indicates that the stub has found the ++requested frame. The response is a series of parts, concatenated ++without separators, describing the frame we selected. Each part has ++one of the following forms: ++ ++@table @samp ++@item F @var{f} ++The selected frame is number @var{n} in the trace frame buffer; ++@var{f} is a hexadecimal number. If @var{f} is @samp{-1}, then there ++was no frame matching the criteria in the request packet. ++ ++@item T @var{t} ++The selected trace frame records a hit of tracepoint number @var{t}; ++@var{t} is a hexadecimal number. ++ ++@end table ++ ++@item QTFrame:pc:@var{addr} ++Like @samp{QTFrame:@var{n}}, but select the first tracepoint frame after the ++currently selected frame whose PC is @var{addr}; ++@var{addr} is a hexadecimal number. ++ ++@item QTFrame:tdp:@var{t} ++Like @samp{QTFrame:@var{n}}, but select the first tracepoint frame after the ++currently selected frame that is a hit of tracepoint @var{t}; @var{t} ++is a hexadecimal number. ++ ++@item QTFrame:range:@var{start}:@var{end} ++Like @samp{QTFrame:@var{n}}, but select the first tracepoint frame after the ++currently selected frame whose PC is between @var{start} (inclusive) ++and @var{end} (inclusive); @var{start} and @var{end} are hexadecimal ++numbers. ++ ++@item QTFrame:outside:@var{start}:@var{end} ++Like @samp{QTFrame:range:@var{start}:@var{end}}, but select the first ++frame @emph{outside} the given range of addresses (exclusive). ++ ++@item qTMinFTPILen ++@cindex @samp{qTMinFTPILen} packet ++This packet requests the minimum length of instruction at which a fast ++tracepoint (@pxref{Set Tracepoints}) may be placed. For instance, on ++the 32-bit x86 architecture, it is possible to use a 4-byte jump, but ++it depends on the target system being able to create trampolines in ++the first 64K of memory, which might or might not be possible for that ++system. So the reply to this packet will be 4 if it is able to ++arrange for that. ++ ++Replies: ++ ++@table @samp ++@item 0 ++The minimum instruction length is currently unknown. ++@item @var{length} ++The minimum instruction length is @var{length}, where @var{length} ++is a hexadecimal number greater or equal to 1. A reply ++of 1 means that a fast tracepoint may be placed on any instruction ++regardless of size. ++@item E ++An error has occurred. ++@item @w{} ++An empty reply indicates that the request is not supported by the stub. ++@end table ++ ++@item QTStart ++@cindex @samp{QTStart} packet ++Begin the tracepoint experiment. Begin collecting data from ++tracepoint hits in the trace frame buffer. This packet supports the ++@samp{qRelocInsn} reply (@pxref{Tracepoint Packets,,Relocate ++instruction reply packet}). ++ ++@item QTStop ++@cindex @samp{QTStop} packet ++End the tracepoint experiment. Stop collecting trace frames. ++ ++@item QTEnable:@var{n}:@var{addr} ++@anchor{QTEnable} ++@cindex @samp{QTEnable} packet ++Enable tracepoint @var{n} at address @var{addr} in a started tracepoint ++experiment. If the tracepoint was previously disabled, then collection ++of data from it will resume. ++ ++@item QTDisable:@var{n}:@var{addr} ++@anchor{QTDisable} ++@cindex @samp{QTDisable} packet ++Disable tracepoint @var{n} at address @var{addr} in a started tracepoint ++experiment. No more data will be collected from the tracepoint unless ++@samp{QTEnable:@var{n}:@var{addr}} is subsequently issued. ++ ++@item QTinit ++@cindex @samp{QTinit} packet ++Clear the table of tracepoints, and empty the trace frame buffer. ++ ++@item QTro:@var{start1},@var{end1}:@var{start2},@var{end2}:@dots{} ++@cindex @samp{QTro} packet ++Establish the given ranges of memory as ``transparent''. The stub ++will answer requests for these ranges from memory's current contents, ++if they were not collected as part of the tracepoint hit. ++ ++@value{GDBN} uses this to mark read-only regions of memory, like those ++containing program code. Since these areas never change, they should ++still have the same contents they did when the tracepoint was hit, so ++there's no reason for the stub to refuse to provide their contents. ++ ++@item QTDisconnected:@var{value} ++@cindex @samp{QTDisconnected} packet ++Set the choice to what to do with the tracing run when @value{GDBN} ++disconnects from the target. A @var{value} of 1 directs the target to ++continue the tracing run, while 0 tells the target to stop tracing if ++@value{GDBN} is no longer in the picture. ++ ++@item qTStatus ++@cindex @samp{qTStatus} packet ++Ask the stub if there is a trace experiment running right now. ++ ++The reply has the form: ++ ++@table @samp ++ ++@item T@var{running}@r{[};@var{field}@r{]}@dots{} ++@var{running} is a single digit @code{1} if the trace is presently ++running, or @code{0} if not. It is followed by semicolon-separated ++optional fields that an agent may use to report additional status. ++ ++@end table ++ ++If the trace is not running, the agent may report any of several ++explanations as one of the optional fields: ++ ++@table @samp ++ ++@item tnotrun:0 ++No trace has been run yet. ++ ++@item tstop[:@var{text}]:0 ++The trace was stopped by a user-originated stop command. The optional ++@var{text} field is a user-supplied string supplied as part of the ++stop command (for instance, an explanation of why the trace was ++stopped manually). It is hex-encoded. ++ ++@item tfull:0 ++The trace stopped because the trace buffer filled up. ++ ++@item tdisconnected:0 ++The trace stopped because @value{GDBN} disconnected from the target. ++ ++@item tpasscount:@var{tpnum} ++The trace stopped because tracepoint @var{tpnum} exceeded its pass count. ++ ++@item terror:@var{text}:@var{tpnum} ++The trace stopped because tracepoint @var{tpnum} had an error. The ++string @var{text} is available to describe the nature of the error ++(for instance, a divide by zero in the condition expression); it ++is hex encoded. ++ ++@item tunknown:0 ++The trace stopped for some other reason. ++ ++@end table ++ ++Additional optional fields supply statistical and other information. ++Although not required, they are extremely useful for users monitoring ++the progress of a trace run. If a trace has stopped, and these ++numbers are reported, they must reflect the state of the just-stopped ++trace. ++ ++@table @samp ++ ++@item tframes:@var{n} ++The number of trace frames in the buffer. ++ ++@item tcreated:@var{n} ++The total number of trace frames created during the run. This may ++be larger than the trace frame count, if the buffer is circular. ++ ++@item tsize:@var{n} ++The total size of the trace buffer, in bytes. ++ ++@item tfree:@var{n} ++The number of bytes still unused in the buffer. ++ ++@item circular:@var{n} ++The value of the circular trace buffer flag. @code{1} means that the ++trace buffer is circular and old trace frames will be discarded if ++necessary to make room, @code{0} means that the trace buffer is linear ++and may fill up. ++ ++@item disconn:@var{n} ++The value of the disconnected tracing flag. @code{1} means that ++tracing will continue after @value{GDBN} disconnects, @code{0} means ++that the trace run will stop. ++ ++@end table ++ ++@item qTP:@var{tp}:@var{addr} ++@cindex tracepoint status, remote request ++@cindex @samp{qTP} packet ++Ask the stub for the current state of tracepoint number @var{tp} at ++address @var{addr}. ++ ++Replies: ++@table @samp ++@item V@var{hits}:@var{usage} ++The tracepoint has been hit @var{hits} times so far during the trace ++run, and accounts for @var{usage} in the trace buffer. Note that ++@code{while-stepping} steps are not counted as separate hits, but the ++steps' space consumption is added into the usage number. ++ ++@end table ++ ++@item qTV:@var{var} ++@cindex trace state variable value, remote request ++@cindex @samp{qTV} packet ++Ask the stub for the value of the trace state variable number @var{var}. ++ ++Replies: ++@table @samp ++@item V@var{value} ++The value of the variable is @var{value}. This will be the current ++value of the variable if the user is examining a running target, or a ++saved value if the variable was collected in the trace frame that the ++user is looking at. Note that multiple requests may result in ++different reply values, such as when requesting values while the ++program is running. ++ ++@item U ++The value of the variable is unknown. This would occur, for example, ++if the user is examining a trace frame in which the requested variable ++was not collected. ++@end table ++ ++@item qTfP ++@cindex @samp{qTfP} packet ++@itemx qTsP ++@cindex @samp{qTsP} packet ++These packets request data about tracepoints that are being used by ++the target. @value{GDBN} sends @code{qTfP} to get the first piece ++of data, and multiple @code{qTsP} to get additional pieces. Replies ++to these packets generally take the form of the @code{QTDP} packets ++that define tracepoints. (FIXME add detailed syntax) ++ ++@item qTfV ++@cindex @samp{qTfV} packet ++@itemx qTsV ++@cindex @samp{qTsV} packet ++These packets request data about trace state variables that are on the ++target. @value{GDBN} sends @code{qTfV} to get the first vari of data, ++and multiple @code{qTsV} to get additional variables. Replies to ++these packets follow the syntax of the @code{QTDV} packets that define ++trace state variables. ++ ++@item qTfSTM ++@itemx qTsSTM ++@anchor{qTfSTM} ++@anchor{qTsSTM} ++@cindex @samp{qTfSTM} packet ++@cindex @samp{qTsSTM} packet ++These packets request data about static tracepoint markers that exist ++in the target program. @value{GDBN} sends @code{qTfSTM} to get the ++first piece of data, and multiple @code{qTsSTM} to get additional ++pieces. Replies to these packets take the following form: ++ ++Reply: ++@table @samp ++@item m @var{address}:@var{id}:@var{extra} ++A single marker ++@item m @var{address}:@var{id}:@var{extra},@var{address}:@var{id}:@var{extra}@dots{} ++a comma-separated list of markers ++@item l ++(lower case letter @samp{L}) denotes end of list. ++@item E @var{nn} ++An error occurred. The error number @var{nn} is given as hex digits. ++@item @w{} ++An empty reply indicates that the request is not supported by the ++stub. ++@end table ++ ++The @var{address} is encoded in hex; ++@var{id} and @var{extra} are strings encoded in hex. ++ ++In response to each query, the target will reply with a list of one or ++more markers, separated by commas. @value{GDBN} will respond to each ++reply with a request for more markers (using the @samp{qs} form of the ++query), until the target responds with @samp{l} (lower-case ell, for ++@dfn{last}). ++ ++@item qTSTMat:@var{address} ++@anchor{qTSTMat} ++@cindex @samp{qTSTMat} packet ++This packets requests data about static tracepoint markers in the ++target program at @var{address}. Replies to this packet follow the ++syntax of the @samp{qTfSTM} and @code{qTsSTM} packets that list static ++tracepoint markers. ++ ++@item QTSave:@var{filename} ++@cindex @samp{QTSave} packet ++This packet directs the target to save trace data to the file name ++@var{filename} in the target's filesystem. The @var{filename} is encoded ++as a hex string; the interpretation of the file name (relative vs ++absolute, wild cards, etc) is up to the target. ++ ++@item qTBuffer:@var{offset},@var{len} ++@cindex @samp{qTBuffer} packet ++Return up to @var{len} bytes of the current contents of trace buffer, ++starting at @var{offset}. The trace buffer is treated as if it were ++a contiguous collection of traceframes, as per the trace file format. ++The reply consists as many hex-encoded bytes as the target can deliver ++in a packet; it is not an error to return fewer than were asked for. ++A reply consisting of just @code{l} indicates that no bytes are ++available. ++ ++@item QTBuffer:circular:@var{value} ++This packet directs the target to use a circular trace buffer if ++@var{value} is 1, or a linear buffer if the value is 0. ++ ++@item QTBuffer:size:@var{size} ++@anchor{QTBuffer-size} ++@cindex @samp{QTBuffer size} packet ++This packet directs the target to make the trace buffer be of size ++@var{size} if possible. A value of @code{-1} tells the target to ++use whatever size it prefers. ++ ++@item QTNotes:@r{[}@var{type}:@var{text}@r{]}@r{[};@var{type}:@var{text}@r{]}@dots{} ++@cindex @samp{QTNotes} packet ++This packet adds optional textual notes to the trace run. Allowable ++types include @code{user}, @code{notes}, and @code{tstop}, the ++@var{text} fields are arbitrary strings, hex-encoded. ++ ++@end table ++ ++@subsection Relocate instruction reply packet ++When installing fast tracepoints in memory, the target may need to ++relocate the instruction currently at the tracepoint address to a ++different address in memory. For most instructions, a simple copy is ++enough, but, for example, call instructions that implicitly push the ++return address on the stack, and relative branches or other ++PC-relative instructions require offset adjustment, so that the effect ++of executing the instruction at a different address is the same as if ++it had executed in the original location. ++ ++In response to several of the tracepoint packets, the target may also ++respond with a number of intermediate @samp{qRelocInsn} request ++packets before the final result packet, to have @value{GDBN} handle ++this relocation operation. If a packet supports this mechanism, its ++documentation will explicitly say so. See for example the above ++descriptions for the @samp{QTStart} and @samp{QTDP} packets. The ++format of the request is: ++ ++@table @samp ++@item qRelocInsn:@var{from};@var{to} ++ ++This requests @value{GDBN} to copy instruction at address @var{from} ++to address @var{to}, possibly adjusted so that executing the ++instruction at @var{to} has the same effect as executing it at ++@var{from}. @value{GDBN} writes the adjusted instruction to target ++memory starting at @var{to}. ++@end table ++ ++Replies: ++@table @samp ++@item qRelocInsn:@var{adjusted_size} ++Informs the stub the relocation is complete. The @var{adjusted_size} is ++the length in bytes of resulting relocated instruction sequence. ++@item E @var{NN} ++A badly formed request was detected, or an error was encountered while ++relocating the instruction. ++@end table ++ ++@node Host I/O Packets ++@section Host I/O Packets ++@cindex Host I/O, remote protocol ++@cindex file transfer, remote protocol ++ ++The @dfn{Host I/O} packets allow @value{GDBN} to perform I/O ++operations on the far side of a remote link. For example, Host I/O is ++used to upload and download files to a remote target with its own ++filesystem. Host I/O uses the same constant values and data structure ++layout as the target-initiated File-I/O protocol. However, the ++Host I/O packets are structured differently. The target-initiated ++protocol relies on target memory to store parameters and buffers. ++Host I/O requests are initiated by @value{GDBN}, and the ++target's memory is not involved. @xref{File-I/O Remote Protocol ++Extension}, for more details on the target-initiated protocol. ++ ++The Host I/O request packets all encode a single operation along with ++its arguments. They have this format: ++ ++@table @samp ++ ++@item vFile:@var{operation}: @var{parameter}@dots{} ++@var{operation} is the name of the particular request; the target ++should compare the entire packet name up to the second colon when checking ++for a supported operation. The format of @var{parameter} depends on ++the operation. Numbers are always passed in hexadecimal. Negative ++numbers have an explicit minus sign (i.e.@: two's complement is not ++used). Strings (e.g.@: filenames) are encoded as a series of ++hexadecimal bytes. The last argument to a system call may be a ++buffer of escaped binary data (@pxref{Binary Data}). ++ ++@end table ++ ++The valid responses to Host I/O packets are: ++ ++@table @samp ++ ++@item F @var{result} [, @var{errno}] [; @var{attachment}] ++@var{result} is the integer value returned by this operation, usually ++non-negative for success and -1 for errors. If an error has occured, ++@var{errno} will be included in the result specifying a ++value defined by the File-I/O protocol (@pxref{Errno Values}). For ++operations which return data, @var{attachment} supplies the data as a ++binary buffer. Binary buffers in response packets are escaped in the ++normal way (@pxref{Binary Data}). See the individual packet ++documentation for the interpretation of @var{result} and ++@var{attachment}. ++ ++@item @w{} ++An empty response indicates that this operation is not recognized. ++ ++@end table ++ ++These are the supported Host I/O operations: ++ ++@table @samp ++@item vFile:open: @var{filename}, @var{flags}, @var{mode} ++Open a file at @var{filename} and return a file descriptor for it, or ++return -1 if an error occurs. The @var{filename} is a string, ++@var{flags} is an integer indicating a mask of open flags ++(@pxref{Open Flags}), and @var{mode} is an integer indicating a mask ++of mode bits to use if the file is created (@pxref{mode_t Values}). ++@xref{open}, for details of the open flags and mode values. ++ ++@item vFile:close: @var{fd} ++Close the open file corresponding to @var{fd} and return 0, or ++-1 if an error occurs. ++ ++@item vFile:pread: @var{fd}, @var{count}, @var{offset} ++Read data from the open file corresponding to @var{fd}. Up to ++@var{count} bytes will be read from the file, starting at @var{offset} ++relative to the start of the file. The target may read fewer bytes; ++common reasons include packet size limits and an end-of-file ++condition. The number of bytes read is returned. Zero should only be ++returned for a successful read at the end of the file, or if ++@var{count} was zero. ++ ++The data read should be returned as a binary attachment on success. ++If zero bytes were read, the response should include an empty binary ++attachment (i.e.@: a trailing semicolon). The return value is the ++number of target bytes read; the binary attachment may be longer if ++some characters were escaped. ++ ++@item vFile:pwrite: @var{fd}, @var{offset}, @var{data} ++Write @var{data} (a binary buffer) to the open file corresponding ++to @var{fd}. Start the write at @var{offset} from the start of the ++file. Unlike many @code{write} system calls, there is no ++separate @var{count} argument; the length of @var{data} in the ++packet is used. @samp{vFile:pwrite} returns the number of bytes written, ++which may be shorter than the length of @var{data}, or -1 if an ++error occurred. ++ ++@item vFile:fstat: @var{fd} ++Get information about the open file corresponding to @var{fd}. ++On success the information is returned as a binary attachment ++and the return value is the size of this attachment in bytes. ++If an error occurs the return value is -1. The format of the ++returned binary attachment is as described in @ref{struct stat}. ++ ++@item vFile:unlink: @var{filename} ++Delete the file at @var{filename} on the target. Return 0, ++or -1 if an error occurs. The @var{filename} is a string. ++ ++@item vFile:readlink: @var{filename} ++Read value of symbolic link @var{filename} on the target. Return ++the number of bytes read, or -1 if an error occurs. ++ ++The data read should be returned as a binary attachment on success. ++If zero bytes were read, the response should include an empty binary ++attachment (i.e.@: a trailing semicolon). The return value is the ++number of target bytes read; the binary attachment may be longer if ++some characters were escaped. ++ ++@item vFile:setfs: @var{pid} ++Select the filesystem on which @code{vFile} operations with ++@var{filename} arguments will operate. This is required for ++@value{GDBN} to be able to access files on remote targets where ++the remote stub does not share a common filesystem with the ++inferior(s). ++ ++If @var{pid} is nonzero, select the filesystem as seen by process ++@var{pid}. If @var{pid} is zero, select the filesystem as seen by ++the remote stub. Return 0 on success, or -1 if an error occurs. ++If @code{vFile:setfs:} indicates success, the selected filesystem ++remains selected until the next successful @code{vFile:setfs:} ++operation. ++ ++@end table ++ ++@node Interrupts ++@section Interrupts ++@cindex interrupts (remote protocol) ++@anchor{interrupting remote targets} ++ ++In all-stop mode, when a program on the remote target is running, ++@value{GDBN} may attempt to interrupt it by sending a @samp{Ctrl-C}, ++@code{BREAK} or a @code{BREAK} followed by @code{g}, control of which ++is specified via @value{GDBN}'s @samp{interrupt-sequence}. ++ ++The precise meaning of @code{BREAK} is defined by the transport ++mechanism and may, in fact, be undefined. @value{GDBN} does not ++currently define a @code{BREAK} mechanism for any of the network ++interfaces except for TCP, in which case @value{GDBN} sends the ++@code{telnet} BREAK sequence. ++ ++@samp{Ctrl-C}, on the other hand, is defined and implemented for all ++transport mechanisms. It is represented by sending the single byte ++@code{0x03} without any of the usual packet overhead described in ++the Overview section (@pxref{Overview}). When a @code{0x03} byte is ++transmitted as part of a packet, it is considered to be packet data ++and does @emph{not} represent an interrupt. E.g., an @samp{X} packet ++(@pxref{X packet}), used for binary downloads, may include an unescaped ++@code{0x03} as part of its packet. ++ ++@code{BREAK} followed by @code{g} is also known as Magic SysRq g. ++When Linux kernel receives this sequence from serial port, ++it stops execution and connects to gdb. ++ ++In non-stop mode, because packet resumptions are asynchronous ++(@pxref{vCont packet}), @value{GDBN} is always free to send a remote ++command to the remote stub, even when the target is running. For that ++reason, @value{GDBN} instead sends a regular packet (@pxref{vCtrlC ++packet}) with the usual packet framing instead of the single byte ++@code{0x03}. ++ ++Stubs are not required to recognize these interrupt mechanisms and the ++precise meaning associated with receipt of the interrupt is ++implementation defined. If the target supports debugging of multiple ++threads and/or processes, it should attempt to interrupt all ++currently-executing threads and processes. ++If the stub is successful at interrupting the ++running program, it should send one of the stop ++reply packets (@pxref{Stop Reply Packets}) to @value{GDBN} as a result ++of successfully stopping the program in all-stop mode, and a stop reply ++for each stopped thread in non-stop mode. ++Interrupts received while the ++program is stopped are queued and the program will be interrupted when ++it is resumed next time. ++ ++@node Notification Packets ++@section Notification Packets ++@cindex notification packets ++@cindex packets, notification ++ ++The @value{GDBN} remote serial protocol includes @dfn{notifications}, ++packets that require no acknowledgment. Both the GDB and the stub ++may send notifications (although the only notifications defined at ++present are sent by the stub). Notifications carry information ++without incurring the round-trip latency of an acknowledgment, and so ++are useful for low-impact communications where occasional packet loss ++is not a problem. ++ ++A notification packet has the form @samp{% @var{data} # ++@var{checksum}}, where @var{data} is the content of the notification, ++and @var{checksum} is a checksum of @var{data}, computed and formatted ++as for ordinary @value{GDBN} packets. A notification's @var{data} ++never contains @samp{$}, @samp{%} or @samp{#} characters. Upon ++receiving a notification, the recipient sends no @samp{+} or @samp{-} ++to acknowledge the notification's receipt or to report its corruption. ++ ++Every notification's @var{data} begins with a name, which contains no ++colon characters, followed by a colon character. ++ ++Recipients should silently ignore corrupted notifications and ++notifications they do not understand. Recipients should restart ++timeout periods on receipt of a well-formed notification, whether or ++not they understand it. ++ ++Senders should only send the notifications described here when this ++protocol description specifies that they are permitted. In the ++future, we may extend the protocol to permit existing notifications in ++new contexts; this rule helps older senders avoid confusing newer ++recipients. ++ ++(Older versions of @value{GDBN} ignore bytes received until they see ++the @samp{$} byte that begins an ordinary packet, so new stubs may ++transmit notifications without fear of confusing older clients. There ++are no notifications defined for @value{GDBN} to send at the moment, but we ++assume that most older stubs would ignore them, as well.) ++ ++Each notification is comprised of three parts: ++@table @samp ++@item @var{name}:@var{event} ++The notification packet is sent by the side that initiates the ++exchange (currently, only the stub does that), with @var{event} ++carrying the specific information about the notification, and ++@var{name} specifying the name of the notification. ++@item @var{ack} ++The acknowledge sent by the other side, usually @value{GDBN}, to ++acknowledge the exchange and request the event. ++@end table ++ ++The purpose of an asynchronous notification mechanism is to report to ++@value{GDBN} that something interesting happened in the remote stub. ++ ++The remote stub may send notification @var{name}:@var{event} ++at any time, but @value{GDBN} acknowledges the notification when ++appropriate. The notification event is pending before @value{GDBN} ++acknowledges. Only one notification at a time may be pending; if ++additional events occur before @value{GDBN} has acknowledged the ++previous notification, they must be queued by the stub for later ++synchronous transmission in response to @var{ack} packets from ++@value{GDBN}. Because the notification mechanism is unreliable, ++the stub is permitted to resend a notification if it believes ++@value{GDBN} may not have received it. ++ ++Specifically, notifications may appear when @value{GDBN} is not ++otherwise reading input from the stub, or when @value{GDBN} is ++expecting to read a normal synchronous response or a ++@samp{+}/@samp{-} acknowledgment to a packet it has sent. ++Notification packets are distinct from any other communication from ++the stub so there is no ambiguity. ++ ++After receiving a notification, @value{GDBN} shall acknowledge it by ++sending a @var{ack} packet as a regular, synchronous request to the ++stub. Such acknowledgment is not required to happen immediately, as ++@value{GDBN} is permitted to send other, unrelated packets to the ++stub first, which the stub should process normally. ++ ++Upon receiving a @var{ack} packet, if the stub has other queued ++events to report to @value{GDBN}, it shall respond by sending a ++normal @var{event}. @value{GDBN} shall then send another @var{ack} ++packet to solicit further responses; again, it is permitted to send ++other, unrelated packets as well which the stub should process ++normally. ++ ++If the stub receives a @var{ack} packet and there are no additional ++@var{event} to report, the stub shall return an @samp{OK} response. ++At this point, @value{GDBN} has finished processing a notification ++and the stub has completed sending any queued events. @value{GDBN} ++won't accept any new notifications until the final @samp{OK} is ++received . If further notification events occur, the stub shall send ++a new notification, @value{GDBN} shall accept the notification, and ++the process shall be repeated. ++ ++The process of asynchronous notification can be illustrated by the ++following example: ++@smallexample ++<- @code{%Stop:T0505:98e7ffbf;04:4ce6ffbf;08:b1b6e54c;thread:p7526.7526;core:0;} ++@code{...} ++-> @code{vStopped} ++<- @code{T0505:68f37db7;04:40f37db7;08:63850408;thread:p7526.7528;core:0;} ++-> @code{vStopped} ++<- @code{T0505:68e3fdb6;04:40e3fdb6;08:63850408;thread:p7526.7529;core:0;} ++-> @code{vStopped} ++<- @code{OK} ++@end smallexample ++ ++The following notifications are defined: ++@multitable @columnfractions 0.12 0.12 0.38 0.38 ++ ++@item Notification ++@tab Ack ++@tab Event ++@tab Description ++ ++@item Stop ++@tab vStopped ++@tab @var{reply}. The @var{reply} has the form of a stop reply, as ++described in @ref{Stop Reply Packets}. Refer to @ref{Remote Non-Stop}, ++for information on how these notifications are acknowledged by ++@value{GDBN}. ++@tab Report an asynchronous stop event in non-stop mode. ++ ++@end multitable ++ ++@node Remote Non-Stop ++@section Remote Protocol Support for Non-Stop Mode ++ ++@value{GDBN}'s remote protocol supports non-stop debugging of ++multi-threaded programs, as described in @ref{Non-Stop Mode}. If the stub ++supports non-stop mode, it should report that to @value{GDBN} by including ++@samp{QNonStop+} in its @samp{qSupported} response (@pxref{qSupported}). ++ ++@value{GDBN} typically sends a @samp{QNonStop} packet only when ++establishing a new connection with the stub. Entering non-stop mode ++does not alter the state of any currently-running threads, but targets ++must stop all threads in any already-attached processes when entering ++all-stop mode. @value{GDBN} uses the @samp{?} packet as necessary to ++probe the target state after a mode change. ++ ++In non-stop mode, when an attached process encounters an event that ++would otherwise be reported with a stop reply, it uses the ++asynchronous notification mechanism (@pxref{Notification Packets}) to ++inform @value{GDBN}. In contrast to all-stop mode, where all threads ++in all processes are stopped when a stop reply is sent, in non-stop ++mode only the thread reporting the stop event is stopped. That is, ++when reporting a @samp{S} or @samp{T} response to indicate completion ++of a step operation, hitting a breakpoint, or a fault, only the ++affected thread is stopped; any other still-running threads continue ++to run. When reporting a @samp{W} or @samp{X} response, all running ++threads belonging to other attached processes continue to run. ++ ++In non-stop mode, the target shall respond to the @samp{?} packet as ++follows. First, any incomplete stop reply notification/@samp{vStopped} ++sequence in progress is abandoned. The target must begin a new ++sequence reporting stop events for all stopped threads, whether or not ++it has previously reported those events to @value{GDBN}. The first ++stop reply is sent as a synchronous reply to the @samp{?} packet, and ++subsequent stop replies are sent as responses to @samp{vStopped} packets ++using the mechanism described above. The target must not send ++asynchronous stop reply notifications until the sequence is complete. ++If all threads are running when the target receives the @samp{?} packet, ++or if the target is not attached to any process, it shall respond ++@samp{OK}. ++ ++If the stub supports non-stop mode, it should also support the ++@samp{swbreak} stop reason if software breakpoints are supported, and ++the @samp{hwbreak} stop reason if hardware breakpoints are supported ++(@pxref{swbreak stop reason}). This is because given the asynchronous ++nature of non-stop mode, between the time a thread hits a breakpoint ++and the time the event is finally processed by @value{GDBN}, the ++breakpoint may have already been removed from the target. Due to ++this, @value{GDBN} needs to be able to tell whether a trap stop was ++caused by a delayed breakpoint event, which should be ignored, as ++opposed to a random trap signal, which should be reported to the user. ++Note the @samp{swbreak} feature implies that the target is responsible ++for adjusting the PC when a software breakpoint triggers, if ++necessary, such as on the x86 architecture. ++ ++@node Packet Acknowledgment ++@section Packet Acknowledgment ++ ++@cindex acknowledgment, for @value{GDBN} remote ++@cindex packet acknowledgment, for @value{GDBN} remote ++By default, when either the host or the target machine receives a packet, ++the first response expected is an acknowledgment: either @samp{+} (to indicate ++the package was received correctly) or @samp{-} (to request retransmission). ++This mechanism allows the @value{GDBN} remote protocol to operate over ++unreliable transport mechanisms, such as a serial line. ++ ++In cases where the transport mechanism is itself reliable (such as a pipe or ++TCP connection), the @samp{+}/@samp{-} acknowledgments are redundant. ++It may be desirable to disable them in that case to reduce communication ++overhead, or for other reasons. This can be accomplished by means of the ++@samp{QStartNoAckMode} packet; @pxref{QStartNoAckMode}. ++ ++When in no-acknowledgment mode, neither the stub nor @value{GDBN} shall send or ++expect @samp{+}/@samp{-} protocol acknowledgments. The packet ++and response format still includes the normal checksum, as described in ++@ref{Overview}, but the checksum may be ignored by the receiver. ++ ++If the stub supports @samp{QStartNoAckMode} and prefers to operate in ++no-acknowledgment mode, it should report that to @value{GDBN} ++by including @samp{QStartNoAckMode+} in its response to @samp{qSupported}; ++@pxref{qSupported}. ++If @value{GDBN} also supports @samp{QStartNoAckMode} and it has not been ++disabled via the @code{set remote noack-packet off} command ++(@pxref{Remote Configuration}), ++@value{GDBN} may then send a @samp{QStartNoAckMode} packet to the stub. ++Only then may the stub actually turn off packet acknowledgments. ++@value{GDBN} sends a final @samp{+} acknowledgment of the stub's @samp{OK} ++response, which can be safely ignored by the stub. ++ ++Note that @code{set remote noack-packet} command only affects negotiation ++between @value{GDBN} and the stub when subsequent connections are made; ++it does not affect the protocol acknowledgment state for any current ++connection. ++Since @samp{+}/@samp{-} acknowledgments are enabled by default when a ++new connection is established, ++there is also no protocol request to re-enable the acknowledgments ++for the current connection, once disabled. ++ ++@node Examples ++@section Examples ++ ++Example sequence of a target being re-started. Notice how the restart ++does not get any direct output: ++ ++@smallexample ++-> @code{R00} ++<- @code{+} ++@emph{target restarts} ++-> @code{?} ++<- @code{+} ++<- @code{T001:1234123412341234} ++-> @code{+} ++@end smallexample ++ ++Example sequence of a target being stepped by a single instruction: ++ ++@smallexample ++-> @code{G1445@dots{}} ++<- @code{+} ++-> @code{s} ++<- @code{+} ++@emph{time passes} ++<- @code{T001:1234123412341234} ++-> @code{+} ++-> @code{g} ++<- @code{+} ++<- @code{1455@dots{}} ++-> @code{+} ++@end smallexample ++ ++@node File-I/O Remote Protocol Extension ++@section File-I/O Remote Protocol Extension ++@cindex File-I/O remote protocol extension ++ ++@menu ++* File-I/O Overview:: ++* Protocol Basics:: ++* The F Request Packet:: ++* The F Reply Packet:: ++* The Ctrl-C Message:: ++* Console I/O:: ++* List of Supported Calls:: ++* Protocol-specific Representation of Datatypes:: ++* Constants:: ++* File-I/O Examples:: ++@end menu ++ ++@node File-I/O Overview ++@subsection File-I/O Overview ++@cindex file-i/o overview ++ ++The @dfn{File I/O remote protocol extension} (short: File-I/O) allows the ++target to use the host's file system and console I/O to perform various ++system calls. System calls on the target system are translated into a ++remote protocol packet to the host system, which then performs the needed ++actions and returns a response packet to the target system. ++This simulates file system operations even on targets that lack file systems. ++ ++The protocol is defined to be independent of both the host and target systems. ++It uses its own internal representation of datatypes and values. Both ++@value{GDBN} and the target's @value{GDBN} stub are responsible for ++translating the system-dependent value representations into the internal ++protocol representations when data is transmitted. ++ ++The communication is synchronous. A system call is possible only when ++@value{GDBN} is waiting for a response from the @samp{C}, @samp{c}, @samp{S} ++or @samp{s} packets. While @value{GDBN} handles the request for a system call, ++the target is stopped to allow deterministic access to the target's ++memory. Therefore File-I/O is not interruptible by target signals. On ++the other hand, it is possible to interrupt File-I/O by a user interrupt ++(@samp{Ctrl-C}) within @value{GDBN}. ++ ++The target's request to perform a host system call does not finish ++the latest @samp{C}, @samp{c}, @samp{S} or @samp{s} action. That means, ++after finishing the system call, the target returns to continuing the ++previous activity (continue, step). No additional continue or step ++request from @value{GDBN} is required. ++ ++@smallexample ++(@value{GDBP}) continue ++ <- target requests 'system call X' ++ target is stopped, @value{GDBN} executes system call ++ -> @value{GDBN} returns result ++ ... target continues, @value{GDBN} returns to wait for the target ++ <- target hits breakpoint and sends a Txx packet ++@end smallexample ++ ++The protocol only supports I/O on the console and to regular files on ++the host file system. Character or block special devices, pipes, ++named pipes, sockets or any other communication method on the host ++system are not supported by this protocol. ++ ++File I/O is not supported in non-stop mode. ++ ++@node Protocol Basics ++@subsection Protocol Basics ++@cindex protocol basics, file-i/o ++ ++The File-I/O protocol uses the @code{F} packet as the request as well ++as reply packet. Since a File-I/O system call can only occur when ++@value{GDBN} is waiting for a response from the continuing or stepping target, ++the File-I/O request is a reply that @value{GDBN} has to expect as a result ++of a previous @samp{C}, @samp{c}, @samp{S} or @samp{s} packet. ++This @code{F} packet contains all information needed to allow @value{GDBN} ++to call the appropriate host system call: ++ ++@itemize @bullet ++@item ++A unique identifier for the requested system call. ++ ++@item ++All parameters to the system call. Pointers are given as addresses ++in the target memory address space. Pointers to strings are given as ++pointer/length pair. Numerical values are given as they are. ++Numerical control flags are given in a protocol-specific representation. ++ ++@end itemize ++ ++At this point, @value{GDBN} has to perform the following actions. ++ ++@itemize @bullet ++@item ++If the parameters include pointer values to data needed as input to a ++system call, @value{GDBN} requests this data from the target with a ++standard @code{m} packet request. This additional communication has to be ++expected by the target implementation and is handled as any other @code{m} ++packet. ++ ++@item ++@value{GDBN} translates all value from protocol representation to host ++representation as needed. Datatypes are coerced into the host types. ++ ++@item ++@value{GDBN} calls the system call. ++ ++@item ++It then coerces datatypes back to protocol representation. ++ ++@item ++If the system call is expected to return data in buffer space specified ++by pointer parameters to the call, the data is transmitted to the ++target using a @code{M} or @code{X} packet. This packet has to be expected ++by the target implementation and is handled as any other @code{M} or @code{X} ++packet. ++ ++@end itemize ++ ++Eventually @value{GDBN} replies with another @code{F} packet which contains all ++necessary information for the target to continue. This at least contains ++ ++@itemize @bullet ++@item ++Return value. ++ ++@item ++@code{errno}, if has been changed by the system call. ++ ++@item ++``Ctrl-C'' flag. ++ ++@end itemize ++ ++After having done the needed type and value coercion, the target continues ++the latest continue or step action. ++ ++@node The F Request Packet ++@subsection The @code{F} Request Packet ++@cindex file-i/o request packet ++@cindex @code{F} request packet ++ ++The @code{F} request packet has the following format: ++ ++@table @samp ++@item F@var{call-id},@var{parameter@dots{}} ++ ++@var{call-id} is the identifier to indicate the host system call to be called. ++This is just the name of the function. ++ ++@var{parameter@dots{}} are the parameters to the system call. ++Parameters are hexadecimal integer values, either the actual values in case ++of scalar datatypes, pointers to target buffer space in case of compound ++datatypes and unspecified memory areas, or pointer/length pairs in case ++of string parameters. These are appended to the @var{call-id} as a ++comma-delimited list. All values are transmitted in ASCII ++string representation, pointer/length pairs separated by a slash. ++ ++@end table ++ ++ ++ ++@node The F Reply Packet ++@subsection The @code{F} Reply Packet ++@cindex file-i/o reply packet ++@cindex @code{F} reply packet ++ ++The @code{F} reply packet has the following format: ++ ++@table @samp ++ ++@item F@var{retcode},@var{errno},@var{Ctrl-C flag};@var{call-specific attachment} ++ ++@var{retcode} is the return code of the system call as hexadecimal value. ++ ++@var{errno} is the @code{errno} set by the call, in protocol-specific ++representation. ++This parameter can be omitted if the call was successful. ++ ++@var{Ctrl-C flag} is only sent if the user requested a break. In this ++case, @var{errno} must be sent as well, even if the call was successful. ++The @var{Ctrl-C flag} itself consists of the character @samp{C}: ++ ++@smallexample ++F0,0,C ++@end smallexample ++ ++@noindent ++or, if the call was interrupted before the host call has been performed: ++ ++@smallexample ++F-1,4,C ++@end smallexample ++ ++@noindent ++assuming 4 is the protocol-specific representation of @code{EINTR}. ++ ++@end table ++ ++ ++@node The Ctrl-C Message ++@subsection The @samp{Ctrl-C} Message ++@cindex ctrl-c message, in file-i/o protocol ++ ++If the @samp{Ctrl-C} flag is set in the @value{GDBN} ++reply packet (@pxref{The F Reply Packet}), ++the target should behave as if it had ++gotten a break message. The meaning for the target is ``system call ++interrupted by @code{SIGINT}''. Consequentially, the target should actually stop ++(as with a break message) and return to @value{GDBN} with a @code{T02} ++packet. ++ ++It's important for the target to know in which ++state the system call was interrupted. There are two possible cases: ++ ++@itemize @bullet ++@item ++The system call hasn't been performed on the host yet. ++ ++@item ++The system call on the host has been finished. ++ ++@end itemize ++ ++These two states can be distinguished by the target by the value of the ++returned @code{errno}. If it's the protocol representation of @code{EINTR}, the system ++call hasn't been performed. This is equivalent to the @code{EINTR} handling ++on POSIX systems. In any other case, the target may presume that the ++system call has been finished --- successfully or not --- and should behave ++as if the break message arrived right after the system call. ++ ++@value{GDBN} must behave reliably. If the system call has not been called ++yet, @value{GDBN} may send the @code{F} reply immediately, setting @code{EINTR} as ++@code{errno} in the packet. If the system call on the host has been finished ++before the user requests a break, the full action must be finished by ++@value{GDBN}. This requires sending @code{M} or @code{X} packets as necessary. ++The @code{F} packet may only be sent when either nothing has happened ++or the full action has been completed. ++ ++@node Console I/O ++@subsection Console I/O ++@cindex console i/o as part of file-i/o ++ ++By default and if not explicitly closed by the target system, the file ++descriptors 0, 1 and 2 are connected to the @value{GDBN} console. Output ++on the @value{GDBN} console is handled as any other file output operation ++(@code{write(1, @dots{})} or @code{write(2, @dots{})}). Console input is handled ++by @value{GDBN} so that after the target read request from file descriptor ++0 all following typing is buffered until either one of the following ++conditions is met: ++ ++@itemize @bullet ++@item ++The user types @kbd{Ctrl-c}. The behaviour is as explained above, and the ++@code{read} ++system call is treated as finished. ++ ++@item ++The user presses @key{RET}. This is treated as end of input with a trailing ++newline. ++ ++@item ++The user types @kbd{Ctrl-d}. This is treated as end of input. No trailing ++character (neither newline nor @samp{Ctrl-D}) is appended to the input. ++ ++@end itemize ++ ++If the user has typed more characters than fit in the buffer given to ++the @code{read} call, the trailing characters are buffered in @value{GDBN} until ++either another @code{read(0, @dots{})} is requested by the target, or debugging ++is stopped at the user's request. ++ ++ ++@node List of Supported Calls ++@subsection List of Supported Calls ++@cindex list of supported file-i/o calls ++ ++@menu ++* open:: ++* close:: ++* read:: ++* write:: ++* lseek:: ++* rename:: ++* unlink:: ++* stat/fstat:: ++* gettimeofday:: ++* isatty:: ++* system:: ++@end menu ++ ++@node open ++@unnumberedsubsubsec open ++@cindex open, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int open(const char *pathname, int flags); ++int open(const char *pathname, int flags, mode_t mode); ++@end smallexample ++ ++@item Request: ++@samp{Fopen,@var{pathptr}/@var{len},@var{flags},@var{mode}} ++ ++@noindent ++@var{flags} is the bitwise @code{OR} of the following values: ++ ++@table @code ++@item O_CREAT ++If the file does not exist it will be created. The host ++rules apply as far as file ownership and time stamps ++are concerned. ++ ++@item O_EXCL ++When used with @code{O_CREAT}, if the file already exists it is ++an error and open() fails. ++ ++@item O_TRUNC ++If the file already exists and the open mode allows ++writing (@code{O_RDWR} or @code{O_WRONLY} is given) it will be ++truncated to zero length. ++ ++@item O_APPEND ++The file is opened in append mode. ++ ++@item O_RDONLY ++The file is opened for reading only. ++ ++@item O_WRONLY ++The file is opened for writing only. ++ ++@item O_RDWR ++The file is opened for reading and writing. ++@end table ++ ++@noindent ++Other bits are silently ignored. ++ ++ ++@noindent ++@var{mode} is the bitwise @code{OR} of the following values: ++ ++@table @code ++@item S_IRUSR ++User has read permission. ++ ++@item S_IWUSR ++User has write permission. ++ ++@item S_IRGRP ++Group has read permission. ++ ++@item S_IWGRP ++Group has write permission. ++ ++@item S_IROTH ++Others have read permission. ++ ++@item S_IWOTH ++Others have write permission. ++@end table ++ ++@noindent ++Other bits are silently ignored. ++ ++ ++@item Return value: ++@code{open} returns the new file descriptor or -1 if an error ++occurred. ++ ++@item Errors: ++ ++@table @code ++@item EEXIST ++@var{pathname} already exists and @code{O_CREAT} and @code{O_EXCL} were used. ++ ++@item EISDIR ++@var{pathname} refers to a directory. ++ ++@item EACCES ++The requested access is not allowed. ++ ++@item ENAMETOOLONG ++@var{pathname} was too long. ++ ++@item ENOENT ++A directory component in @var{pathname} does not exist. ++ ++@item ENODEV ++@var{pathname} refers to a device, pipe, named pipe or socket. ++ ++@item EROFS ++@var{pathname} refers to a file on a read-only filesystem and ++write access was requested. ++ ++@item EFAULT ++@var{pathname} is an invalid pointer value. ++ ++@item ENOSPC ++No space on device to create the file. ++ ++@item EMFILE ++The process already has the maximum number of files open. ++ ++@item ENFILE ++The limit on the total number of files open on the system ++has been reached. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node close ++@unnumberedsubsubsec close ++@cindex close, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int close(int fd); ++@end smallexample ++ ++@item Request: ++@samp{Fclose,@var{fd}} ++ ++@item Return value: ++@code{close} returns zero on success, or -1 if an error occurred. ++ ++@item Errors: ++ ++@table @code ++@item EBADF ++@var{fd} isn't a valid open file descriptor. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node read ++@unnumberedsubsubsec read ++@cindex read, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int read(int fd, void *buf, unsigned int count); ++@end smallexample ++ ++@item Request: ++@samp{Fread,@var{fd},@var{bufptr},@var{count}} ++ ++@item Return value: ++On success, the number of bytes read is returned. ++Zero indicates end of file. If count is zero, read ++returns zero as well. On error, -1 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EBADF ++@var{fd} is not a valid file descriptor or is not open for ++reading. ++ ++@item EFAULT ++@var{bufptr} is an invalid pointer value. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node write ++@unnumberedsubsubsec write ++@cindex write, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int write(int fd, const void *buf, unsigned int count); ++@end smallexample ++ ++@item Request: ++@samp{Fwrite,@var{fd},@var{bufptr},@var{count}} ++ ++@item Return value: ++On success, the number of bytes written are returned. ++Zero indicates nothing was written. On error, -1 ++is returned. ++ ++@item Errors: ++ ++@table @code ++@item EBADF ++@var{fd} is not a valid file descriptor or is not open for ++writing. ++ ++@item EFAULT ++@var{bufptr} is an invalid pointer value. ++ ++@item EFBIG ++An attempt was made to write a file that exceeds the ++host-specific maximum file size allowed. ++ ++@item ENOSPC ++No space on device to write the data. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node lseek ++@unnumberedsubsubsec lseek ++@cindex lseek, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++long lseek (int fd, long offset, int flag); ++@end smallexample ++ ++@item Request: ++@samp{Flseek,@var{fd},@var{offset},@var{flag}} ++ ++@var{flag} is one of: ++ ++@table @code ++@item SEEK_SET ++The offset is set to @var{offset} bytes. ++ ++@item SEEK_CUR ++The offset is set to its current location plus @var{offset} ++bytes. ++ ++@item SEEK_END ++The offset is set to the size of the file plus @var{offset} ++bytes. ++@end table ++ ++@item Return value: ++On success, the resulting unsigned offset in bytes from ++the beginning of the file is returned. Otherwise, a ++value of -1 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EBADF ++@var{fd} is not a valid open file descriptor. ++ ++@item ESPIPE ++@var{fd} is associated with the @value{GDBN} console. ++ ++@item EINVAL ++@var{flag} is not a proper value. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node rename ++@unnumberedsubsubsec rename ++@cindex rename, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int rename(const char *oldpath, const char *newpath); ++@end smallexample ++ ++@item Request: ++@samp{Frename,@var{oldpathptr}/@var{len},@var{newpathptr}/@var{len}} ++ ++@item Return value: ++On success, zero is returned. On error, -1 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EISDIR ++@var{newpath} is an existing directory, but @var{oldpath} is not a ++directory. ++ ++@item EEXIST ++@var{newpath} is a non-empty directory. ++ ++@item EBUSY ++@var{oldpath} or @var{newpath} is a directory that is in use by some ++process. ++ ++@item EINVAL ++An attempt was made to make a directory a subdirectory ++of itself. ++ ++@item ENOTDIR ++A component used as a directory in @var{oldpath} or new ++path is not a directory. Or @var{oldpath} is a directory ++and @var{newpath} exists but is not a directory. ++ ++@item EFAULT ++@var{oldpathptr} or @var{newpathptr} are invalid pointer values. ++ ++@item EACCES ++No access to the file or the path of the file. ++ ++@item ENAMETOOLONG ++ ++@var{oldpath} or @var{newpath} was too long. ++ ++@item ENOENT ++A directory component in @var{oldpath} or @var{newpath} does not exist. ++ ++@item EROFS ++The file is on a read-only filesystem. ++ ++@item ENOSPC ++The device containing the file has no room for the new ++directory entry. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node unlink ++@unnumberedsubsubsec unlink ++@cindex unlink, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int unlink(const char *pathname); ++@end smallexample ++ ++@item Request: ++@samp{Funlink,@var{pathnameptr}/@var{len}} ++ ++@item Return value: ++On success, zero is returned. On error, -1 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EACCES ++No access to the file or the path of the file. ++ ++@item EPERM ++The system does not allow unlinking of directories. ++ ++@item EBUSY ++The file @var{pathname} cannot be unlinked because it's ++being used by another process. ++ ++@item EFAULT ++@var{pathnameptr} is an invalid pointer value. ++ ++@item ENAMETOOLONG ++@var{pathname} was too long. ++ ++@item ENOENT ++A directory component in @var{pathname} does not exist. ++ ++@item ENOTDIR ++A component of the path is not a directory. ++ ++@item EROFS ++The file is on a read-only filesystem. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node stat/fstat ++@unnumberedsubsubsec stat/fstat ++@cindex fstat, file-i/o system call ++@cindex stat, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int stat(const char *pathname, struct stat *buf); ++int fstat(int fd, struct stat *buf); ++@end smallexample ++ ++@item Request: ++@samp{Fstat,@var{pathnameptr}/@var{len},@var{bufptr}}@* ++@samp{Ffstat,@var{fd},@var{bufptr}} ++ ++@item Return value: ++On success, zero is returned. On error, -1 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EBADF ++@var{fd} is not a valid open file. ++ ++@item ENOENT ++A directory component in @var{pathname} does not exist or the ++path is an empty string. ++ ++@item ENOTDIR ++A component of the path is not a directory. ++ ++@item EFAULT ++@var{pathnameptr} is an invalid pointer value. ++ ++@item EACCES ++No access to the file or the path of the file. ++ ++@item ENAMETOOLONG ++@var{pathname} was too long. ++ ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@node gettimeofday ++@unnumberedsubsubsec gettimeofday ++@cindex gettimeofday, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int gettimeofday(struct timeval *tv, void *tz); ++@end smallexample ++ ++@item Request: ++@samp{Fgettimeofday,@var{tvptr},@var{tzptr}} ++ ++@item Return value: ++On success, 0 is returned, -1 otherwise. ++ ++@item Errors: ++ ++@table @code ++@item EINVAL ++@var{tz} is a non-NULL pointer. ++ ++@item EFAULT ++@var{tvptr} and/or @var{tzptr} is an invalid pointer value. ++@end table ++ ++@end table ++ ++@node isatty ++@unnumberedsubsubsec isatty ++@cindex isatty, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int isatty(int fd); ++@end smallexample ++ ++@item Request: ++@samp{Fisatty,@var{fd}} ++ ++@item Return value: ++Returns 1 if @var{fd} refers to the @value{GDBN} console, 0 otherwise. ++ ++@item Errors: ++ ++@table @code ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++Note that the @code{isatty} call is treated as a special case: it returns ++1 to the target if the file descriptor is attached ++to the @value{GDBN} console, 0 otherwise. Implementing through system calls ++would require implementing @code{ioctl} and would be more complex than ++needed. ++ ++ ++@node system ++@unnumberedsubsubsec system ++@cindex system, file-i/o system call ++ ++@table @asis ++@item Synopsis: ++@smallexample ++int system(const char *command); ++@end smallexample ++ ++@item Request: ++@samp{Fsystem,@var{commandptr}/@var{len}} ++ ++@item Return value: ++If @var{len} is zero, the return value indicates whether a shell is ++available. A zero return value indicates a shell is not available. ++For non-zero @var{len}, the value returned is -1 on error and the ++return status of the command otherwise. Only the exit status of the ++command is returned, which is extracted from the host's @code{system} ++return value by calling @code{WEXITSTATUS(retval)}. In case ++@file{/bin/sh} could not be executed, 127 is returned. ++ ++@item Errors: ++ ++@table @code ++@item EINTR ++The call was interrupted by the user. ++@end table ++ ++@end table ++ ++@value{GDBN} takes over the full task of calling the necessary host calls ++to perform the @code{system} call. The return value of @code{system} on ++the host is simplified before it's returned ++to the target. Any termination signal information from the child process ++is discarded, and the return value consists ++entirely of the exit status of the called command. ++ ++Due to security concerns, the @code{system} call is by default refused ++by @value{GDBN}. The user has to allow this call explicitly with the ++@code{set remote system-call-allowed 1} command. ++ ++@table @code ++@item set remote system-call-allowed ++@kindex set remote system-call-allowed ++Control whether to allow the @code{system} calls in the File I/O ++protocol for the remote target. The default is zero (disabled). ++ ++@item show remote system-call-allowed ++@kindex show remote system-call-allowed ++Show whether the @code{system} calls are allowed in the File I/O ++protocol. ++@end table ++ ++@node Protocol-specific Representation of Datatypes ++@subsection Protocol-specific Representation of Datatypes ++@cindex protocol-specific representation of datatypes, in file-i/o protocol ++ ++@menu ++* Integral Datatypes:: ++* Pointer Values:: ++* Memory Transfer:: ++* struct stat:: ++* struct timeval:: ++@end menu ++ ++@node Integral Datatypes ++@unnumberedsubsubsec Integral Datatypes ++@cindex integral datatypes, in file-i/o protocol ++ ++The integral datatypes used in the system calls are @code{int}, ++@code{unsigned int}, @code{long}, @code{unsigned long}, ++@code{mode_t}, and @code{time_t}. ++ ++@code{int}, @code{unsigned int}, @code{mode_t} and @code{time_t} are ++implemented as 32 bit values in this protocol. ++ ++@code{long} and @code{unsigned long} are implemented as 64 bit types. ++ ++@xref{Limits}, for corresponding MIN and MAX values (similar to those ++in @file{limits.h}) to allow range checking on host and target. ++ ++@code{time_t} datatypes are defined as seconds since the Epoch. ++ ++All integral datatypes transferred as part of a memory read or write of a ++structured datatype e.g.@: a @code{struct stat} have to be given in big endian ++byte order. ++ ++@node Pointer Values ++@unnumberedsubsubsec Pointer Values ++@cindex pointer values, in file-i/o protocol ++ ++Pointers to target data are transmitted as they are. An exception ++is made for pointers to buffers for which the length isn't ++transmitted as part of the function call, namely strings. Strings ++are transmitted as a pointer/length pair, both as hex values, e.g.@: ++ ++@smallexample ++@code{1aaf/12} ++@end smallexample ++ ++@noindent ++which is a pointer to data of length 18 bytes at position 0x1aaf. ++The length is defined as the full string length in bytes, including ++the trailing null byte. For example, the string @code{"hello world"} ++at address 0x123456 is transmitted as ++ ++@smallexample ++@code{123456/d} ++@end smallexample ++ ++@node Memory Transfer ++@unnumberedsubsubsec Memory Transfer ++@cindex memory transfer, in file-i/o protocol ++ ++Structured data which is transferred using a memory read or write (for ++example, a @code{struct stat}) is expected to be in a protocol-specific format ++with all scalar multibyte datatypes being big endian. Translation to ++this representation needs to be done both by the target before the @code{F} ++packet is sent, and by @value{GDBN} before ++it transfers memory to the target. Transferred pointers to structured ++data should point to the already-coerced data at any time. ++ ++ ++@node struct stat ++@unnumberedsubsubsec struct stat ++@cindex struct stat, in file-i/o protocol ++ ++The buffer of type @code{struct stat} used by the target and @value{GDBN} ++is defined as follows: ++ ++@smallexample ++struct stat @{ ++ unsigned int st_dev; /* device */ ++ unsigned int st_ino; /* inode */ ++ mode_t st_mode; /* protection */ ++ unsigned int st_nlink; /* number of hard links */ ++ unsigned int st_uid; /* user ID of owner */ ++ unsigned int st_gid; /* group ID of owner */ ++ unsigned int st_rdev; /* device type (if inode device) */ ++ unsigned long st_size; /* total size, in bytes */ ++ unsigned long st_blksize; /* blocksize for filesystem I/O */ ++ unsigned long st_blocks; /* number of blocks allocated */ ++ time_t st_atime; /* time of last access */ ++ time_t st_mtime; /* time of last modification */ ++ time_t st_ctime; /* time of last change */ ++@}; ++@end smallexample ++ ++The integral datatypes conform to the definitions given in the ++appropriate section (see @ref{Integral Datatypes}, for details) so this ++structure is of size 64 bytes. ++ ++The values of several fields have a restricted meaning and/or ++range of values. ++ ++@table @code ++ ++@item st_dev ++A value of 0 represents a file, 1 the console. ++ ++@item st_ino ++No valid meaning for the target. Transmitted unchanged. ++ ++@item st_mode ++Valid mode bits are described in @ref{Constants}. Any other ++bits have currently no meaning for the target. ++ ++@item st_uid ++@itemx st_gid ++@itemx st_rdev ++No valid meaning for the target. Transmitted unchanged. ++ ++@item st_atime ++@itemx st_mtime ++@itemx st_ctime ++These values have a host and file system dependent ++accuracy. Especially on Windows hosts, the file system may not ++support exact timing values. ++@end table ++ ++The target gets a @code{struct stat} of the above representation and is ++responsible for coercing it to the target representation before ++continuing. ++ ++Note that due to size differences between the host, target, and protocol ++representations of @code{struct stat} members, these members could eventually ++get truncated on the target. ++ ++@node struct timeval ++@unnumberedsubsubsec struct timeval ++@cindex struct timeval, in file-i/o protocol ++ ++The buffer of type @code{struct timeval} used by the File-I/O protocol ++is defined as follows: ++ ++@smallexample ++struct timeval @{ ++ time_t tv_sec; /* second */ ++ long tv_usec; /* microsecond */ ++@}; ++@end smallexample ++ ++The integral datatypes conform to the definitions given in the ++appropriate section (see @ref{Integral Datatypes}, for details) so this ++structure is of size 8 bytes. ++ ++@node Constants ++@subsection Constants ++@cindex constants, in file-i/o protocol ++ ++The following values are used for the constants inside of the ++protocol. @value{GDBN} and target are responsible for translating these ++values before and after the call as needed. ++ ++@menu ++* Open Flags:: ++* mode_t Values:: ++* Errno Values:: ++* Lseek Flags:: ++* Limits:: ++@end menu ++ ++@node Open Flags ++@unnumberedsubsubsec Open Flags ++@cindex open flags, in file-i/o protocol ++ ++All values are given in hexadecimal representation. ++ ++@smallexample ++ O_RDONLY 0x0 ++ O_WRONLY 0x1 ++ O_RDWR 0x2 ++ O_APPEND 0x8 ++ O_CREAT 0x200 ++ O_TRUNC 0x400 ++ O_EXCL 0x800 ++@end smallexample ++ ++@node mode_t Values ++@unnumberedsubsubsec mode_t Values ++@cindex mode_t values, in file-i/o protocol ++ ++All values are given in octal representation. ++ ++@smallexample ++ S_IFREG 0100000 ++ S_IFDIR 040000 ++ S_IRUSR 0400 ++ S_IWUSR 0200 ++ S_IXUSR 0100 ++ S_IRGRP 040 ++ S_IWGRP 020 ++ S_IXGRP 010 ++ S_IROTH 04 ++ S_IWOTH 02 ++ S_IXOTH 01 ++@end smallexample ++ ++@node Errno Values ++@unnumberedsubsubsec Errno Values ++@cindex errno values, in file-i/o protocol ++ ++All values are given in decimal representation. ++ ++@smallexample ++ EPERM 1 ++ ENOENT 2 ++ EINTR 4 ++ EBADF 9 ++ EACCES 13 ++ EFAULT 14 ++ EBUSY 16 ++ EEXIST 17 ++ ENODEV 19 ++ ENOTDIR 20 ++ EISDIR 21 ++ EINVAL 22 ++ ENFILE 23 ++ EMFILE 24 ++ EFBIG 27 ++ ENOSPC 28 ++ ESPIPE 29 ++ EROFS 30 ++ ENAMETOOLONG 91 ++ EUNKNOWN 9999 ++@end smallexample ++ ++ @code{EUNKNOWN} is used as a fallback error value if a host system returns ++ any error value not in the list of supported error numbers. ++ ++@node Lseek Flags ++@unnumberedsubsubsec Lseek Flags ++@cindex lseek flags, in file-i/o protocol ++ ++@smallexample ++ SEEK_SET 0 ++ SEEK_CUR 1 ++ SEEK_END 2 ++@end smallexample ++ ++@node Limits ++@unnumberedsubsubsec Limits ++@cindex limits, in file-i/o protocol ++ ++All values are given in decimal representation. ++ ++@smallexample ++ INT_MIN -2147483648 ++ INT_MAX 2147483647 ++ UINT_MAX 4294967295 ++ LONG_MIN -9223372036854775808 ++ LONG_MAX 9223372036854775807 ++ ULONG_MAX 18446744073709551615 ++@end smallexample ++ ++@node File-I/O Examples ++@subsection File-I/O Examples ++@cindex file-i/o examples ++ ++Example sequence of a write call, file descriptor 3, buffer is at target ++address 0x1234, 6 bytes should be written: ++ ++@smallexample ++<- @code{Fwrite,3,1234,6} ++@emph{request memory read from target} ++-> @code{m1234,6} ++<- XXXXXX ++@emph{return "6 bytes written"} ++-> @code{F6} ++@end smallexample ++ ++Example sequence of a read call, file descriptor 3, buffer is at target ++address 0x1234, 6 bytes should be read: ++ ++@smallexample ++<- @code{Fread,3,1234,6} ++@emph{request memory write to target} ++-> @code{X1234,6:XXXXXX} ++@emph{return "6 bytes read"} ++-> @code{F6} ++@end smallexample ++ ++Example sequence of a read call, call fails on the host due to invalid ++file descriptor (@code{EBADF}): ++ ++@smallexample ++<- @code{Fread,3,1234,6} ++-> @code{F-1,9} ++@end smallexample ++ ++Example sequence of a read call, user presses @kbd{Ctrl-c} before syscall on ++host is called: ++ ++@smallexample ++<- @code{Fread,3,1234,6} ++-> @code{F-1,4,C} ++<- @code{T02} ++@end smallexample ++ ++Example sequence of a read call, user presses @kbd{Ctrl-c} after syscall on ++host is called: ++ ++@smallexample ++<- @code{Fread,3,1234,6} ++-> @code{X1234,6:XXXXXX} ++<- @code{T02} ++@end smallexample ++ ++@node Library List Format ++@section Library List Format ++@cindex library list format, remote protocol ++ ++On some platforms, a dynamic loader (e.g.@: @file{ld.so}) runs in the ++same process as your application to manage libraries. In this case, ++@value{GDBN} can use the loader's symbol table and normal memory ++operations to maintain a list of shared libraries. On other ++platforms, the operating system manages loaded libraries. ++@value{GDBN} can not retrieve the list of currently loaded libraries ++through memory operations, so it uses the @samp{qXfer:libraries:read} ++packet (@pxref{qXfer library list read}) instead. The remote stub ++queries the target's operating system and reports which libraries ++are loaded. ++ ++The @samp{qXfer:libraries:read} packet returns an XML document which ++lists loaded libraries and their offsets. Each library has an ++associated name and one or more segment or section base addresses, ++which report where the library was loaded in memory. ++ ++For the common case of libraries that are fully linked binaries, the ++library should have a list of segments. If the target supports ++dynamic linking of a relocatable object file, its library XML element ++should instead include a list of allocated sections. The segment or ++section bases are start addresses, not relocation offsets; they do not ++depend on the library's link-time base addresses. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++library lists. @xref{Expat}. ++ ++A simple memory map, with one loaded library relocated by a single ++offset, looks like this: ++ ++@smallexample ++ ++ ++ ++ ++ ++@end smallexample ++ ++Another simple memory map, with one loaded library with three ++allocated sections (.text, .data, .bss), looks like this: ++ ++@smallexample ++ ++ ++
++
++
++ ++ ++@end smallexample ++ ++The format of a library list is described by this DTD: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++In addition, segments and section descriptors cannot be mixed within a ++single library element, and you must supply at least one segment or ++section for each library. ++ ++@node Library List Format for SVR4 Targets ++@section Library List Format for SVR4 Targets ++@cindex library list format, remote protocol ++ ++On SVR4 platforms @value{GDBN} can use the symbol table of a dynamic loader ++(e.g.@: @file{ld.so}) and normal memory operations to maintain a list of ++shared libraries. Still a special library list provided by this packet is ++more efficient for the @value{GDBN} remote protocol. ++ ++The @samp{qXfer:libraries-svr4:read} packet returns an XML document which lists ++loaded libraries and their SVR4 linker parameters. For each library on SVR4 ++target, the following parameters are reported: ++ ++@itemize @minus ++@item ++@code{name}, the absolute file name from the @code{l_name} field of ++@code{struct link_map}. ++@item ++@code{lm} with address of @code{struct link_map} used for TLS ++(Thread Local Storage) access. ++@item ++@code{l_addr}, the displacement as read from the field @code{l_addr} of ++@code{struct link_map}. For prelinked libraries this is not an absolute ++memory address. It is a displacement of absolute memory address against ++address the file was prelinked to during the library load. ++@item ++@code{l_ld}, which is memory address of the @code{PT_DYNAMIC} segment ++@end itemize ++ ++Additionally the single @code{main-lm} attribute specifies address of ++@code{struct link_map} used for the main executable. This parameter is used ++for TLS access and its presence is optional. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++SVR4 library lists. @xref{Expat}. ++ ++A simple memory map, with two loaded libraries (which do not use prelink), ++looks like this: ++ ++@smallexample ++ ++ ++ ++ ++@end smallexample ++ ++The format of an SVR4 library list is described by this DTD: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++@node Memory Map Format ++@section Memory Map Format ++@cindex memory map format ++ ++To be able to write into flash memory, @value{GDBN} needs to obtain a ++memory map from the target. This section describes the format of the ++memory map. ++ ++The memory map is obtained using the @samp{qXfer:memory-map:read} ++(@pxref{qXfer memory map read}) packet and is an XML document that ++lists memory regions. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++memory maps. @xref{Expat}. ++ ++The top-level structure of the document is shown below: ++ ++@smallexample ++ ++ ++ ++ region... ++ ++@end smallexample ++ ++Each region can be either: ++ ++@itemize ++ ++@item ++A region of RAM starting at @var{addr} and extending for @var{length} ++bytes from there: ++ ++@smallexample ++ ++@end smallexample ++ ++ ++@item ++A region of read-only memory: ++ ++@smallexample ++ ++@end smallexample ++ ++ ++@item ++A region of flash memory, with erasure blocks @var{blocksize} ++bytes in length: ++ ++@smallexample ++ ++ @var{blocksize} ++ ++@end smallexample ++ ++@end itemize ++ ++Regions must not overlap. @value{GDBN} assumes that areas of memory not covered ++by the memory map are RAM, and uses the ordinary @samp{M} and @samp{X} ++packets to write to addresses in such ranges. ++ ++The formal DTD for memory map format is given below: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++@node Thread List Format ++@section Thread List Format ++@cindex thread list format ++ ++To efficiently update the list of threads and their attributes, ++@value{GDBN} issues the @samp{qXfer:threads:read} packet ++(@pxref{qXfer threads read}) and obtains the XML document with ++the following structure: ++ ++@smallexample ++ ++ ++ ++ ... description ... ++ ++ ++@end smallexample ++ ++Each @samp{thread} element must have the @samp{id} attribute that ++identifies the thread (@pxref{thread-id syntax}). The ++@samp{core} attribute, if present, specifies which processor core ++the thread was last executing on. The @samp{name} attribute, if ++present, specifies the human-readable name of the thread. The content ++of the of @samp{thread} element is interpreted as human-readable ++auxiliary information. The @samp{handle} attribute, if present, ++is a hex encoded representation of the thread handle. ++ ++ ++@node Traceframe Info Format ++@section Traceframe Info Format ++@cindex traceframe info format ++ ++To be able to know which objects in the inferior can be examined when ++inspecting a tracepoint hit, @value{GDBN} needs to obtain the list of ++memory ranges, registers and trace state variables that have been ++collected in a traceframe. ++ ++This list is obtained using the @samp{qXfer:traceframe-info:read} ++(@pxref{qXfer traceframe info read}) packet and is an XML document. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++traceframe info discovery. @xref{Expat}. ++ ++The top-level structure of the document is shown below: ++ ++@smallexample ++ ++ ++ ++ block... ++ ++@end smallexample ++ ++Each traceframe block can be either: ++ ++@itemize ++ ++@item ++A region of collected memory starting at @var{addr} and extending for ++@var{length} bytes from there: ++ ++@smallexample ++ ++@end smallexample ++ ++@item ++A block indicating trace state variable numbered @var{number} has been ++collected: ++ ++@smallexample ++ ++@end smallexample ++ ++@end itemize ++ ++The formal DTD for the traceframe info format is given below: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++@node Branch Trace Format ++@section Branch Trace Format ++@cindex branch trace format ++ ++In order to display the branch trace of an inferior thread, ++@value{GDBN} needs to obtain the list of branches. This list is ++represented as list of sequential code blocks that are connected via ++branches. The code in each block has been executed sequentially. ++ ++This list is obtained using the @samp{qXfer:btrace:read} ++(@pxref{qXfer btrace read}) packet and is an XML document. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++traceframe info discovery. @xref{Expat}. ++ ++The top-level structure of the document is shown below: ++ ++@smallexample ++ ++ ++ ++ block... ++ ++@end smallexample ++ ++@itemize ++ ++@item ++A block of sequentially executed instructions starting at @var{begin} ++and ending at @var{end}: ++ ++@smallexample ++ ++@end smallexample ++ ++@end itemize ++ ++The formal DTD for the branch trace format is given below: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++@node Branch Trace Configuration Format ++@section Branch Trace Configuration Format ++@cindex branch trace configuration format ++ ++For each inferior thread, @value{GDBN} can obtain the branch trace ++configuration using the @samp{qXfer:btrace-conf:read} ++(@pxref{qXfer btrace-conf read}) packet. ++ ++The configuration describes the branch trace format and configuration ++settings for that format. The following information is described: ++ ++@table @code ++@item bts ++This thread uses the @dfn{Branch Trace Store} (@acronym{BTS}) format. ++@table @code ++@item size ++The size of the @acronym{BTS} ring buffer in bytes. ++@end table ++@item pt ++This thread uses the @dfn{Intel Processor Trace} (@acronym{Intel ++PT}) format. ++@table @code ++@item size ++The size of the @acronym{Intel PT} ring buffer in bytes. ++@end table ++@end table ++ ++@value{GDBN} must be linked with the Expat library to support XML ++branch trace configuration discovery. @xref{Expat}. ++ ++The formal DTD for the branch trace configuration format is given below: ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++@include agentexpr.texi ++ ++@node Target Descriptions ++@appendix Target Descriptions ++@cindex target descriptions ++ ++One of the challenges of using @value{GDBN} to debug embedded systems ++is that there are so many minor variants of each processor ++architecture in use. It is common practice for vendors to start with ++a standard processor core --- ARM, PowerPC, or @acronym{MIPS}, for example --- ++and then make changes to adapt it to a particular market niche. Some ++architectures have hundreds of variants, available from dozens of ++vendors. This leads to a number of problems: ++ ++@itemize @bullet ++@item ++With so many different customized processors, it is difficult for ++the @value{GDBN} maintainers to keep up with the changes. ++@item ++Since individual variants may have short lifetimes or limited ++audiences, it may not be worthwhile to carry information about every ++variant in the @value{GDBN} source tree. ++@item ++When @value{GDBN} does support the architecture of the embedded system ++at hand, the task of finding the correct architecture name to give the ++@command{set architecture} command can be error-prone. ++@end itemize ++ ++To address these problems, the @value{GDBN} remote protocol allows a ++target system to not only identify itself to @value{GDBN}, but to ++actually describe its own features. This lets @value{GDBN} support ++processor variants it has never seen before --- to the extent that the ++descriptions are accurate, and that @value{GDBN} understands them. ++ ++@value{GDBN} must be linked with the Expat library to support XML ++target descriptions. @xref{Expat}. ++ ++@menu ++* Retrieving Descriptions:: How descriptions are fetched from a target. ++* Target Description Format:: The contents of a target description. ++* Predefined Target Types:: Standard types available for target ++ descriptions. ++* Enum Target Types:: How to define enum target types. ++* Standard Target Features:: Features @value{GDBN} knows about. ++@end menu ++ ++@node Retrieving Descriptions ++@section Retrieving Descriptions ++ ++Target descriptions can be read from the target automatically, or ++specified by the user manually. The default behavior is to read the ++description from the target. @value{GDBN} retrieves it via the remote ++protocol using @samp{qXfer} requests (@pxref{General Query Packets, ++qXfer}). The @var{annex} in the @samp{qXfer} packet will be ++@samp{target.xml}. The contents of the @samp{target.xml} annex are an ++XML document, of the form described in @ref{Target Description ++Format}. ++ ++Alternatively, you can specify a file to read for the target description. ++If a file is set, the target will not be queried. The commands to ++specify a file are: ++ ++@table @code ++@cindex set tdesc filename ++@item set tdesc filename @var{path} ++Read the target description from @var{path}. ++ ++@cindex unset tdesc filename ++@item unset tdesc filename ++Do not read the XML target description from a file. @value{GDBN} ++will use the description supplied by the current target. ++ ++@cindex show tdesc filename ++@item show tdesc filename ++Show the filename to read for a target description, if any. ++@end table ++ ++ ++@node Target Description Format ++@section Target Description Format ++@cindex target descriptions, XML format ++ ++A target description annex is an @uref{http://www.w3.org/XML/, XML} ++document which complies with the Document Type Definition provided in ++the @value{GDBN} sources in @file{gdb/features/gdb-target.dtd}. This ++means you can use generally available tools like @command{xmllint} to ++check that your feature descriptions are well-formed and valid. ++However, to help people unfamiliar with XML write descriptions for ++their targets, we also describe the grammar here. ++ ++Target descriptions can identify the architecture of the remote target ++and (for some architectures) provide information about custom register ++sets. They can also identify the OS ABI of the remote target. ++@value{GDBN} can use this information to autoconfigure for your ++target, or to warn you if you connect to an unsupported target. ++ ++Here is a simple target description: ++ ++@smallexample ++ ++ i386:x86-64 ++ ++@end smallexample ++ ++@noindent ++This minimal description only says that the target uses ++the x86-64 architecture. ++ ++A target description has the following overall form, with [ ] marking ++optional elements and @dots{} marking repeatable elements. The elements ++are explained further below. ++ ++@smallexample ++ ++ ++ ++ @r{[}@var{architecture}@r{]} ++ @r{[}@var{osabi}@r{]} ++ @r{[}@var{compatible}@r{]} ++ @r{[}@var{feature}@dots{}@r{]} ++ ++@end smallexample ++ ++@noindent ++The description is generally insensitive to whitespace and line ++breaks, under the usual common-sense rules. The XML version ++declaration and document type declaration can generally be omitted ++(@value{GDBN} does not require them), but specifying them may be ++useful for XML validation tools. The @samp{version} attribute for ++@samp{} may also be omitted, but we recommend ++including it; if future versions of @value{GDBN} use an incompatible ++revision of @file{gdb-target.dtd}, they will detect and report ++the version mismatch. ++ ++@subsection Inclusion ++@cindex target descriptions, inclusion ++@cindex XInclude ++@ifnotinfo ++@cindex ++@end ifnotinfo ++ ++It can sometimes be valuable to split a target description up into ++several different annexes, either for organizational purposes, or to ++share files between different possible target descriptions. You can ++divide a description into multiple files by replacing any element of ++the target description with an inclusion directive of the form: ++ ++@smallexample ++ ++@end smallexample ++ ++@noindent ++When @value{GDBN} encounters an element of this form, it will retrieve ++the named XML @var{document}, and replace the inclusion directive with ++the contents of that document. If the current description was read ++using @samp{qXfer}, then so will be the included document; ++@var{document} will be interpreted as the name of an annex. If the ++current description was read from a file, @value{GDBN} will look for ++@var{document} as a file in the same directory where it found the ++original description. ++ ++@subsection Architecture ++@cindex ++ ++An @samp{} element has this form: ++ ++@smallexample ++ @var{arch} ++@end smallexample ++ ++@var{arch} is one of the architectures from the set accepted by ++@code{set architecture} (@pxref{Targets, ,Specifying a Debugging Target}). ++ ++@subsection OS ABI ++@cindex @code{} ++ ++This optional field was introduced in @value{GDBN} version 7.0. ++Previous versions of @value{GDBN} ignore it. ++ ++An @samp{} element has this form: ++ ++@smallexample ++ @var{abi-name} ++@end smallexample ++ ++@var{abi-name} is an OS ABI name from the same selection accepted by ++@w{@code{set osabi}} (@pxref{ABI, ,Configuring the Current ABI}). ++ ++@subsection Compatible Architecture ++@cindex @code{} ++ ++This optional field was introduced in @value{GDBN} version 7.0. ++Previous versions of @value{GDBN} ignore it. ++ ++A @samp{} element has this form: ++ ++@smallexample ++ @var{arch} ++@end smallexample ++ ++@var{arch} is one of the architectures from the set accepted by ++@code{set architecture} (@pxref{Targets, ,Specifying a Debugging Target}). ++ ++A @samp{} element is used to specify that the target ++is able to run binaries in some other than the main target architecture ++given by the @samp{} element. For example, on the ++Cell Broadband Engine, the main architecture is @code{powerpc:common} ++or @code{powerpc:common64}, but the system is able to run binaries ++in the @code{spu} architecture as well. The way to describe this ++capability with @samp{} is as follows: ++ ++@smallexample ++ powerpc:common ++ spu ++@end smallexample ++ ++@subsection Features ++@cindex ++ ++Each @samp{} describes some logical portion of the target ++system. Features are currently used to describe available CPU ++registers and the types of their contents. A @samp{} element ++has this form: ++ ++@smallexample ++ ++ @r{[}@var{type}@dots{}@r{]} ++ @var{reg}@dots{} ++ ++@end smallexample ++ ++@noindent ++Each feature's name should be unique within the description. The name ++of a feature does not matter unless @value{GDBN} has some special ++knowledge of the contents of that feature; if it does, the feature ++should have its standard name. @xref{Standard Target Features}. ++ ++@subsection Types ++ ++Any register's value is a collection of bits which @value{GDBN} must ++interpret. The default interpretation is a two's complement integer, ++but other types can be requested by name in the register description. ++Some predefined types are provided by @value{GDBN} (@pxref{Predefined ++Target Types}), and the description can define additional composite ++and enum types. ++ ++Each type element must have an @samp{id} attribute, which gives ++a unique (within the containing @samp{}) name to the type. ++Types must be defined before they are used. ++ ++@cindex ++Some targets offer vector registers, which can be treated as arrays ++of scalar elements. These types are written as @samp{} elements, ++specifying the array element type, @var{type}, and the number of elements, ++@var{count}: ++ ++@smallexample ++ ++@end smallexample ++ ++@cindex ++If a register's value is usefully viewed in multiple ways, define it ++with a union type containing the useful representations. The ++@samp{} element contains one or more @samp{} elements, ++each of which has a @var{name} and a @var{type}: ++ ++@smallexample ++ ++ ++ @dots{} ++ ++@end smallexample ++ ++@cindex ++@cindex ++If a register's value is composed from several separate values, define ++it with either a structure type or a flags type. ++A flags type may only contain bitfields. ++A structure type may either contain only bitfields or contain no bitfields. ++If the value contains only bitfields, its total size in bytes must be ++specified. ++ ++Non-bitfield values have a @var{name} and @var{type}. ++ ++@smallexample ++ ++ ++ @dots{} ++ ++@end smallexample ++ ++Both @var{name} and @var{type} values are required. ++No implicit padding is added. ++ ++Bitfield values have a @var{name}, @var{start}, @var{end} and @var{type}. ++ ++@smallexample ++ ++ ++ @dots{} ++ ++@end smallexample ++ ++@smallexample ++ ++ ++ @dots{} ++ ++@end smallexample ++ ++The @var{name} value is required. ++Bitfield values may be named with the empty string, @samp{""}, ++in which case the field is ``filler'' and its value is not printed. ++Not all bits need to be specified, so ``filler'' fields are optional. ++ ++The @var{start} and @var{end} values are required, and @var{type} ++is optional. ++The field's @var{start} must be less than or equal to its @var{end}, ++and zero represents the least significant bit. ++ ++The default value of @var{type} is @code{bool} for single bit fields, ++and an unsigned integer otherwise. ++ ++Which to choose? Structures or flags? ++ ++Registers defined with @samp{flags} have these advantages over ++defining them with @samp{struct}: ++ ++@itemize @bullet ++@item ++Arithmetic may be performed on them as if they were integers. ++@item ++They are printed in a more readable fashion. ++@end itemize ++ ++Registers defined with @samp{struct} have one advantage over ++defining them with @samp{flags}: ++ ++@itemize @bullet ++@item ++One can fetch individual fields like in @samp{C}. ++ ++@smallexample ++(gdb) print $my_struct_reg.field3 ++$1 = 42 ++@end smallexample ++ ++@end itemize ++ ++@subsection Registers ++@cindex ++ ++Each register is represented as an element with this form: ++ ++@smallexample ++ ++@end smallexample ++ ++@noindent ++The components are as follows: ++ ++@table @var ++ ++@item name ++The register's name; it must be unique within the target description. ++ ++@item bitsize ++The register's size, in bits. ++ ++@item regnum ++The register's number. If omitted, a register's number is one greater ++than that of the previous register (either in the current feature or in ++a preceding feature); the first register in the target description ++defaults to zero. This register number is used to read or write ++the register; e.g.@: it is used in the remote @code{p} and @code{P} ++packets, and registers appear in the @code{g} and @code{G} packets ++in order of increasing register number. ++ ++@item save-restore ++Whether the register should be preserved across inferior function ++calls; this must be either @code{yes} or @code{no}. The default is ++@code{yes}, which is appropriate for most registers except for ++some system control registers; this is not related to the target's ++ABI. ++ ++@item type ++The type of the register. It may be a predefined type, a type ++defined in the current feature, or one of the special types @code{int} ++and @code{float}. @code{int} is an integer type of the correct size ++for @var{bitsize}, and @code{float} is a floating point type (in the ++architecture's normal floating point format) of the correct size for ++@var{bitsize}. The default is @code{int}. ++ ++@item group ++The register group to which this register belongs. It can be one of the ++standard register groups @code{general}, @code{float}, @code{vector} or an ++arbitrary string. Group names should be limited to alphanumeric characters. ++If a group name is made up of multiple words the words may be separated by ++hyphens; e.g.@: @code{special-group} or @code{ultra-special-group}. If no ++@var{group} is specified, @value{GDBN} will not display the register in ++@code{info registers}. ++ ++@end table ++ ++@node Predefined Target Types ++@section Predefined Target Types ++@cindex target descriptions, predefined types ++ ++Type definitions in the self-description can build up composite types ++from basic building blocks, but can not define fundamental types. Instead, ++standard identifiers are provided by @value{GDBN} for the fundamental ++types. The currently supported types are: ++ ++@table @code ++ ++@item bool ++Boolean type, occupying a single bit. ++ ++@item int8 ++@itemx int16 ++@itemx int24 ++@itemx int32 ++@itemx int64 ++@itemx int128 ++Signed integer types holding the specified number of bits. ++ ++@item uint8 ++@itemx uint16 ++@itemx uint24 ++@itemx uint32 ++@itemx uint64 ++@itemx uint128 ++Unsigned integer types holding the specified number of bits. ++ ++@item code_ptr ++@itemx data_ptr ++Pointers to unspecified code and data. The program counter and ++any dedicated return address register may be marked as code ++pointers; printing a code pointer converts it into a symbolic ++address. The stack pointer and any dedicated address registers ++may be marked as data pointers. ++ ++@item ieee_single ++Single precision IEEE floating point. ++ ++@item ieee_double ++Double precision IEEE floating point. ++ ++@item arm_fpa_ext ++The 12-byte extended precision format used by ARM FPA registers. ++ ++@item i387_ext ++The 10-byte extended precision format used by x87 registers. ++ ++@item i386_eflags ++32bit @sc{eflags} register used by x86. ++ ++@item i386_mxcsr ++32bit @sc{mxcsr} register used by x86. ++ ++@end table ++ ++@node Enum Target Types ++@section Enum Target Types ++@cindex target descriptions, enum types ++ ++Enum target types are useful in @samp{struct} and @samp{flags} ++register descriptions. @xref{Target Description Format}. ++ ++Enum types have a name, size and a list of name/value pairs. ++ ++@smallexample ++ ++ ++ @dots{} ++ ++@end smallexample ++ ++Enums must be defined before they are used. ++ ++@smallexample ++ ++ ++ ++ ++ ++ ++ ++ ++ ++@end smallexample ++ ++Given that description, a value of 3 for the @samp{flags} register ++would be printed as: ++ ++@smallexample ++(gdb) info register flags ++flags 0x3 [ X LEVEL=high ] ++@end smallexample ++ ++@node Standard Target Features ++@section Standard Target Features ++@cindex target descriptions, standard features ++ ++A target description must contain either no registers or all the ++target's registers. If the description contains no registers, then ++@value{GDBN} will assume a default register layout, selected based on ++the architecture. If the description contains any registers, the ++default layout will not be used; the standard registers must be ++described in the target description, in such a way that @value{GDBN} ++can recognize them. ++ ++This is accomplished by giving specific names to feature elements ++which contain standard registers. @value{GDBN} will look for features ++with those names and verify that they contain the expected registers; ++if any known feature is missing required registers, or if any required ++feature is missing, @value{GDBN} will reject the target ++description. You can add additional registers to any of the ++standard features --- @value{GDBN} will display them just as if ++they were added to an unrecognized feature. ++ ++This section lists the known features and their expected contents. ++Sample XML documents for these features are included in the ++@value{GDBN} source tree, in the directory @file{gdb/features}. ++ ++Names recognized by @value{GDBN} should include the name of the ++company or organization which selected the name, and the overall ++architecture to which the feature applies; so e.g.@: the feature ++containing ARM core registers is named @samp{org.gnu.gdb.arm.core}. ++ ++The names of registers are not case sensitive for the purpose ++of recognizing standard features, but @value{GDBN} will only display ++registers using the capitalization used in the description. ++ ++@menu ++* AArch64 Features:: ++* ARC Features:: ++* ARM Features:: ++* i386 Features:: ++* MicroBlaze Features:: ++* MIPS Features:: ++* M68K Features:: ++* NDS32 Features:: ++* Nios II Features:: ++* OpenRISC 1000 Features:: ++* PowerPC Features:: ++* RISC-V Features:: ++* RX Features:: ++* S/390 and System z Features:: ++* Sparc Features:: ++* TIC6x Features:: ++@end menu ++ ++ ++@node AArch64 Features ++@subsection AArch64 Features ++@cindex target descriptions, AArch64 features ++ ++The @samp{org.gnu.gdb.aarch64.core} feature is required for AArch64 ++targets. It should contain registers @samp{x0} through @samp{x30}, ++@samp{sp}, @samp{pc}, and @samp{cpsr}. ++ ++The @samp{org.gnu.gdb.aarch64.fpu} feature is optional. If present, ++it should contain registers @samp{v0} through @samp{v31}, @samp{fpsr}, ++and @samp{fpcr}. ++ ++The @samp{org.gnu.gdb.aarch64.sve} feature is optional. If present, ++it should contain registers @samp{z0} through @samp{z31}, @samp{p0} ++through @samp{p15}, @samp{ffr} and @samp{vg}. ++ ++The @samp{org.gnu.gdb.aarch64.pauth} feature is optional. If present, ++it should contain registers @samp{pauth_dmask} and @samp{pauth_cmask}. ++ ++@node ARC Features ++@subsection ARC Features ++@cindex target descriptions, ARC Features ++ ++ARC processors are so configurable that even core registers and their numbers ++are not predetermined completely. Moreover, @emph{flags} and @emph{PC} ++registers, which are important to @value{GDBN}, are not ``core'' registers in ++ARC. Therefore, there are two features that their presence is mandatory: ++@samp{org.gnu.gdb.arc.core} and @samp{org.gnu.gdb.arc.aux}. ++ ++The @samp{org.gnu.gdb.arc.core} feature is required for all targets. It must ++contain registers: ++ ++@itemize @minus ++@item ++@samp{r0} through @samp{r25} for normal register file targets. ++@item ++@samp{r0} through @samp{r3}, and @samp{r10} through @samp{r15} for reduced ++register file targets. ++@item ++@samp{gp}, @samp{fp}, @samp{sp}, @samp{r30}@footnote{Not necessary for ARCv1.}, ++@samp{blink}, @samp{lp_count}, @samp{pcl}. ++@end itemize ++ ++In case of an ARCompact target (ARCv1 ISA), the @samp{org.gnu.gdb.arc.core} ++feature may contain registers @samp{ilink1} and @samp{ilink2}. While in case ++of ARC EM and ARC HS targets (ARCv2 ISA), register @samp{ilink} may be present. ++The difference between ARCv1 and ARCv2 is the naming of registers @emph{29th} ++and @emph{30th}. They are called @samp{ilink1} and @samp{ilink2} for ARCv1 and ++are optional. For ARCv2, they are called @samp{ilink} and @samp{r30} and only ++@samp{ilink} is optional. The optionality of @samp{ilink*} registers is ++because of their inaccessibility during user space debugging sessions. ++ ++Extension core registers @samp{r32} through @samp{r59} are optional and their ++existence depends on the configuration. When debugging GNU/Linux applications, ++i.e.@: user space debugging, these core registers are not available. ++ ++The @samp{org.gnu.gdb.arc.aux} feature is required for all ARC targets. Here ++is the list of registers pertinent to this feature: ++ ++@itemize @minus ++@item ++mandatory: @samp{pc} and @samp{status32}. ++@item ++optional: @samp{lp_start}, @samp{lp_end}, and @samp{bta}. ++@end itemize ++ ++@node ARM Features ++@subsection ARM Features ++@cindex target descriptions, ARM features ++ ++The @samp{org.gnu.gdb.arm.core} feature is required for non-M-profile ++ARM targets. ++It should contain registers @samp{r0} through @samp{r13}, @samp{sp}, ++@samp{lr}, @samp{pc}, and @samp{cpsr}. ++ ++For M-profile targets (e.g. Cortex-M3), the @samp{org.gnu.gdb.arm.core} ++feature is replaced by @samp{org.gnu.gdb.arm.m-profile}. It should contain ++registers @samp{r0} through @samp{r13}, @samp{sp}, @samp{lr}, @samp{pc}, ++and @samp{xpsr}. ++ ++The @samp{org.gnu.gdb.arm.fpa} feature is optional. If present, it ++should contain registers @samp{f0} through @samp{f7} and @samp{fps}. ++ ++The @samp{org.gnu.gdb.xscale.iwmmxt} feature is optional. If present, ++it should contain at least registers @samp{wR0} through @samp{wR15} and ++@samp{wCGR0} through @samp{wCGR3}. The @samp{wCID}, @samp{wCon}, ++@samp{wCSSF}, and @samp{wCASF} registers are optional. ++ ++The @samp{org.gnu.gdb.arm.vfp} feature is optional. If present, it ++should contain at least registers @samp{d0} through @samp{d15}. If ++they are present, @samp{d16} through @samp{d31} should also be included. ++@value{GDBN} will synthesize the single-precision registers from ++halves of the double-precision registers. ++ ++The @samp{org.gnu.gdb.arm.neon} feature is optional. It does not ++need to contain registers; it instructs @value{GDBN} to display the ++VFP double-precision registers as vectors and to synthesize the ++quad-precision registers from pairs of double-precision registers. ++If this feature is present, @samp{org.gnu.gdb.arm.vfp} must also ++be present and include 32 double-precision registers. ++ ++@node i386 Features ++@subsection i386 Features ++@cindex target descriptions, i386 features ++ ++The @samp{org.gnu.gdb.i386.core} feature is required for i386/amd64 ++targets. It should describe the following registers: ++ ++@itemize @minus ++@item ++@samp{eax} through @samp{edi} plus @samp{eip} for i386 ++@item ++@samp{rax} through @samp{r15} plus @samp{rip} for amd64 ++@item ++@samp{eflags}, @samp{cs}, @samp{ss}, @samp{ds}, @samp{es}, ++@samp{fs}, @samp{gs} ++@item ++@samp{st0} through @samp{st7} ++@item ++@samp{fctrl}, @samp{fstat}, @samp{ftag}, @samp{fiseg}, @samp{fioff}, ++@samp{foseg}, @samp{fooff} and @samp{fop} ++@end itemize ++ ++The register sets may be different, depending on the target. ++ ++The @samp{org.gnu.gdb.i386.sse} feature is optional. It should ++describe registers: ++ ++@itemize @minus ++@item ++@samp{xmm0} through @samp{xmm7} for i386 ++@item ++@samp{xmm0} through @samp{xmm15} for amd64 ++@item ++@samp{mxcsr} ++@end itemize ++ ++The @samp{org.gnu.gdb.i386.avx} feature is optional and requires the ++@samp{org.gnu.gdb.i386.sse} feature. It should ++describe the upper 128 bits of @sc{ymm} registers: ++ ++@itemize @minus ++@item ++@samp{ymm0h} through @samp{ymm7h} for i386 ++@item ++@samp{ymm0h} through @samp{ymm15h} for amd64 ++@end itemize ++ ++The @samp{org.gnu.gdb.i386.mpx} is an optional feature representing Intel ++Memory Protection Extension (MPX). It should describe the following registers: ++ ++@itemize @minus ++@item ++@samp{bnd0raw} through @samp{bnd3raw} for i386 and amd64. ++@item ++@samp{bndcfgu} and @samp{bndstatus} for i386 and amd64. ++@end itemize ++ ++The @samp{org.gnu.gdb.i386.linux} feature is optional. It should ++describe a single register, @samp{orig_eax}. ++ ++The @samp{org.gnu.gdb.i386.segments} feature is optional. It should ++describe two system registers: @samp{fs_base} and @samp{gs_base}. ++ ++The @samp{org.gnu.gdb.i386.avx512} feature is optional and requires the ++@samp{org.gnu.gdb.i386.avx} feature. It should ++describe additional @sc{xmm} registers: ++ ++@itemize @minus ++@item ++@samp{xmm16h} through @samp{xmm31h}, only valid for amd64. ++@end itemize ++ ++It should describe the upper 128 bits of additional @sc{ymm} registers: ++ ++@itemize @minus ++@item ++@samp{ymm16h} through @samp{ymm31h}, only valid for amd64. ++@end itemize ++ ++It should ++describe the upper 256 bits of @sc{zmm} registers: ++ ++@itemize @minus ++@item ++@samp{zmm0h} through @samp{zmm7h} for i386. ++@item ++@samp{zmm0h} through @samp{zmm15h} for amd64. ++@end itemize ++ ++It should ++describe the additional @sc{zmm} registers: ++ ++@itemize @minus ++@item ++@samp{zmm16h} through @samp{zmm31h}, only valid for amd64. ++@end itemize ++ ++The @samp{org.gnu.gdb.i386.pkeys} feature is optional. It should ++describe a single register, @samp{pkru}. It is a 32-bit register ++valid for i386 and amd64. ++ ++@node MicroBlaze Features ++@subsection MicroBlaze Features ++@cindex target descriptions, MicroBlaze features ++ ++The @samp{org.gnu.gdb.microblaze.core} feature is required for MicroBlaze ++targets. It should contain registers @samp{r0} through @samp{r31}, ++@samp{rpc}, @samp{rmsr}, @samp{rear}, @samp{resr}, @samp{rfsr}, @samp{rbtr}, ++@samp{rpvr}, @samp{rpvr1} through @samp{rpvr11}, @samp{redr}, @samp{rpid}, ++@samp{rzpr}, @samp{rtlbx}, @samp{rtlbsx}, @samp{rtlblo}, and @samp{rtlbhi}. ++ ++The @samp{org.gnu.gdb.microblaze.stack-protect} feature is optional. ++If present, it should contain registers @samp{rshr} and @samp{rslr} ++ ++@node MIPS Features ++@subsection @acronym{MIPS} Features ++@cindex target descriptions, @acronym{MIPS} features ++ ++The @samp{org.gnu.gdb.mips.cpu} feature is required for @acronym{MIPS} targets. ++It should contain registers @samp{r0} through @samp{r31}, @samp{lo}, ++@samp{hi}, and @samp{pc}. They may be 32-bit or 64-bit depending ++on the target. ++ ++The @samp{org.gnu.gdb.mips.cp0} feature is also required. It should ++contain at least the @samp{status}, @samp{badvaddr}, and @samp{cause} ++registers. They may be 32-bit or 64-bit depending on the target. ++ ++The @samp{org.gnu.gdb.mips.fpu} feature is currently required, though ++it may be optional in a future version of @value{GDBN}. It should ++contain registers @samp{f0} through @samp{f31}, @samp{fcsr}, and ++@samp{fir}. They may be 32-bit or 64-bit depending on the target. ++ ++The @samp{org.gnu.gdb.mips.dsp} feature is optional. It should ++contain registers @samp{hi1} through @samp{hi3}, @samp{lo1} through ++@samp{lo3}, and @samp{dspctl}. The @samp{dspctl} register should ++be 32-bit and the rest may be 32-bit or 64-bit depending on the target. ++ ++The @samp{org.gnu.gdb.mips.linux} feature is optional. It should ++contain a single register, @samp{restart}, which is used by the ++Linux kernel to control restartable syscalls. ++ ++@node M68K Features ++@subsection M68K Features ++@cindex target descriptions, M68K features ++ ++@table @code ++@item @samp{org.gnu.gdb.m68k.core} ++@itemx @samp{org.gnu.gdb.coldfire.core} ++@itemx @samp{org.gnu.gdb.fido.core} ++One of those features must be always present. ++The feature that is present determines which flavor of m68k is ++used. The feature that is present should contain registers ++@samp{d0} through @samp{d7}, @samp{a0} through @samp{a5}, @samp{fp}, ++@samp{sp}, @samp{ps} and @samp{pc}. ++ ++@item @samp{org.gnu.gdb.coldfire.fp} ++This feature is optional. If present, it should contain registers ++@samp{fp0} through @samp{fp7}, @samp{fpcontrol}, @samp{fpstatus} and ++@samp{fpiaddr}. ++ ++Note that, despite the fact that this feature's name says ++@samp{coldfire}, it is used to describe any floating point registers. ++The size of the registers must match the main m68k flavor; so, for ++example, if the primary feature is reported as @samp{coldfire}, then ++64-bit floating point registers are required. ++@end table ++ ++@node NDS32 Features ++@subsection NDS32 Features ++@cindex target descriptions, NDS32 features ++ ++The @samp{org.gnu.gdb.nds32.core} feature is required for NDS32 ++targets. It should contain at least registers @samp{r0} through ++@samp{r10}, @samp{r15}, @samp{fp}, @samp{gp}, @samp{lp}, @samp{sp}, ++and @samp{pc}. ++ ++The @samp{org.gnu.gdb.nds32.fpu} feature is optional. If present, ++it should contain 64-bit double-precision floating-point registers ++@samp{fd0} through @emph{fdN}, which should be @samp{fd3}, @samp{fd7}, ++@samp{fd15}, or @samp{fd31} based on the FPU configuration implemented. ++ ++@emph{Note:} The first sixteen 64-bit double-precision floating-point ++registers are overlapped with the thirty-two 32-bit single-precision ++floating-point registers. The 32-bit single-precision registers, if ++not being listed explicitly, will be synthesized from halves of the ++overlapping 64-bit double-precision registers. Listing 32-bit ++single-precision registers explicitly is deprecated, and the ++support to it could be totally removed some day. ++ ++@node Nios II Features ++@subsection Nios II Features ++@cindex target descriptions, Nios II features ++ ++The @samp{org.gnu.gdb.nios2.cpu} feature is required for Nios II ++targets. It should contain the 32 core registers (@samp{zero}, ++@samp{at}, @samp{r2} through @samp{r23}, @samp{et} through @samp{ra}), ++@samp{pc}, and the 16 control registers (@samp{status} through ++@samp{mpuacc}). ++ ++@node OpenRISC 1000 Features ++@subsection Openrisc 1000 Features ++@cindex target descriptions, OpenRISC 1000 features ++ ++The @samp{org.gnu.gdb.or1k.group0} feature is required for OpenRISC 1000 ++targets. It should contain the 32 general purpose registers (@samp{r0} ++through @samp{r31}), @samp{ppc}, @samp{npc} and @samp{sr}. ++ ++@node PowerPC Features ++@subsection PowerPC Features ++@cindex target descriptions, PowerPC features ++ ++The @samp{org.gnu.gdb.power.core} feature is required for PowerPC ++targets. It should contain registers @samp{r0} through @samp{r31}, ++@samp{pc}, @samp{msr}, @samp{cr}, @samp{lr}, @samp{ctr}, and ++@samp{xer}. They may be 32-bit or 64-bit depending on the target. ++ ++The @samp{org.gnu.gdb.power.fpu} feature is optional. It should ++contain registers @samp{f0} through @samp{f31} and @samp{fpscr}. ++ ++The @samp{org.gnu.gdb.power.altivec} feature is optional. It should ++contain registers @samp{vr0} through @samp{vr31}, @samp{vscr}, and ++@samp{vrsave}. @value{GDBN} will define pseudo-registers @samp{v0} ++through @samp{v31} as aliases for the corresponding @samp{vrX} ++registers. ++ ++The @samp{org.gnu.gdb.power.vsx} feature is optional. It should ++contain registers @samp{vs0h} through @samp{vs31h}. @value{GDBN} will ++combine these registers with the floating point registers (@samp{f0} ++through @samp{f31}) and the altivec registers (@samp{vr0} through ++@samp{vr31}) to present the 128-bit wide registers @samp{vs0} through ++@samp{vs63}, the set of vector-scalar registers for POWER7. ++Therefore, this feature requires both @samp{org.gnu.gdb.power.fpu} and ++@samp{org.gnu.gdb.power.altivec}. ++ ++The @samp{org.gnu.gdb.power.spe} feature is optional. It should ++contain registers @samp{ev0h} through @samp{ev31h}, @samp{acc}, and ++@samp{spefscr}. SPE targets should provide 32-bit registers in ++@samp{org.gnu.gdb.power.core} and provide the upper halves in ++@samp{ev0h} through @samp{ev31h}. @value{GDBN} will combine ++these to present registers @samp{ev0} through @samp{ev31} to the ++user. ++ ++The @samp{org.gnu.gdb.power.ppr} feature is optional. It should ++contain the 64-bit register @samp{ppr}. ++ ++The @samp{org.gnu.gdb.power.dscr} feature is optional. It should ++contain the 64-bit register @samp{dscr}. ++ ++The @samp{org.gnu.gdb.power.tar} feature is optional. It should ++contain the 64-bit register @samp{tar}. ++ ++The @samp{org.gnu.gdb.power.ebb} feature is optional. It should ++contain registers @samp{bescr}, @samp{ebbhr} and @samp{ebbrr}, all ++64-bit wide. ++ ++The @samp{org.gnu.gdb.power.linux.pmu} feature is optional. It should ++contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar} ++and @samp{sier}, all 64-bit wide. This is the subset of the isa 2.07 ++server PMU registers provided by @sc{gnu}/Linux. ++ ++The @samp{org.gnu.gdb.power.htm.spr} feature is optional. It should ++contain registers @samp{tfhar}, @samp{texasr} and @samp{tfiar}, all ++64-bit wide. ++ ++The @samp{org.gnu.gdb.power.htm.core} feature is optional. It should ++contain the checkpointed general-purpose registers @samp{cr0} through ++@samp{cr31}, as well as the checkpointed registers @samp{clr} and ++@samp{cctr}. These registers may all be either 32-bit or 64-bit ++depending on the target. It should also contain the checkpointed ++registers @samp{ccr} and @samp{cxer}, which should both be 32-bit ++wide. ++ ++The @samp{org.gnu.gdb.power.htm.fpu} feature is optional. It should ++contain the checkpointed 64-bit floating-point registers @samp{cf0} ++through @samp{cf31}, as well as the checkpointed 64-bit register ++@samp{cfpscr}. ++ ++The @samp{org.gnu.gdb.power.htm.altivec} feature is optional. It ++should contain the checkpointed altivec registers @samp{cvr0} through ++@samp{cvr31}, all 128-bit wide. It should also contain the ++checkpointed registers @samp{cvscr} and @samp{cvrsave}, both 32-bit ++wide. ++ ++The @samp{org.gnu.gdb.power.htm.vsx} feature is optional. It should ++contain registers @samp{cvs0h} through @samp{cvs31h}. @value{GDBN} ++will combine these registers with the checkpointed floating point ++registers (@samp{cf0} through @samp{cf31}) and the checkpointed ++altivec registers (@samp{cvr0} through @samp{cvr31}) to present the ++128-bit wide checkpointed vector-scalar registers @samp{cvs0} through ++@samp{cvs63}. Therefore, this feature requires both ++@samp{org.gnu.gdb.power.htm.altivec} and ++@samp{org.gnu.gdb.power.htm.fpu}. ++ ++The @samp{org.gnu.gdb.power.htm.ppr} feature is optional. It should ++contain the 64-bit checkpointed register @samp{cppr}. ++ ++The @samp{org.gnu.gdb.power.htm.dscr} feature is optional. It should ++contain the 64-bit checkpointed register @samp{cdscr}. ++ ++The @samp{org.gnu.gdb.power.htm.tar} feature is optional. It should ++contain the 64-bit checkpointed register @samp{ctar}. ++ ++ ++@node RISC-V Features ++@subsection RISC-V Features ++@cindex target descriptions, RISC-V Features ++ ++The @samp{org.gnu.gdb.riscv.cpu} feature is required for RISC-V ++targets. It should contain the registers @samp{x0} through ++@samp{x31}, and @samp{pc}. Either the architectural names (@samp{x0}, ++@samp{x1}, etc) can be used, or the ABI names (@samp{zero}, @samp{ra}, ++etc). ++ ++The @samp{org.gnu.gdb.riscv.fpu} feature is optional. If present, it ++should contain registers @samp{f0} through @samp{f31}, @samp{fflags}, ++@samp{frm}, and @samp{fcsr}. As with the cpu feature, either the ++architectural register names, or the ABI names can be used. ++ ++The @samp{org.gnu.gdb.riscv.virtual} feature is optional. If present, ++it should contain registers that are not backed by real registers on ++the target, but are instead virtual, where the register value is ++derived from other target state. In many ways these are like ++@value{GDBN}s pseudo-registers, except implemented by the target. ++Currently the only register expected in this set is the one byte ++@samp{priv} register that contains the target's privilege level in the ++least significant two bits. ++ ++The @samp{org.gnu.gdb.riscv.csr} feature is optional. If present, it ++should contain all of the target's standard CSRs. Standard CSRs are ++those defined in the RISC-V specification documents. There is some ++overlap between this feature and the fpu feature; the @samp{fflags}, ++@samp{frm}, and @samp{fcsr} registers could be in either feature. The ++expectation is that these registers will be in the fpu feature if the ++target has floating point hardware, but can be moved into the csr ++feature if the target has the floating point control registers, but no ++other floating point hardware. ++ ++@node RX Features ++@subsection RX Features ++@cindex target descriptions, RX Features ++ ++The @samp{org.gnu.gdb.rx.core} feature is required for RX ++targets. It should contain the registers @samp{r0} through ++@samp{r15}, @samp{usp}, @samp{isp}, @samp{psw}, @samp{pc}, @samp{intb}, ++@samp{bpsw}, @samp{bpc}, @samp{fintv}, @samp{fpsw}, and @samp{acc}. ++ ++@node S/390 and System z Features ++@subsection S/390 and System z Features ++@cindex target descriptions, S/390 features ++@cindex target descriptions, System z features ++ ++The @samp{org.gnu.gdb.s390.core} feature is required for S/390 and ++System z targets. It should contain the PSW and the 16 general ++registers. In particular, System z targets should provide the 64-bit ++registers @samp{pswm}, @samp{pswa}, and @samp{r0} through @samp{r15}. ++S/390 targets should provide the 32-bit versions of these registers. ++A System z target that runs in 31-bit addressing mode should provide ++32-bit versions of @samp{pswm} and @samp{pswa}, as well as the general ++register's upper halves @samp{r0h} through @samp{r15h}, and their ++lower halves @samp{r0l} through @samp{r15l}. ++ ++The @samp{org.gnu.gdb.s390.fpr} feature is required. It should ++contain the 64-bit registers @samp{f0} through @samp{f15}, and ++@samp{fpc}. ++ ++The @samp{org.gnu.gdb.s390.acr} feature is required. It should ++contain the 32-bit registers @samp{acr0} through @samp{acr15}. ++ ++The @samp{org.gnu.gdb.s390.linux} feature is optional. It should ++contain the register @samp{orig_r2}, which is 64-bit wide on System z ++targets and 32-bit otherwise. In addition, the feature may contain ++the @samp{last_break} register, whose width depends on the addressing ++mode, as well as the @samp{system_call} register, which is always ++32-bit wide. ++ ++The @samp{org.gnu.gdb.s390.tdb} feature is optional. It should ++contain the 64-bit registers @samp{tdb0}, @samp{tac}, @samp{tct}, ++@samp{atia}, and @samp{tr0} through @samp{tr15}. ++ ++The @samp{org.gnu.gdb.s390.vx} feature is optional. It should contain ++64-bit wide registers @samp{v0l} through @samp{v15l}, which will be ++combined by @value{GDBN} with the floating point registers @samp{f0} ++through @samp{f15} to present the 128-bit wide vector registers ++@samp{v0} through @samp{v15}. In addition, this feature should ++contain the 128-bit wide vector registers @samp{v16} through ++@samp{v31}. ++ ++The @samp{org.gnu.gdb.s390.gs} feature is optional. It should contain ++the 64-bit wide guarded-storage-control registers @samp{gsd}, ++@samp{gssm}, and @samp{gsepla}. ++ ++The @samp{org.gnu.gdb.s390.gsbc} feature is optional. It should contain ++the 64-bit wide guarded-storage broadcast control registers ++@samp{bc_gsd}, @samp{bc_gssm}, and @samp{bc_gsepla}. ++ ++@node Sparc Features ++@subsection Sparc Features ++@cindex target descriptions, sparc32 features ++@cindex target descriptions, sparc64 features ++The @samp{org.gnu.gdb.sparc.cpu} feature is required for sparc32/sparc64 ++targets. It should describe the following registers: ++ ++@itemize @minus ++@item ++@samp{g0} through @samp{g7} ++@item ++@samp{o0} through @samp{o7} ++@item ++@samp{l0} through @samp{l7} ++@item ++@samp{i0} through @samp{i7} ++@end itemize ++ ++They may be 32-bit or 64-bit depending on the target. ++ ++Also the @samp{org.gnu.gdb.sparc.fpu} feature is required for sparc32/sparc64 ++targets. It should describe the following registers: ++ ++@itemize @minus ++@item ++@samp{f0} through @samp{f31} ++@item ++@samp{f32} through @samp{f62} for sparc64 ++@end itemize ++ ++The @samp{org.gnu.gdb.sparc.cp0} feature is required for sparc32/sparc64 ++targets. It should describe the following registers: ++ ++@itemize @minus ++@item ++@samp{y}, @samp{psr}, @samp{wim}, @samp{tbr}, @samp{pc}, @samp{npc}, ++@samp{fsr}, and @samp{csr} for sparc32 ++@item ++@samp{pc}, @samp{npc}, @samp{state}, @samp{fsr}, @samp{fprs}, and @samp{y} ++for sparc64 ++@end itemize ++ ++@node TIC6x Features ++@subsection TMS320C6x Features ++@cindex target descriptions, TIC6x features ++@cindex target descriptions, TMS320C6x features ++The @samp{org.gnu.gdb.tic6x.core} feature is required for TMS320C6x ++targets. It should contain registers @samp{A0} through @samp{A15}, ++registers @samp{B0} through @samp{B15}, @samp{CSR} and @samp{PC}. ++ ++The @samp{org.gnu.gdb.tic6x.gp} feature is optional. It should ++contain registers @samp{A16} through @samp{A31} and @samp{B16} ++through @samp{B31}. ++ ++The @samp{org.gnu.gdb.tic6x.c6xp} feature is optional. It should ++contain registers @samp{TSR}, @samp{ILC} and @samp{RILC}. ++ ++@node Operating System Information ++@appendix Operating System Information ++@cindex operating system information ++ ++@menu ++* Process list:: ++@end menu ++ ++Users of @value{GDBN} often wish to obtain information about the state of ++the operating system running on the target---for example the list of ++processes, or the list of open files. This section describes the ++mechanism that makes it possible. This mechanism is similar to the ++target features mechanism (@pxref{Target Descriptions}), but focuses ++on a different aspect of target. ++ ++Operating system information is retrieved from the target via the ++remote protocol, using @samp{qXfer} requests (@pxref{qXfer osdata ++read}). The object name in the request should be @samp{osdata}, and ++the @var{annex} identifies the data to be fetched. ++ ++@node Process list ++@appendixsection Process list ++@cindex operating system information, process list ++ ++When requesting the process list, the @var{annex} field in the ++@samp{qXfer} request should be @samp{processes}. The returned data is ++an XML document. The formal syntax of this document is defined in ++@file{gdb/features/osdata.dtd}. ++ ++An example document is: ++ ++@smallexample ++ ++ ++ ++ ++ 1 ++ root ++ /sbin/init ++ 1,2,3 ++ ++ ++@end smallexample ++ ++Each item should include a column whose name is @samp{pid}. The value ++of that column should identify the process on the target. The ++@samp{user} and @samp{command} columns are optional, and will be ++displayed by @value{GDBN}. The @samp{cores} column, if present, ++should contain a comma-separated list of cores that this process ++is running on. Target may provide additional columns, ++which @value{GDBN} currently ignores. ++ ++@node Trace File Format ++@appendix Trace File Format ++@cindex trace file format ++ ++The trace file comes in three parts: a header, a textual description ++section, and a trace frame section with binary data. ++ ++The header has the form @code{\x7fTRACE0\n}. The first byte is ++@code{0x7f} so as to indicate that the file contains binary data, ++while the @code{0} is a version number that may have different values ++in the future. ++ ++The description section consists of multiple lines of @sc{ascii} text ++separated by newline characters (@code{0xa}). The lines may include a ++variety of optional descriptive or context-setting information, such ++as tracepoint definitions or register set size. @value{GDBN} will ++ignore any line that it does not recognize. An empty line marks the end ++of this section. ++ ++@table @code ++@item R @var{size} ++Specifies the size of a register block in bytes. This is equal to the ++size of a @code{g} packet payload in the remote protocol. @var{size} ++is an ascii decimal number. There should be only one such line in ++a single trace file. ++ ++@item status @var{status} ++Trace status. @var{status} has the same format as a @code{qTStatus} ++remote packet reply. There should be only one such line in a single trace ++file. ++ ++@item tp @var{payload} ++Tracepoint definition. The @var{payload} has the same format as ++@code{qTfP}/@code{qTsP} remote packet reply payload. A single tracepoint ++may take multiple lines of definition, corresponding to the multiple ++reply packets. ++ ++@item tsv @var{payload} ++Trace state variable definition. The @var{payload} has the same format as ++@code{qTfV}/@code{qTsV} remote packet reply payload. A single variable ++may take multiple lines of definition, corresponding to the multiple ++reply packets. ++ ++@item tdesc @var{payload} ++Target description in XML format. The @var{payload} is a single line of ++the XML file. All such lines should be concatenated together to get ++the original XML file. This file is in the same format as @code{qXfer} ++@code{features} payload, and corresponds to the main @code{target.xml} ++file. Includes are not allowed. ++ ++@end table ++ ++The trace frame section consists of a number of consecutive frames. ++Each frame begins with a two-byte tracepoint number, followed by a ++four-byte size giving the amount of data in the frame. The data in ++the frame consists of a number of blocks, each introduced by a ++character indicating its type (at least register, memory, and trace ++state variable). The data in this section is raw binary, not a ++hexadecimal or other encoding; its endianness matches the target's ++endianness. ++ ++@c FIXME bi-arch may require endianness/arch info in description section ++ ++@table @code ++@item R @var{bytes} ++Register block. The number and ordering of bytes matches that of a ++@code{g} packet in the remote protocol. Note that these are the ++actual bytes, in target order, not a hexadecimal encoding. ++ ++@item M @var{address} @var{length} @var{bytes}... ++Memory block. This is a contiguous block of memory, at the 8-byte ++address @var{address}, with a 2-byte length @var{length}, followed by ++@var{length} bytes. ++ ++@item V @var{number} @var{value} ++Trace state variable block. This records the 8-byte signed value ++@var{value} of trace state variable numbered @var{number}. ++ ++@end table ++ ++Future enhancements of the trace file format may include additional types ++of blocks. ++ ++@node Index Section Format ++@appendix @code{.gdb_index} section format ++@cindex .gdb_index section format ++@cindex index section format ++ ++This section documents the index section that is created by @code{save ++gdb-index} (@pxref{Index Files}). The index section is ++DWARF-specific; some knowledge of DWARF is assumed in this ++description. ++ ++The mapped index file format is designed to be directly ++@code{mmap}able on any architecture. In most cases, a datum is ++represented using a little-endian 32-bit integer value, called an ++@code{offset_type}. Big endian machines must byte-swap the values ++before using them. Exceptions to this rule are noted. The data is ++laid out such that alignment is always respected. ++ ++A mapped index consists of several areas, laid out in order. ++ ++@enumerate ++@item ++The file header. This is a sequence of values, of @code{offset_type} ++unless otherwise noted: ++ ++@enumerate ++@item ++The version number, currently 8. Versions 1, 2 and 3 are obsolete. ++Version 4 uses a different hashing function from versions 5 and 6. ++Version 6 includes symbols for inlined functions, whereas versions 4 ++and 5 do not. Version 7 adds attributes to the CU indices in the ++symbol table. Version 8 specifies that symbols from DWARF type units ++(@samp{DW_TAG_type_unit}) refer to the type unit's symbol table and not the ++compilation unit (@samp{DW_TAG_comp_unit}) using the type. ++ ++@value{GDBN} will only read version 4, 5, or 6 indices ++by specifying @code{set use-deprecated-index-sections on}. ++GDB has a workaround for potentially broken version 7 indices so it is ++currently not flagged as deprecated. ++ ++@item ++The offset, from the start of the file, of the CU list. ++ ++@item ++The offset, from the start of the file, of the types CU list. Note ++that this area can be empty, in which case this offset will be equal ++to the next offset. ++ ++@item ++The offset, from the start of the file, of the address area. ++ ++@item ++The offset, from the start of the file, of the symbol table. ++ ++@item ++The offset, from the start of the file, of the constant pool. ++@end enumerate ++ ++@item ++The CU list. This is a sequence of pairs of 64-bit little-endian ++values, sorted by the CU offset. The first element in each pair is ++the offset of a CU in the @code{.debug_info} section. The second ++element in each pair is the length of that CU. References to a CU ++elsewhere in the map are done using a CU index, which is just the ++0-based index into this table. Note that if there are type CUs, then ++conceptually CUs and type CUs form a single list for the purposes of ++CU indices. ++ ++@item ++The types CU list. This is a sequence of triplets of 64-bit ++little-endian values. In a triplet, the first value is the CU offset, ++the second value is the type offset in the CU, and the third value is ++the type signature. The types CU list is not sorted. ++ ++@item ++The address area. The address area consists of a sequence of address ++entries. Each address entry has three elements: ++ ++@enumerate ++@item ++The low address. This is a 64-bit little-endian value. ++ ++@item ++The high address. This is a 64-bit little-endian value. Like ++@code{DW_AT_high_pc}, the value is one byte beyond the end. ++ ++@item ++The CU index. This is an @code{offset_type} value. ++@end enumerate ++ ++@item ++The symbol table. This is an open-addressed hash table. The size of ++the hash table is always a power of 2. ++ ++Each slot in the hash table consists of a pair of @code{offset_type} ++values. The first value is the offset of the symbol's name in the ++constant pool. The second value is the offset of the CU vector in the ++constant pool. ++ ++If both values are 0, then this slot in the hash table is empty. This ++is ok because while 0 is a valid constant pool index, it cannot be a ++valid index for both a string and a CU vector. ++ ++The hash value for a table entry is computed by applying an ++iterative hash function to the symbol's name. Starting with an ++initial value of @code{r = 0}, each (unsigned) character @samp{c} in ++the string is incorporated into the hash using the formula depending on the ++index version: ++ ++@table @asis ++@item Version 4 ++The formula is @code{r = r * 67 + c - 113}. ++ ++@item Versions 5 to 7 ++The formula is @code{r = r * 67 + tolower (c) - 113}. ++@end table ++ ++The terminating @samp{\0} is not incorporated into the hash. ++ ++The step size used in the hash table is computed via ++@code{((hash * 17) & (size - 1)) | 1}, where @samp{hash} is the hash ++value, and @samp{size} is the size of the hash table. The step size ++is used to find the next candidate slot when handling a hash ++collision. ++ ++The names of C@t{++} symbols in the hash table are canonicalized. We ++don't currently have a simple description of the canonicalization ++algorithm; if you intend to create new index sections, you must read ++the code. ++ ++@item ++The constant pool. This is simply a bunch of bytes. It is organized ++so that alignment is correct: CU vectors are stored first, followed by ++strings. ++ ++A CU vector in the constant pool is a sequence of @code{offset_type} ++values. The first value is the number of CU indices in the vector. ++Each subsequent value is the index and symbol attributes of a CU in ++the CU list. This element in the hash table is used to indicate which ++CUs define the symbol and how the symbol is used. ++See below for the format of each CU index+attributes entry. ++ ++A string in the constant pool is zero-terminated. ++@end enumerate ++ ++Attributes were added to CU index values in @code{.gdb_index} version 7. ++If a symbol has multiple uses within a CU then there is one ++CU index+attributes value for each use. ++ ++The format of each CU index+attributes entry is as follows ++(bit 0 = LSB): ++ ++@table @asis ++ ++@item Bits 0-23 ++This is the index of the CU in the CU list. ++@item Bits 24-27 ++These bits are reserved for future purposes and must be zero. ++@item Bits 28-30 ++The kind of the symbol in the CU. ++ ++@table @asis ++@item 0 ++This value is reserved and should not be used. ++By reserving zero the full @code{offset_type} value is backwards compatible ++with previous versions of the index. ++@item 1 ++The symbol is a type. ++@item 2 ++The symbol is a variable or an enum value. ++@item 3 ++The symbol is a function. ++@item 4 ++Any other kind of symbol. ++@item 5,6,7 ++These values are reserved. ++@end table ++ ++@item Bit 31 ++This bit is zero if the value is global and one if it is static. ++ ++The determination of whether a symbol is global or static is complicated. ++The authorative reference is the file @file{dwarf2read.c} in ++@value{GDBN} sources. ++ ++@end table ++ ++This pseudo-code describes the computation of a symbol's kind and ++global/static attributes in the index. ++ ++@smallexample ++is_external = get_attribute (die, DW_AT_external); ++language = get_attribute (cu_die, DW_AT_language); ++switch (die->tag) ++ @{ ++ case DW_TAG_typedef: ++ case DW_TAG_base_type: ++ case DW_TAG_subrange_type: ++ kind = TYPE; ++ is_static = 1; ++ break; ++ case DW_TAG_enumerator: ++ kind = VARIABLE; ++ is_static = language != CPLUS; ++ break; ++ case DW_TAG_subprogram: ++ kind = FUNCTION; ++ is_static = ! (is_external || language == ADA); ++ break; ++ case DW_TAG_constant: ++ kind = VARIABLE; ++ is_static = ! is_external; ++ break; ++ case DW_TAG_variable: ++ kind = VARIABLE; ++ is_static = ! is_external; ++ break; ++ case DW_TAG_namespace: ++ kind = TYPE; ++ is_static = 0; ++ break; ++ case DW_TAG_class_type: ++ case DW_TAG_interface_type: ++ case DW_TAG_structure_type: ++ case DW_TAG_union_type: ++ case DW_TAG_enumeration_type: ++ kind = TYPE; ++ is_static = language != CPLUS; ++ break; ++ default: ++ assert (0); ++ @} ++@end smallexample ++ ++@node Man Pages ++@appendix Manual pages ++@cindex Man pages ++ ++@menu ++* gdb man:: The GNU Debugger man page ++* gdbserver man:: Remote Server for the GNU Debugger man page ++* gcore man:: Generate a core file of a running program ++* gdbinit man:: gdbinit scripts ++* gdb-add-index man:: Add index files to speed up GDB ++@end menu ++ ++@node gdb man ++@heading gdb man ++ ++@c man title gdb The GNU Debugger ++ ++@c man begin SYNOPSIS gdb ++gdb [@option{-help}] [@option{-nh}] [@option{-nx}] [@option{-q}] ++[@option{-batch}] [@option{-cd=}@var{dir}] [@option{-f}] ++[@option{-b}@w{ }@var{bps}] ++ [@option{-tty=}@var{dev}] [@option{-s} @var{symfile}] ++[@option{-e}@w{ }@var{prog}] [@option{-se}@w{ }@var{prog}] ++[@option{-c}@w{ }@var{core}] [@option{-p}@w{ }@var{procID}] ++ [@option{-x}@w{ }@var{cmds}] [@option{-d}@w{ }@var{dir}] ++[@var{prog}|@var{prog} @var{procID}|@var{prog} @var{core}] ++@c man end ++ ++@c man begin DESCRIPTION gdb ++The purpose of a debugger such as @value{GDBN} is to allow you to see what is ++going on ``inside'' another program while it executes -- or what another ++program was doing at the moment it crashed. ++ ++@value{GDBN} can do four main kinds of things (plus other things in support of ++these) to help you catch bugs in the act: ++ ++@itemize @bullet ++@item ++Start your program, specifying anything that might affect its behavior. ++ ++@item ++Make your program stop on specified conditions. ++ ++@item ++Examine what has happened, when your program has stopped. ++ ++@item ++Change things in your program, so you can experiment with correcting the ++effects of one bug and go on to learn about another. ++@end itemize ++ ++You can use @value{GDBN} to debug programs written in C, C@t{++}, Fortran and ++Modula-2. ++ ++@value{GDBN} is invoked with the shell command @code{gdb}. Once started, it reads ++commands from the terminal until you tell it to exit with the @value{GDBN} ++command @code{quit}. You can get online help from @value{GDBN} itself ++by using the command @code{help}. ++ ++You can run @code{gdb} with no arguments or options; but the most ++usual way to start @value{GDBN} is with one argument or two, specifying an ++executable program as the argument: ++ ++@smallexample ++gdb program ++@end smallexample ++ ++You can also start with both an executable program and a core file specified: ++ ++@smallexample ++gdb program core ++@end smallexample ++ ++You can, instead, specify a process ID as a second argument or use option ++@code{-p}, if you want to debug a running process: ++ ++@smallexample ++gdb program 1234 ++gdb -p 1234 ++@end smallexample ++ ++@noindent ++would attach @value{GDBN} to process @code{1234}. With option @option{-p} you ++can omit the @var{program} filename. ++ ++Here are some of the most frequently needed @value{GDBN} commands: ++ ++@c pod2man highlights the right hand side of the @item lines. ++@table @env ++@item break [@var{file}:]@var{function} ++Set a breakpoint at @var{function} (in @var{file}). ++ ++@item run [@var{arglist}] ++Start your program (with @var{arglist}, if specified). ++ ++@item bt ++Backtrace: display the program stack. ++ ++@item print @var{expr} ++Display the value of an expression. ++ ++@item c ++Continue running your program (after stopping, e.g. at a breakpoint). ++ ++@item next ++Execute next program line (after stopping); step @emph{over} any ++function calls in the line. ++ ++@item edit [@var{file}:]@var{function} ++look at the program line where it is presently stopped. ++ ++@item list [@var{file}:]@var{function} ++type the text of the program in the vicinity of where it is presently stopped. ++ ++@item step ++Execute next program line (after stopping); step @emph{into} any ++function calls in the line. ++ ++@item help [@var{name}] ++Show information about @value{GDBN} command @var{name}, or general information ++about using @value{GDBN}. ++ ++@item quit ++Exit from @value{GDBN}. ++@end table ++ ++@ifset man ++For full details on @value{GDBN}, ++see @cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++by Richard M. Stallman and Roland H. Pesch. The same text is available online ++as the @code{gdb} entry in the @code{info} program. ++@end ifset ++@c man end ++ ++@c man begin OPTIONS gdb ++Any arguments other than options specify an executable ++file and core file (or process ID); that is, the first argument ++encountered with no ++associated option flag is equivalent to a @option{-se} option, and the second, ++if any, is equivalent to a @option{-c} option if it's the name of a file. ++Many options have ++both long and short forms; both are shown here. The long forms are also ++recognized if you truncate them, so long as enough of the option is ++present to be unambiguous. (If you prefer, you can flag option ++arguments with @option{+} rather than @option{-}, though we illustrate the ++more usual convention.) ++ ++All the options and command line arguments you give are processed ++in sequential order. The order makes a difference when the @option{-x} ++option is used. ++ ++@table @env ++@item -help ++@itemx -h ++List all options, with brief explanations. ++ ++@item -symbols=@var{file} ++@itemx -s @var{file} ++Read symbol table from file @var{file}. ++ ++@item -write ++Enable writing into executable and core files. ++ ++@item -exec=@var{file} ++@itemx -e @var{file} ++Use file @var{file} as the executable file to execute when ++appropriate, and for examining pure data in conjunction with a core ++dump. ++ ++@item -se=@var{file} ++Read symbol table from file @var{file} and use it as the executable ++file. ++ ++@item -core=@var{file} ++@itemx -c @var{file} ++Use file @var{file} as a core dump to examine. ++ ++@item -command=@var{file} ++@itemx -x @var{file} ++Execute @value{GDBN} commands from file @var{file}. ++ ++@item -ex @var{command} ++Execute given @value{GDBN} @var{command}. ++ ++@item -directory=@var{directory} ++@itemx -d @var{directory} ++Add @var{directory} to the path to search for source files. ++ ++@item -nh ++Do not execute commands from @file{~/.gdbinit}. ++ ++@item -nx ++@itemx -n ++Do not execute commands from any @file{.gdbinit} initialization files. ++ ++@item -quiet ++@itemx -q ++``Quiet''. Do not print the introductory and copyright messages. These ++messages are also suppressed in batch mode. ++ ++@item -batch ++Run in batch mode. Exit with status @code{0} after processing all the command ++files specified with @option{-x} (and @file{.gdbinit}, if not inhibited). ++Exit with nonzero status if an error occurs in executing the @value{GDBN} ++commands in the command files. ++ ++Batch mode may be useful for running @value{GDBN} as a filter, for example to ++download and run a program on another computer; in order to make this ++more useful, the message ++ ++@smallexample ++Program exited normally. ++@end smallexample ++ ++@noindent ++(which is ordinarily issued whenever a program running under @value{GDBN} control ++terminates) is not issued when running in batch mode. ++ ++@item -cd=@var{directory} ++Run @value{GDBN} using @var{directory} as its working directory, ++instead of the current directory. ++ ++@item -fullname ++@itemx -f ++Emacs sets this option when it runs @value{GDBN} as a subprocess. It tells ++@value{GDBN} to output the full file name and line number in a standard, ++recognizable fashion each time a stack frame is displayed (which ++includes each time the program stops). This recognizable format looks ++like two @samp{\032} characters, followed by the file name, line number ++and character position separated by colons, and a newline. The ++Emacs-to-@value{GDBN} interface program uses the two @samp{\032} ++characters as a signal to display the source code for the frame. ++ ++@item -b @var{bps} ++Set the line speed (baud rate or bits per second) of any serial ++interface used by @value{GDBN} for remote debugging. ++ ++@item -tty=@var{device} ++Run using @var{device} for your program's standard input and output. ++@end table ++@c man end ++ ++@c man begin SEEALSO gdb ++@ifset man ++The full documentation for @value{GDBN} is maintained as a Texinfo manual. ++If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo ++documentation are properly installed at your site, the command ++ ++@smallexample ++info gdb ++@end smallexample ++ ++@noindent ++should give you access to the complete manual. ++ ++@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++Richard M. Stallman and Roland H. Pesch, July 1991. ++@end ifset ++@c man end ++ ++@node gdbserver man ++@heading gdbserver man ++ ++@c man title gdbserver Remote Server for the GNU Debugger ++@format ++@c man begin SYNOPSIS gdbserver ++gdbserver @var{comm} @var{prog} [@var{args}@dots{}] ++ ++gdbserver --attach @var{comm} @var{pid} ++ ++gdbserver --multi @var{comm} ++@c man end ++@end format ++ ++@c man begin DESCRIPTION gdbserver ++@command{gdbserver} is a program that allows you to run @value{GDBN} on a different machine ++than the one which is running the program being debugged. ++ ++@ifclear man ++@subheading Usage (server (target) side) ++@end ifclear ++@ifset man ++Usage (server (target) side): ++@end ifset ++ ++First, you need to have a copy of the program you want to debug put onto ++the target system. The program can be stripped to save space if needed, as ++@command{gdbserver} doesn't care about symbols. All symbol handling is taken care of by ++the @value{GDBN} running on the host system. ++ ++To use the server, you log on to the target system, and run the @command{gdbserver} ++program. You must tell it (a) how to communicate with @value{GDBN}, (b) the name of ++your program, and (c) its arguments. The general syntax is: ++ ++@smallexample ++target> gdbserver @var{comm} @var{program} [@var{args} ...] ++@end smallexample ++ ++For example, using a serial port, you might say: ++ ++@smallexample ++@ifset man ++@c @file would wrap it as F. ++target> gdbserver /dev/com1 emacs foo.txt ++@end ifset ++@ifclear man ++target> gdbserver @file{/dev/com1} emacs foo.txt ++@end ifclear ++@end smallexample ++ ++This tells @command{gdbserver} to debug emacs with an argument of foo.txt, and ++to communicate with @value{GDBN} via @file{/dev/com1}. @command{gdbserver} now ++waits patiently for the host @value{GDBN} to communicate with it. ++ ++To use a TCP connection, you could say: ++ ++@smallexample ++target> gdbserver host:2345 emacs foo.txt ++@end smallexample ++ ++This says pretty much the same thing as the last example, except that we are ++going to communicate with the @code{host} @value{GDBN} via TCP. The @code{host:2345} argument means ++that we are expecting to see a TCP connection from @code{host} to local TCP port ++2345. (Currently, the @code{host} part is ignored.) You can choose any number you ++want for the port number as long as it does not conflict with any existing TCP ++ports on the target system. This same port number must be used in the host ++@value{GDBN}s @code{target remote} command, which will be described shortly. Note that if ++you chose a port number that conflicts with another service, @command{gdbserver} will ++print an error message and exit. ++ ++@command{gdbserver} can also attach to running programs. ++This is accomplished via the @option{--attach} argument. The syntax is: ++ ++@smallexample ++target> gdbserver --attach @var{comm} @var{pid} ++@end smallexample ++ ++@var{pid} is the process ID of a currently running process. It isn't ++necessary to point @command{gdbserver} at a binary for the running process. ++ ++To start @code{gdbserver} without supplying an initial command to run ++or process ID to attach, use the @option{--multi} command line option. ++In such case you should connect using @kbd{target extended-remote} to start ++the program you want to debug. ++ ++@smallexample ++target> gdbserver --multi @var{comm} ++@end smallexample ++ ++@ifclear man ++@subheading Usage (host side) ++@end ifclear ++@ifset man ++Usage (host side): ++@end ifset ++ ++You need an unstripped copy of the target program on your host system, since ++@value{GDBN} needs to examine its symbol tables and such. Start up @value{GDBN} as you normally ++would, with the target program as the first argument. (You may need to use the ++@option{--baud} option if the serial line is running at anything except 9600 baud.) ++That is @code{gdb TARGET-PROG}, or @code{gdb --baud BAUD TARGET-PROG}. After that, the only ++new command you need to know about is @code{target remote} ++(or @code{target extended-remote}). Its argument is either ++a device name (usually a serial device, like @file{/dev/ttyb}), or a @code{HOST:PORT} ++descriptor. For example: ++ ++@smallexample ++@ifset man ++@c @file would wrap it as F. ++(gdb) target remote /dev/ttyb ++@end ifset ++@ifclear man ++(gdb) target remote @file{/dev/ttyb} ++@end ifclear ++@end smallexample ++ ++@noindent ++communicates with the server via serial line @file{/dev/ttyb}, and: ++ ++@smallexample ++(gdb) target remote the-target:2345 ++@end smallexample ++ ++@noindent ++communicates via a TCP connection to port 2345 on host `the-target', where ++you previously started up @command{gdbserver} with the same port number. Note that for ++TCP connections, you must start up @command{gdbserver} prior to using the `target remote' ++command, otherwise you may get an error that looks something like ++`Connection refused'. ++ ++@command{gdbserver} can also debug multiple inferiors at once, ++described in ++@ifset man ++the @value{GDBN} manual in node @code{Inferiors Connections and Programs} ++-- shell command @code{info -f gdb -n 'Inferiors Connections and Programs'}. ++@end ifset ++@ifclear man ++@ref{Inferiors Connections and Programs}. ++@end ifclear ++In such case use the @code{extended-remote} @value{GDBN} command variant: ++ ++@smallexample ++(gdb) target extended-remote the-target:2345 ++@end smallexample ++ ++The @command{gdbserver} option @option{--multi} may or may not be used in such ++case. ++@c man end ++ ++@c man begin OPTIONS gdbserver ++There are three different modes for invoking @command{gdbserver}: ++ ++@itemize @bullet ++ ++@item ++Debug a specific program specified by its program name: ++ ++@smallexample ++gdbserver @var{comm} @var{prog} [@var{args}@dots{}] ++@end smallexample ++ ++The @var{comm} parameter specifies how should the server communicate ++with @value{GDBN}; it is either a device name (to use a serial line), ++a TCP port number (@code{:1234}), or @code{-} or @code{stdio} to use ++stdin/stdout of @code{gdbserver}. Specify the name of the program to ++debug in @var{prog}. Any remaining arguments will be passed to the ++program verbatim. When the program exits, @value{GDBN} will close the ++connection, and @code{gdbserver} will exit. ++ ++@item ++Debug a specific program by specifying the process ID of a running ++program: ++ ++@smallexample ++gdbserver --attach @var{comm} @var{pid} ++@end smallexample ++ ++The @var{comm} parameter is as described above. Supply the process ID ++of a running program in @var{pid}; @value{GDBN} will do everything ++else. Like with the previous mode, when the process @var{pid} exits, ++@value{GDBN} will close the connection, and @code{gdbserver} will exit. ++ ++@item ++Multi-process mode -- debug more than one program/process: ++ ++@smallexample ++gdbserver --multi @var{comm} ++@end smallexample ++ ++In this mode, @value{GDBN} can instruct @command{gdbserver} which ++command(s) to run. Unlike the other 2 modes, @value{GDBN} will not ++close the connection when a process being debugged exits, so you can ++debug several processes in the same session. ++@end itemize ++ ++In each of the modes you may specify these options: ++ ++@table @env ++ ++@item --help ++List all options, with brief explanations. ++ ++@item --version ++This option causes @command{gdbserver} to print its version number and exit. ++ ++@item --attach ++@command{gdbserver} will attach to a running program. The syntax is: ++ ++@smallexample ++target> gdbserver --attach @var{comm} @var{pid} ++@end smallexample ++ ++@var{pid} is the process ID of a currently running process. It isn't ++necessary to point @command{gdbserver} at a binary for the running process. ++ ++@item --multi ++To start @code{gdbserver} without supplying an initial command to run ++or process ID to attach, use this command line option. ++Then you can connect using @kbd{target extended-remote} and start ++the program you want to debug. The syntax is: ++ ++@smallexample ++target> gdbserver --multi @var{comm} ++@end smallexample ++ ++@item --debug ++Instruct @code{gdbserver} to display extra status information about the debugging ++process. ++This option is intended for @code{gdbserver} development and for bug reports to ++the developers. ++ ++@item --remote-debug ++Instruct @code{gdbserver} to display remote protocol debug output. ++This option is intended for @code{gdbserver} development and for bug reports to ++the developers. ++ ++@item --debug-file=@var{filename} ++Instruct @code{gdbserver} to send any debug output to the given @var{filename}. ++This option is intended for @code{gdbserver} development and for bug reports to ++the developers. ++ ++@item --debug-format=option1@r{[},option2,...@r{]} ++Instruct @code{gdbserver} to include extra information in each line ++of debugging output. ++@xref{Other Command-Line Arguments for gdbserver}. ++ ++@item --wrapper ++Specify a wrapper to launch programs ++for debugging. The option should be followed by the name of the ++wrapper, then any command-line arguments to pass to the wrapper, then ++@kbd{--} indicating the end of the wrapper arguments. ++ ++@item --once ++By default, @command{gdbserver} keeps the listening TCP port open, so that ++additional connections are possible. However, if you start @code{gdbserver} ++with the @option{--once} option, it will stop listening for any further ++connection attempts after connecting to the first @value{GDBN} session. ++ ++@c --disable-packet is not documented for users. ++ ++@c --disable-randomization and --no-disable-randomization are superseded by ++@c QDisableRandomization. ++ ++@end table ++@c man end ++ ++@c man begin SEEALSO gdbserver ++@ifset man ++The full documentation for @value{GDBN} is maintained as a Texinfo manual. ++If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo ++documentation are properly installed at your site, the command ++ ++@smallexample ++info gdb ++@end smallexample ++ ++should give you access to the complete manual. ++ ++@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++Richard M. Stallman and Roland H. Pesch, July 1991. ++@end ifset ++@c man end ++ ++@node gcore man ++@heading gcore ++ ++@c man title gcore Generate a core file of a running program ++ ++@format ++@c man begin SYNOPSIS gcore ++gcore [-a] [-o @var{prefix}] @var{pid1} [@var{pid2}...@var{pidN}] ++@c man end ++@end format ++ ++@c man begin DESCRIPTION gcore ++Generate core dumps of one or more running programs with process IDs ++@var{pid1}, @var{pid2}, etc. A core file produced by @command{gcore} ++is equivalent to one produced by the kernel when the process crashes ++(and when @kbd{ulimit -c} was used to set up an appropriate core dump ++limit). However, unlike after a crash, after @command{gcore} finishes ++its job the program remains running without any change. ++@c man end ++ ++@c man begin OPTIONS gcore ++@table @env ++@item -a ++Dump all memory mappings. The actual effect of this option depends on ++the Operating System. On @sc{gnu}/Linux, it will disable ++@code{use-coredump-filter} (@pxref{set use-coredump-filter}) and ++enable @code{dump-excluded-mappings} (@pxref{set ++dump-excluded-mappings}). ++ ++@item -o @var{prefix} ++The optional argument @var{prefix} specifies the prefix to be used ++when composing the file names of the core dumps. The file name is ++composed as @file{@var{prefix}.@var{pid}}, where @var{pid} is the ++process ID of the running program being analyzed by @command{gcore}. ++If not specified, @var{prefix} defaults to @var{gcore}. ++@end table ++@c man end ++ ++@c man begin SEEALSO gcore ++@ifset man ++The full documentation for @value{GDBN} is maintained as a Texinfo manual. ++If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo ++documentation are properly installed at your site, the command ++ ++@smallexample ++info gdb ++@end smallexample ++ ++@noindent ++should give you access to the complete manual. ++ ++@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++Richard M. Stallman and Roland H. Pesch, July 1991. ++@end ifset ++@c man end ++ ++@node gdbinit man ++@heading gdbinit ++ ++@c man title gdbinit GDB initialization scripts ++ ++@format ++@c man begin SYNOPSIS gdbinit ++@ifset SYSTEM_GDBINIT ++@value{SYSTEM_GDBINIT} ++@end ifset ++ ++@ifset SYSTEM_GDBINIT_DIR ++@value{SYSTEM_GDBINIT_DIR}/* ++@end ifset ++ ++~/.gdbinit ++ ++./.gdbinit ++@c man end ++@end format ++ ++@c man begin DESCRIPTION gdbinit ++These files contain @value{GDBN} commands to automatically execute during ++@value{GDBN} startup. The lines of contents are canned sequences of commands, ++described in ++@ifset man ++the @value{GDBN} manual in node @code{Sequences} ++-- shell command @code{info -f gdb -n Sequences}. ++@end ifset ++@ifclear man ++@ref{Sequences}. ++@end ifclear ++ ++Please read more in ++@ifset man ++the @value{GDBN} manual in node @code{Startup} ++-- shell command @code{info -f gdb -n Startup}. ++@end ifset ++@ifclear man ++@ref{Startup}. ++@end ifclear ++ ++@table @env ++@ifset SYSTEM_GDBINIT ++@item @value{SYSTEM_GDBINIT} ++@end ifset ++@ifclear SYSTEM_GDBINIT ++@item (not enabled with @code{--with-system-gdbinit} during compilation) ++@end ifclear ++System-wide initialization file. It is executed unless user specified ++@value{GDBN} option @code{-nx} or @code{-n}. ++See more in ++@ifset man ++the @value{GDBN} manual in node @code{System-wide configuration} ++-- shell command @code{info -f gdb -n 'System-wide configuration'}. ++@end ifset ++@ifset SYSTEM_GDBINIT_DIR ++@item @value{SYSTEM_GDBINIT_DIR} ++@end ifset ++@ifclear SYSTEM_GDBINIT_DIR ++@item (not enabled with @code{--with-system-gdbinit-dir} during compilation) ++@end ifclear ++System-wide initialization directory. All files in this directory are ++executed on startup unless user specified @value{GDBN} option @code{-nx} or ++@code{-n}, as long as they have a recognized file extension. ++See more in ++@ifset man ++the @value{GDBN} manual in node @code{System-wide configuration} ++-- shell command @code{info -f gdb -n 'System-wide configuration'}. ++@end ifset ++@ifclear man ++@ref{System-wide configuration}. ++@end ifclear ++ ++@item ~/.gdbinit ++User initialization file. It is executed unless user specified ++@value{GDBN} options @code{-nx}, @code{-n} or @code{-nh}. ++ ++@item ./.gdbinit ++Initialization file for current directory. It may need to be enabled with ++@value{GDBN} security command @code{set auto-load local-gdbinit}. ++See more in ++@ifset man ++the @value{GDBN} manual in node @code{Init File in the Current Directory} ++-- shell command @code{info -f gdb -n 'Init File in the Current Directory'}. ++@end ifset ++@ifclear man ++@ref{Init File in the Current Directory}. ++@end ifclear ++@end table ++@c man end ++ ++@c man begin SEEALSO gdbinit ++@ifset man ++gdb(1), @code{info -f gdb -n Startup} ++ ++The full documentation for @value{GDBN} is maintained as a Texinfo manual. ++If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo ++documentation are properly installed at your site, the command ++ ++@smallexample ++info gdb ++@end smallexample ++ ++should give you access to the complete manual. ++ ++@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++Richard M. Stallman and Roland H. Pesch, July 1991. ++@end ifset ++@c man end ++ ++@node gdb-add-index man ++@heading gdb-add-index ++@pindex gdb-add-index ++@anchor{gdb-add-index} ++ ++@c man title gdb-add-index Add index files to speed up GDB ++ ++@c man begin SYNOPSIS gdb-add-index ++gdb-add-index @var{filename} ++@c man end ++ ++@c man begin DESCRIPTION gdb-add-index ++When @value{GDBN} finds a symbol file, it scans the symbols in the ++file in order to construct an internal symbol table. This lets most ++@value{GDBN} operations work quickly--at the cost of a delay early on. ++For large programs, this delay can be quite lengthy, so @value{GDBN} ++provides a way to build an index, which speeds up startup. ++ ++To determine whether a file contains such an index, use the command ++@kbd{readelf -S filename}: the index is stored in a section named ++@code{.gdb_index}. The index file can only be produced on systems ++which use ELF binaries and DWARF debug information (i.e., sections ++named @code{.debug_*}). ++ ++@command{gdb-add-index} uses @value{GDBN} and @command{objdump} found ++in the @env{PATH} environment variable. If you want to use different ++versions of these programs, you can specify them through the ++@env{GDB} and @env{OBJDUMP} environment variables. ++ ++See more in ++@ifset man ++the @value{GDBN} manual in node @code{Index Files} ++-- shell command @kbd{info -f gdb -n "Index Files"}. ++@end ifset ++@ifclear man ++@ref{Index Files}. ++@end ifclear ++@c man end ++ ++@c man begin SEEALSO gdb-add-index ++@ifset man ++The full documentation for @value{GDBN} is maintained as a Texinfo manual. ++If the @code{info} and @code{gdb} programs and @value{GDBN}'s Texinfo ++documentation are properly installed at your site, the command ++ ++@smallexample ++info gdb ++@end smallexample ++ ++should give you access to the complete manual. ++ ++@cite{Using GDB: A Guide to the GNU Source-Level Debugger}, ++Richard M. Stallman and Roland H. Pesch, July 1991. ++@end ifset ++@c man end ++ ++@include gpl.texi ++ ++@node GNU Free Documentation License ++@appendix GNU Free Documentation License ++@include fdl.texi ++ ++@node Concept Index ++@unnumbered Concept Index ++ ++@printindex cp ++ ++@node Command and Variable Index ++@unnumbered Command, Variable, and Function Index ++ ++@printindex fn ++ ++@tex ++% I think something like @@colophon should be in texinfo. In the ++% meantime: ++\long\def\colophon{\hbox to0pt{}\vfill ++\centerline{The body of this manual is set in} ++\centerline{\fontname\tenrm,} ++\centerline{with headings in {\bf\fontname\tenbf}} ++\centerline{and examples in {\tt\fontname\tentt}.} ++\centerline{{\it\fontname\tenit\/},} ++\centerline{{\bf\fontname\tenbf}, and} ++\centerline{{\sl\fontname\tensl\/}} ++\centerline{are used for emphasis.}\vfill} ++\page\colophon ++% Blame: doc@@cygnus.com, 1991. ++@end tex ++ ++@bye +diff -Nuar gdb-10.2/gdb/gdbtypes.c gdb-10.2/gdb/gdbtypes.c +--- gdb-10.2/gdb/gdbtypes.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/gdbtypes.c 2025-04-16 17:06:41.932086800 +0800 +@@ -5492,27 +5492,25 @@ + } + + /* Make a copy of the given TYPE, except that the pointer & reference +- types are not preserved. +- +- This function assumes that the given type has an associated objfile. +- This objfile is used to allocate the new type. */ ++ types are not preserved. */ + + struct type * + copy_type (const struct type *type) + { +- struct type *new_type; ++ struct type *new_type = alloc_type_copy (type); + +- gdb_assert (TYPE_OBJFILE_OWNED (type)); +- +- new_type = alloc_type_copy (type); + TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); + TYPE_LENGTH (new_type) = TYPE_LENGTH (type); + memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type), + sizeof (struct main_type)); + if (type->main_type->dyn_prop_list != NULL) +- new_type->main_type->dyn_prop_list +- = copy_dynamic_prop_list (&TYPE_OBJFILE (type) -> objfile_obstack, +- type->main_type->dyn_prop_list); ++ { ++ struct obstack *storage = (TYPE_OBJFILE_OWNED (type) ++ ? &TYPE_OBJFILE (type)->objfile_obstack ++ : gdbarch_obstack (TYPE_OWNER (type).gdbarch)); ++ new_type->main_type->dyn_prop_list ++ = copy_dynamic_prop_list (storage, type->main_type->dyn_prop_list); ++ } + + return new_type; + } +diff -Nuar gdb-10.2/gdb/linux-waitpid.c gdb-10.2/gdb/linux-waitpid.c +--- gdb-10.2/gdb/linux-waitpid.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/linux-waitpid.c 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,74 @@ ++/* Wrapper implementation for waitpid for GNU/Linux (LWP layer). ++ ++ Copyright (C) 2001-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "gdbsupport/common-defs.h" ++ ++#ifdef GDBSERVER ++/* FIXME: server.h is required for the definition of debug_threads ++ which is used in the gdbserver-specific debug printing in ++ linux_debug. This code should be made available to GDB also, ++ but the lack of a suitable flag to enable it prevents this. */ ++#include "server.h" ++#endif ++ ++#include "linux-nat.h" ++#include "linux-waitpid.h" ++#include "gdbsupport/gdb_wait.h" ++ ++/* Convert wait status STATUS to a string. Used for printing debug ++ messages only. */ ++ ++char * ++status_to_str (int status) ++{ ++ static char buf[64]; ++ ++ if (WIFSTOPPED (status)) ++ { ++ if (WSTOPSIG (status) == SYSCALL_SIGTRAP) ++ snprintf (buf, sizeof (buf), "%s (stopped at syscall)", ++ strsignal (SIGTRAP)); ++ else ++ snprintf (buf, sizeof (buf), "%s (stopped)", ++ strsignal (WSTOPSIG (status))); ++ } ++ else if (WIFSIGNALED (status)) ++ snprintf (buf, sizeof (buf), "%s (terminated)", ++ strsignal (WTERMSIG (status))); ++ else ++ snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status)); ++ ++ return buf; ++} ++ ++/* See linux-waitpid.h. */ ++ ++int ++my_waitpid (int pid, int *status, int flags) ++{ ++ int ret; ++ ++ do ++ { ++ ret = waitpid (pid, status, flags); ++ } ++ while (ret == -1 && errno == EINTR); ++ ++ return ret; ++} +diff -Nuar gdb-10.2/gdb/linux-waitpid.h gdb-10.2/gdb/linux-waitpid.h +--- gdb-10.2/gdb/linux-waitpid.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/linux-waitpid.h 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,31 @@ ++/* Wrapper for waitpid for GNU/Linux (LWP layer). ++ ++ Copyright (C) 2000-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef NAT_LINUX_WAITPID_H ++#define NAT_LINUX_WAITPID_H ++ ++#define MAXCGS 4//sw_64-linux-watch.c ++/* Wrapper function for waitpid which handles EINTR. */ ++extern int my_waitpid (int pid, int *status, int flags); ++ ++/* Convert wait status STATUS to a string. Used for printing debug ++ messages only. */ ++extern char *status_to_str (int status); ++ ++#endif /* NAT_LINUX_WAITPID_H */ +diff -Nuar gdb-10.2/gdb/main.c gdb-10.2/gdb/main.c +--- gdb-10.2/gdb/main.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/main.c 2025-04-16 17:06:41.902086800 +0800 +@@ -392,6 +392,14 @@ + return; + } + ++#ifdef CRASH_MERGE ++extern "C" void update_gdb_hooks(void); ++extern "C" void main_loop(void); ++extern "C" unsigned long crash_get_kaslr_offset(void); ++extern "C" int console(const char *, ...); ++void crash_target_init (void); ++#endif ++ + /* Call command_loop. */ + + /* Prevent inlining this function for the benefit of GDB's selftests +@@ -925,7 +933,11 @@ + } + } + ++#ifdef CRASH_MERGE ++ save_original_signals_state (1); ++#else + save_original_signals_state (quiet); ++#endif + + /* Try to set up an alternate signal stack for SIGSEGV handlers. */ + gdb::alternate_signal_stack signal_stack; +@@ -999,7 +1011,7 @@ + { + print_gdb_version (gdb_stdout, false); + wrap_here (""); +- printf_filtered ("\n"); ++ printf_filtered ("\n\n"); + exit (0); + } + +@@ -1038,6 +1050,10 @@ + look at things by now. Initialize the default interpreter. */ + set_top_level_interpreter (interpreter_p); + ++#ifdef CRASH_MERGE ++ update_gdb_hooks(); ++#endif ++ + /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets + GDB retain the old MI1 interpreter startup behavior. Output the + copyright message after the interpreter is installed when it is +@@ -1066,7 +1082,11 @@ + if (!system_gdbinit.empty () && !inhibit_gdbinit) + { + for (const std::string &file : system_gdbinit) ++#ifdef CRASH_MERGE ++ ret = catch_command_errors (source_script, file.c_str (), -1); ++#else + ret = catch_command_errors (source_script, file.c_str (), 0); ++#endif + } + + /* Read and execute $HOME/.gdbinit file, if it exists. This is done +@@ -1075,7 +1095,11 @@ + debugging or what directory you are in. */ + + if (!home_gdbinit.empty () && !inhibit_gdbinit && !inhibit_home_gdbinit) ++#ifdef CRASH_MERGE ++ ret = catch_command_errors (source_script, home_gdbinit.c_str (), -1); ++#else + ret = catch_command_errors (source_script, home_gdbinit.c_str (), 0); ++#endif + + /* Process '-ix' and '-iex' options early. */ + for (i = 0; i < cmdarg_vec.size (); i++) +@@ -1121,7 +1145,11 @@ + !batch_flag); + if (ret != 0) + ret = catch_command_errors (symbol_file_add_main_adapter, ++#ifdef CRASH_MERGE ++ symarg, 0); ++#else + symarg, !batch_flag); ++#endif + } + else + { +@@ -1191,7 +1219,11 @@ + { + auto_load_local_gdbinit_loaded = 1; + ++#ifdef CRASH_MERGE ++ ret = catch_command_errors (source_script, local_gdbinit.c_str (), -1); ++#else + ret = catch_command_errors (source_script, local_gdbinit.c_str (), 0); ++#endif + } + } + +@@ -1242,6 +1274,16 @@ + + captured_main_1 (context); + ++#ifdef CRASH_MERGE ++ /* Relocate the vmlinux. */ ++ objfile_rebase (symfile_objfile, crash_get_kaslr_offset()); ++ ++ crash_target_init(); ++ ++ /* Back to crash. */ ++ main_loop(); ++#endif ++ + /* NOTE: cagney/1999-11-07: There is probably no reason for not + moving this loop and the code found in captured_command_loop() + into the command_loop() proper. The main thing holding back that +@@ -1256,6 +1298,9 @@ + { + exception_print (gdb_stderr, ex); + } ++#ifdef CRASH_MERGE ++ console("\n"); ++#endif + } + /* No exit -- exit is through quit_command. */ + } +@@ -1277,6 +1322,22 @@ + return 1; + } + ++#ifdef CRASH_MERGE ++/* ++ * NOTE: adapted from gdb.c, which is no longer built in; changed name of ++ * original main() to gdb_main_entry() for use as crash entry point ++ */ ++int ++gdb_main_entry (int argc, char **argv) ++{ ++ struct captured_main_args args; ++ memset (&args, 0, sizeof args); ++ args.argc = argc; ++ args.argv = argv; ++ args.interpreter_p = INTERP_CONSOLE; ++ return gdb_main (&args); ++} ++#endif + + /* Don't use *_filtered for printing help. We don't want to prompt + for continue no matter how small the screen or how much we're going +diff -Nuar gdb-10.2/gdb/Makefile.in gdb-10.2/gdb/Makefile.in +--- gdb-10.2/gdb/Makefile.in 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/Makefile.in 2025-04-16 17:06:51.932086800 +0800 +@@ -1,4 +1,4 @@ +-# Copyright (C) 1989-2021 Free Software Foundation, Inc. ++# Copyright (C) 1989-2020 Free Software Foundation, Inc. + + # This file is part of GDB. + +@@ -571,7 +571,7 @@ + # It is also possible that you will need to add -I/usr/include/sys if + # your system doesn't have fcntl.h in /usr/include (which is where it + # should be according to Posix). +-DEFS = @DEFS@ ++DEFS = -DCRASH_MERGE @DEFS@ + GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/config \ + -DLOCALEDIR="\"$(localedir)\"" $(DEFS) + +@@ -676,6 +676,14 @@ + alpha-nbsd-tdep.o \ + alpha-obsd-tdep.o \ + alpha-tdep.o \ ++ sw_64-bsd-tdep.o \ ++ sw_64-bsd-nat.o \ ++ sw_64-linux-tdep.o \ ++ sw_64-mdebug-tdep.o \ ++ sw_64-nbsd-tdep.o \ ++ sw_64-obsd-tdep.o \ ++ sw_64-tdep.o \ ++ sw_64-linux-nat.o \ + amd64-darwin-tdep.o \ + amd64-dicos-tdep.o \ + amd64-fbsd-tdep.o \ +@@ -1135,6 +1143,7 @@ + symmisc.c \ + symtab.c \ + target.c \ ++ ../../crash_target.c \ + target-connection.c \ + target-dcache.c \ + target-descriptions.c \ +@@ -1211,6 +1220,9 @@ + addrmap.h \ + alpha-bsd-tdep.h \ + alpha-tdep.h \ ++ sw_64-bsd-tdep.h \ ++ sw_64-tdep.h \ ++ nat/sw_64-linux-watch.h \ + amd64-darwin-tdep.h \ + amd64-linux-tdep.h \ + amd64-nat.h \ +@@ -1564,7 +1576,7 @@ + $(SUBDIR_TARGET_OBS) \ + $(SUBDIR_GCC_COMPILE_OBS) + +-SUBDIRS = doc @subdirs@ data-directory ++SUBDIRS = build_no_subdirs + CLEANDIRS = $(SUBDIRS) + + # List of subdirectories in the build tree that must exist. +@@ -1606,8 +1618,8 @@ + # Flags needed to compile Python code + PYTHON_CFLAGS = @PYTHON_CFLAGS@ + +-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb +- @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do ++all: gdb$(EXEEXT) gdb-gdb.py gdb-gdb.gdb ++ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do + + # Rule for compiling .c files in the top-level gdb directory. + # The order-only dependencies ensure that we create the build subdirectories. +@@ -1864,9 +1876,10 @@ + # Removing the old gdb first works better if it is running, at least on SunOS. + gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS) + $(SILENCE) rm -f gdb$(EXEEXT) ++ @$(MAKE) -C ../.. GDB_FLAGS=-DGDB_10_2 library + $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ +- -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \ +- $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) ++ -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \ ++ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs) + ifneq ($(CODESIGN_CERT),) + $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT) + endif +@@ -2122,6 +2135,14 @@ + alpha-nbsd-tdep.c \ + alpha-obsd-tdep.c \ + alpha-tdep.c \ ++ sw_64-bsd-nat.c \ ++ sw_64-bsd-tdep.c \ ++ sw_64-linux-nat.c \ ++ sw_64-linux-tdep.c \ ++ sw_64-mdebug-tdep.c \ ++ sw_64-nbsd-tdep.c \ ++ sw_64-obsd-tdep.c \ ++ sw_64-tdep.c \ + amd64-bsd-nat.c \ + amd64-darwin-tdep.c \ + amd64-dicos-tdep.c \ +@@ -2530,9 +2551,9 @@ + # into place if the compile succeeds. We need this because gcc does + # not atomically write the dependency output file. + override COMPILE.post = -c -o $@ -MT $@ -MMD -MP \ +- -MF $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo +-override POSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo \ +- $(@D)/$(DEPDIR)/$(basename $(@F)).Po ++ -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo ++override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo \ ++ $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Po + else + override COMPILE.pre = source='$<' object='$@' libtool=no \ + DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \ +diff -Nuar gdb-10.2/gdb/Makefile.in.orig gdb-10.2/gdb/Makefile.in.orig +--- gdb-10.2/gdb/Makefile.in.orig 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/Makefile.in.orig 2025-04-16 17:06:41.922086800 +0800 +@@ -0,0 +1,2571 @@ ++# Copyright (C) 1989-2021 Free Software Foundation, Inc. ++ ++# This file is part of GDB. ++ ++# 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 . ++ ++# Please keep lists in this file sorted alphabetically, with one item per line. ++# Here are the general guidelines for ordering files and directories: ++# ++# - Files come before directories. ++# - The extensions are not taken into account when comparing filenames, except ++# if the filenames are otherwise equal. ++# - A filename that is a prefix of another one comes before. ++# - Underscores and dashes are treated equally, and come before alphanumeric ++# characters. ++# ++# For example: ++# ++# SOME_FILES = \ ++# foo.c \ ++# foo.h \ ++# foo-bar.c \ ++# foobar.c \ ++# foo/bar.c ++ ++prefix = @prefix@ ++exec_prefix = @exec_prefix@ ++ ++host_alias = @host_alias@ ++target_alias = @target_alias@ ++program_transform_name = @program_transform_name@ ++bindir = @bindir@ ++libdir = @libdir@ ++tooldir = $(libdir)/$(target_alias) ++ ++datadir = @datadir@ ++localedir = @localedir@ ++mandir = @mandir@ ++man1dir = $(mandir)/man1 ++man2dir = $(mandir)/man2 ++man3dir = $(mandir)/man3 ++man4dir = $(mandir)/man4 ++man5dir = $(mandir)/man5 ++man6dir = $(mandir)/man6 ++man7dir = $(mandir)/man7 ++man8dir = $(mandir)/man8 ++man9dir = $(mandir)/man9 ++infodir = @infodir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++htmldir = @htmldir@ ++pdfdir = @pdfdir@ ++includedir = @includedir@ ++ ++install_sh = @install_sh@ ++ ++# This can be referenced by `LIBINTL' as computed by ++# ZW_GNU_GETTEXT_SISTER_DIR. ++top_builddir = . ++ ++SHELL = @SHELL@ ++EXEEXT = @EXEEXT@ ++ ++AWK = @AWK@ ++LN_S = @LN_S@ ++ ++INSTALL = @INSTALL@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++INSTALL_DATA = @INSTALL_DATA@ ++ ++DESTDIR = ++ ++AR = @AR@ ++AR_FLAGS = qv ++RANLIB = @RANLIB@ ++DLLTOOL = @DLLTOOL@ ++WINDRES = @WINDRES@ ++MIG = @MIG@ ++STRIP = @STRIP@ ++ ++XGETTEXT = @XGETTEXT@ ++GMSGFMT = @GMSGFMT@ ++MSGMERGE = msgmerge ++ ++PACKAGE = @PACKAGE@ ++CATALOGS = @CATALOGS@ ++ ++CC = @CC@ ++CXX = @CXX@ ++CXX_DIALECT = @CXX_DIALECT@ ++ ++# Dependency tracking information. ++DEPMODE = @CCDEPMODE@ ++DEPDIR = @DEPDIR@ ++depcomp = $(SHELL) $(srcdir)/../depcomp ++ ++# Directory containing source files. ++srcdir = @srcdir@ ++VPATH = @srcdir@ ++top_srcdir = @top_srcdir@ ++ ++include $(srcdir)/silent-rules.mk ++ ++# Note that these are overridden by GNU make-specific code below if ++# GNU make is used. The overrides implement dependency tracking. ++COMPILE.pre = $(CXX) -x c++ $(CXX_DIALECT) ++COMPILE.post = -c -o $@ ++COMPILE = $(ECHO_CXX) $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) ++POSTCOMPILE = @true ++ ++YACC = @YACC@ ++ ++# This is used to rebuild ada-lex.c from ada-lex.l. If the program is ++# not defined, but ada-lex.c is present, compilation will continue, ++# possibly with a warning. ++FLEX = flex ++ ++YLWRAP = $(srcdir)/../ylwrap ++ ++# where to find makeinfo, preferably one designed for texinfo-2 ++MAKEINFO = @MAKEINFO@ ++MAKEINFOFLAGS = @MAKEINFOFLAGS@ ++MAKEINFO_EXTRA_FLAGS = @MAKEINFO_EXTRA_FLAGS@ ++MAKEINFO_CMD = $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFO_EXTRA_FLAGS) ++ ++MAKEHTML = $(MAKEINFO_CMD) --html ++MAKEHTMLFLAGS = ++ ++# Set this up with gcc if you have gnu ld and the loader will print out ++# line numbers for undefined references. ++#CC_LD = g++ -static ++CC_LD = $(CXX) $(CXX_DIALECT) ++ ++# Where is our "include" directory? Typically $(srcdir)/../include. ++# This is essentially the header file directory for the library ++# routines in libiberty. ++INCLUDE_DIR = $(srcdir)/../include ++INCLUDE_CFLAGS = -I$(INCLUDE_DIR) ++ ++# Where is the "-liberty" library? Typically in ../libiberty. ++LIBIBERTY = ../libiberty/libiberty.a ++ ++# Where is the CTF library? Typically in ../libctf. ++LIBCTF = @LIBCTF@ ++CTF_DEPS = @CTF_DEPS@ ++ ++# Where is the BFD library? Typically in ../bfd. ++BFD_DIR = ../bfd ++BFD = $(BFD_DIR)/libbfd.a ++BFD_SRC = $(srcdir)/$(BFD_DIR) ++BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) ++ ++# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is ++# -I../zlib, unless we were configured with --with-system-zlib, in which ++# case both are empty. ++ZLIB = @zlibdir@ -lz ++ZLIBINC = @zlibinc@ ++ ++# Where is the decnumber library? Typically in ../libdecnumber. ++LIBDECNUMBER_DIR = ../libdecnumber ++LIBDECNUMBER = $(LIBDECNUMBER_DIR)/libdecnumber.a ++LIBDECNUMBER_SRC = $(srcdir)/$(LIBDECNUMBER_DIR) ++LIBDECNUMBER_CFLAGS = -I$(LIBDECNUMBER_DIR) -I$(LIBDECNUMBER_SRC) ++ ++# Where is the READLINE library? Typically in ../readline/readline. ++READLINE_DIR = ../readline/readline ++READLINE_SRC = $(srcdir)/$(READLINE_DIR) ++READLINE = @READLINE@ ++READLINE_DEPS = @READLINE_DEPS@ ++READLINE_CFLAGS = @READLINE_CFLAGS@ ++ ++# Where is expat? This will be empty if expat was not available. ++LIBEXPAT = @LIBEXPAT@ ++ ++# Where is lzma? This will be empty if lzma was not available. ++LIBLZMA = @LIBLZMA@ ++ ++# Where is libbabeltrace? This will be empty if libbabeltrace was not ++# available. ++LIBBABELTRACE = @LIBBABELTRACE@ ++ ++# Where is libxxhash? This will be empty if libxxhash was not ++# available. ++LIBXXHASH = @LIBXXHASH@ ++ ++# Where is libipt? This will be empty if libipt was not available. ++LIBIPT = @LIBIPT@ ++ ++# Where is libmpfr? This will be empty if libmpfr was not available. ++LIBMPFR = @LIBMPFR@ ++ ++# GNU source highlight library. ++SRCHIGH_LIBS = @SRCHIGH_LIBS@ ++SRCHIGH_CFLAGS = @SRCHIGH_CFLAGS@ ++ ++WARN_CFLAGS = @WARN_CFLAGS@ ++WERROR_CFLAGS = @WERROR_CFLAGS@ ++GDB_WARN_CFLAGS = $(WARN_CFLAGS) ++GDB_WERROR_CFLAGS = $(WERROR_CFLAGS) ++ ++PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ ++PTHREAD_LIBS = @PTHREAD_LIBS@ ++ ++DEBUGINFOD_CFLAGS = @DEBUGINFOD_CFLAGS@ ++DEBUGINFOD_LIBS = @DEBUGINFOD_LIBS@ ++ ++RDYNAMIC = @RDYNAMIC@ ++ ++# Where is the INTL library? Typically in ../intl. ++INTL = @LIBINTL@ ++INTL_DEPS = @LIBINTL_DEP@ ++INTL_CFLAGS = @INCINTL@ ++ ++# Where is the ICONV library? This will be empty if in libc or not available. ++LIBICONV = @LIBICONV@ ++ ++# Did the user give us a --with-gdb-datadir option? ++GDB_DATADIR = @GDB_DATADIR@ ++ ++# Code signing. ++CODESIGN = codesign ++CODESIGN_CERT = @CODESIGN_CERT@ ++ ++# Flags to pass to gdb when invoked with "make run". ++GDBFLAGS = ++ ++# Helper code from gnulib. ++GNULIB_BUILDDIR = ../gnulib ++LIBGNU = $(GNULIB_BUILDDIR)/import/libgnu.a ++INCGNU = -I$(srcdir)/../gnulib/import -I$(GNULIB_BUILDDIR)/import ++ ++SUPPORT = ../gdbsupport ++LIBSUPPORT = $(SUPPORT)/libgdbsupport.a ++INCSUPPORT = -I$(srcdir)/.. -I.. ++ ++# ++# CLI sub directory definitons ++# ++SUBDIR_CLI_SRCS = \ ++ cli/cli-cmds.c \ ++ cli/cli-decode.c \ ++ cli/cli-dump.c \ ++ cli/cli-interp.c \ ++ cli/cli-logging.c \ ++ cli/cli-option.c \ ++ cli/cli-script.c \ ++ cli/cli-setshow.c \ ++ cli/cli-style.c \ ++ cli/cli-utils.c ++ ++SUBDIR_CLI_OBS = $(patsubst %.c,%.o,$(SUBDIR_CLI_SRCS)) ++ ++# ++# MI sub directory definitons ++# ++SUBDIR_MI_SRCS = \ ++ mi/mi-cmd-break.c \ ++ mi/mi-cmd-catch.c \ ++ mi/mi-cmd-disas.c \ ++ mi/mi-cmd-env.c \ ++ mi/mi-cmd-file.c \ ++ mi/mi-cmd-info.c \ ++ mi/mi-cmd-stack.c \ ++ mi/mi-cmd-target.c \ ++ mi/mi-cmd-var.c \ ++ mi/mi-cmds.c \ ++ mi/mi-console.c \ ++ mi/mi-getopt.c \ ++ mi/mi-interp.c \ ++ mi/mi-main.c \ ++ mi/mi-out.c \ ++ mi/mi-parse.c \ ++ mi/mi-symbol-cmds.c ++ ++SUBDIR_MI_OBS = $(patsubst %.c,%.o,$(SUBDIR_MI_SRCS)) ++ ++SUBDIR_MI_DEPS = ++SUBDIR_MI_LDFLAGS = ++SUBDIR_MI_CFLAGS = ++ ++# ++# TUI sub directory definitions ++# ++SUBDIR_TUI_SRCS = \ ++ tui/tui.c \ ++ tui/tui-command.c \ ++ tui/tui-data.c \ ++ tui/tui-disasm.c \ ++ tui/tui-file.c \ ++ tui/tui-hooks.c \ ++ tui/tui-interp.c \ ++ tui/tui-io.c \ ++ tui/tui-layout.c \ ++ tui/tui-out.c \ ++ tui/tui-regs.c \ ++ tui/tui-source.c \ ++ tui/tui-stack.c \ ++ tui/tui-win.c \ ++ tui/tui-wingeneral.c \ ++ tui/tui-winsource.c ++ ++SUBDIR_TUI_OBS = $(patsubst %.c,%.o,$(SUBDIR_TUI_SRCS)) ++ ++SUBDIR_TUI_DEPS = ++SUBDIR_TUI_LDFLAGS = ++SUBDIR_TUI_CFLAGS = -DTUI=1 ++ ++# ++# GCC Compile support sub-directory definitions ++# ++SUBDIR_GCC_COMPILE_SRCS = \ ++ compile/compile.c \ ++ compile/compile-c-support.c \ ++ compile/compile-c-symbols.c \ ++ compile/compile-c-types.c \ ++ compile/compile-cplus-symbols.c \ ++ compile/compile-cplus-types.c \ ++ compile/compile-loc2c.c \ ++ compile/compile-object-load.c \ ++ compile/compile-object-run.c ++ ++SUBDIR_GCC_COMPILE_OBS = $(patsubst %.c,%.o,$(filter %.c,$(SUBDIR_GCC_COMPILE_SRCS))) ++ ++# ++# Guile sub directory definitons for guile support. ++# ++SUBDIR_GUILE_SRCS = \ ++ guile/guile.c \ ++ guile/scm-arch.c \ ++ guile/scm-auto-load.c \ ++ guile/scm-block.c \ ++ guile/scm-breakpoint.c \ ++ guile/scm-cmd.c \ ++ guile/scm-disasm.c \ ++ guile/scm-exception.c \ ++ guile/scm-frame.c \ ++ guile/scm-gsmob.c \ ++ guile/scm-iterator.c \ ++ guile/scm-lazy-string.c \ ++ guile/scm-math.c \ ++ guile/scm-objfile.c \ ++ guile/scm-param.c \ ++ guile/scm-ports.c \ ++ guile/scm-pretty-print.c \ ++ guile/scm-progspace.c \ ++ guile/scm-safe-call.c \ ++ guile/scm-string.c \ ++ guile/scm-symbol.c \ ++ guile/scm-symtab.c \ ++ guile/scm-type.c \ ++ guile/scm-utils.c \ ++ guile/scm-value.c ++ ++SUBDIR_GUILE_OBS = $(patsubst %.c,%.o,$(SUBDIR_GUILE_SRCS)) ++ ++SUBDIR_GUILE_DEPS = ++SUBDIR_GUILE_LDFLAGS = ++SUBDIR_GUILE_CFLAGS = ++ ++# ++# python sub directory definitons ++# ++SUBDIR_PYTHON_SRCS = \ ++ python/py-arch.c \ ++ python/py-auto-load.c \ ++ python/py-block.c \ ++ python/py-bpevent.c \ ++ python/py-breakpoint.c \ ++ python/py-cmd.c \ ++ python/py-continueevent.c \ ++ python/py-event.c \ ++ python/py-evtregistry.c \ ++ python/py-evts.c \ ++ python/py-exitedevent.c \ ++ python/py-finishbreakpoint.c \ ++ python/py-frame.c \ ++ python/py-framefilter.c \ ++ python/py-function.c \ ++ python/py-gdb-readline.c \ ++ python/py-inferior.c \ ++ python/py-infevents.c \ ++ python/py-infthread.c \ ++ python/py-instruction.c \ ++ python/py-lazy-string.c \ ++ python/py-linetable.c \ ++ python/py-newobjfileevent.c \ ++ python/py-objfile.c \ ++ python/py-param.c \ ++ python/py-prettyprint.c \ ++ python/py-progspace.c \ ++ python/py-record.c \ ++ python/py-record-btrace.c \ ++ python/py-record-full.c \ ++ python/py-registers.c \ ++ python/py-signalevent.c \ ++ python/py-stopevent.c \ ++ python/py-symbol.c \ ++ python/py-symtab.c \ ++ python/py-threadevent.c \ ++ python/py-tui.c \ ++ python/py-type.c \ ++ python/py-unwind.c \ ++ python/py-utils.c \ ++ python/py-value.c \ ++ python/py-varobj.c \ ++ python/py-xmethods.c \ ++ python/python.c ++ ++SUBDIR_PYTHON_OBS = $(patsubst %.c,%.o,$(SUBDIR_PYTHON_SRCS)) ++ ++SUBDIR_PYTHON_DEPS = ++SUBDIR_PYTHON_LDFLAGS = ++SUBDIR_PYTHON_CFLAGS = ++ ++SELFTESTS_SRCS = \ ++ disasm-selftests.c \ ++ gdbarch-selftests.c \ ++ selftest-arch.c \ ++ unittests/array-view-selftests.c \ ++ unittests/child-path-selftests.c \ ++ unittests/cli-utils-selftests.c \ ++ unittests/command-def-selftests.c \ ++ unittests/common-utils-selftests.c \ ++ unittests/copy_bitwise-selftests.c \ ++ unittests/environ-selftests.c \ ++ unittests/filtered_iterator-selftests.c \ ++ unittests/format_pieces-selftests.c \ ++ unittests/function-view-selftests.c \ ++ unittests/lookup_name_info-selftests.c \ ++ unittests/memory-map-selftests.c \ ++ unittests/memrange-selftests.c \ ++ unittests/offset-type-selftests.c \ ++ unittests/observable-selftests.c \ ++ unittests/optional-selftests.c \ ++ unittests/parse-connection-spec-selftests.c \ ++ unittests/ptid-selftests.c \ ++ unittests/main-thread-selftests.c \ ++ unittests/mkdir-recursive-selftests.c \ ++ unittests/rsp-low-selftests.c \ ++ unittests/scoped_fd-selftests.c \ ++ unittests/scoped_mmap-selftests.c \ ++ unittests/scoped_restore-selftests.c \ ++ unittests/string_view-selftests.c \ ++ unittests/style-selftests.c \ ++ unittests/tracepoint-selftests.c \ ++ unittests/tui-selftests.c \ ++ unittests/unpack-selftests.c \ ++ unittests/utils-selftests.c \ ++ unittests/vec-utils-selftests.c \ ++ unittests/xml-utils-selftests.c ++ ++SELFTESTS_OBS = $(patsubst %.c,%.o,$(SELFTESTS_SRCS)) ++ ++SUBDIR_TARGET_SRCS = target/waitstatus.c ++SUBDIR_TARGET_OBS = $(patsubst %.c,%.o,$(SUBDIR_TARGET_SRCS)) ++ ++ ++# Opcodes currently live in one of two places. Either they are in the ++# opcode library, typically ../opcodes, or they are in a header file ++# in INCLUDE_DIR. ++# Where is the "-lopcodes" library, with (some of) the opcode tables and ++# disassemblers? ++OPCODES_DIR = ../opcodes ++OPCODES_SRC = $(srcdir)/$(OPCODES_DIR) ++OPCODES = $(OPCODES_DIR)/libopcodes.a ++# Where are the other opcode tables which only have header file ++# versions? ++OP_INCLUDE = $(INCLUDE_DIR)/opcode ++# See TOP_CFLAGS as well. ++OPCODES_CFLAGS = -I$(OP_INCLUDE) ++ ++# Allow includes like "opcodes/mumble.h". ++TOP_CFLAGS = -I$(top_srcdir)/.. ++ ++# The simulator is usually nonexistent; targets that include one ++# should set this to list all the .o or .a files to be linked in. ++SIM = @SIM@ ++ ++WIN32LIBS = @WIN32LIBS@ ++ ++# Tcl et al cflags and libraries ++TCL = @TCL_LIBRARY@ ++TCL_CFLAGS = @TCL_INCLUDE@ ++GDBTKLIBS = @GDBTKLIBS@ ++# Extra flags that the GDBTK files need: ++GDBTK_CFLAGS = @GDBTK_CFLAGS@ ++ ++TK = @TK_LIBRARY@ ++TK_CFLAGS = @TK_INCLUDE@ ++ ++X11_CFLAGS = @TK_XINCLUDES@ ++X11_LDFLAGS = ++X11_LIBS = ++ ++WIN32LDAPP = @WIN32LDAPP@ ++ ++LIBGUI = @LIBGUI@ ++GUI_CFLAGS_X = @GUI_CFLAGS_X@ ++IDE_CFLAGS = $(GUI_CFLAGS_X) $(IDE_CFLAGS_X) ++ ++ALL_TCL_CFLAGS = $(TCL_CFLAGS) $(TK_CFLAGS) ++ ++# The version of gdbtk we're building. This should be kept ++# in sync with GDBTK_VERSION and friends in gdbtk.h. ++GDBTK_VERSION = 1.0 ++GDBTK_LIBRARY = $(datadir)/insight$(GDBTK_VERSION) ++ ++# Gdbtk requires an absolute path to the source directory or ++# the testsuite won't run properly. ++GDBTK_SRC_DIR = @GDBTK_SRC_DIR@ ++ ++SUBDIR_GDBTK_OBS = \ ++ gdbtk.o \ ++ gdbtk-bp.o \ ++ gdbtk-cmds.o \ ++ gdbtk-hooks.o \ ++ gdbtk-interp.o \ ++ gdbtk-register.o \ ++ gdbtk-stack.o \ ++ gdbtk-varobj.o \ ++ gdbtk-wrapper.o ++ ++SUBDIR_GDBTK_SRCS = \ ++ gdbtk/generic/gdbtk.c \ ++ gdbtk/generic/gdbtk-bp.c \ ++ gdbtk/generic/gdbtk-cmds.c \ ++ gdbtk/generic/gdbtk-hooks.c \ ++ gdbtk/generic/gdbtk-interp.c \ ++ gdbtk/generic/gdbtk-main.c \ ++ gdbtk/generic/gdbtk-register.c \ ++ gdbtk/generic/gdbtk-stack.c \ ++ gdbtk/generic/gdbtk-varobj.c \ ++ gdbtk/generic/gdbtk-wrapper.c ++ ++SUBDIR_GDBTK_DEPS = $(LIBGUI) $(TCL_DEPS) $(TK_DEPS) ++SUBDIR_GDBTK_LDFLAGS = ++SUBDIR_GDBTK_CFLAGS = -DGDBTK ++ ++CONFIG_OBS = @CONFIG_OBS@ ++CONFIG_SRCS = @CONFIG_SRCS@ ++CONFIG_DEPS = @CONFIG_DEPS@ ++CONFIG_LDFLAGS = @CONFIG_LDFLAGS@ ++ENABLE_CFLAGS = @ENABLE_CFLAGS@ ++CONFIG_ALL = @CONFIG_ALL@ ++CONFIG_CLEAN = @CONFIG_CLEAN@ ++CONFIG_INSTALL = @CONFIG_INSTALL@ ++CONFIG_UNINSTALL = @CONFIG_UNINSTALL@ ++HAVE_NATIVE_GCORE_TARGET = @HAVE_NATIVE_GCORE_TARGET@ ++ ++CONFIG_SRC_SUBDIR = arch cli dwarf2 mi compile tui unittests guile python \ ++ target nat ++CONFIG_DEP_SUBDIR = $(addsuffix /$(DEPDIR),$(CONFIG_SRC_SUBDIR)) ++ ++# -I. for config files. ++# -I$(srcdir) for gdb internal headers. ++# -I$(srcdir)/config for more generic config files. ++ ++# It is also possible that you will need to add -I/usr/include/sys if ++# your system doesn't have fcntl.h in /usr/include (which is where it ++# should be according to Posix). ++DEFS = -DCRASH_MERGE @DEFS@ ++GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/config \ ++ -DLOCALEDIR="\"$(localedir)\"" $(DEFS) ++ ++# MH_CFLAGS, if defined, has host-dependent CFLAGS from the config directory. ++GLOBAL_CFLAGS = $(MH_CFLAGS) ++ ++PROFILE_CFLAGS = @PROFILE_CFLAGS@ ++ ++# These are specifically reserved for setting from the command line ++# when running make. I.E.: "make CFLAGS=-Wmissing-prototypes". ++CFLAGS = @CFLAGS@ ++CXXFLAGS = @CXXFLAGS@ ++CPPFLAGS = @CPPFLAGS@ ++ ++# Set by configure, for e.g. expat. Python installations are such that ++# C headers are included using their basename (for example, we #include ++# rather than, say, ). Since the file names ++# are sometimes a little generic, we think that the risk of collision ++# with other header files is high. If that happens, we try to mitigate ++# a bit the consequences by putting the Python includes last in the list. ++INTERNAL_CPPFLAGS = $(CPPFLAGS) @GUILE_CPPFLAGS@ @PYTHON_CPPFLAGS@ \ ++ @LARGEFILE_CPPFLAGS@ ++ ++# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. ++INTERNAL_CFLAGS_BASE = \ ++ $(CXXFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ ++ $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) $(ZLIBINC) \ ++ $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \ ++ $(INTL_CFLAGS) $(INCGNU) $(INCSUPPORT) $(ENABLE_CFLAGS) \ ++ $(INTERNAL_CPPFLAGS) $(SRCHIGH_CFLAGS) $(TOP_CFLAGS) $(PTHREAD_CFLAGS) \ ++ $(DEBUGINFOD_CFLAGS) ++INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS) ++INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS) ++ ++# LDFLAGS is specifically reserved for setting from the command line ++# when running make. ++LDFLAGS = @LDFLAGS@ ++ ++# Profiling options need to go here to work. ++# I think it's perfectly reasonable for a user to set -pg in CFLAGS ++# and have it work; that's why CFLAGS is here. ++# PROFILE_CFLAGS is _not_ included, however, because we use monstartup. ++INTERNAL_LDFLAGS = \ ++ $(CXXFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) \ ++ $(LDFLAGS) $(CONFIG_LDFLAGS) $(PTHREAD_CFLAGS) ++ ++# Libraries and corresponding dependencies for compiling gdb. ++# XM_CLIBS, defined in *config files, have host-dependent libs. ++# LIBIBERTY appears twice on purpose. ++CLIBS = $(SIM) $(READLINE) $(OPCODES) $(LIBCTF) $(BFD) $(ZLIB) \ ++ $(LIBSUPPORT) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \ ++ $(XM_CLIBS) $(GDBTKLIBS) \ ++ @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \ ++ $(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \ ++ $(WIN32LIBS) $(LIBGNU) $(LIBICONV) \ ++ $(LIBMPFR) $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \ ++ $(DEBUGINFOD_LIBS) ++CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) $(CTF_DEPS) \ ++ $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU) \ ++ $(LIBSUPPORT) ++ ++DIST = gdb ++ ++RUNTEST = runtest ++RUNTESTFLAGS = ++ ++# XML files to build in to GDB. ++XMLFILES = \ ++ $(srcdir)/features/btrace.dtd \ ++ $(srcdir)/features/btrace-conf.dtd \ ++ $(srcdir)/features/gdb-target.dtd \ ++ $(srcdir)/features/library-list.dtd \ ++ $(srcdir)/features/library-list-aix.dtd \ ++ $(srcdir)/features/library-list-svr4.dtd \ ++ $(srcdir)/features/osdata.dtd \ ++ $(srcdir)/features/threads.dtd \ ++ $(srcdir)/features/traceframe-info.dtd \ ++ $(srcdir)/features/xinclude.dtd ++ ++# Build the ser-*.o files the host supports. This includes ser-unix.o ++# for any system that supports a POSIX interface to the serial port. ++# See configure.ac. ++SER_HARDWIRE = @SER_HARDWIRE@ ++ ++# This is remote-sim.o if a simulator is to be linked in. ++SIM_OBS = @SIM_OBS@ ++ ++# Target-dependent object files. ++TARGET_OBS = @TARGET_OBS@ ++ ++# All target-dependent objects files that require 64-bit CORE_ADDR ++# (used with --enable-targets=all --enable-64-bit-bfd). ++ALL_64_TARGET_OBS = \ ++ aarch64-fbsd-tdep.o \ ++ aarch64-linux-tdep.o \ ++ aarch64-newlib-tdep.o \ ++ aarch64-ravenscar-thread.o \ ++ aarch64-tdep.o \ ++ alpha-bsd-tdep.o \ ++ alpha-linux-tdep.o \ ++ alpha-mdebug-tdep.o \ ++ alpha-nbsd-tdep.o \ ++ alpha-obsd-tdep.o \ ++ alpha-tdep.o \ ++ amd64-darwin-tdep.o \ ++ amd64-dicos-tdep.o \ ++ amd64-fbsd-tdep.o \ ++ amd64-linux-tdep.o \ ++ amd64-nbsd-tdep.o \ ++ amd64-obsd-tdep.o \ ++ amd64-sol2-tdep.o \ ++ amd64-tdep.o \ ++ amd64-windows-tdep.o \ ++ arch/aarch64.o \ ++ arch/aarch64-insn.o \ ++ arch/amd64.o \ ++ ia64-linux-tdep.o \ ++ ia64-tdep.o \ ++ ia64-vms-tdep.o \ ++ mips64-obsd-tdep.o \ ++ sparc64-fbsd-tdep.o \ ++ sparc64-linux-tdep.o \ ++ sparc64-nbsd-tdep.o \ ++ sparc64-obsd-tdep.o \ ++ sparc64-sol2-tdep.o \ ++ sparc64-tdep.o ++ ++# All other target-dependent objects files (used with --enable-targets=all). ++ALL_TARGET_OBS = \ ++ aarch32-tdep.o \ ++ arc-linux-tdep.o \ ++ arc-tdep.o \ ++ arch/aarch32.o \ ++ arch/arc.o \ ++ arch/arm.o \ ++ arch/arm-get-next-pcs.o \ ++ arch/arm-linux.o \ ++ arch/i386.o \ ++ arch/ppc-linux-common.o \ ++ arch/riscv.o \ ++ arm-bsd-tdep.o \ ++ arm-fbsd-tdep.o \ ++ arm-linux-tdep.o \ ++ arm-nbsd-tdep.o \ ++ arm-obsd-tdep.o \ ++ arm-pikeos-tdep.o \ ++ arm-symbian-tdep.o \ ++ arm-tdep.o \ ++ arm-wince-tdep.o \ ++ avr-tdep.o \ ++ bfin-linux-tdep.o \ ++ bfin-tdep.o \ ++ bpf-tdep.o \ ++ bsd-uthread.o \ ++ cris-linux-tdep.o \ ++ cris-tdep.o \ ++ csky-linux-tdep.o \ ++ csky-tdep.o \ ++ dicos-tdep.o \ ++ fbsd-tdep.o \ ++ frv-linux-tdep.o \ ++ frv-tdep.o \ ++ ft32-tdep.o \ ++ glibc-tdep.o \ ++ h8300-tdep.o \ ++ hppa-bsd-tdep.o \ ++ hppa-linux-tdep.o \ ++ hppa-nbsd-tdep.o \ ++ hppa-obsd-tdep.o \ ++ hppa-tdep.o \ ++ i386-bsd-tdep.o \ ++ i386-darwin-tdep.o \ ++ i386-dicos-tdep.o \ ++ i386-fbsd-tdep.o \ ++ i386-gnu-tdep.o \ ++ i386-go32-tdep.o \ ++ i386-linux-tdep.o \ ++ i386-nbsd-tdep.o \ ++ i386-nto-tdep.o \ ++ i386-obsd-tdep.o \ ++ i386-sol2-tdep.o \ ++ i386-tdep.o \ ++ i386-windows-tdep.o \ ++ i387-tdep.o \ ++ iq2000-tdep.o \ ++ linux-record.o \ ++ linux-tdep.o \ ++ lm32-tdep.o \ ++ m32c-tdep.o \ ++ m32r-linux-tdep.o \ ++ m32r-tdep.o \ ++ m68hc11-tdep.o \ ++ m68k-bsd-tdep.o \ ++ m68k-linux-tdep.o \ ++ m68k-tdep.o \ ++ mep-tdep.o \ ++ microblaze-linux-tdep.o \ ++ microblaze-tdep.o \ ++ mips-fbsd-tdep.o \ ++ mips-linux-tdep.o \ ++ mips-nbsd-tdep.o \ ++ mips-sde-tdep.o \ ++ mips-tdep.o \ ++ mn10300-linux-tdep.o \ ++ mn10300-tdep.o \ ++ moxie-tdep.o \ ++ msp430-tdep.o \ ++ nbsd-tdep.o \ ++ nds32-tdep.o \ ++ nios2-linux-tdep.o \ ++ nios2-tdep.o \ ++ nto-tdep.o \ ++ obsd-tdep.o \ ++ or1k-linux-tdep.o \ ++ or1k-tdep.o \ ++ ppc-fbsd-tdep.o \ ++ ppc-linux-tdep.o \ ++ ppc-nbsd-tdep.o \ ++ ppc-obsd-tdep.o \ ++ ppc-ravenscar-thread.o \ ++ ppc-sysv-tdep.o \ ++ ppc64-tdep.o \ ++ ravenscar-thread.o \ ++ riscv-fbsd-tdep.o \ ++ riscv-linux-tdep.o \ ++ riscv-ravenscar-thread.o \ ++ riscv-tdep.o \ ++ rl78-tdep.o \ ++ rs6000-aix-tdep.o \ ++ rs6000-lynx178-tdep.o \ ++ rs6000-tdep.o \ ++ rx-tdep.o \ ++ s12z-tdep.o \ ++ s390-linux-tdep.o \ ++ s390-tdep.o \ ++ score-tdep.o \ ++ sh-linux-tdep.o \ ++ sh-nbsd-tdep.o \ ++ sh-tdep.o \ ++ sol2-tdep.o \ ++ solib-aix.o \ ++ solib-darwin.o \ ++ solib-dsbt.o \ ++ solib-frv.o \ ++ solib-svr4.o \ ++ sparc-linux-tdep.o \ ++ sparc-nbsd-tdep.o \ ++ sparc-obsd-tdep.o \ ++ sparc-ravenscar-thread.o \ ++ sparc-sol2-tdep.o \ ++ sparc-tdep.o \ ++ symfile-mem.o \ ++ tic6x-linux-tdep.o \ ++ tic6x-tdep.o \ ++ tilegx-linux-tdep.o \ ++ tilegx-tdep.o \ ++ v850-tdep.o \ ++ vax-nbsd-tdep.o \ ++ vax-tdep.o \ ++ windows-tdep.o \ ++ x86-tdep.o \ ++ xcoffread.o \ ++ xstormy16-tdep.o \ ++ xtensa-config.o \ ++ xtensa-linux-tdep.o \ ++ xtensa-tdep.o ++ ++# The following native-target dependent variables are defined on ++# configure.nat. ++NAT_FILE = @NAT_FILE@ ++NATDEPFILES = @NATDEPFILES@ ++NAT_CDEPS = @NAT_CDEPS@ ++LOADLIBES = @LOADLIBES@ ++MH_CFLAGS = @MH_CFLAGS@ ++XM_CLIBS = @XM_CLIBS@ ++NAT_GENERATED_FILES = @NAT_GENERATED_FILES@ ++NM_H = @NM_H@ ++HAVE_NATIVE_GCORE_HOST = @HAVE_NATIVE_GCORE_HOST@ ++ ++# Native-target dependent makefile fragment comes in here. ++@nat_makefile_frag@ ++ ++# End of native-target dependent variables. ++ ++FLAGS_TO_PASS = \ ++ "prefix=$(prefix)" \ ++ "exec_prefix=$(exec_prefix)" \ ++ "infodir=$(infodir)" \ ++ "datarootdir=$(datarootdir)" \ ++ "docdir=$(docdir)" \ ++ "htmldir=$(htmldir)" \ ++ "pdfdir=$(pdfdir)" \ ++ "libdir=$(libdir)" \ ++ "mandir=$(mandir)" \ ++ "datadir=$(datadir)" \ ++ "includedir=$(includedir)" \ ++ "against=$(against)" \ ++ "DESTDIR=$(DESTDIR)" \ ++ "AR=$(AR)" \ ++ "AR_FLAGS=$(AR_FLAGS)" \ ++ "CC=$(CC)" \ ++ "CFLAGS=$(CFLAGS)" \ ++ "CXX=$(CXX)" \ ++ "CXX_DIALECT=$(CXX_DIALECT)" \ ++ "CXXFLAGS=$(CXXFLAGS)" \ ++ "DLLTOOL=$(DLLTOOL)" \ ++ "LDFLAGS=$(LDFLAGS)" \ ++ "RANLIB=$(RANLIB)" \ ++ "MAKEINFO=$(MAKEINFO)" \ ++ "MAKEINFOFLAGS=$(MAKEINFOFLAGS)" \ ++ "MAKEINFO_EXTRA_FLAGS=$(MAKEINFO_EXTRA_FLAGS)" \ ++ "MAKEHTML=$(MAKEHTML)" \ ++ "MAKEHTMLFLAGS=$(MAKEHTMLFLAGS)" \ ++ "INSTALL=$(INSTALL)" \ ++ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ ++ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ ++ "INSTALL_DATA=$(INSTALL_DATA)" \ ++ "RUNTEST=$(RUNTEST)" \ ++ "RUNTESTFLAGS=$(RUNTESTFLAGS)" ++ ++# Flags that we pass when building the testsuite. ++ ++# empty for native, $(target_alias)/ for cross ++target_subdir = @target_subdir@ ++ ++CC_FOR_TARGET = ` \ ++ if [ -f $${rootme}/../gcc/xgcc ] ; then \ ++ if [ -f $${rootme}/../$(target_subdir)newlib/Makefile ] ; then \ ++ echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/ -idirafter $${rootme}/$(target_subdir)newlib/targ-include -idirafter $${rootsrc}/../$(target_subdir)newlib/libc/include -nostdinc -B$${rootme}/../$(target_subdir)newlib/; \ ++ else \ ++ echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/; \ ++ fi; \ ++ else \ ++ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \ ++ echo $(CC); \ ++ else \ ++ t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \ ++ fi; \ ++ fi` ++ ++CXX_FOR_TARGET = ` \ ++ if [ -f $${rootme}/../gcc/xg++ ] ; then \ ++ if [ -f $${rootme}/../$(target_subdir)newlib/Makefile ] ; then \ ++ echo $${rootme}/../gcc/xg++ -B$${rootme}/../gcc/ -idirafter $${rootme}/$(target_subdir)newlib/targ-include -idirafter $${rootsrc}/../$(target_subdir)newlib/libc/include -nostdinc -B$${rootme}/../$(target_subdir)newlib/; \ ++ else \ ++ echo $${rootme}/../gcc/xg++ -B$${rootme}/../gcc/; \ ++ fi; \ ++ else \ ++ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \ ++ echo $(CXX); \ ++ else \ ++ t='$(program_transform_name)'; echo g++ | sed -e '' $$t; \ ++ fi; \ ++ fi` ++ ++# The use of $$(x_FOR_TARGET) reduces the command line length by not ++# duplicating the lengthy definition. ++TARGET_FLAGS_TO_PASS = \ ++ "prefix=$(prefix)" \ ++ "exec_prefix=$(exec_prefix)" \ ++ "against=$(against)" \ ++ 'CC=$$(CC_FOR_TARGET)' \ ++ "CC_FOR_TARGET=$(CC_FOR_TARGET)" \ ++ "CFLAGS=$(CFLAGS)" \ ++ 'CXX=$$(CXX_FOR_TARGET)' \ ++ "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \ ++ "CXXFLAGS=$(CXXFLAGS)" \ ++ "INSTALL=$(INSTALL)" \ ++ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ ++ "INSTALL_DATA=$(INSTALL_DATA)" \ ++ "MAKEINFO=$(MAKEINFO)" \ ++ "MAKEHTML=$(MAKEHTML)" \ ++ "RUNTEST=$(RUNTEST)" \ ++ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ ++ "FORCE_PARALLEL=$(FORCE_PARALLEL)" \ ++ "TESTS=$(TESTS)" ++ ++# All source files that go into linking GDB. ++ ++# Files that should wind up in SFILES and whose corresponding .o ++# should be in COMMON_OBS. ++COMMON_SFILES = \ ++ ada-lang.c \ ++ ada-tasks.c \ ++ ada-typeprint.c \ ++ ada-valprint.c \ ++ ada-varobj.c \ ++ addrmap.c \ ++ agent.c \ ++ alloc.c \ ++ annotate.c \ ++ arch-utils.c \ ++ async-event.c \ ++ auto-load.c \ ++ auxv.c \ ++ ax-gdb.c \ ++ ax-general.c \ ++ bcache.c \ ++ bfd-target.c \ ++ block.c \ ++ blockframe.c \ ++ break-catch-sig.c \ ++ break-catch-syscall.c \ ++ break-catch-throw.c \ ++ breakpoint.c \ ++ btrace.c \ ++ build-id.c \ ++ buildsym-legacy.c \ ++ buildsym.c \ ++ c-lang.c \ ++ c-typeprint.c \ ++ c-valprint.c \ ++ c-varobj.c \ ++ charset.c \ ++ cli-out.c \ ++ coff-pe-read.c \ ++ coffread.c \ ++ complaints.c \ ++ completer.c \ ++ continuations.c \ ++ copying.c \ ++ corefile.c \ ++ corelow.c \ ++ cp-abi.c \ ++ cp-namespace.c \ ++ cp-support.c \ ++ cp-valprint.c \ ++ ctfread.c \ ++ d-lang.c \ ++ d-namespace.c \ ++ d-valprint.c \ ++ dbxread.c \ ++ dcache.c \ ++ debug.c \ ++ debuginfod-support.c \ ++ dictionary.c \ ++ disasm.c \ ++ dummy-frame.c \ ++ dwarf2/abbrev.c \ ++ dwarf2/attribute.c \ ++ dwarf2/comp-unit.c \ ++ dwarf2/dwz.c \ ++ dwarf2/expr.c \ ++ dwarf2/frame-tailcall.c \ ++ dwarf2/frame.c \ ++ dwarf2/index-cache.c \ ++ dwarf2/index-common.c \ ++ dwarf2/index-write.c \ ++ dwarf2/leb.c \ ++ dwarf2/line-header.c \ ++ dwarf2/loc.c \ ++ dwarf2/macro.c \ ++ dwarf2/read.c \ ++ dwarf2/section.c \ ++ dwarf2/stringify.c \ ++ eval.c \ ++ event-top.c \ ++ exceptions.c \ ++ exec.c \ ++ expprint.c \ ++ extension.c \ ++ f-lang.c \ ++ f-typeprint.c \ ++ f-valprint.c \ ++ filename-seen-cache.c \ ++ filesystem.c \ ++ findcmd.c \ ++ findvar.c \ ++ frame.c \ ++ frame-base.c \ ++ frame-unwind.c \ ++ gcore.c \ ++ gdb-demangle.c \ ++ gdb_bfd.c \ ++ gdb_obstack.c \ ++ gdb_regex.c \ ++ gdbarch.c \ ++ gdbtypes.c \ ++ gnu-v2-abi.c \ ++ gnu-v3-abi.c \ ++ go-lang.c \ ++ go-typeprint.c \ ++ go-valprint.c \ ++ inf-child.c \ ++ inf-loop.c \ ++ infcall.c \ ++ infcmd.c \ ++ inferior.c \ ++ inflow.c \ ++ infrun.c \ ++ inline-frame.c \ ++ interps.c \ ++ jit.c \ ++ language.c \ ++ linespec.c \ ++ location.c \ ++ m2-lang.c \ ++ m2-typeprint.c \ ++ m2-valprint.c \ ++ macrocmd.c \ ++ macroexp.c \ ++ macroscope.c \ ++ macrotab.c \ ++ main.c \ ++ maint.c \ ++ maint-test-options.c \ ++ maint-test-settings.c \ ++ mdebugread.c \ ++ mem-break.c \ ++ memattr.c \ ++ memory-map.c \ ++ memrange.c \ ++ minidebug.c \ ++ minsyms.c \ ++ mipsread.c \ ++ namespace.c \ ++ objc-lang.c \ ++ objfiles.c \ ++ observable.c \ ++ opencl-lang.c \ ++ osabi.c \ ++ osdata.c \ ++ p-lang.c \ ++ p-typeprint.c \ ++ p-valprint.c \ ++ parse.c \ ++ printcmd.c \ ++ probe.c \ ++ process-stratum-target.c \ ++ producer.c \ ++ progspace.c \ ++ progspace-and-thread.c \ ++ prologue-value.c \ ++ psymtab.c \ ++ record.c \ ++ record-btrace.c \ ++ record-full.c \ ++ regcache.c \ ++ regcache-dump.c \ ++ reggroups.c \ ++ registry.c \ ++ remote.c \ ++ remote-fileio.c \ ++ remote-notif.c \ ++ reverse.c \ ++ run-on-main-thread.c \ ++ rust-lang.c \ ++ sentinel-frame.c \ ++ ser-event.c \ ++ serial.c \ ++ skip.c \ ++ solib.c \ ++ solib-target.c \ ++ source.c \ ++ source-cache.c \ ++ stabsread.c \ ++ stack.c \ ++ std-regs.c \ ++ symfile.c \ ++ symfile-debug.c \ ++ symmisc.c \ ++ symtab.c \ ++ target.c \ ++ ../../crash_target.c \ ++ target-connection.c \ ++ target-dcache.c \ ++ target-descriptions.c \ ++ target-memory.c \ ++ test-target.c \ ++ thread.c \ ++ thread-iter.c \ ++ tid-parse.c \ ++ top.c \ ++ tracectf.c \ ++ tracefile.c \ ++ tracefile-tfile.c \ ++ tracepoint.c \ ++ trad-frame.c \ ++ tramp-frame.c \ ++ target-float.c \ ++ type-stack.c \ ++ typeprint.c \ ++ ui-file.c \ ++ ui-out.c \ ++ ui-style.c \ ++ user-regs.c \ ++ utils.c \ ++ valarith.c \ ++ valops.c \ ++ valprint.c \ ++ value.c \ ++ varobj.c \ ++ xml-support.c \ ++ xml-syscall.c \ ++ xml-tdesc.c ++ ++# Links made at configuration time should not be specified here, since ++# SFILES is used in building the distribution archive. ++SFILES = \ ++ ada-exp.y \ ++ arch/i386.c \ ++ c-exp.y \ ++ cp-name-parser.y \ ++ d-exp.y \ ++ dtrace-probe.c \ ++ elfread.c \ ++ f-exp.y \ ++ gdb.c \ ++ go-exp.y \ ++ m2-exp.y \ ++ p-exp.y \ ++ proc-service.list \ ++ rust-exp.y \ ++ ser-base.c \ ++ ser-unix.c \ ++ sol-thread.c \ ++ stap-probe.c \ ++ stub-termcap.c \ ++ symfile-mem.c \ ++ ui-file.h \ ++ mi/mi-common.c \ ++ $(SUBDIR_CLI_SRCS) \ ++ $(SUBDIR_TARGET_SRCS) \ ++ $(COMMON_SFILES) \ ++ $(SUBDIR_GCC_COMPILE_SRCS) ++ ++# Header files that need to have srcdir added. Note that in the cases ++# where we use a macro like $(gdbcmd_h), things are carefully arranged ++# so that each .h file is listed exactly once (M-x tags-search works ++# wrong if TAGS has files twice). Because this is tricky to get ++# right, it is probably easiest just to list .h files here directly. ++ ++HFILES_NO_SRCDIR = \ ++ aarch32-tdep.h \ ++ aarch64-ravenscar-thread.h \ ++ aarch64-tdep.h \ ++ ada-lang.h \ ++ addrmap.h \ ++ alpha-bsd-tdep.h \ ++ alpha-tdep.h \ ++ amd64-darwin-tdep.h \ ++ amd64-linux-tdep.h \ ++ amd64-nat.h \ ++ amd64-tdep.h \ ++ annotate.h \ ++ arc-tdep.h \ ++ arch-utils.h \ ++ arm-linux-tdep.h \ ++ arm-nbsd-tdep.h \ ++ arm-tdep.h \ ++ async-event.h \ ++ auto-load.h \ ++ auxv.h \ ++ ax.h \ ++ ax-gdb.h \ ++ bcache.h \ ++ bfd-target.h \ ++ bfin-tdep.h \ ++ block.h \ ++ breakpoint.h \ ++ bsd-kvm.h \ ++ bsd-uthread.h \ ++ build-id.h \ ++ buildsym-legacy.h \ ++ buildsym.h \ ++ c-lang.h \ ++ charset.h \ ++ charset-list.h \ ++ cli-out.h \ ++ coff-pe-read.h \ ++ command.h \ ++ complaints.h \ ++ completer.h \ ++ cp-abi.h \ ++ cp-support.h \ ++ csky-tdep.h \ ++ d-lang.h \ ++ darwin-nat.h \ ++ dcache.h \ ++ defs.h \ ++ dicos-tdep.h \ ++ dictionary.h \ ++ disasm.h \ ++ dummy-frame.h \ ++ dwarf2/frame-tailcall.h \ ++ dwarf2/frame.h \ ++ dwarf2/expr.h \ ++ dwarf2/index-cache.h \ ++ dwarf2/index-common.h \ ++ dwarf2/loc.h \ ++ dwarf2/read.h \ ++ event-top.h \ ++ exceptions.h \ ++ exec.h \ ++ expression.h \ ++ extension.h \ ++ extension-priv.h \ ++ f-lang.h \ ++ fbsd-nat.h \ ++ fbsd-tdep.h \ ++ filesystem.h \ ++ frame.h \ ++ frame-base.h \ ++ frame-unwind.h \ ++ frv-tdep.h \ ++ ft32-tdep.h \ ++ gcore.h \ ++ gdb_bfd.h \ ++ gdb_curses.h \ ++ gdb_expat.h \ ++ gdb_obstack.h \ ++ gdb_proc_service.h \ ++ gdb_regex.h \ ++ gdb_select.h \ ++ gdb-stabs.h \ ++ gdb_vfork.h \ ++ gdb_wchar.h \ ++ gdbarch.h \ ++ gdbcmd.h \ ++ gdbcore.h \ ++ gdbthread.h \ ++ gdbtypes.h \ ++ glibc-tdep.h \ ++ gnu-nat.h \ ++ go-lang.h \ ++ gregset.h \ ++ hppa-bsd-tdep.h \ ++ hppa-linux-offsets.h \ ++ hppa-tdep.h \ ++ i386-bsd-nat.h \ ++ i386-darwin-tdep.h \ ++ i386-linux-nat.h \ ++ i386-linux-tdep.h \ ++ i386-tdep.h \ ++ i387-tdep.h \ ++ ia64-libunwind-tdep.h \ ++ ia64-tdep.h \ ++ inf-child.h \ ++ inf-loop.h \ ++ inf-ptrace.h \ ++ infcall.h \ ++ inferior.h \ ++ inflow.h \ ++ inline-frame.h \ ++ interps.h \ ++ jit.h \ ++ language.h \ ++ linespec.h \ ++ linux-fork.h \ ++ linux-nat.h \ ++ linux-record.h \ ++ linux-tdep.h \ ++ location.h \ ++ m2-lang.h \ ++ m32r-tdep.h \ ++ m68k-tdep.h \ ++ macroexp.h \ ++ macroscope.h \ ++ macrotab.h \ ++ main.h \ ++ mdebugread.h \ ++ memattr.h \ ++ memory-map.h \ ++ memrange.h \ ++ microblaze-tdep.h \ ++ mips-linux-tdep.h \ ++ mips-nbsd-tdep.h \ ++ mips-tdep.h \ ++ mn10300-tdep.h \ ++ moxie-tdep.h \ ++ nbsd-nat.h \ ++ nbsd-tdep.h \ ++ nds32-tdep.h \ ++ nios2-tdep.h \ ++ nto-tdep.h \ ++ objc-lang.h \ ++ objfiles.h \ ++ obsd-nat.h \ ++ obsd-tdep.h \ ++ osabi.h \ ++ osdata.h \ ++ p-lang.h \ ++ parser-defs.h \ ++ ppc-fbsd-tdep.h \ ++ ppc-linux-tdep.h \ ++ ppc-nbsd-tdep.h \ ++ ppc-obsd-tdep.h \ ++ ppc-ravenscar-thread.h \ ++ ppc-tdep.h \ ++ ppc64-tdep.h \ ++ probe.h \ ++ proc-utils.h \ ++ procfs.h \ ++ progspace.h \ ++ progspace-and-thread.h \ ++ prologue-value.h \ ++ psympriv.h \ ++ psymtab.h \ ++ ravenscar-thread.h \ ++ record.h \ ++ record-full.h \ ++ regcache.h \ ++ reggroups.h \ ++ regset.h \ ++ remote.h \ ++ remote-fileio.h \ ++ remote-notif.h \ ++ riscv-fbsd-tdep.h \ ++ riscv-ravenscar-thread.h \ ++ riscv-tdep.h \ ++ rs6000-aix-tdep.h \ ++ rs6000-tdep.h \ ++ run-on-main-thread.h \ ++ s390-linux-tdep.h \ ++ s390-tdep.h \ ++ score-tdep.h \ ++ selftest-arch.h \ ++ sentinel-frame.h \ ++ ser-base.h \ ++ ser-event.h \ ++ ser-tcp.h \ ++ ser-unix.h \ ++ serial.h \ ++ sh-tdep.h \ ++ sim-regno.h \ ++ skip.h \ ++ sol2-tdep.h \ ++ solib.h \ ++ solib-aix.h \ ++ solib-darwin.h \ ++ solib-svr4.h \ ++ solib-target.h \ ++ solist.h \ ++ source.h \ ++ source-cache.h \ ++ sparc-nat.h \ ++ sparc-ravenscar-thread.h \ ++ sparc-tdep.h \ ++ sparc64-tdep.h \ ++ stabsread.h \ ++ stack.h \ ++ stap-probe.h \ ++ symfile.h \ ++ symtab.h \ ++ target.h \ ++ target-dcache.h \ ++ target-descriptions.h \ ++ terminal.h \ ++ tid-parse.h \ ++ top.h \ ++ tracectf.h \ ++ tracefile.h \ ++ tracepoint.h \ ++ trad-frame.h \ ++ target-float.h \ ++ tramp-frame.h \ ++ type-stack.h \ ++ typeprint.h \ ++ ui-file.h \ ++ ui-out.h \ ++ ui-style.h \ ++ user-regs.h \ ++ utils.h \ ++ valprint.h \ ++ value.h \ ++ varobj.h \ ++ varobj-iter.h \ ++ vax-tdep.h \ ++ windows-nat.h \ ++ windows-tdep.h \ ++ x86-bsd-nat.h \ ++ x86-linux-nat.h \ ++ x86-nat.h \ ++ xcoffread.h \ ++ xml-builtin.h \ ++ xml-support.h \ ++ xml-syscall.h \ ++ xml-tdesc.h \ ++ xtensa-tdep.h \ ++ arch/aarch32.h \ ++ arch/aarch64.h \ ++ arch/aarch64-insn.h \ ++ arch/arc.h \ ++ arch/arm.h \ ++ arch/i386.h \ ++ arch/ppc-linux-common.h \ ++ arch/ppc-linux-tdesc.h \ ++ arch/riscv.h \ ++ cli/cli-cmds.h \ ++ cli/cli-decode.h \ ++ cli/cli-script.h \ ++ cli/cli-setshow.h \ ++ cli/cli-style.h \ ++ cli/cli-utils.h \ ++ compile/compile.h \ ++ compile/compile-c.h \ ++ compile/compile-cplus.h \ ++ compile/compile-internal.h \ ++ compile/compile-object-load.h \ ++ compile/compile-object-run.h \ ++ compile/gcc-c-plugin.h \ ++ compile/gcc-cp-plugin.h \ ++ config/nm-linux.h \ ++ config/nm-nto.h \ ++ config/djgpp/langinfo.h \ ++ config/djgpp/nl_types.h \ ++ config/i386/nm-i386gnu.h \ ++ config/sparc/nm-sol2.h \ ++ mi/mi-cmds.h \ ++ mi/mi-common.h \ ++ mi/mi-console.h \ ++ mi/mi-getopt.h \ ++ mi/mi-main.h \ ++ mi/mi-out.h \ ++ mi/mi-parse.h \ ++ nat/aarch64-linux.h \ ++ nat/aarch64-linux-hw-point.h \ ++ nat/aarch64-sve-linux-ptrace.h \ ++ nat/amd64-linux-siginfo.h \ ++ nat/gdb_ptrace.h \ ++ nat/gdb_thread_db.h \ ++ nat/fork-inferior.h \ ++ nat/linux-btrace.h \ ++ nat/linux-namespaces.h \ ++ nat/linux-nat.h \ ++ nat/linux-osdata.h \ ++ nat/linux-personality.h \ ++ nat/linux-ptrace.h \ ++ nat/linux-waitpid.h \ ++ nat/mips-linux-watch.h \ ++ nat/ppc-linux.h \ ++ nat/x86-cpuid.h \ ++ nat/x86-dregs.h \ ++ nat/x86-gcc-cpuid.h \ ++ nat/x86-linux.h \ ++ nat/x86-linux-dregs.h \ ++ python/py-event.h \ ++ python/py-events.h \ ++ python/py-stopevent.h \ ++ python/python.h \ ++ python/python-internal.h \ ++ regformats/regdef.h \ ++ target/resume.h \ ++ target/target.h \ ++ target/wait.h \ ++ target/waitstatus.h \ ++ tui/tui.h \ ++ tui/tui-command.h \ ++ tui/tui-data.h \ ++ tui/tui-disasm.h \ ++ tui/tui-file.h \ ++ tui/tui-hooks.h \ ++ tui/tui-io.h \ ++ tui/tui-layout.h \ ++ tui/tui-regs.h \ ++ tui/tui-source.h \ ++ tui/tui-stack.h \ ++ tui/tui-win.h \ ++ tui/tui-windata.h \ ++ tui/tui-wingeneral.h \ ++ tui/tui-winsource.h \ ++ x86-tdep.h ++ ++# Header files that already have srcdir in them, or which are in objdir. ++ ++HFILES_WITH_SRCDIR = \ ++ ../bfd/bfd.h \ ++ jit-reader.h ++ ++# {X,T,NAT}DEPFILES are something of a pain in that it's hard to ++# default their values the way we do for SER_HARDWIRE; in the future ++# maybe much of the stuff now in {X,T,NAT}DEPFILES will go into other ++# variables analogous to SER_HARDWIRE which get defaulted in this ++# Makefile.in ++ ++DEPFILES = $(TARGET_OBS) $(SER_HARDWIRE) $(NATDEPFILES) $(SIM_OBS) ++ ++SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) $(CONFIG_SRCS) ++# Don't include YYFILES (*.c) because we already include *.y in SFILES, ++# and it's more useful to see it in the .y file. ++TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \ ++ $(CONFIG_SRCS) ++TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR) ++ ++COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ ++ mi/mi-common.o \ ++ version.o \ ++ xml-builtin.o \ ++ $(patsubst %.c,%.o,$(COMMON_SFILES)) \ ++ $(SUBDIR_CLI_OBS) \ ++ $(SUBDIR_TARGET_OBS) \ ++ $(SUBDIR_GCC_COMPILE_OBS) ++ ++SUBDIRS = build_no_subdirs ++CLEANDIRS = $(SUBDIRS) ++ ++# List of subdirectories in the build tree that must exist. ++# This is used to force build failures in existing trees when ++# a new directory is added. ++# The format here is for the `case' shell command. ++REQUIRED_SUBDIRS = doc | testsuite | data-directory ++ ++# Parser intermediate files. ++YYFILES = \ ++ ada-exp.c \ ++ ada-lex.c \ ++ c-exp.c \ ++ cp-name-parser.c \ ++ d-exp.c \ ++ f-exp.c \ ++ go-exp.c \ ++ m2-exp.c \ ++ p-exp.c \ ++ rust-exp.c ++ ++# ada-lex.c is included by another file, so it shouldn't wind up as a ++# .o itself. ++YYOBJ = $(filter-out ada-lex.o,$(patsubst %.c,%.o,$(YYFILES))) ++ ++# Things which need to be built when making a distribution. ++ ++DISTSTUFF = $(YYFILES) ++ ++ ++# All generated files which can be included by another file. ++generated_files = \ ++ ada-lex.c \ ++ config.h \ ++ jit-reader.h \ ++ $(NAT_GENERATED_FILES) \ ++ $(NM_H) ++ ++# Flags needed to compile Python code ++PYTHON_CFLAGS = @PYTHON_CFLAGS@ ++ ++all: gdb$(EXEEXT) gdb-gdb.py gdb-gdb.gdb ++ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do ++ ++# Rule for compiling .c files in the top-level gdb directory. ++# The order-only dependencies ensure that we create the build subdirectories. ++%.o: %.c | $(CONFIG_DEP_SUBDIR) ++ $(COMPILE) $< ++ $(POSTCOMPILE) ++ ++$(CONFIG_DEP_SUBDIR): ++ $(SHELL) $(srcdir)/../mkinstalldirs $@ ++ ++# Python files need special flags. ++python/%.o: INTERNAL_CFLAGS += $(PYTHON_CFLAGS) ++ ++# Rules for compiling .c files in the various source subdirectories. ++%.o: $(srcdir)/gdbtk/generic/%.c ++ $(COMPILE) $(all_gdbtk_cflags) $< ++ $(POSTCOMPILE) ++ ++installcheck: ++ ++# The check target can not use subdir_do, because subdir_do does not ++# use TARGET_FLAGS_TO_PASS. ++check: force ++ @if [ -f testsuite/Makefile ]; then \ ++ rootme=`pwd`; export rootme; \ ++ rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ ++ cd testsuite; \ ++ $(MAKE) $(TARGET_FLAGS_TO_PASS) check; \ ++ else true; fi ++ ++check-perf: force ++ @if [ -f testsuite/Makefile ]; then \ ++ rootme=`pwd`; export rootme; \ ++ rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ ++ cd testsuite; \ ++ $(MAKE) $(TARGET_FLAGS_TO_PASS) check-perf; \ ++ else true; fi ++ ++check-read1: force ++ @if [ -f testsuite/Makefile ]; then \ ++ rootme=`pwd`; export rootme; \ ++ rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ ++ cd testsuite; \ ++ $(MAKE) $(TARGET_FLAGS_TO_PASS) check-read1; \ ++ else true; fi ++ ++check-parallel: force ++ @if [ -f testsuite/Makefile ]; then \ ++ rootme=`pwd`; export rootme; \ ++ rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ ++ cd testsuite; \ ++ $(MAKE) $(TARGET_FLAGS_TO_PASS) check-parallel; \ ++ else true; fi ++ ++# The idea is to parallelize testing of multilibs, for example: ++# make -j3 check//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu} ++# will run 3 concurrent sessions of check, eventually testing all 10 ++# combinations. GNU make is required for the % pattern to work, as is ++# a shell that expands alternations within braces. If GNU make is not ++# used, this rule will harmlessly fail to match. Used FORCE_PARALLEL to ++# prevent serialized checking due to the passed RUNTESTFLAGS. ++# FIXME: use config.status --config not --version, when available. ++check//%: force ++ @if [ -f testsuite/config.status ]; then \ ++ rootme=`pwd`; export rootme; \ ++ rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ ++ target=`echo "$@" | sed 's,//.*,,'`; \ ++ variant=`echo "$@" | sed 's,^[^/]*//,,'`; \ ++ vardots=`echo "$$variant" | sed 's,/,.,g'`; \ ++ testdir=testsuite.$$vardots; \ ++ if [ ! -f $$testdir/Makefile ] && [ -f testsuite/config.status ]; then \ ++ configargs=`cd testsuite && ./config.status --version | \ ++ sed -n -e 's,"$$,,' -e 's,^ *with options ",,p'`; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $$testdir && \ ++ (cd $$testdir && \ ++ eval $(SHELL) "\"\$$rootsrc/testsuite/configure\" $$configargs" \ ++ "\"--srcdir=\$$rootsrc/testsuite\"" \ ++ ); \ ++ else :; fi && cd $$testdir && \ ++ $(MAKE) $(TARGET_FLAGS_TO_PASS) \ ++ RUNTESTFLAGS="--target_board=$$variant $(RUNTESTFLAGS)" \ ++ FORCE_PARALLEL=$(if $(FORCE_PARALLEL),1,$(if $(RUNTESTFLAGS),,1)) \ ++ "$$target"; \ ++ else true; fi ++ ++# The set of headers checked by 'check-headers' by default. ++CHECK_HEADERS = $(HFILES_NO_SRCDIR) ++ ++# Try to compile each header in isolation, thus ensuring headers are ++# self-contained. ++# ++# Defaults to checking all $HFILES_NO_SRCDIR headers. ++# ++# Do: ++# ++# make check-headers CHECK_HEADERS="header.h list.h" ++# ++# to check specific headers. ++# ++check-headers: ++ @echo Checking headers. ++ for i in $(CHECK_HEADERS) ; do \ ++ $(CXX) $(CXX_DIALECT) -x c++-header -c -fsyntax-only \ ++ $(INTERNAL_CFLAGS) -include defs.h $(srcdir)/$$i ; \ ++ done ++.PHONY: check-headers ++ ++info install-info clean-info dvi pdf install-pdf html install-html: force ++ @$(MAKE) $(FLAGS_TO_PASS) DO=$@ "DODIRS=$(SUBDIRS)" subdir_do ++ ++# Traditionally "install" depends on "all". But it may be useful ++# not to; for example, if the user has made some trivial change to a ++# source file and doesn't care about rebuilding or just wants to save the ++# time it takes for make to check that all is up to date. ++# install-only is intended to address that need. ++install: all ++ @$(MAKE) $(FLAGS_TO_PASS) install-only ++ ++install-only: $(CONFIG_INSTALL) ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo gdb | sed -e "$$t"` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=gdb ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \ ++ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) gdb$(EXEEXT) \ ++ $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(includedir)/gdb ; \ ++ $(INSTALL_DATA) jit-reader.h $(DESTDIR)$(includedir)/gdb/jit-reader.h ++ if test "x$(HAVE_NATIVE_GCORE_TARGET)$(HAVE_NATIVE_GCORE_HOST)" != x; \ ++ then \ ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo gcore | sed -e "$$t"` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=gcore ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \ ++ $(INSTALL_SCRIPT) gcore \ ++ $(DESTDIR)$(bindir)/$$transformed_name; \ ++ fi ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo gdb-add-index | sed -e "$$t"` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=gdb-add-index ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ $(INSTALL_SCRIPT) $(srcdir)/contrib/gdb-add-index.sh \ ++ $(DESTDIR)$(bindir)/$$transformed_name ++ @$(MAKE) DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do ++ ++install-strip: ++ $(MAKE) $(FLAGS_TO_PASS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install-only ++ ++install-guile: ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/guile/gdb ++ ++install-python: ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb ++ ++uninstall: force $(CONFIG_UNINSTALL) ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo gdb | sed -e $$t` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=gdb ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \ ++ $(DESTDIR)$(man1dir)/$$transformed_name.1 ++ if test "x$(HAVE_NATIVE_GCORE_TARGET)$(HAVE_NATIVE_GCORE_HOST)" != x; \ ++ then \ ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo gcore | sed -e "$$t"` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=gcore ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ rm -f $(DESTDIR)$(bindir)/$$transformed_name; \ ++ fi ++ @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do ++ ++# The C++ name parser can be built standalone for testing. ++test-cp-name-parser.o: cp-name-parser.c ++ $(COMPILE) -DTEST_CPNAMES cp-name-parser.c ++ $(POSTCOMPILE) ++ ++test-cp-name-parser$(EXEEXT): test-cp-name-parser.o $(LIBIBERTY) ++ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) \ ++ -o test-cp-name-parser$(EXEEXT) test-cp-name-parser.o \ ++ $(LIBIBERTY) ++ ++# We do this by grepping through sources. If that turns out to be too slow, ++# maybe we could just require every .o file to have an initialization routine ++# of a given name (top.o -> _initialize_top, etc.). ++# ++# Formatting conventions: The name of the _initialize_* routines must start ++# in column zero, and must not be inside #if. ++# ++# Note that the set of files with init functions might change, or the names ++# of the functions might change, so this files needs to depend on all the ++# source files that will be linked into gdb. However, due to the way ++# this Makefile has generally been written, we do this indirectly, by ++# computing the list of source files from the list of object files. ++ ++INIT_FILES = \ ++ $(patsubst %.o,%.c, \ ++ $(patsubst %-exp.o,%-exp.y, \ ++ $(filter-out init.o version.o %_S.o %_U.o,\ ++ $(COMMON_OBS)))) ++ ++init.c: stamp-init; @true ++stamp-init: $(INIT_FILES) ++ @$(ECHO_INIT_C) echo "Making init.c" ++ @rm -f init.c-tmp init.l-tmp ++ @touch init.c-tmp ++ @-for f in $(INIT_FILES); do \ ++ sed -n -e 's/^_initialize_\([a-z_0-9A-Z]*\).*/\1/p' \ ++ $(srcdir)/$$f 2>/dev/null; \ ++ done > init.l-tmp ++ @echo '/* Do not modify this file. */' >>init.c-tmp ++ @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp ++ @echo '#include "defs.h" /* For initialize_file_ftype. */' >>init.c-tmp ++ @echo 'extern void initialize_all_files(void);' >>init.c-tmp ++ @sed -e 's/\(.*\)/extern initialize_file_ftype _initialize_\1;/' >init.c-tmp ++ @echo 'void' >>init.c-tmp ++ @echo 'initialize_all_files (void)' >>init.c-tmp ++ @echo '{' >>init.c-tmp ++ @sed -e 's/\(.*\)/ _initialize_\1 ();/' >init.c-tmp ++ @echo '}' >>init.c-tmp ++ @$(SHELL) $(srcdir)/../move-if-change init.c-tmp init.c ++ @echo stamp > stamp-init ++ ++.PRECIOUS: init.c ++ ++# Create a library of the gdb object files and build GDB by linking ++# against that. ++# ++# init.o is very important. It pulls in the rest of GDB. ++LIBGDB_OBS = $(sort $(COMMON_OBS)) init.o ++libgdb.a: $(LIBGDB_OBS) ++ -rm -f libgdb.a ++ $(AR) q libgdb.a $(LIBGDB_OBS) ++ $(RANLIB) libgdb.a ++ ++# Removing the old gdb first works better if it is running, at least on SunOS. ++gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS) ++ $(SILENCE) rm -f gdb$(EXEEXT) ++ @$(MAKE) -C ../.. GDB_FLAGS=-DGDB_10_2 library ++ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ ++ -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \ ++ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs) ++ifneq ($(CODESIGN_CERT),) ++ $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT) ++endif ++ ++# Convenience rule to handle recursion. ++.PHONY: all-data-directory ++all-data-directory: data-directory/Makefile ++ @$(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=data-directory subdir_do ++ ++# This is useful when debugging GDB, because some Unix's don't let you run GDB ++# on itself without copying the executable. So "make gdb1" will make ++# gdb and put a copy in gdb1, and you can run it with "gdb gdb1". ++# Removing gdb1 before the copy is the right thing if gdb1 is open ++# in another process. ++gdb1$(EXEEXT): gdb$(EXEEXT) ++ rm -f gdb1$(EXEEXT) ++ cp gdb$(EXEEXT) gdb1$(EXEEXT) ++ ++# Put the proper machine-specific files first, so M-. on a machine ++# specific routine gets the one for the correct machine. (FIXME: those ++# files go in twice; we should be removing them from the main list). ++ ++# TAGS depends on all the files that go into it so you can rebuild TAGS ++# with `make TAGS' and not have to say `rm TAGS' first. ++ ++GDB_NM_FILE = @GDB_NM_FILE@ ++TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR) ++ @echo Making TAGS ++ etags `(test -n "$(GDB_NM_FILE)" && echo "$(srcdir)/$(GDB_NM_FILE)")` \ ++ `(for i in $(DEPFILES) $(TAGFILES_NO_SRCDIR); do \ ++ echo $(srcdir)/$$i ; \ ++ done ; for i in $(TAGFILES_WITH_SRCDIR); do \ ++ echo $$i ; \ ++ done) | sed -e 's/\.o$$/\.c/'` \ ++ `find $(srcdir)/config -name '*.h' -print` ++ ++tags: TAGS ++ ++clean mostlyclean: $(CONFIG_CLEAN) ++ @$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do ++ rm -f *.o *.a *~ init.c-tmp init.l-tmp version.c-tmp ++ rm -f init.c stamp-init version.c stamp-version ++ rm -f gdb$(EXEEXT) core make.log ++ rm -f gdb[0-9]$(EXEEXT) ++ rm -f test-cp-name-parser$(EXEEXT) ++ rm -f xml-builtin.c stamp-xml ++ rm -f $(DEPDIR)/* ++ for i in $(CONFIG_SRC_SUBDIR); do \ ++ rm -f $$i/*.o; \ ++ rm -f $$i/$(DEPDIR)/*; \ ++ done ++ ++# This used to depend on c-exp.c m2-exp.c TAGS ++# I believe this is wrong; the makefile standards for distclean just ++# describe removing files; the only sort of "re-create a distribution" ++# functionality described is if the distributed files are unmodified. ++distclean: clean ++ @$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(CLEANDIRS)" subdir_do ++ rm -f nm.h config.status config.h stamp-h b jit-reader.h ++ rm -f gdb-gdb.py gdb-gdb.gdb ++ rm -f y.output yacc.acts yacc.tmp y.tab.h ++ rm -f config.log config.cache ++ rm -f Makefile ++ rm -rf $(DEPDIR) ++ for i in $(CONFIG_SRC_SUBDIR); do \ ++ if test -d $$i/$(DEPDIR); then rmdir $$i/$(DEPDIR); fi \ ++ done ++ ++maintainer-clean: local-maintainer-clean do-maintainer-clean distclean ++realclean: maintainer-clean ++ ++local-maintainer-clean: ++ @echo "This command is intended for maintainers to use;" ++ @echo "it deletes files that may require special tools to rebuild." ++ rm -f c-exp.c \ ++ cp-name-parser.c \ ++ ada-lex.c ada-exp.c \ ++ d-exp.c f-exp.c go-exp.c m2-exp.c p-exp.c rust-exp.c ++ rm -f TAGS ++ rm -f $(YYFILES) ++ rm -f nm.h config.status ++ ++do-maintainer-clean: ++ @$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(CLEANDIRS)" \ ++ subdir_do ++ ++diststuff: $(DISTSTUFF) $(PACKAGE).pot $(CATALOGS) ++ cd doc; $(MAKE) $(MFLAGS) diststuff ++ ++subdir_do: force ++ @for i in $(DODIRS); do \ ++ case $$i in \ ++ $(REQUIRED_SUBDIRS)) \ ++ if [ ! -f ./$$i/Makefile ] ; then \ ++ echo "Missing $$i/Makefile" >&2 ; \ ++ exit 1 ; \ ++ fi ;; \ ++ esac ; \ ++ if [ -f ./$$i/Makefile ] ; then \ ++ if (cd ./$$i; \ ++ $(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \ ++ else exit 1 ; fi ; \ ++ else true ; fi ; \ ++ done ++ ++Makefile: Makefile.in config.status ++ $(SHELL) config.status $@ ++ ++data-directory/Makefile: data-directory/Makefile.in config.status ++ $(SHELL) config.status $@ ++ ++.PHONY: run ++run: Makefile ++ ./gdb$(EXEEXT) --data-directory=`pwd`/data-directory $(GDBFLAGS) ++ ++jit-reader.h: $(srcdir)/jit-reader.in ++ $(SHELL) config.status $@ ++ ++gcore: $(srcdir)/gcore.in ++ $(SHELL) config.status $@ ++ ++gdb-gdb.py: $(srcdir)/gdb-gdb.py.in ++ $(SHELL) config.status $@ ++ ++gdb-gdb.gdb: $(srcdir)/gdb-gdb.gdb.in ++ $(SHELL) config.status $@ ++ ++config.h: stamp-h ; @true ++stamp-h: $(srcdir)/config.in config.status ++ $(SHELL) config.status config.h ++ ++nm.h: stamp-nmh ; @true ++stamp-nmh: config.status ++ $(SHELL) config.status nm.h ++ ++config.status: $(srcdir)/configure configure.nat configure.tgt configure.host ../bfd/development.sh ++ $(SHELL) config.status --recheck ++ ++ACLOCAL = aclocal ++ACLOCAL_AMFLAGS = -I ../config ++ ++# Keep these in sync with the includes in acinclude.m4. ++aclocal_m4_deps = \ ++ configure.ac \ ++ acx_configure_dir.m4 \ ++ transform.m4 \ ++ ../bfd/bfd.m4 \ ++ ../config/acinclude.m4 \ ++ ../config/enable.m4 \ ++ ../config/plugins.m4 \ ++ ../config/lead-dot.m4 \ ++ ../config/override.m4 \ ++ ../config/largefile.m4 \ ++ ../config/gettext-sister.m4 \ ++ ../config/lib-ld.m4 \ ++ ../config/lib-prefix.m4 \ ++ ../config/lib-link.m4 \ ++ ../config/acx.m4 \ ++ ../config/tcl.m4 \ ++ ../config/depstand.m4 \ ++ ../config/lcmessage.m4 \ ++ ../config/codeset.m4 \ ++ ../config/zlib.m4 \ ++ ../config/ax_pthread.m4 ++ ++$(srcdir)/aclocal.m4: @MAINTAINER_MODE_TRUE@ $(aclocal_m4_deps) ++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) ++ ++AUTOCONF = autoconf ++configure_deps = $(srcdir)/configure.ac $(srcdir)/aclocal.m4 ++$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(configure_deps) ++ cd $(srcdir) && $(AUTOCONF) ++ ++AUTOHEADER = autoheader ++$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@ $(configure_deps) ++ cd $(srcdir) && $(AUTOHEADER) ++ rm -f stamp-h ++ touch $@ ++ ++# automatic rebuilding in automake-generated Makefiles requires ++# this rule in the toplevel Makefile, which, with GNU make, causes ++# the desired updates through the implicit regeneration of the Makefile ++# and all of its prerequisites. ++am--refresh: ++ @: ++ ++force: ++ ++# Documentation! ++# GDB QUICK REFERENCE (TeX dvi file, CM fonts) ++doc/refcard.dvi: ++ cd doc; $(MAKE) refcard.dvi $(FLAGS_TO_PASS) ++ ++# GDB QUICK REFERENCE (PostScript output, common PS fonts) ++doc/refcard.ps: ++ cd doc; $(MAKE) refcard.ps $(FLAGS_TO_PASS) ++ ++# GDB MANUAL: TeX dvi file ++doc/gdb.dvi: ++ cd doc; $(MAKE) gdb.dvi $(FLAGS_TO_PASS) ++ ++# GDB MANUAL: info file ++doc/gdb.info: ++ cd doc; $(MAKE) gdb.info $(FLAGS_TO_PASS) ++ ++# Make copying.c from COPYING ++$(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copying.awk ++ awk -f $(srcdir)/copying.awk \ ++ < $(srcdir)/../COPYING3 > $(srcdir)/copying.tmp ++ mv $(srcdir)/copying.tmp $(srcdir)/copying.c ++ ++version.c: stamp-version; @true ++# Note that the obvious names for the temp file are taken by ++# create-version.sh. ++stamp-version: Makefile version.in $(srcdir)/../bfd/version.h $(srcdir)/../gdbsupport/create-version.sh ++ $(ECHO_GEN) $(SHELL) $(srcdir)/../gdbsupport/create-version.sh $(srcdir) \ ++ $(host_alias) $(target_alias) version-t.t ++ @$(SHELL) $(srcdir)/../move-if-change version-t.t version.c ++ @echo stamp > stamp-version ++ ++ ++gdb.cxref: $(SFILES) ++ cxref -I. $(SFILES) >gdb.cxref ++ ++force_update: ++ ++# GNU Make has an annoying habit of putting *all* the Makefile variables ++# into the environment, unless you include this target as a circumvention. ++# Rumor is that this will be fixed (and this target can be removed) ++# in GNU Make 4.0. ++.NOEXPORT: ++ ++# GNU Make 3.63 has a different problem: it keeps tacking command line ++# overrides onto the definition of $(MAKE). This variable setting ++# will remove them. ++MAKEOVERRIDES = ++ ++ALLDEPFILES = \ ++ aarch32-tdep.c \ ++ aarch64-fbsd-nat.c \ ++ aarch64-fbsd-tdep.c \ ++ aarch64-linux-nat.c \ ++ aarch64-linux-tdep.c \ ++ aarch64-newlib-tdep.c \ ++ aarch64-ravenscar-thread.c \ ++ aarch64-tdep.c \ ++ aix-thread.c \ ++ alpha-bsd-nat.c \ ++ alpha-bsd-tdep.c \ ++ alpha-linux-nat.c \ ++ alpha-linux-tdep.c \ ++ alpha-mdebug-tdep.c \ ++ alpha-nbsd-tdep.c \ ++ alpha-obsd-tdep.c \ ++ alpha-tdep.c \ ++ amd64-bsd-nat.c \ ++ amd64-darwin-tdep.c \ ++ amd64-dicos-tdep.c \ ++ amd64-fbsd-nat.c \ ++ amd64-fbsd-tdep.c \ ++ amd64-linux-nat.c \ ++ amd64-linux-tdep.c \ ++ amd64-nat.c \ ++ amd64-nbsd-nat.c \ ++ amd64-nbsd-tdep.c \ ++ amd64-obsd-nat.c \ ++ amd64-obsd-tdep.c \ ++ amd64-sol2-tdep.c \ ++ amd64-tdep.c \ ++ arc-tdep.c \ ++ arm.c \ ++ arm-bsd-tdep.c \ ++ arm-fbsd-nat.c \ ++ arm-fbsd-tdep.c \ ++ arm-get-next-pcs.c \ ++ arm-linux.c \ ++ arm-linux-nat.c \ ++ arm-linux-tdep.c \ ++ arm-nbsd-nat.c \ ++ arm-nbsd-tdep.c \ ++ arm-obsd-tdep.c \ ++ arm-symbian-tdep.c \ ++ arm-tdep.c \ ++ avr-tdep.c \ ++ bfin-linux-tdep.c \ ++ bfin-tdep.c \ ++ bpf-tdep.c \ ++ bsd-kvm.c \ ++ bsd-uthread.c \ ++ csky-linux-tdep.c \ ++ csky-tdep.c \ ++ darwin-nat.c \ ++ dicos-tdep.c \ ++ fbsd-nat.c \ ++ fbsd-tdep.c \ ++ fork-child.c \ ++ ft32-tdep.c \ ++ glibc-tdep.c \ ++ go32-nat.c \ ++ h8300-tdep.c \ ++ hppa-bsd-tdep.c \ ++ hppa-linux-nat.c \ ++ hppa-linux-tdep.c \ ++ hppa-nbsd-nat.c \ ++ hppa-nbsd-tdep.c \ ++ hppa-obsd-nat.c \ ++ hppa-obsd-tdep.c \ ++ hppa-tdep.c \ ++ i386-bsd-nat.c \ ++ i386-bsd-tdep.c \ ++ i386-darwin-nat.c \ ++ i386-darwin-tdep.c \ ++ i386-dicos-tdep.c \ ++ i386-fbsd-nat.c \ ++ i386-fbsd-tdep.c \ ++ i386-gnu-nat.c \ ++ i386-gnu-tdep.c \ ++ i386-linux-nat.c \ ++ i386-linux-tdep.c \ ++ i386-nbsd-nat.c \ ++ i386-nbsd-tdep.c \ ++ i386-obsd-nat.c \ ++ i386-obsd-tdep.c \ ++ i386-sol2-nat.c \ ++ i386-sol2-tdep.c \ ++ i386-tdep.c \ ++ i386-windows-tdep.c \ ++ i387-tdep.c \ ++ ia64-libunwind-tdep.c \ ++ ia64-linux-nat.c \ ++ ia64-linux-tdep.c \ ++ ia64-tdep.c \ ++ ia64-vms-tdep.c \ ++ inf-ptrace.c \ ++ linux-fork.c \ ++ linux-record.c \ ++ linux-tdep.c \ ++ lm32-tdep.c \ ++ m32r-linux-nat.c \ ++ m32r-linux-tdep.c \ ++ m32r-tdep.c \ ++ m68hc11-tdep.c \ ++ m68k-bsd-nat.c \ ++ m68k-bsd-tdep.c \ ++ m68k-linux-nat.c \ ++ m68k-linux-tdep.c \ ++ m68k-tdep.c \ ++ microblaze-linux-tdep.c \ ++ microblaze-tdep.c \ ++ mingw-hdep.c \ ++ mips-fbsd-nat.c \ ++ mips-fbsd-tdep.c \ ++ mips-linux-nat.c \ ++ mips-linux-tdep.c \ ++ mips-nbsd-nat.c \ ++ mips-nbsd-tdep.c \ ++ mips-sde-tdep.c \ ++ mips-tdep.c \ ++ mips64-obsd-nat.c \ ++ mips64-obsd-tdep.c \ ++ msp430-tdep.c \ ++ nbsd-nat.c \ ++ nbsd-tdep.c \ ++ nds32-tdep.c \ ++ nios2-linux-tdep.c \ ++ nios2-tdep.c \ ++ obsd-nat.c \ ++ obsd-tdep.c \ ++ posix-hdep.c \ ++ ppc-fbsd-nat.c \ ++ ppc-fbsd-tdep.c \ ++ ppc-linux-nat.c \ ++ ppc-linux-tdep.c \ ++ ppc-nbsd-nat.c \ ++ ppc-nbsd-tdep.c \ ++ ppc-obsd-nat.c \ ++ ppc-obsd-tdep.c \ ++ ppc-ravenscar-thread.c \ ++ ppc-sysv-tdep.c \ ++ ppc64-tdep.c \ ++ procfs.c \ ++ ravenscar-thread.c \ ++ remote-sim.c \ ++ riscv-fbsd-nat.c \ ++ riscv-fbsd-tdep.c \ ++ riscv-linux-nat.c \ ++ riscv-linux-tdep.c \ ++ riscv-ravenscar-thread.c \ ++ riscv-tdep.c \ ++ rl78-tdep.c \ ++ rs6000-lynx178-tdep.c \ ++ rs6000-nat.c \ ++ rs6000-tdep.c \ ++ rx-tdep.c \ ++ s390-linux-nat.c \ ++ s390-linux-tdep.c \ ++ s390-tdep.c \ ++ score-tdep.c \ ++ ser-go32.c \ ++ ser-mingw.c \ ++ ser-pipe.c \ ++ ser-tcp.c \ ++ ser-uds.c \ ++ sh-nbsd-nat.c \ ++ sh-nbsd-tdep.c \ ++ sh-tdep.c \ ++ sol2-tdep.c \ ++ solib-aix.c \ ++ solib-svr4.c \ ++ sparc-linux-nat.c \ ++ sparc-linux-tdep.c \ ++ sparc-nat.c \ ++ sparc-nbsd-nat.c \ ++ sparc-nbsd-tdep.c \ ++ sparc-obsd-tdep.c \ ++ sparc-ravenscar-thread.c \ ++ sparc-sol2-nat.c \ ++ sparc-sol2-tdep.c \ ++ sparc-tdep.c \ ++ sparc64-fbsd-nat.c \ ++ sparc64-fbsd-tdep.c \ ++ sparc64-linux-nat.c \ ++ sparc64-linux-tdep.c \ ++ sparc64-nat.c \ ++ sparc64-nbsd-nat.c \ ++ sparc64-nbsd-tdep.c \ ++ sparc64-obsd-nat.c \ ++ sparc64-obsd-tdep.c \ ++ sparc64-sol2-tdep.c \ ++ sparc64-tdep.c \ ++ tilegx-linux-nat.c \ ++ tilegx-linux-tdep.c \ ++ tilegx-tdep.c \ ++ v850-tdep.c \ ++ vax-bsd-nat.c \ ++ vax-nbsd-tdep.c \ ++ vax-tdep.c \ ++ windows-nat.c \ ++ windows-tdep.c \ ++ x86-nat.c \ ++ x86-tdep.c \ ++ xcoffread.c \ ++ xstormy16-tdep.c \ ++ xtensa-config.c \ ++ xtensa-linux-nat.c \ ++ xtensa-linux-tdep.c \ ++ xtensa-tdep.c \ ++ xtensa-xtregs.c ++ ++# Some files need explicit build rules (due to -Werror problems) or due ++# to sub-directory fun 'n' games. ++ ++# ada-exp.c can appear in srcdir, for releases; or in ., for ++# development builds. ++ADA_EXP_C = `if test -f ada-exp.c; then echo ada-exp.c; else echo $(srcdir)/ada-exp.c; fi` ++ ++ada-exp.o: ada-exp.c ++ $(COMPILE) $(ADA_EXP_C) ++ $(POSTCOMPILE) ++ ++# Message files. Based on code in gcc/Makefile.in. ++ ++# Rules for generating translated message descriptions. Disabled by ++# autoconf if the tools are not available. ++ ++.PHONY: all-po install-po uninstall-po clean-po update-po $(PACKAGE).pot ++ ++all-po: $(CATALOGS) ++ ++# This notation should be acceptable to all Make implementations used ++# by people who are interested in updating .po files. ++update-po: $(CATALOGS:.gmo=.pox) ++ ++# N.B. We do not attempt to copy these into $(srcdir). The snapshot ++# script does that. ++%.gmo: %.po ++ -test -d po || mkdir po ++ $(GMSGFMT) --statistics -o $@ $< ++ ++# The new .po has to be gone over by hand, so we deposit it into ++# build/po with a different extension. If build/po/$(PACKAGE).pot ++# exists, use it (it was just created), else use the one in srcdir. ++%.pox: %.po ++ -test -d po || mkdir po ++ $(MSGMERGE) $< `if test -f po/$(PACKAGE).pot; \ ++ then echo po/$(PACKAGE).pot; \ ++ else echo $(srcdir)/po/$(PACKAGE).pot; fi` -o $@ ++ ++# This rule has to look for .gmo modules in both srcdir and the cwd, ++# and has to check that we actually have a catalog for each language, ++# in case they weren't built or included with the distribution. ++install-po: ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(datadir) ++ cats="$(CATALOGS)"; for cat in $$cats; do \ ++ lang=`basename $$cat | sed 's/\.gmo$$//'`; \ ++ if [ -f $$cat ]; then :; \ ++ elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \ ++ else continue; \ ++ fi; \ ++ dir=$(localedir)/$$lang/LC_MESSAGES; \ ++ echo $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$$dir; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$$dir || exit 1; \ ++ echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ ++ $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ ++ done ++uninstall-po: ++ cats="$(CATALOGS)"; for cat in $$cats; do \ ++ lang=`basename $$cat | sed 's/\.gmo$$//'`; \ ++ if [ -f $$cat ]; then :; \ ++ elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \ ++ else continue; \ ++ fi; \ ++ dir=$(localedir)/$$lang/LC_MESSAGES; \ ++ rm -f $(DESTDIR)$$dir/$(PACKAGE).mo; \ ++ done ++# Delete po/*.gmo only if we are not building in the source directory. ++clean-po: ++ -if [ ! -f Makefile.in ]; then rm -f po/*.gmo; fi ++ ++# Rule for regenerating the message template (gdb.pot). Instead of ++# forcing everyone to edit POTFILES.in, which proved impractical, this ++# rule has no dependencies and always regenerates gdb.pot. This is ++# relatively harmless since the .po files do not directly depend on ++# it. The .pot file is left in the build directory. Since GDB's ++# Makefile lacks a cannonical list of sources (missing xm, tm and nm ++# files) force this rule. ++$(PACKAGE).pot: po/$(PACKAGE).pot ++po/$(PACKAGE).pot: force ++ -test -d po || mkdir po ++ sh -e $(srcdir)/po/gdbtext $(XGETTEXT) $(PACKAGE) . $(srcdir) ++ ++ ++# ++# YACC/LEX dependencies ++# ++# LANG-exp.c is generated in objdir from LANG-exp.y if it doesn't ++# exist in srcdir, then compiled in objdir to LANG-exp.o. If we ++# said LANG-exp.c rather than ./c-exp.c some makes would ++# sometimes re-write it into $(srcdir)/c-exp.c. Remove bogus ++# decls for malloc/realloc/free which conflict with everything else. ++# Strictly speaking c-exp.c should therefore depend on ++# Makefile.in, but that was a pretty big annoyance. ++ ++%.c: %.y ++ $(ECHO_YACC) $(SHELL) $(YLWRAP) $< y.tab.c $@.tmp -- \ ++ $(YACC) $(YFLAGS) || (rm -f $@.tmp; false) ++ @sed -e '/extern.*malloc/d' \ ++ -e '/extern.*realloc/d' \ ++ -e '/extern.*free/d' \ ++ -e '/include.*malloc.h/d' \ ++ -e 's/\([^x]\)malloc/\1xmalloc/g' \ ++ -e 's/\([^x]\)realloc/\1xrealloc/g' \ ++ -e 's/\([ \t;,(]\)free\([ \t]*[&(),]\)/\1xfree\2/g' \ ++ -e 's/\([ \t;,(]\)free$$/\1xfree/g' \ ++ -e '/^#line.*y.tab.c/d' \ ++ -e 's/YY_NULL/YY_NULLPTR/g' \ ++ < $@.tmp > $@.new && \ ++ rm -f $@.tmp && \ ++ mv $@.new $@ ++%.c: %.l ++ $(ECHO_LEX) $(FLEX) -t $< \ ++ | sed -e '/extern.*malloc/d' \ ++ -e '/extern.*realloc/d' \ ++ -e '/extern.*free/d' \ ++ -e '/include.*malloc.h/d' \ ++ -e 's/\([^x]\)malloc/\1xmalloc/g' \ ++ -e 's/\([^x]\)realloc/\1xrealloc/g' \ ++ -e 's/\([ \t;,(]\)free\([ \t]*[&(),]\)/\1xfree\2/g' \ ++ -e 's/\([ \t;,(]\)free$$/\1xfree/g' \ ++ -e 's/yy_flex_xrealloc/yyxrealloc/g' \ ++ > $@.new && \ ++ mv $@.new $@ ++ ++.PRECIOUS: ada-lex.c ++ ++# XML rules ++ ++xml-builtin.c: stamp-xml; @true ++stamp-xml: $(srcdir)/features/feature_to_c.sh Makefile $(XMLFILES) ++ $(SILENCE) rm -f xml-builtin.tmp ++ $(ECHO_GEN_XML_BUILTIN) AWK="$(AWK)" \ ++ $(SHELL) $(srcdir)/features/feature_to_c.sh \ ++ xml-builtin.tmp $(XMLFILES) ++ $(SILENCE) $(SHELL) $(srcdir)/../move-if-change xml-builtin.tmp xml-builtin.c ++ $(SILENCE) echo stamp > stamp-xml ++ ++.PRECIOUS: xml-builtin.c ++ ++# ++# GDBTK sub-directory ++# ++ ++all-gdbtk: insight$(EXEEXT) ++ ++install-gdbtk: ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo insight | sed -e $$t` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=insight ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir); \ ++ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) insight$(EXEEXT) \ ++ $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs \ ++ $(DESTDIR)$(GDBTK_LIBRARY) ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs \ ++ $(DESTDIR)$(libdir)/insight$(GDBTK_VERSION) ; \ ++ $(INSTALL_DATA) $(srcdir)/gdbtk/plugins/plugins.tcl \ ++ $(DESTDIR)$(libdir)/insight$(GDBTK_VERSION)/plugins.tcl ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs \ ++ $(DESTDIR)$(GDBTK_LIBRARY)/images \ ++ $(DESTDIR)$(GDBTK_LIBRARY)/images2 ; \ ++ $(SHELL) $(srcdir)/../mkinstalldirs \ ++ $(DESTDIR)$(GDBTK_LIBRARY)/help \ ++ $(DESTDIR)$(GDBTK_LIBRARY)/help/images \ ++ $(DESTDIR)$(GDBTK_LIBRARY)/help/trace ; \ ++ cd $(srcdir)/gdbtk/library ; \ ++ for i in *.tcl *.itcl *.ith *.itb images/*.gif images2/*.gif images/icons.txt images2/icons.txt tclIndex help/*.html help/trace/*.html help/trace/index.toc help/images/*.gif help/images/*.png; \ ++ do \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(GDBTK_LIBRARY)/$$i ; \ ++ done ; ++ ++uninstall-gdbtk: ++ transformed_name=`t='$(program_transform_name)'; \ ++ echo insight | sed -e $$t` ; \ ++ if test "x$$transformed_name" = x; then \ ++ transformed_name=insight ; \ ++ else \ ++ true ; \ ++ fi ; \ ++ rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \ ++ rm -rf $(DESTDIR)$(GDBTK_LIBRARY) ++ ++clean-gdbtk: ++ rm -f insight$(EXEEXT) ++ ++# Removing the old gdb first works better if it is running, at least on SunOS. ++insight$(EXEEXT): gdbtk-main.o libgdb.a $(CDEPS) $(TDEPLIBS) ++ rm -f insight$(EXEEXT) ++ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ ++ -o insight$(EXEEXT) gdbtk-main.o libgdb.a \ ++ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) ++ ++gdbres.o: $(srcdir)/gdbtk/gdb.rc $(srcdir)/gdbtk/gdbtool.ico ++ $(WINDRES) --include $(srcdir)/gdbtk $(srcdir)/gdbtk/gdb.rc gdbres.o ++ ++all_gdbtk_cflags = $(IDE_CFLAGS) $(ITCL_CFLAGS) \ ++ $(ITK_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \ ++ $(GDBTK_CFLAGS) \ ++ -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\" \ ++ -DSRC_DIR=\"$(GDBTK_SRC_DIR)\" ++ ++# ++# Dependency tracking. ++# ++ ++ifeq ($(DEPMODE),depmode=gcc3) ++# Note that we put the dependencies into a .Tpo file, then move them ++# into place if the compile succeeds. We need this because gcc does ++# not atomically write the dependency output file. ++override COMPILE.post = -c -o $@ -MT $@ -MMD -MP \ ++ -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo ++override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo \ ++ $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Po ++else ++override COMPILE.pre = source='$<' object='$@' libtool=no \ ++ DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \ ++ $(CXX) -x c++ $(CXX_DIALECT) ++# depcomp handles atomicity for us, so we don't need a postcompile ++# step. ++override POSTCOMPILE = ++endif ++ ++# A list of all the objects we might care about in this build, for ++# dependency tracking. ++all_object_files = gdb.o $(LIBGDB_OBS) gdbtk-main.o \ ++ test-cp-name-parser.o ++ ++# All the .deps files to include. ++all_deps_files = $(foreach dep,$(patsubst %.o,%.Po,$(all_object_files)),\ ++ $(dir $(dep))/$(DEPDIR)/$(notdir $(dep))) ++ ++# Ensure that generated files are created early. Use order-only ++# dependencies if available. They require GNU make 3.80 or newer, ++# and the .VARIABLES variable was introduced at the same time. ++ifdef .VARIABLES ++$(all_object_files): | $(generated_files) ++else ++$(all_object_files) : $(generated_files) ++endif ++ ++# Dependencies. ++-include $(all_deps_files) ++ ++# Disable implicit make rules. ++include $(srcdir)/disable-implicit-rules.mk ++ ++### end of the gdb Makefile.in. +diff -Nuar gdb-10.2/gdb/nat/linux-waitpid.h gdb-10.2/gdb/nat/linux-waitpid.h +--- gdb-10.2/gdb/nat/linux-waitpid.h 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdb/nat/linux-waitpid.h 2025-04-16 17:06:51.972086800 +0800 +@@ -1,6 +1,6 @@ + /* Wrapper for waitpid for GNU/Linux (LWP layer). + +- Copyright (C) 2000-2021 Free Software Foundation, Inc. ++ Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -20,6 +20,7 @@ + #ifndef NAT_LINUX_WAITPID_H + #define NAT_LINUX_WAITPID_H + ++#define MAXCGS 4//sw_64-linux-watch.c + /* Wrapper function for waitpid which handles EINTR. */ + extern int my_waitpid (int pid, int *status, int flags); + +diff -Nuar gdb-10.2/gdb/nat/sw_64-linux-watch.c gdb-10.2/gdb/nat/sw_64-linux-watch.c +--- gdb-10.2/gdb/nat/sw_64-linux-watch.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/nat/sw_64-linux-watch.c 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,224 @@ ++/* Copyright (C) 2009-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "gdbsupport/common-defs.h" ++#include "nat/gdb_ptrace.h" ++#include "nat/linux-ptrace.h" ++#include "sw_64-linux-watch.h" ++#include ++#include ++#include ++#include ++#include ++ ++unsigned long cgmap, spemap[MAXCGS]; ++ ++/* It's decided by NINSERTS_INIT and entry__init. ++ * NINSERTS_INIT defined in nat/sw_64-linux-watch.h and filled in alpha-tdep.c. ++ * The number of NINSERTS_INIT must be fully filled at entry__init and equal to the inserted instructions ++ **/ ++//extern long slave_Ax_hwbpt; ++ ++//slave_state_t slave_state[MAXCGS]; ++ ++#ifdef GDBSERVER ++extern int debug_threads; ++#define debug(format, ... ) do { \ ++ if (debug_threads) {\ ++ fprintf(stdout, "%s,%d:%s:", __FILE__, __LINE__,__func__); \ ++ fprintf(stdout, format, ##__VA_ARGS__); \ ++ fprintf(stdout, "\n"); \ ++ fflush(stdout); \ ++ } \ ++ } while (0) ++extern int delete_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind); ++#else ++extern int debug_infrun; ++#define debug(format, ... ) do { \ ++ if (debug_infrun){ \ ++ fprintf(stdout, "%s,%d:%s:", __FILE__, __LINE__,__func__); \ ++ fprintf(stdout, format, ##__VA_ARGS__); \ ++ fprintf(stdout, "\n"); \ ++ fflush(stdout); \ ++ } \ ++ } while (0) ++#endif ++ ++int read_debug_register (pid_t pid, int regno, long *val) ++{ ++ int ret; ++ errno = 0; ++ ++ if (SPE_LWP(pid)) ++ ret = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3) regno, val); ++ else ++ *val = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3) regno, 0); ++ ++ if ( ret < 0 || errno != 0) ++ { ++ warning("lwp %x write $%d failed \n", pid, regno); ++ return 0; ++ } ++ return 1; ++} ++ ++int store_debug_register (pid_t pid, int regno, long val) ++{ ++ int ret; ++ debug("store tid %x CSR %d, val = %#lx", pid, regno, val); ++ errno = 0; ++ ret = ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3) regno, val); ++ errno = 0; ++ errno = 0; ++ ret = ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3) regno, val); ++ if ( ret < 0 || errno != 0) ++ { ++ warning("lwp %x write $%d failed \n", pid, regno); ++ return 0; ++ } ++ return 1; ++} ++ ++int is_power_of_2 (int val) ++{ ++ int i, onecount; ++ ++ onecount = 0; ++ for (i = 0; i < 8 * sizeof (val); i++) ++ if (val & (1 << i)) ++ onecount++; ++ ++ return onecount <= 1; ++} ++ ++int sw_64_read_insn(pid_t pid, ulong pc) ++{ ++ int insn; ++ long tmp, data; ++ ++ tmp = pc & ~0x7; ++ data = ptrace(PTRACE_PEEKTEXT, pid, tmp, 0); ++ if ( pc & 0x7) ++ insn = (int)(data>>32); ++ else ++ insn = (int)data; ++ return insn; ++} ++ ++int sw_64_linux_try_one_watch (pid_t lwpid, struct arch_lwp_info *info, ++ enum sw_64_hw_bp_type wpt_type, long addr, int len) ++{ ++ long data; ++ int found = 0; ++ struct pt_watch_regs *wpt = info->wpt; ++ ++ if (!addr || !is_power_of_2 (len)) ++ return 0; ++ if ( wpt_type == sw_64_vstore) ++ { ++ debug("insert master wp %lx, dv_match len = %d", (long)addr, len); ++ ++ info->value_address = addr; //saved ++ wpt[1].match = ptrace(PTRACE_PEEKDATA, lwpid, addr, 0); //dv_match ++ wpt[1].mask = (len &0x8)?0xffffffffffffffffUL:0xffffffffUL; //dv_mask ++ wpt[1].match &= wpt[1].mask; ++ wpt[1].valid = 1; ++ ++ if (wpt[0].valid) ++ { ++ data = wpt[0].match & ((1L<<53)-1); ++ ++ wpt[0].match = sw_64_write; ++ wpt->match <<= 53; ++ wpt->match |= data; ++ /* wpt->mask not changed */ ++ } ++ } ++ else ++ { ++ debug("insert master wp %lx, da_match len = %d", (long)addr, len); ++ wpt->match = wpt_type&0x3; ++ wpt->match <<= 53; ++ wpt->match |= addr & ((1L<<53)-1); ++ data = len -1; ++ wpt->mask = ~data & ((1L<<53)-1); ++ wpt->valid = 1; ++ } ++ ++ found = 1; ++ ++ if (!found) ++ error("hardware wpt resource empty\n"); ++ return 1; ++} ++ ++ ++int sw_64_linux_del_one_watch (pid_t lwpid, struct arch_lwp_info *info, ++ enum sw_64_hw_bp_type wpt_type, long addr, int len) ++{ ++ int deleted_one = 0; ++ long match; ++ struct pt_watch_regs *wpt = info->wpt; ++ ++ if ( wpt_type == sw_64_vstore ) ++ { ++ wpt[1].valid = 0; ++ wpt[0].valid = 0; ++ debug("to remove master wp %#lx, dv_match", (long)addr); ++ info->value_address = 0L; //clr the saved ++ return 1; ++ } ++ match = wpt_type&0x3; ++ match <<= 53; ++ match |= addr&((1L<<53)-1); ++ ++ if ( wpt->valid && (match == wpt->match )) ++ { ++ wpt->match &= ~(0x3L<<53); ++ wpt->valid = 0; ++ // deleted_one ++; ++ debug("to remove master wp %#lx, da_match", (long)addr); ++ return 1; ++ } ++ ++ return deleted_one>0; ++} ++ ++/* gdb712 has this function, but gdb821 deleted the interface of ptid_get_pid */ ++//int sw_64_linux_enable_sdebug(ptid_t master) ++//{ ++// int i; ++// pid_t pid; ++// ++// /* sw7run calloc score!!!! */ ++// //pid = ptid_get_pid(master); ++// pid = master.pid (); ++// /* Maybe master-only, maybe slave unspawned */ ++// if ( !cgmap) ++// return 1; ++// ++// ALLCGS(cgmap, i) ++// { ++// //debug("set debugging flag for scores %#lx", spemap[i]); ++// if ( ptrace(PTRACE_TRACESPE, 1<<31|i<<6, spemap[i], 0) < 0) ++// { ++// warning("PTRACE_TRACESPE: CG<%d>SPE<%lx> ...", i, spemap[i]); ++// return 0; ++// } ++// } ++// return 1; ++//} +diff -Nuar gdb-10.2/gdb/nat/sw_64-linux-watch.h gdb-10.2/gdb/nat/sw_64-linux-watch.h +--- gdb-10.2/gdb/nat/sw_64-linux-watch.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/nat/sw_64-linux-watch.h 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,178 @@ ++/* Copyright (C) 2009-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef NAT_SW_64_LINUX_WATCH_H ++#define NAT_SW_64_LINUX_WATCH_H 1 ++ ++#include ++#include "gdbsupport/break-common.h" ++#include "linux-waitpid.h" // include defs of MAXCGS ++ ++#define MAXSPE 64 ++#define SW7AOP 28 ++#define SW7ARA 22 ++#define SW7ARB 16 ++#define SW7ARC 6 ++#define MAXDISPI 10 ++#define NINSERTS_INIT 68 //must be actual number of inserted ++#define OFFSET22b 0x3fffff ++ ++/* master watchpoint si_code == __SI_FAULT|M_DA_MATCH_TRAP */ ++#define __SI_FAULT (3 << 16) ++#define M_DA_MATCH_TRAP 4 ++ ++#ifndef ALPHA_INSN_SIZE ++#define ALPHA_INSN_SIZE 4 ++#endif ++#define SPE_COREID(pid) (pid & 0x3fUL) ++#define SPE_CGID(pid) (0x7&(pid>>6)) ++#define SPE_TID(cg,core) (unsigned long)(SPE_COREID(core) | 1UL<<31 | (cg)<<6) ++#define SPE_LWP(pid) (pid&(1<<31)) ++ ++enum ptrace_extend_request { ++ PTRACE_TRACESPE = 10, ++ PTRACE_GET_SCORE = 20, ++}; ++ ++enum { ++ REG_R0 = 0, ++ REG_SP = 30, ++ REG_F0 = 32, ++ REG_FPCR = 63, ++ REG_PC = 64, ++ UNIQUE_ADDR =65, ++ REG_V0F1 = 67, ++ SPE_V0 = 70, ++ REG_V0F2 = 99, ++ REG_V0F3 = 131, ++ M_DA_MATCH = 163 , ++ M_DA_MASK, ++ M_DV_MATCH = 165 , ++ M_DV_MASK, ++}; ++ ++enum { ++ S_DA_MATCH0 = 65, ++ S_DA_MATCH1, ++ S_DA_MASK0, ++ S_DA_MASK1, ++}; ++ ++ ++enum sw_64_hw_bp_type ++{ ++ sw_64_none = 0, /* not match, or Execute HW breakpoint */ ++ sw_64_read = 1, /* Read HW watchpoint */ ++ sw_64_write = 2, /* Common HW watchpoint */ ++ sw_64_access = 3, /* Access HW watchpoint */ ++ sw_64_vstore = 4, ++}; ++ ++typedef unsigned long ulong; ++ ++#define ALLCGS(bitmap, cg) \ ++ for (cg=0; cg>32)) ++#define IBXBPT_L_SET(ibx, addr) {\ ++ ibx &= ~0x0ffffffffUL;\ ++ ibx |= SPCMASK(addr);\ ++ ibx |= (1UL<<31); \ ++} ++ ++#define IBXBPT_H_SET(ibx, addr) {\ ++ ibx &= ~(0xffffffffL<<32); \ ++ ibx |= (1UL<<63)|(SPCMASK(addr)<<32); \ ++} ++ ++ ++#define STOPPED_SPC(cg,core) slave_state[cg].pc[core] ++ ++extern unsigned long entry__init; ++extern unsigned int size__init; ++extern unsigned long cgmap, spemap[]; ++ ++/* A value of zero in a watchlo indicates that it is available. */ ++ ++struct pt_watch_regs ++{ ++ uint64_t match; ++ uint64_t mask; ++ int valid; ++} __attribute__ ((aligned (8))); ++ ++ ++/* Per-thread arch-specific data we want to keep. */ ++#define MAX_BPTS 1 ++#define MAX_WPTS 2 ++ ++#define MAX_DA_MATECH 2 ++struct arch_lwp_info ++{ ++ /* Non-zero if our copy differs from what's recorded in the thread. */ ++ int watch_registers_changed; ++ int watch_matched; ++ ++ struct pt_watch_regs wpt[MAX_DA_MATECH]; ++ ++ /* Cached stopped data address. */ ++ CORE_ADDR stopped_data_address; ++ CORE_ADDR value_address; ++ /* tls cs */ ++ long ebxio_def0; ++#ifndef LHX20201112 ++ char matched; ++ /* Non-zero if our copy differs from what's recorded in the thread. */ ++ char bpts_changed[MAX_BPTS]; ++ char wpts_changed[MAX_WPTS]; ++#endif ++ ++}; ++ ++ ++#define IRW_MASK 0xffffffffffffUL ++ ++/* We keep list of all watchpoints we should install and calculate the ++ watch register values each time the list changes. This allows for ++ easy sharing of watch registers for more than one watchpoint. */ ++ ++struct sw_64_watchpoint ++{ ++ CORE_ADDR addr; ++ int len; ++ enum target_hw_bp_type type; ++ struct sw_64_watchpoint *next; ++}; ++ ++ ++int is_power_of_2 (int val); ++int sw_64_linux_try_one_watch (pid_t , struct arch_lwp_info *, enum sw_64_hw_bp_type , long , int ); ++int sw_64_linux_del_one_watch (pid_t , struct arch_lwp_info *, enum sw_64_hw_bp_type , long , int ); ++int read_debug_register (pid_t pid, int regno, long *val); ++int store_debug_register (pid_t pid, int regno, long val); ++int expt_thr_handler(ptid_t ptid/* master */, int cg, int core, struct expt_inf *inf); ++ ++#endif /* NAT_SW_64_LINUX_WATCH_H */ +diff -Nuar gdb-10.2/gdb/objfiles.h gdb-10.2/gdb/objfiles.h +--- gdb-10.2/gdb/objfiles.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/objfiles.h 2025-04-16 17:06:41.902086800 +0800 +@@ -747,9 +747,9 @@ + + extern int objfile_has_symbols (struct objfile *objfile); + +-extern int have_partial_symbols (void); ++extern "C" int have_partial_symbols (void); + +-extern int have_full_symbols (void); ++extern "C" int have_full_symbols (void); + + extern void objfile_set_sym_fns (struct objfile *objfile, + const struct sym_fns *sf); +diff -Nuar gdb-10.2/gdb/printcmd.c gdb-10.2/gdb/printcmd.c +--- gdb-10.2/gdb/printcmd.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/printcmd.c 2025-04-16 17:06:41.922086800 +0800 +@@ -524,6 +524,9 @@ + form. However note that DO_DEMANGLE can be overridden by the specific + settings of the demangle and asm_demangle variables. Returns + non-zero if anything was printed; zero otherwise. */ ++#ifdef CRASH_MERGE ++extern "C" int gdb_print_callback(unsigned long); ++#endif + + int + print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, +@@ -535,6 +538,12 @@ + int offset = 0; + int line = 0; + ++#ifdef CRASH_MERGE ++ if (!gdb_print_callback(addr)) { ++ return 0; ++ } ++#endif ++ + if (build_address_symbolic (gdbarch, addr, do_demangle, false, &name, + &offset, &filename, &line, &unmapped)) + return 0; +@@ -567,6 +576,10 @@ + + /* See valprint.h. */ + ++#ifdef CRASH_MERGE ++extern "C" char *gdb_lookup_module_symbol(unsigned long, unsigned long *); ++#endif ++ + int + build_address_symbolic (struct gdbarch *gdbarch, + CORE_ADDR addr, /* IN */ +@@ -673,7 +686,19 @@ + } + } + if (symbol == NULL && msymbol.minsym == NULL) ++#ifdef CRASH_MERGE ++ { ++ char *name_ptr = gdb_lookup_module_symbol(addr, (unsigned long *)offset); ++ if (name_ptr) { ++ *name = name_ptr; ++ return 0; ++ } else { ++ return 1; ++ } ++ } ++#else + return 1; ++#endif + + /* If the nearest symbol is too far away, don't print anything symbolic. */ + +@@ -1221,6 +1246,43 @@ + print_value (val, print_opts); + } + ++static void ++print_command_2 (const char *args, int voidprint) ++{ ++ struct value *val; ++ value_print_options print_opts; ++ ++ get_user_print_options (&print_opts); ++ /* Override global settings with explicit options, if any. */ ++ auto group = make_value_print_options_def_group (&print_opts); ++ gdb::option::process_options ++ (&args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group); ++ ++ print_command_parse_format (&args, "print", &print_opts); ++ ++ const char *exp = args; ++ ++ if (exp != nullptr && *exp) ++ { ++ expression_up expr = parse_expression (exp); ++ val = evaluate_expression (expr.get ()); ++ } ++ else ++ val = access_value_history (0); ++ ++ printf_filtered ("%d %d %ld %ld %ld %ld\n", ++ check_typedef(value_type (val))->code(), ++ TYPE_UNSIGNED (check_typedef(value_type (val))), ++ TYPE_LENGTH (check_typedef(value_type(val))), ++ value_offset (val), value_bitpos (val), value_bitsize(val)); ++} ++ ++static void ++printm_command (const char *exp, int from_tty) ++{ ++ print_command_2 (exp, 1); ++} ++ + /* See valprint.h. */ + + void +@@ -2855,6 +2917,12 @@ + c = add_com ("print", class_vars, print_command, print_help.c_str ()); + set_cmd_completer_handle_brkchars (c, print_command_completer); + add_com_alias ("p", "print", class_vars, 1); ++ ++ c = add_com ("printm", class_vars, printm_command, _("\ ++Similar to \"print\" command, but it used to print the type, size, offset,\n\ ++bitpos and bitsize of the expression EXP.")); ++ set_cmd_completer (c, expression_completer); ++ + add_com_alias ("inspect", "print", class_vars, 1); + + add_setshow_uinteger_cmd ("max-symbolic-offset", no_class, +diff -Nuar gdb-10.2/gdb/psymtab.c gdb-10.2/gdb/psymtab.c +--- gdb-10.2/gdb/psymtab.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/psymtab.c 2025-04-16 17:06:41.902086800 +0800 +@@ -283,6 +283,9 @@ + return best_pst; + } + ++#ifdef CRASH_MERGE ++ extern "C" int gdb_line_number_callback(unsigned long, unsigned long, unsigned long); ++#endif + /* Find which partial symtab contains PC and SECTION. Return NULL if + none. We return the psymtab that contains a symbol whose address + exactly matches PC, or, if we cannot find an exact match, the +@@ -363,7 +366,12 @@ + + best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst, + msymbol); ++#ifdef CRASH_MERGE ++ if ((best_pst != NULL) && ++ gdb_line_number_callback(pc, pst->text_low (objfile), pst->text_high (objfile))) ++#else + if (best_pst != NULL) ++#endif + return best_pst; + } + +diff -Nuar gdb-10.2/gdb/regcache.c gdb-10.2/gdb/regcache.c +--- gdb-10.2/gdb/regcache.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/regcache.c 2025-04-16 17:06:51.972086800 +0800 +@@ -1,6 +1,6 @@ + /* Cache and manage the values of registers for GDB, the GNU debugger. + +- Copyright (C) 1986-2021 Free Software Foundation, Inc. ++ Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -222,13 +222,23 @@ + } + + /* Return a pointer to register REGNUM's buffer cache. */ +- + gdb_byte * + reg_buffer::register_buffer (int regnum) const + { + return m_registers.get () + m_descr->register_offset[regnum]; + } + ++/*gdb_byte * ++reg_buffer::register_buffer0 (int regnum) const ++{ ++ //return m_registers.get () + m_descr->register_offset[regnum]; ++ gdb_byte *pR0; ++ asm("mov $0,%0" ++ :"=r"(pR0)); ++ ++ return pR0 ; ++}*/ ++ + void + reg_buffer::save (register_read_ftype cooked_read) + { +@@ -598,10 +608,12 @@ + + if (m_register_status[regnum] != REG_VALID) + memset (buf, 0, m_descr->sizeof_register[regnum]); +- else ++ /*else if(regnum == 0) ++ memcpy (buf, register_buffer0 (regnum), ++ m_descr->sizeof_register[regnum]);*/ ++ else + memcpy (buf, register_buffer (regnum), +- m_descr->sizeof_register[regnum]); +- ++ m_descr->sizeof_register[regnum]); + return m_register_status[regnum]; + } + +@@ -1856,6 +1868,7 @@ + if (bfd_arch == bfd_arch_frv || bfd_arch == bfd_arch_h8300 + || bfd_arch == bfd_arch_m32c || bfd_arch == bfd_arch_sh + || bfd_arch == bfd_arch_alpha || bfd_arch == bfd_arch_v850 ++ || bfd_arch == bfd_arch_sw_64 + || bfd_arch == bfd_arch_msp430 || bfd_arch == bfd_arch_mep + || bfd_arch == bfd_arch_mips || bfd_arch == bfd_arch_v850_rh850 + || bfd_arch == bfd_arch_tic6x || bfd_arch == bfd_arch_mn10300 +diff -Nuar gdb-10.2/gdb/regcache.h gdb-10.2/gdb/regcache.h +--- gdb-10.2/gdb/regcache.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/regcache.h 2025-04-16 17:06:51.972086800 +0800 +@@ -1,6 +1,6 @@ + /* Cache and manage the values of registers for GDB, the GNU debugger. + +- Copyright (C) 1986-2021 Free Software Foundation, Inc. ++ Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -242,6 +242,7 @@ + int num_raw_registers () const; + + gdb_byte *register_buffer (int regnum) const; ++ gdb_byte *register_buffer0 (int regnum) const; + + /* Save a register cache. The set of registers saved into the + regcache determined by the save_reggroup. COOKED_READ returns +diff -Nuar gdb-10.2/gdb/regformats/sw_64-linux.dat gdb-10.2/gdb/regformats/sw_64-linux.dat +--- gdb-10.2/gdb/regformats/sw_64-linux.dat 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/regformats/sw_64-linux.dat 2025-04-16 17:06:51.972086800 +0800 +@@ -0,0 +1,168 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: sw64-linux.xml ++name:sw_64_linux ++xmltarget:sw_64-linux.xml ++expedite:fp,sp,pc ++64:v0 ++64:t0 ++64:t1 ++64:t2 ++64:t3 ++64:t4 ++64:t5 ++64:t6 ++64:t7 ++64:s0 ++64:s1 ++64:s2 ++64:s3 ++64:s4 ++64:s5 ++64:fp ++64:a0 ++64:a1 ++64:a2 ++64:a3 ++64:a4 ++64:a5 ++64:t8 ++64:t9 ++64:t10 ++64:t11 ++64:ra ++64:t12 ++64:at ++64:gp ++64:sp ++64:zero ++64:f0 ++64:f1 ++64:f2 ++64:f3 ++64:f4 ++64:f5 ++64:f6 ++64:f7 ++64:f8 ++64:f9 ++64:f10 ++64:f11 ++64:f12 ++64:f13 ++64:f14 ++64:f15 ++64:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:fcsr ++64:pc ++64: ++64:unique ++64:ef0 ++64:ef1 ++64:ef2 ++64:ef3 ++64:ef4 ++64:ef5 ++64:ef6 ++64:ef7 ++64:ef8 ++64:ef9 ++64:ef10 ++64:ef11 ++64:ef12 ++64:ef13 ++64:ef14 ++64:ef15 ++64:ef16 ++64:ef17 ++64:ef18 ++64:ef19 ++64:ef20 ++64:ef21 ++64:ef22 ++64:ef23 ++64:ef24 ++64:ef25 ++64:ef26 ++64:ef27 ++64:ef28 ++64:ef29 ++64:ef30 ++64:ef31 ++64:ef0 ++64:ef1 ++64:ef2 ++64:ef3 ++64:ef4 ++64:ef5 ++64:ef6 ++64:ef7 ++64:ef8 ++64:ef9 ++64:ef10 ++64:ef11 ++64:ef12 ++64:ef13 ++64:ef14 ++64:ef15 ++64:ef16 ++64:ef17 ++64:ef18 ++64:ef19 ++64:ef20 ++64:ef21 ++64:ef22 ++64:ef23 ++64:ef24 ++64:ef25 ++64:ef26 ++64:ef27 ++64:ef28 ++64:ef29 ++64:ef30 ++64:ef31 ++64:ef0 ++64:ef1 ++64:ef2 ++64:ef3 ++64:ef4 ++64:ef5 ++64:ef6 ++64:ef7 ++64:ef8 ++64:ef9 ++64:ef10 ++64:ef11 ++64:ef12 ++64:ef13 ++64:ef14 ++64:ef15 ++64:ef16 ++64:ef17 ++64:ef18 ++64:ef19 ++64:ef20 ++64:ef21 ++64:ef22 ++64:ef23 ++64:ef24 ++64:ef25 ++64:ef26 ++64:ef27 ++64:ef28 ++64:ef29 ++64:ef30 ++64:ef31 +diff -Nuar gdb-10.2/gdb/remote.c gdb-10.2/gdb/remote.c +--- gdb-10.2/gdb/remote.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/remote.c 2025-04-16 17:06:51.982086800 +0800 +@@ -1,6 +1,6 @@ + /* Remote target communications for serial-line targets in custom GDB protocol + +- Copyright (C) 1988-2021 Free Software Foundation, Inc. ++ Copyright (C) 1988-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -2171,6 +2171,9 @@ + Z_PACKET_WRITE_WP, + Z_PACKET_READ_WP, + Z_PACKET_ACCESS_WP, ++#ifndef XWB20200308 ++ Z_PACKET_DV_WP, ++#endif + NR_Z_PACKET_TYPES + }; + +@@ -10401,6 +10404,11 @@ + case hw_access: + return Z_PACKET_ACCESS_WP; + break; ++#ifndef XWB20200308 ++ case hw_vstore: ++ return Z_PACKET_DV_WP; ++ break; ++#endif + default: + internal_error (__FILE__, __LINE__, + _("hw_bp_to_z: bad watchpoint type %d"), type); +@@ -14163,13 +14171,9 @@ + static void + remote_async_inferior_event_handler (gdb_client_data data) + { +- remote_target *remote = (remote_target *) data; +- /* Hold a strong reference to the remote target while handling an +- event, since that could result in closing the connection. */ +- auto remote_ref = target_ops_ref::new_reference (remote); +- + inferior_event_handler (INF_REG_EVENT); + ++ remote_target *remote = (remote_target *) data; + remote_state *rs = remote->get_remote_state (); + + /* inferior_event_handler may have consumed an event pending on the +diff -Nuar gdb-10.2/gdb/sw_64-bsd-nat.c gdb-10.2/gdb/sw_64-bsd-nat.c +--- gdb-10.2/gdb/sw_64-bsd-nat.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-bsd-nat.c 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,202 @@ ++/* Native-dependent code for SW_64 BSD's. ++ ++ Copyright (C) 2000-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "defs.h" ++#include "inferior.h" ++#include "regcache.h" ++ ++#include "sw_64-tdep.h" ++#include "sw_64-bsd-tdep.h" ++#include "inf-ptrace.h" ++ ++#include ++#include ++#include ++ ++#ifdef HAVE_SYS_PROCFS_H ++#include ++#endif ++ ++#ifndef HAVE_GREGSET_T ++typedef struct reg gregset_t; ++#endif ++ ++#ifndef HAVE_FPREGSET_T ++typedef struct fpreg fpregset_t; ++#endif ++ ++#include "gregset.h" ++ ++struct sw_64_bsd_nat_target final : public inf_ptrace_target ++{ ++ void fetch_registers (struct regcache *, int) override; ++ void store_registers (struct regcache *, int) override; ++}; ++ ++static sw_64_bsd_nat_target the_sw_64_bsd_nat_target; ++ ++/* Provide *regset() wrappers around the generic SW_64 BSD register ++ supply/fill routines. */ ++ ++void ++supply_gregset (struct regcache *regcache, const gregset_t *gregsetp) ++{ ++ sw_64bsd_supply_reg (regcache, (const char *) gregsetp, -1); ++} ++ ++void ++fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno) ++{ ++ sw_64bsd_fill_reg (regcache, (char *) gregsetp, regno); ++} ++ ++void ++supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp) ++{ ++ sw_64bsd_supply_fpreg (regcache, (const char *) fpregsetp, -1); ++} ++ ++void ++fill_fpregset (const struct regcache *regcache, ++ fpregset_t *fpregsetp, int regno) ++{ ++ sw_64bsd_fill_fpreg (regcache, (char *) fpregsetp, regno); ++} ++ ++/* Determine if PT_GETREGS fetches this register. */ ++ ++static int ++getregs_supplies (int regno) ++{ ++ return ((regno >= SW_64_V0_REGNUM && regno <= SW_64_ZERO_REGNUM) ++ || regno >= SW_64_PC_REGNUM); ++} ++ ++/* Fetch register REGNO from the inferior. If REGNO is -1, do this ++ for all registers (including the floating point registers). */ ++ ++void ++sw_64_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno) ++{ ++ if (regno == -1 || getregs_supplies (regno)) ++ { ++ struct reg gregs; ++ ++ if (ptrace (PT_GETREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &gregs, 0) == -1) ++ perror_with_name (_("Couldn't get registers")); ++ ++ sw_64bsd_supply_reg (regcache, (char *) &gregs, regno); ++ if (regno != -1) ++ return; ++ } ++ ++ if (regno == -1 ++ || regno >= gdbarch_fp0_regnum (regcache->arch ())) ++ { ++ struct fpreg fpregs; ++ ++ if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) ++ perror_with_name (_("Couldn't get floating point status")); ++ ++ sw_64bsd_supply_fpreg (regcache, (char *) &fpregs, regno); ++ } ++} ++ ++/* Store register REGNO back into the inferior. If REGNO is -1, do ++ this for all registers (including the floating point registers). */ ++ ++void ++sw_64_bsd_nat_target::store_registers (struct regcache *regcache, int regno) ++{ ++ if (regno == -1 || getregs_supplies (regno)) ++ { ++ struct reg gregs; ++ if (ptrace (PT_GETREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &gregs, 0) == -1) ++ perror_with_name (_("Couldn't get registers")); ++ ++ sw_64bsd_fill_reg (regcache, (char *) &gregs, regno); ++ ++ if (ptrace (PT_SETREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &gregs, 0) == -1) ++ perror_with_name (_("Couldn't write registers")); ++ ++ if (regno != -1) ++ return; ++ } ++ ++ if (regno == -1 ++ || regno >= gdbarch_fp0_regnum (regcache->arch ())) ++ { ++ struct fpreg fpregs; ++ ++ if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) ++ perror_with_name (_("Couldn't get floating point status")); ++ ++ sw_64bsd_fill_fpreg (regcache, (char *) &fpregs, regno); ++ ++ if (ptrace (PT_SETFPREGS, regcache->ptid ().pid (), ++ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) ++ perror_with_name (_("Couldn't write floating point status")); ++ } ++} ++ ++ ++/* Support for debugging kernel virtual memory images. */ ++ ++#include ++#include ++ ++#include "bsd-kvm.h" ++ ++static int ++sw_64bsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) ++{ ++ int regnum; ++ ++ /* The following is true for OpenBSD 3.9: ++ ++ The pcb contains the register state at the context switch inside ++ cpu_switch(). */ ++ ++ /* The stack pointer shouldn't be zero. */ ++ if (pcb->pcb_hw.apcb_ksp == 0) ++ return 0; ++ ++ regcache->raw_supply (SW_64_SP_REGNUM, &pcb->pcb_hw.apcb_ksp); ++ ++ for (regnum = SW_64_S0_REGNUM; regnum < SW_64_A0_REGNUM; regnum++) ++ regcache->raw_supply (regnum, &pcb->pcb_context[regnum - SW_64_S0_REGNUM]); ++ regcache->raw_supply (SW_64_RA_REGNUM, &pcb->pcb_context[7]); ++ ++ return 1; ++} ++ ++ ++void ++_initialize_sw_64bsd_nat (void) ++{ ++ add_inf_child_target (&the_sw_64_bsd_nat_target); ++ ++ /* Support debugging kernel virtual memory images. */ ++ bsd_kvm_add_target (sw_64bsd_supply_pcb); ++} +diff -Nuar gdb-10.2/gdb/sw_64-cpu.xml gdb-10.2/gdb/sw_64-cpu.xml +--- gdb-10.2/gdb/sw_64-cpu.xml 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-cpu.xml 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/sw_64-efu.xml gdb-10.2/gdb/sw_64-efu.xml +--- gdb-10.2/gdb/sw_64-efu.xml 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-efu.xml 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,106 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/sw_64-fpu.xml gdb-10.2/gdb/sw_64-fpu.xml +--- gdb-10.2/gdb/sw_64-fpu.xml 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-fpu.xml 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,42 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/sw_64-linux-nat.c gdb-10.2/gdb/sw_64-linux-nat.c +--- gdb-10.2/gdb/sw_64-linux-nat.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-linux-nat.c 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,365 @@ ++/* Low level SW_64 GNU/Linux interface, for GDB when running native. ++ Copyright (C) 2005-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "defs.h" ++#include "target.h" ++#include "regcache.h" ++#include "linux-nat-trad.h" ++ ++#include "sw_64-tdep.h" ++#include "gdbarch.h" ++ ++#include "nat/gdb_ptrace.h" ++#include "nat/sw_64-linux-watch.h" ++#include ++ ++#include ++#include "gregset.h" ++#include "inferior.h" ++ ++/* The address of UNIQUE for ptrace. */ ++#define SW_UNIQUE_PTRACE_ADDR 65 ++ ++/* -1 if the kernel and/or CPU do not support watch registers. ++ * 1 if watch_readback is valid and we can read style, num_valid ++ * and the masks. ++ * 0 if we need to read the watch_readback. */ ++ ++static int watch_readback_valid; ++ ++/* Cached watch register read values. */ ++ ++static struct arch_lwp_info watch_readback; ++//static struct pt_watch_regs watch_readback; ++ ++ ++class sw_64_linux_nat_target final : public linux_nat_trad_target ++{ ++public: ++ void close () override; ++ ++#ifdef LHX20201012 ++ int can_use_hw_breakpoint (enum bptype, int, int) override; ++ ++ int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, ++ struct expression *) override; ++ ++ int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, ++ struct expression *) override; ++ ++ bool stopped_by_watchpoint () override; ++ ++ bool stopped_data_address (CORE_ADDR *) override; ++#endif ++ ++ int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; ++ ++ void low_prepare_to_resume (struct lwp_info *lp) override; ++ ++protected: ++ /* Override linux_nat_trad_target methods. */ ++ CORE_ADDR register_u_offset (struct gdbarch *gdbarch, ++ int regno, int store_p) override; ++ ++ ++private: ++}; ++ ++static sw_64_linux_nat_target the_sw_64_linux_nat_target; ++ ++/* See the comment in m68k-tdep.c regarding the utility of these ++ functions. */ ++ ++void ++supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) ++{ ++ const long *regp = (const long *)gregsetp; ++ ++ /* PC is in slot 32, UNIQUE is in slot 33. */ ++ sw_64_supply_int_regs (regcache, -1, regp, regp + 31, regp + 32); ++} ++ ++void ++fill_gregset (const struct regcache *regcache, ++ gdb_gregset_t *gregsetp, int regno) ++{ ++ long *regp = (long *)gregsetp; ++ ++ /* PC is in slot 32, UNIQUE is in slot 33. */ ++ sw_64_fill_int_regs (regcache, regno, regp, regp + 31, regp + 32); ++} ++ ++/* Now we do the same thing for floating-point registers. ++ Again, see the comments in m68k-tdep.c. */ ++ ++void ++supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) ++{ ++ const long *regp = (const long *)fpregsetp; ++ ++ /* FPCR is in slot 32. */ ++ sw_64_supply_fp_regs (regcache, -1, regp, regp + 31); ++} ++ ++void ++fill_fpregset (const struct regcache *regcache, ++ gdb_fpregset_t *fpregsetp, int regno) ++{ ++ long *regp = (long *)fpregsetp; ++ ++ /* FPCR is in slot 32. */ ++ sw_64_fill_fp_regs (regcache, regno, regp, regp + 31); ++} ++ ++CORE_ADDR ++sw_64_linux_nat_target::register_u_offset (struct gdbarch *gdbarch, ++ int regno, int store_p) ++{ ++ if (regno == gdbarch_pc_regnum (gdbarch)) ++ return PC; ++ if (regno == SW_UNIQUE_REGNUM) ++ return SW_UNIQUE_PTRACE_ADDR; ++ if (regno < gdbarch_fp0_regnum (gdbarch)) ++ return GPR_BASE + regno; ++ else ++ return FPR_BASE + regno - gdbarch_fp0_regnum (gdbarch); ++} ++ ++#ifdef LHX20201012 ++/* Target to_can_use_hw_breakpoint implementation. Return 1 if we can ++ handle the specified watch type. */ ++ ++int ++sw_64_linux_nat_target::can_use_hw_breakpoint (enum bptype type, ++ int cnt, int ot) ++{ ++ debug("type:%d,cnt:%d,ot:%d", type,cnt,ot); ++ ++ if (type == bp_hardware_watchpoint || type == bp_read_watchpoint ++ || type == bp_access_watchpoint || type == bp_watchpoint) ++ return !(watch_readback.wpt[0].valid); ++ ++ if (type == bp_value_watchpoint) ++ return !watch_readback.wpt[1].valid; ++ ++ return (cnt == 0) ? 1 : 0; ++} ++ ++/* Target to_stopped_by_watchpoint implementation. Return 1 if ++ stopped by watchpoint. The watchhi R and W bits indicate the watch ++ register triggered. */ ++ ++bool ++sw_64_linux_nat_target::stopped_by_watchpoint () ++{ ++ siginfo_t siginfo; ++ pid_t lwpid = inferior_ptid.lwp(); ++ ++ /* Retrieve siginfo. */ ++ errno = 0; ++ ptrace (PTRACE_GETSIGINFO, lwpid, 0, &siginfo); ++ if (errno != 0) ++ { ++ warning("%s:%d GETSIGINFO return %d\n", __FILE__, __LINE__, errno); ++ return false; ++ } ++ /* This must be a hardware breakpoint. */ ++ if (siginfo.si_signo != SIGTRAP ++ || (siginfo.si_code & 0xffff) != M_DA_MATCH_TRAP/* TRAP_HWBKPT */) ++ return false; ++ ++ debug("si_code=%#x si_signo=%d si_errno = %x pc=%#lx, data_address %#lx", ++ siginfo.si_code, siginfo.si_signo,siginfo.si_errno,(long)siginfo.si_value.sival_ptr, (long)siginfo.si_addr); ++ /* siginfo should return the accessed data address, not pc */ ++ switch (siginfo.si_errno){ ++ case 1: //si_errno[0]: ++ case 4: ++ case 7: //si_errno[2]: ++ watch_readback.stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (watch_readback.wpt[0].match & ((1L<<53)-1)); ++ watch_readback.matched = 1; ++ break; ++ case 2: //si_errno[`] ++ watch_readback.stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (watch_readback.value_address); // get the saved ++ watch_readback.matched = 1; ++ break; ++ default: ++ ;; ++ } ++ return true; ++} ++ ++/* Target to_stopped_data_address implementation. Set the address ++ where the watch triggered (if known). Return 1 if the address was ++ known. */ ++ ++bool ++sw_64_linux_nat_target::stopped_data_address (CORE_ADDR *paddr) ++{ ++ if (watch_readback.matched) ++ { ++ *paddr = watch_readback.stopped_data_address; ++ return true; ++ } ++ return false; ++} ++#endif ++ ++/* Target to_region_ok_for_hw_watchpoint implementation. Return 1 if ++ the specified region can be covered by the watch registers. */ ++ ++int ++sw_64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) ++{ ++ /* Can not set watchpoints for zero or negative lengths. */ ++ if (len <= 0) ++ return 0; ++ ++ /* The current ptrace interface can only handle watchpoints that are a ++ * power of 2. */ ++ if ((len & (len - 1)) != 0) ++ return 0; ++ ++ /* All tests passed so we must be able to set a watchpoint. */ ++ return 1; ++} ++ ++enum sw_64_hw_bp_type ++sw_64_hw_bp_type_from_target_hw_bp_type (enum target_hw_bp_type raw_type) ++{ ++ switch (raw_type) ++ { ++ case hw_execute: ++ /* permit r/w */ ++ return sw_64_none; ++ case hw_write: ++ return sw_64_write; ++ case hw_read: ++ return sw_64_read; ++ case hw_access: ++ return sw_64_access; ++ case hw_vstore: ++ return sw_64_vstore; ++ default: ++ error ( "bad raw breakpoint type %d", (int) raw_type); ++ } ++} ++ ++#ifdef LHX20201012 ++/* Target to_insert_watchpoint implementation. Try to insert a new ++ watch. Return zero on success. */ ++ ++int ++sw_64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len, ++ enum target_hw_bp_type type, ++ struct expression *cond) ++{ ++ enum sw_64_hw_bp_type watch_type; ++ ++ debug("%s insert wpt at %#lx type %d", target_pid_to_str(inferior_ptid), ++ addr, type); ++ ++ ++ watch_type = sw_64_hw_bp_type_from_target_hw_bp_type(type); ++ ++ if (sw_64_linux_try_one_watch(inferior_ptid.lwp(), &watch_readback, watch_type,addr,len)) ++ return 0; ++ return -1; ++} ++ ++/* Target to_remove_watchpoint implementation. Try to remove a watch. ++ Return zero on success. */ ++ ++int ++sw_64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len, ++ enum target_hw_bp_type type, ++ struct expression *cond) ++{ ++ enum sw_64_hw_bp_type watch_type; ++ ++ watch_type = sw_64_hw_bp_type_from_target_hw_bp_type(type); ++ if (sw_64_linux_del_one_watch(&watch_readback, watch_type,addr,len)) ++ return 0; ++ return -1; ++} ++#endif ++ ++/* Target to_close implementation. Free any watches and call the ++ super implementation. */ ++ ++void ++sw_64_linux_nat_target::close () ++{ ++ linux_nat_trad_target::close (); ++} ++ ++/* Called when resuming a thread. ++ The hardware debug registers are updated when there is any change. */ ++ ++void ++sw_64_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp) ++{ ++ int i,ctl; ++ int lwpid = lwp->ptid.lwp(); ++ int regno[2]= {M_DA_MATCH,M_DV_MATCH}; ++ struct pt_watch_regs *wpt = watch_readback.wpt; ++ ++ /* NULL means this is the main thread still going through the shell, ++ or, no watchpoint has been set yet. In that case, there's ++ nothing to do. */ ++ ++ for (i = 0, ctl=0; i < MAX_WPTS; i++) ++ if (watch_readback.wpts_changed[i]) ++ { ++ //debug("write master da/dv_match %#lx, mask %#lx", wpt[i].match, wpt[i].mask); ++ store_debug_register (lwpid, regno[i], wpt[i].match); ++ store_debug_register (lwpid, regno[i]+1, wpt[i].mask); ++ //perror_with_name (_("Unexpected error setting watchpoint")); ++ ctl |= watch_readback.wpts_changed[i] <. */ ++#include "defs.h" ++#include "frame.h" ++#include "osabi.h" ++#include "solib-svr4.h" ++#include "symtab.h" ++#include "regset.h" ++#include "regcache.h" ++#include "linux-tdep.h" ++#include "sw_64-tdep.h" ++#include "gdbarch.h" ++#ifndef LHX20210326 ++#include "xml-syscall.h" ++#endif ++ ++ ++//sw_64-linux-tdep.c ++ ++ ++#include "glibc-tdep.h" ++#include "sw_64-linux-tdep.h" ++#include "tramp-frame.h" ++#include "trad-frame.h" ++#include "target/target.h" ++ ++ ++#include "stap-probe.h" ++#include "parser-defs.h" ++#include "user-regs.h" ++#include ++ ++#include "record-full.h" ++#include "linux-record.h" ++/* This enum represents the signals' numbers on the Alpha ++ architecture. It just contains the signal definitions which are ++ different from the generic implementation. ++ ++ It is derived from the file , ++ from the Linux kernel tree. */ ++ ++enum ++ { ++ /* SIGABRT is the same as in the generic implementation, but is ++ defined here because SIGIOT depends on it. */ ++ SW_LINUX_SIGABRT = 6, ++ SW_LINUX_SIGEMT = 7, ++ SW_LINUX_SIGBUS = 10, ++ SW_LINUX_SIGSYS = 12, ++ SW_LINUX_SIGURG = 16, ++ SW_LINUX_SIGSTOP = 17, ++ SW_LINUX_SIGTSTP = 18, ++ SW_LINUX_SIGCONT = 19, ++ SW_LINUX_SIGCHLD = 20, ++ SW_LINUX_SIGIO = 23, ++ SW_LINUX_SIGINFO = 29, ++ SW_LINUX_SIGUSR1 = 30, ++ SW_LINUX_SIGUSR2 = 31, ++ SW_LINUX_SIGPOLL = SW_LINUX_SIGIO, ++ SW_LINUX_SIGPWR = SW_LINUX_SIGINFO, ++ SW_LINUX_SIGIOT = SW_LINUX_SIGABRT, ++ }; ++ ++/* Under GNU/Linux, signal handler invocations can be identified by ++ the designated code sequence that is used to return from a signal ++ handler. In particular, the return address of a signal handler ++ points to a sequence that copies $sp to $16, loads $0 with the ++ appropriate syscall number, and finally enters the kernel. ++ ++ This is somewhat complicated in that: ++ (1) the expansion of the "mov" assembler macro has changed over ++ time, from "bis src,src,dst" to "bis zero,src,dst", ++ (2) the kernel has changed from using "addq" to "lda" to load the ++ syscall number, ++ (3) there is a "normal" sigreturn and an "rt" sigreturn which ++ has a different stack layout. */ ++ ++static long ++sw_64_linux_sigtramp_offset_1 (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ switch (sw_64_read_insn (gdbarch, pc)) ++ { ++ case 0x47de0410: /* bis $30,$30,$16 */ ++ case 0x47fe0410: /* bis $31,$30,$16 */ ++ return 0; ++ ++ case 0x43ecf400: /* addq $31,103,$0 */ ++#if 0 ++ case 0x201f0067: /* lda $0,103($31) */ ++ case 0x201f015f: /* lda $0,351($31) */ ++#else ++ case 0xf81f0067U: ++ case 0xf81f015fU: ++#endif ++ return 4; ++ ++ case 0x00000083: /* call_pal callsys */ ++ return 8; ++ ++ default: ++ return -1; ++ } ++} ++ ++static LONGEST ++sw_64_linux_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ long i, off; ++ ++ if (pc & 3) ++ return -1; ++ ++ /* Guess where we might be in the sequence. */ ++ off = sw_64_linux_sigtramp_offset_1 (gdbarch, pc); ++ if (off < 0) ++ return -1; ++ ++ /* Verify that the other two insns of the sequence are as we expect. */ ++ pc -= off; ++ for (i = 0; i < 12; i += 4) ++ { ++ if (i == off) ++ continue; ++ if (sw_64_linux_sigtramp_offset_1 (gdbarch, pc + i) != i) ++ return -1; ++ } ++ ++ return off; ++} ++ ++static int ++sw_64_linux_pc_in_sigtramp (struct gdbarch *gdbarch, ++ CORE_ADDR pc, const char *func_name) ++{ ++ return sw_64_linux_sigtramp_offset (gdbarch, pc) >= 0; ++} ++ ++static CORE_ADDR ++sw_64_linux_sigcontext_addr (struct frame_info *this_frame) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ CORE_ADDR pc; ++ ULONGEST sp; ++ long off; ++ ++ pc = get_frame_pc (this_frame); ++ sp = get_frame_register_unsigned (this_frame, SW_SP_REGNUM); ++ ++ off = sw_64_linux_sigtramp_offset (gdbarch, pc); ++ gdb_assert (off >= 0); ++ ++ /* __NR_rt_sigreturn has a couple of structures on the stack. This is: ++ ++ struct rt_sigframe { ++ struct siginfo info; ++ struct ucontext uc; ++ }; ++ ++ offsetof (struct rt_sigframe, uc.uc_mcontext); */ ++ ++ if (sw_64_read_insn (gdbarch, pc - off + 4) == 0xf81f015fU) ++ return sp + 176; ++ ++ /* __NR_sigreturn has the sigcontext structure at the top of the stack. */ ++ return sp; ++} ++ ++/* Supply register REGNUM from the buffer specified by GREGS and LEN ++ in the general-purpose register set REGSET to register cache ++ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ ++ ++static void ++sw_64_linux_supply_gregset (const struct regset *regset, ++ struct regcache *regcache, ++ int regnum, const void *gregs, size_t len) ++{ ++ const gdb_byte *regs = (const gdb_byte *) gregs; ++ ++ gdb_assert (len >= 32 * 8); ++ sw_64_supply_int_regs (regcache, regnum, regs, regs + 31 * 8, ++ len >= 33 * 8 ? regs + 32 * 8 : NULL); ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++ it in the buffer specified by GREGS and LEN as described by the ++ general-purpose register set REGSET. If REGNUM is -1, do this for ++ all registers in REGSET. */ ++ ++static void ++sw_64_linux_collect_gregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *gregs, size_t len) ++{ ++ gdb_byte *regs = (gdb_byte *) gregs; ++ ++ gdb_assert (len >= 32 * 8); ++ sw_64_fill_int_regs (regcache, regnum, regs, regs + 31 * 8, ++ len >= 33 * 8 ? regs + 32 * 8 : NULL); ++} ++ ++/* Supply register REGNUM from the buffer specified by FPREGS and LEN ++ in the floating-point register set REGSET to register cache ++ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ ++ ++static void ++sw_64_linux_supply_fpregset (const struct regset *regset, ++ struct regcache *regcache, ++ int regnum, const void *fpregs, size_t len) ++{ ++ const gdb_byte *regs = (const gdb_byte *) fpregs; ++ ++ gdb_assert (len >= 32 * 8); ++ sw_64_supply_fp_regs (regcache, regnum, regs, regs + 31 * 8); ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++ it in the buffer specified by FPREGS and LEN as described by the ++ general-purpose register set REGSET. If REGNUM is -1, do this for ++ all registers in REGSET. */ ++ ++static void ++sw_64_linux_collect_fpregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *fpregs, size_t len) ++{ ++ gdb_byte *regs = (gdb_byte *) fpregs; ++ ++ gdb_assert (len >= 32 * 8); ++ sw_64_fill_fp_regs (regcache, regnum, regs, regs + 31 * 8); ++} ++ ++static const struct regset sw_64_linux_gregset = ++{ ++ NULL, ++ sw_64_linux_supply_gregset, sw_64_linux_collect_gregset ++}; ++ ++static const struct regset sw_64_linux_fpregset = ++{ ++ NULL, ++ sw_64_linux_supply_fpregset, sw_64_linux_collect_fpregset ++}; ++ ++/* Iterate over core file register note sections. */ ++ ++static void ++sw_64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, ++ iterate_over_regset_sections_cb *cb, ++ void *cb_data, ++ const struct regcache *regcache) ++{ ++ cb (".reg", 32 * 8, 32 * 8, &sw_64_linux_gregset, NULL, cb_data); ++ cb (".reg2", 32 * 8, 32 * 8, &sw_64_linux_fpregset, NULL, cb_data); ++} ++ ++/* Implementation of `gdbarch_gdb_signal_from_target', as defined in ++ gdbarch.h. */ ++ ++static enum gdb_signal ++sw_64_linux_gdb_signal_from_target (struct gdbarch *gdbarch, ++ int signal) ++{ ++ switch (signal) ++ { ++ case SW_LINUX_SIGEMT: ++ return GDB_SIGNAL_EMT; ++ ++ case SW_LINUX_SIGBUS: ++ return GDB_SIGNAL_BUS; ++ ++ case SW_LINUX_SIGSYS: ++ return GDB_SIGNAL_SYS; ++ ++ case SW_LINUX_SIGURG: ++ return GDB_SIGNAL_URG; ++ ++ case SW_LINUX_SIGSTOP: ++ return GDB_SIGNAL_STOP; ++ ++ case SW_LINUX_SIGTSTP: ++ return GDB_SIGNAL_TSTP; ++ ++ case SW_LINUX_SIGCONT: ++ return GDB_SIGNAL_CONT; ++ ++ case SW_LINUX_SIGCHLD: ++ return GDB_SIGNAL_CHLD; ++ ++ /* No way to differentiate between SIGIO and SIGPOLL. ++ Therefore, we just handle the first one. */ ++ case SW_LINUX_SIGIO: ++ return GDB_SIGNAL_IO; ++ ++ /* No way to differentiate between SIGINFO and SIGPWR. ++ Therefore, we just handle the first one. */ ++ case SW_LINUX_SIGINFO: ++ return GDB_SIGNAL_INFO; ++ ++ case SW_LINUX_SIGUSR1: ++ return GDB_SIGNAL_USR1; ++ ++ case SW_LINUX_SIGUSR2: ++ return GDB_SIGNAL_USR2; ++ } ++ ++ return linux_gdb_signal_from_target (gdbarch, signal); ++} ++ ++/* Implementation of `gdbarch_gdb_signal_to_target', as defined in ++ gdbarch.h. */ ++ ++static int ++sw_64_linux_gdb_signal_to_target (struct gdbarch *gdbarch, ++ enum gdb_signal signal) ++{ ++ switch (signal) ++ { ++ case GDB_SIGNAL_EMT: ++ return SW_LINUX_SIGEMT; ++ ++ case GDB_SIGNAL_BUS: ++ return SW_LINUX_SIGBUS; ++ ++ case GDB_SIGNAL_SYS: ++ return SW_LINUX_SIGSYS; ++ ++ case GDB_SIGNAL_URG: ++ return SW_LINUX_SIGURG; ++ ++ case GDB_SIGNAL_STOP: ++ return SW_LINUX_SIGSTOP; ++ ++ case GDB_SIGNAL_TSTP: ++ return SW_LINUX_SIGTSTP; ++ ++ case GDB_SIGNAL_CONT: ++ return SW_LINUX_SIGCONT; ++ ++ case GDB_SIGNAL_CHLD: ++ return SW_LINUX_SIGCHLD; ++ ++ case GDB_SIGNAL_IO: ++ return SW_LINUX_SIGIO; ++ ++ case GDB_SIGNAL_INFO: ++ return SW_LINUX_SIGINFO; ++ ++ case GDB_SIGNAL_USR1: ++ return SW_LINUX_SIGUSR1; ++ ++ case GDB_SIGNAL_USR2: ++ return SW_LINUX_SIGUSR2; ++ ++ case GDB_SIGNAL_POLL: ++ return SW_LINUX_SIGPOLL; ++ ++ case GDB_SIGNAL_PWR: ++ return SW_LINUX_SIGPWR; ++ } ++ ++ return linux_gdb_signal_to_target (gdbarch, signal); ++} ++ ++#ifndef LHX20210326 ++/* Return the current system call's number present in the ++ v0 register. When the function fails, it returns -1. */ ++ ++static LONGEST ++sw_64_linux_get_syscall_number (struct gdbarch *gdbarch, ++ thread_info *thread) ++{ ++ struct regcache *regcache = get_thread_regcache (thread); ++ //struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ int regsize = register_size (gdbarch, SW_V0_REGNUM); ++ /* The content of a register */ ++ gdb_byte buf[8]; ++ /* The result */ ++ LONGEST ret; ++ ++// /* Make sure we're in a known ABI */ ++// gdb_assert (tdep->mips_abi == MIPS_ABI_O32 ++// || tdep->mips_abi == MIPS_ABI_N32 ++// || tdep->mips_abi == MIPS_ABI_N64); ++// ++// gdb_assert (regsize <= sizeof (buf)); ++ ++ /* Getting the system call number from the register. ++ syscall number is in v0 or $0. */ ++ regcache->cooked_read (SW_V0_REGNUM, buf); ++ ++ ret = extract_signed_integer (buf, regsize, byte_order); ++ ++ return ret; ++} ++#endif ++ ++/* Initialize linux_record_tdep if not initialized yet. ++ WORDSIZE is 4 or 8 for 32- or 64-bit PowerPC Linux respectively. ++ Sizes of data structures are initialized accordingly. */ ++ ++static void ++sw_64_init_linux_record_tdep (struct linux_record_tdep *record_tdep, ++ int wordsize) ++ ++{ ++ /* Simply return if it had been initialized. */ ++ if (record_tdep->size_pointer != 0) ++ return; ++ ++ /* These values are the size of the type that will be used in a system ++ call. They are obtained from Linux Kernel source. */ ++ ++ if (wordsize == 8) ++ { ++ record_tdep->size_pointer = 8; ++ record_tdep->size__old_kernel_stat = 32; ++ record_tdep->size_tms = 32; ++ record_tdep->size_loff_t = 8; ++ record_tdep->size_flock = 32; ++ record_tdep->size_oldold_utsname = 45; ++ record_tdep->size_ustat = 32; ++ record_tdep->size_old_sigaction = 32; ++ record_tdep->size_old_sigset_t = 8; ++ record_tdep->size_rlimit = 16; ++ record_tdep->size_rusage = 144; ++ record_tdep->size_timeval = 16; ++ record_tdep->size_timezone = 8; ++ record_tdep->size_old_gid_t = 4; ++ record_tdep->size_old_uid_t = 4; ++ record_tdep->size_fd_set = 128; ++ record_tdep->size_old_dirent = 280; ++ record_tdep->size_statfs = 120; ++ record_tdep->size_statfs64 = 120; ++ record_tdep->size_sockaddr = 16; ++ record_tdep->size_int = 4; ++ record_tdep->size_long = 8; ++ record_tdep->size_ulong = 8; ++ record_tdep->size_msghdr = 56; ++ record_tdep->size_itimerval = 32; ++ record_tdep->size_stat = 144; ++ record_tdep->size_old_utsname = 325; ++ record_tdep->size_sysinfo = 112; ++ record_tdep->size_msqid_ds = 120; ++ record_tdep->size_shmid_ds = 112; ++ record_tdep->size_new_utsname = 390; ++ record_tdep->size_timex = 208; ++ record_tdep->size_mem_dqinfo = 24; ++ record_tdep->size_if_dqblk = 72; ++ record_tdep->size_fs_quota_stat = 80; ++ record_tdep->size_timespec = 16; ++ record_tdep->size_pollfd = 8; ++ record_tdep->size_NFS_FHSIZE = 32; ++ record_tdep->size_knfsd_fh = 132; ++ record_tdep->size_TASK_COMM_LEN = 16; ++ record_tdep->size_sigaction = 32; ++ record_tdep->size_sigset_t = 8; ++ record_tdep->size_siginfo_t = 128; ++ record_tdep->size_cap_user_data_t = 8; ++ record_tdep->size_stack_t = 24; ++ record_tdep->size_off_t = 8; ++ record_tdep->size_stat64 = 104; ++ record_tdep->size_gid_t = 4; ++ record_tdep->size_uid_t = 4; ++ record_tdep->size_PAGE_SIZE = 0x10000; /* 64KB */ ++ record_tdep->size_flock64 = 32; ++ record_tdep->size_io_event = 32; ++ record_tdep->size_iocb = 64; ++ record_tdep->size_epoll_event = 16; ++ record_tdep->size_itimerspec = 32; ++ record_tdep->size_mq_attr = 64; ++ record_tdep->size_termios = 44; ++ record_tdep->size_pid_t = 4; ++ record_tdep->size_winsize = 8; ++ record_tdep->size_serial_struct = 72; ++ record_tdep->size_serial_icounter_struct = 80; ++ record_tdep->size_size_t = 8; ++ record_tdep->size_iovec = 16; ++ record_tdep->size_time_t = 8; ++ } ++ else if (wordsize == 4) ++ { ++ record_tdep->size_pointer = 4; ++ record_tdep->size__old_kernel_stat = 32; ++ record_tdep->size_tms = 16; ++ record_tdep->size_loff_t = 8; ++ record_tdep->size_flock = 16; ++ record_tdep->size_oldold_utsname = 45; ++ record_tdep->size_ustat = 20; ++ record_tdep->size_old_sigaction = 16; ++ record_tdep->size_old_sigset_t = 4; ++ record_tdep->size_rlimit = 8; ++ record_tdep->size_rusage = 72; ++ record_tdep->size_timeval = 8; ++ record_tdep->size_timezone = 8; ++ record_tdep->size_old_gid_t = 4; ++ record_tdep->size_old_uid_t = 4; ++ record_tdep->size_fd_set = 128; ++ record_tdep->size_old_dirent = 268; ++ record_tdep->size_statfs = 64; ++ record_tdep->size_statfs64 = 88; ++ record_tdep->size_sockaddr = 16; ++ record_tdep->size_int = 4; ++ record_tdep->size_long = 4; ++ record_tdep->size_ulong = 4; ++ record_tdep->size_msghdr = 28; ++ record_tdep->size_itimerval = 16; ++ record_tdep->size_stat = 88; ++ record_tdep->size_old_utsname = 325; ++ record_tdep->size_sysinfo = 64; ++ record_tdep->size_msqid_ds = 68; ++ record_tdep->size_shmid_ds = 60; ++ record_tdep->size_new_utsname = 390; ++ record_tdep->size_timex = 128; ++ record_tdep->size_mem_dqinfo = 24; ++ record_tdep->size_if_dqblk = 72; ++ record_tdep->size_fs_quota_stat = 80; ++ record_tdep->size_timespec = 8; ++ record_tdep->size_pollfd = 8; ++ record_tdep->size_NFS_FHSIZE = 32; ++ record_tdep->size_knfsd_fh = 132; ++ record_tdep->size_TASK_COMM_LEN = 16; ++ record_tdep->size_sigaction = 20; ++ record_tdep->size_sigset_t = 8; ++ record_tdep->size_siginfo_t = 128; ++ record_tdep->size_cap_user_data_t = 4; ++ record_tdep->size_stack_t = 12; ++ record_tdep->size_off_t = 4; ++ record_tdep->size_stat64 = 104; ++ record_tdep->size_gid_t = 4; ++ record_tdep->size_uid_t = 4; ++ record_tdep->size_PAGE_SIZE = 0x10000; /* 64KB */ ++ record_tdep->size_flock64 = 32; ++ record_tdep->size_io_event = 32; ++ record_tdep->size_iocb = 64; ++ record_tdep->size_epoll_event = 16; ++ record_tdep->size_itimerspec = 16; ++ record_tdep->size_mq_attr = 32; ++ record_tdep->size_termios = 44; ++ record_tdep->size_pid_t = 4; ++ record_tdep->size_winsize = 8; ++ record_tdep->size_serial_struct = 60; ++ record_tdep->size_serial_icounter_struct = 80; ++ record_tdep->size_size_t = 4; ++ record_tdep->size_iovec = 8; ++ record_tdep->size_time_t = 4; ++ } ++ else ++ internal_error (__FILE__, __LINE__, _("unexpected wordsize")); ++ ++ /* These values are the second argument of system call "sys_fcntl" ++ and "sys_fcntl64". They are obtained from Linux Kernel source. */ ++ record_tdep->fcntl_F_GETLK = 5; ++ record_tdep->fcntl_F_GETLK64 = 12; ++ record_tdep->fcntl_F_SETLK64 = 13; ++ record_tdep->fcntl_F_SETLKW64 = 14; ++ ++ record_tdep->arg1 = SW_A0_REGNUM + 0; ++ record_tdep->arg2 = SW_A0_REGNUM + 1; ++ record_tdep->arg3 = SW_A0_REGNUM + 2; ++ record_tdep->arg4 = SW_A0_REGNUM + 3; ++ record_tdep->arg5 = SW_A0_REGNUM + 4; ++ record_tdep->arg6 = SW_A0_REGNUM + 5; ++ ++ /* These values are the second argument of system call "sys_ioctl". ++ They are obtained from Linux Kernel source. ++ See arch/powerpc/include/uapi/asm/ioctls.h. */ ++ record_tdep->ioctl_TCGETS = 0x403c7413;//402c7413 ++ record_tdep->ioctl_TCSETS = 0x802c7414;//802c7414 ++ record_tdep->ioctl_TCSETSW = 0x802c7415;//802c7415 ++ record_tdep->ioctl_TCSETSF = 0x802c7416;//802c7416 ++ record_tdep->ioctl_TCGETA = 0x40127417;//40127417 ++ record_tdep->ioctl_TCSETA = 0x80127418;//80127418 ++ record_tdep->ioctl_TCSETAW = 0x80127419;//80127419 ++ record_tdep->ioctl_TCSETAF = 0x8012741c;//8012741c ++ record_tdep->ioctl_TCSBRK = 0x2000741d;//2000741d ++ record_tdep->ioctl_TCXONC = 0x2000741e;//2000741e ++ record_tdep->ioctl_TCFLSH = 0x2000741f;//2000741f ++ record_tdep->ioctl_TIOCEXCL = 0x540c;// ++ record_tdep->ioctl_TIOCNXCL = 0x540d;// ++ record_tdep->ioctl_TIOCSCTTY = 0x540e;// ++ record_tdep->ioctl_TIOCGPGRP = 0x40047477;//40047477 ++ record_tdep->ioctl_TIOCSPGRP = 0x80047476;//80047476 ++ record_tdep->ioctl_TIOCOUTQ = 0x40047473;//40047473 ++ record_tdep->ioctl_TIOCSTI = 0x5412;//5412 ++ record_tdep->ioctl_TIOCGWINSZ = 0x40087468;//40087468 ++ record_tdep->ioctl_TIOCSWINSZ = 0x80087467;//80087467 ++ record_tdep->ioctl_TIOCMGET = 0x5415;// ++ record_tdep->ioctl_TIOCMBIS = 0x5416;// ++ record_tdep->ioctl_TIOCMBIC = 0x5417;// ++ record_tdep->ioctl_TIOCMSET = 0x5418;// ++ record_tdep->ioctl_TIOCGSOFTCAR = 0x5419;// ++ record_tdep->ioctl_TIOCSSOFTCAR = 0x541a;// ++ record_tdep->ioctl_FIONREAD = 0x4004667f;//4004667f ++ record_tdep->ioctl_TIOCINQ = 0x4004667f;//4004667f ++ record_tdep->ioctl_TIOCLINUX = 0x541c;// ++ record_tdep->ioctl_TIOCCONS = 0x541d;// ++ record_tdep->ioctl_TIOCGSERIAL = 0x541e;// ++ record_tdep->ioctl_TIOCSSERIAL = 0x541f;// ++ record_tdep->ioctl_TIOCPKT = 0x5420;// ++ record_tdep->ioctl_FIONBIO = 0x8004667e;//8004667e ++ record_tdep->ioctl_TIOCNOTTY = 0x5422;// ++ record_tdep->ioctl_TIOCSETD = 0x5423;// ++ record_tdep->ioctl_TIOCGETD = 0x5424;// ++ record_tdep->ioctl_TCSBRKP = 0x5425;// ++ record_tdep->ioctl_TIOCSBRK = 0x5427; ++ record_tdep->ioctl_TIOCCBRK = 0x5428; ++ record_tdep->ioctl_TIOCGSID = 0x5429; ++ record_tdep->ioctl_TIOCGPTN = 0x40045430;//40045430 ++ record_tdep->ioctl_TIOCSPTLCK = 0x80045431;//80045431 ++ record_tdep->ioctl_FIONCLEX = 0x20006602;//20006602 ++ record_tdep->ioctl_FIOCLEX = 0x20006601;//20006601 ++ record_tdep->ioctl_FIOASYNC = 0x8004667d;//8004667d ++ record_tdep->ioctl_TIOCSERCONFIG = 0x5453;// ++ record_tdep->ioctl_TIOCSERGWILD = 0x5454; ++ record_tdep->ioctl_TIOCSERSWILD = 0x5455; ++ record_tdep->ioctl_TIOCGLCKTRMIOS = 0x5456; ++ record_tdep->ioctl_TIOCSLCKTRMIOS = 0x5457; ++ record_tdep->ioctl_TIOCSERGSTRUCT = 0x5458; ++ record_tdep->ioctl_TIOCSERGETLSR = 0x5459; ++ record_tdep->ioctl_TIOCSERGETMULTI = 0x545a; ++ record_tdep->ioctl_TIOCSERSETMULTI = 0x545b; ++ record_tdep->ioctl_TIOCMIWAIT = 0x545c; ++ record_tdep->ioctl_TIOCGICOUNT = 0x545d; ++ record_tdep->ioctl_FIOQSIZE = 0x40086680;// ++} ++ ++/* Implementation of `gdbarch_stap_is_single_operand', as defined in ++ gdbarch.h. */ ++ ++//static int ++//sw_64_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) ++//{ ++// return (*s == 'i' /* Literal number. */ ++ // || (isdigit (*s) && s[1] == '(' ++ // && isdigit (s[2])) /* Displacement. */ ++ // || (*s == '(' && isdigit (s[1])) /* Register indirection. */ ++ // || isdigit (*s)); /* Register value. */ ++//} ++ ++ ++ ++/* Target-dependent code for GNU/Linux AArch64. ++ ++ Copyright (C) 2009-2020 Free Software Foundation, Inc. ++ Contributed by ARM Ltd. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++/* Signal frame handling. ++ ++ +------------+ ^ ++ | saved lr | | ++ +->| saved fp |--+ ++ | | | ++ | | | ++ | +------------+ ++ | | saved lr | ++ +--| saved fp | ++ ^ | | ++ | | | ++ | +------------+ ++ ^ | | ++ | | signal | ++ | | | SIGTRAMP_FRAME (struct rt_sigframe) ++ | | saved regs | ++ +--| saved sp |--> interrupted_sp ++ | | saved pc |--> interrupted_pc ++ | | | ++ | +------------+ ++ | | saved lr |--> default_restorer (movz x8, NR_sys_rt_sigreturn; svc 0) ++ +--| saved fp |<- FP ++ | | NORMAL_FRAME ++ | |<- SP ++ +------------+ ++ ++ On signal delivery, the kernel will create a signal handler stack ++ frame and setup the return address in LR to point at restorer stub. ++ The signal stack frame is defined by: ++ ++ struct rt_sigframe ++ { ++ siginfo_t info; ++ struct ucontext uc; ++ }; ++ ++ The ucontext has the following form: ++ struct ucontext ++ { ++ unsigned long uc_flags; ++ struct ucontext *uc_link; ++ stack_t uc_stack; ++ sigset_t uc_sigmask; ++ struct sigcontext uc_mcontext; ++ }; ++ ++ struct sigcontext ++ { ++ unsigned long fault_address; ++ unsigned long regs[31]; ++ unsigned long sp; / * 31 * / ++ unsigned long pc; / * 32 * / ++ unsigned long pstate; / * 33 * / ++ __u8 __reserved[4096] ++ }; ++ ++ The reserved space in sigcontext contains additional structures, each starting ++ with a sw_64_ctx, which specifies a unique identifier and the total size of ++ the structure. The final structure in reserved will start will a null ++ sw_64_ctx. The penultimate entry in reserved may be a extra_context which ++ then points to a further block of reserved space. ++ ++ struct sw_64_ctx { ++ u32 magic; ++ u32 size; ++ }; ++ ++ The restorer stub will always have the form: ++ ++ d28015a8 movz x8, #0xad ++ d4000001 svc #0x0 ++ ++ This is a system call sys_rt_sigreturn. ++ ++ We detect signal frames by snooping the return code for the restorer ++ instruction sequence. ++ ++ The handler then needs to recover the saved register set from ++ ucontext.uc_mcontext. */ ++ ++/* These magic numbers need to reflect the layout of the kernel ++ defined struct rt_sigframe and ucontext. */ ++#define SW_SIGCONTEXT_REG_SIZE 8 ++#define SW_RT_SIGFRAME_UCONTEXT_OFFSET 128 ++#define SW_UCONTEXT_SIGCONTEXT_OFFSET 176 ++#define SW_SIGCONTEXT_XO_OFFSET 8 ++#define SW_SIGCONTEXT_RESERVED_OFFSET 288 ++ ++#define SW_SIGCONTEXT_RESERVED_SIZE 4096 ++ ++/* Unique identifiers that may be used for sw_64_ctx.magic. */ ++#define SW_EXTRA_MAGIC 0x45585401 ++#define SW_FPSIMD_MAGIC 0x46508001 ++#define SW_SVE_MAGIC 0x53564501 ++ ++/* Defines for the extra_context that follows an SW_EXTRA_MAGIC. */ ++#define SW_EXTRA_DATAP_OFFSET 8 ++ ++/* Defines for the fpsimd that follows an SW_FPSIMD_MAGIC. */ ++#define SW_FPSIMD_FPSR_OFFSET 8 ++#define SW_FPSIMD_FPCR_OFFSET 12 ++#define SW_FPSIMD_V0_OFFSET 16 ++#define SW_FPSIMD_VREG_SIZE 16 ++ ++/* Defines for the sve structure that follows an SW_SVE_MAGIC. */ ++#define SW_SVE_CONTEXT_VL_OFFSET 8 ++#define SW_SVE_CONTEXT_REGS_OFFSET 16 ++#define SW_SVE_CONTEXT_P_REGS_OFFSET(vq) (32 * vq * 16) ++#define SW_SVE_CONTEXT_FFR_OFFSET(vq) \ ++ (SW_SVE_CONTEXT_P_REGS_OFFSET (vq) + (16 * vq * 2)) ++#define SW_SVE_CONTEXT_SIZE(vq) \ ++ (SW_SVE_CONTEXT_FFR_OFFSET (vq) + (vq * 2)) ++ ++ ++/* Read an sw_64_ctx, returning the magic value, and setting *SIZE to the ++ size, or return 0 on error. */ ++ ++static uint32_t ++read_sw_64_ctx (CORE_ADDR ctx_addr, enum bfd_endian byte_order, ++ uint32_t *size) ++{ ++ uint32_t magic = 0; ++ gdb_byte buf[4]; ++ ++ if (target_read_memory (ctx_addr, buf, 4) != 0) ++ return 0; ++ magic = extract_unsigned_integer (buf, 4, byte_order); ++ ++ if (target_read_memory (ctx_addr + 4, buf, 4) != 0) ++ return 0; ++ *size = extract_unsigned_integer (buf, 4, byte_order); ++ ++ return magic; ++} ++ ++/* Implement the "init" method of struct tramp_frame. */ ++ ++/*static void ++sw_64_linux_sigframe_init (const struct tramp_frame *self, ++ struct frame_info *this_frame, ++ struct trad_frame_cache *this_cache, ++ CORE_ADDR func) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ CORE_ADDR sp = get_frame_register_unsigned (this_frame, SW_SP_REGNUM); ++ CORE_ADDR sigcontext_addr = (sp + SW_RT_SIGFRAME_UCONTEXT_OFFSET ++ + SW_UCONTEXT_SIGCONTEXT_OFFSET ); ++ CORE_ADDR section = sigcontext_addr + SW_SIGCONTEXT_RESERVED_OFFSET; ++ CORE_ADDR section_end = section + SW_SIGCONTEXT_RESERVED_SIZE; ++ CORE_ADDR fpsimd = 0; ++ CORE_ADDR sve_regs = 0; ++ uint32_t size, magic; ++ bool extra_found = false; ++ int num_regs = gdbarch_num_regs (gdbarch); ++ ++ // Read in the integer registers. ++ ++ for (int i = 0; i < 31; i++) ++ { ++ trad_frame_set_reg_addr (this_cache, ++ SW_A0_REGNUM + i, ++ sigcontext_addr + SW_SIGCONTEXT_XO_OFFSET ++ + i * SW_SIGCONTEXT_REG_SIZE); ++ } ++ trad_frame_set_reg_addr (this_cache, SW_SP_REGNUM, ++ sigcontext_addr + SW_SIGCONTEXT_XO_OFFSET ++ + 31 * SW_SIGCONTEXT_REG_SIZE); ++ trad_frame_set_reg_addr (this_cache, SW_PC_REGNUM, ++ sigcontext_addr + SW_SIGCONTEXT_XO_OFFSET ++ + 32 * SW_SIGCONTEXT_REG_SIZE); ++ ++ // Search for the FP and SVE sections, stopping at null. ++ while ((magic = read_sw_64_ctx (section, byte_order, &size)) != 0 ++ && size != 0) ++ { ++ switch (magic) ++ { ++ case SW_FPSIMD_MAGIC: ++ fpsimd = section; ++ section += size; ++ break; ++ ++ case SW_SVE_MAGIC: ++ { ++ // Check if the section is followed by a full SVE dump, and set ++ // sve_regs if it is. ++ gdb_byte buf[4]; ++ uint16_t vq; ++ ++ if (!tdep->has_sve ()) ++ break; ++ ++ if (target_read_memory (section + SW_SVE_CONTEXT_VL_OFFSET, ++ buf, 2) != 0) ++ { ++ section += size; ++ break; ++ } ++ vq = sve_vq_from_vl (extract_unsigned_integer (buf, 2, byte_order)); ++ ++ if (vq != tdep->vq) ++ error (_("Invalid vector length in signal frame %d vs %s."), vq, ++ pulongest (tdep->vq)); ++ ++ if (size >= SW_SVE_CONTEXT_SIZE (vq)) ++ sve_regs = section + SW_SVE_CONTEXT_REGS_OFFSET; ++ ++ section += size; ++ break; ++ } ++ ++ case SW_EXTRA_MAGIC: ++ { ++ // Extra is always the last valid section in reserved and points to ++ // an additional block of memory filled with more sections. Reset ++ // the address to the extra section and continue looking for more ++ // structures. ++ gdb_byte buf[8]; ++ ++ if (target_read_memory (section + SW_EXTRA_DATAP_OFFSET, ++ buf, 8) != 0) ++ { ++ section += size; ++ break; ++ } ++ ++ section = extract_unsigned_integer (buf, 8, byte_order); ++ extra_found = true; ++ break; ++ } ++ ++ default: ++ section += size; ++ break; ++ } ++ ++ // Prevent searching past the end of the reserved section. The extra ++ section does not have a hard coded limit - we have to rely on it ending ++ with nulls. ++ if (!extra_found && section > section_end) ++ break; ++ } ++ ++ if (sve_regs != 0) ++ { ++ CORE_ADDR offset; ++ ++ for (int i = 0; i < 32; i++) ++ { ++ offset = sve_regs + (i * tdep->vq * 16); ++ trad_frame_set_reg_addr (this_cache, SW_SVE_Z0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_SVE_V0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, num_regs + SW_Q0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, num_regs + SW_D0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, num_regs + SW_S0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, num_regs + SW_H0_REGNUM + i, ++ offset); ++ trad_frame_set_reg_addr (this_cache, num_regs + SW_B0_REGNUM + i, ++ offset); ++ } ++ ++ offset = sve_regs + SW_SVE_CONTEXT_P_REGS_OFFSET (tdep->vq); ++ for (int i = 0; i < 16; i++) ++ trad_frame_set_reg_addr (this_cache, SW_SVE_P0_REGNUM + i, ++ offset + (i * tdep->vq * 2)); ++ ++ offset = sve_regs + SW_SVE_CONTEXT_FFR_OFFSET (tdep->vq); ++ trad_frame_set_reg_addr (this_cache, SW_SVE_FFR_REGNUM, offset); ++ } ++ ++ if (fpsimd != 0) ++ { ++ trad_frame_set_reg_addr (this_cache, SW_FPSR_REGNUM, ++ fpsimd + SW_FPSIMD_FPSR_OFFSET); ++ trad_frame_set_reg_addr (this_cache, SW_FPCR_REGNUM, ++ fpsimd + SW_FPSIMD_FPCR_OFFSET); ++ ++ // If there was no SVE section then set up the V registers. ++ if (sve_regs == 0) ++ for (int i = 0; i < 32; i++) ++ { ++ CORE_ADDR offset = (fpsimd + SW_FPSIMD_V0_OFFSET ++ + (i * SW_FPSIMD_VREG_SIZE)); ++ ++ trad_frame_set_reg_addr (this_cache, SW_V0_REGNUM + i, offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_Q0_REGNUM + i, offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_D0_REGNUM + i, offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_S0_REGNUM + i, offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_H0_REGNUM + i, offset); ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_B0_REGNUM + i, offset); ++ if (tdep->has_sve ()) ++ trad_frame_set_reg_addr (this_cache, ++ num_regs + SW_SVE_V0_REGNUM + i, ++ offset); ++ } ++ } ++ ++ trad_frame_set_id (this_cache, frame_id_build (sp, func)); ++} */ ++//rewrite ++/*static const struct tramp_frame sw_64_linux_rt_sigframe = ++{ ++ SIGTRAMP_FRAME, ++ 4, ++ { ++ // / movz x8, 0x8b (S=1,o=10,h=0,i=0x8b,r=8) ++ Soo1 0010 1hhi iiii iiii iiii iiir rrrr ++ {0xd2801168, ULONGEST_MAX}, ++ ++ svc 0x0 (o=0, l=1) ++ // 1101 0100 oooi iiii iiii iiii iii0 00ll ++ {0xd4000001, ULONGEST_MAX}, ++ {TRAMP_SENTINEL_INSN, ULONGEST_MAX} ++ }, ++ sw_64_linux_sigframe_init ++}; ++ ++ Register maps. ++ ++sve_vq_from_vl (vl); ++ ++ if (vq > SW_MAX_SVE_VQ) ++ { ++ warning (_("SVE Vector length in core file not supported by this version" ++ " of GDB. (VQ=%s)"), pulongest (vq)); ++ return 0; ++ } ++ else if (vq == 0) ++ { ++ warning (_("SVE Vector length in core file is invalid. (VQ=%s"), ++ pulongest (vq)); ++ return 0; ++ } ++ ++ return vq; ++}*/ ++ ++/* Supply register REGNUM from BUF to REGCACHE, using the register map ++ in REGSET. If REGNUM is -1, do this for all registers in REGSET. ++ If BUF is NULL, set the registers to "unavailable" status. */ ++ ++ ++/* Collect register REGNUM from REGCACHE to BUF, using the register ++ map in REGSET. If REGNUM is -1, do this for all registers in ++ REGSET. */ ++ ++ ++ ++/* Implement the "core_read_description" gdbarch method. */ ++ ++/*static const struct target_desc * ++sw_64_linux_core_read_description (struct gdbarch *gdbarch, ++ struct target_ops *target, bfd *abfd) ++{ ++ CORE_ADDR hwcap = linux_get_hwcap (target); ++ ++ return sw_64_read_description (sw_64_linux_core_read_vq (gdbarch, abfd), ++ hwcap & SW_64_HWCAP_PACA); ++}*/ ++ ++ ++ ++/* This routine is used to parse a special token in AArch64's assembly. ++ ++ The special tokens parsed by it are: ++ ++ - Register displacement (e.g, [fp, #-8]) ++ ++ It returns one if the special token has been parsed successfully, ++ or zero if the current token is not considered special. */ ++ ++/*static int ++sw_64_stap_parse_special_token (struct gdbarch *gdbarch, ++ struct stap_parse_info *p) ++{ ++ if (*p->arg == '[') ++ { ++ // / Temporary holder for lookahead. / ++ const char *tmp = p->arg; ++ char *endp; ++ // Used to save the register name. / ++ const char *start; ++ char *regname; ++ int len; ++ int got_minus = 0; ++ long displacement; ++ struct stoken str; ++ ++ ++tmp; ++ start = tmp; ++ ++ / Register name. / ++ while (isalnum (*tmp)) ++ ++tmp; ++ ++ if (*tmp != ',') ++ return 0; ++ ++ len = tmp - start; ++ regname = (char *) alloca (len + 2); ++ ++ strncpy (regname, start, len); ++ regname[len] = '\0'; ++ ++ if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1) ++ error (_("Invalid register name `%s' on expression `%s'."), ++ regname, p->saved_arg); ++ ++ ++tmp; ++ tmp = skip_spaces (tmp); ++ /* Now we expect a number. It can begin with '#' or simply ++ a digit. / ++ if (*tmp == '#') ++ ++tmp; ++ ++ if (*tmp == '-') ++ { ++ ++tmp; ++ got_minus = 1; ++ } ++ else if (*tmp == '+') ++ ++tmp; ++ ++ if (!isdigit (*tmp)) ++ return 0; ++ ++ displacement = strtol (tmp, &endp, 10); ++ tmp = endp; ++ ++ /* Skipping last `]'. / ++ if (*tmp++ != ']') ++ return 0; ++ ++ /* The displacement. / ++ write_exp_elt_opcode (&p->pstate, OP_LONG); ++ write_exp_elt_type (&p->pstate, builtin_type (gdbarch)->builtin_long); ++ write_exp_elt_longcst (&p->pstate, displacement); ++ write_exp_elt_opcode (&p->pstate, OP_LONG); ++ if (got_minus) ++ write_exp_elt_opcode (&p->pstate, UNOP_NEG); ++ ++ /* The register name. / ++ write_exp_elt_opcode (&p->pstate, OP_REGISTER); ++ str.ptr = regname; ++ str.length = len; ++ write_exp_string (&p->pstate, str); ++ write_exp_elt_opcode (&p->pstate, OP_REGISTER); ++ ++ write_exp_elt_opcode (&p->pstate, BINOP_ADD); ++ ++ /* Casting to the expected type. / ++ write_exp_elt_opcode (&p->pstate, UNOP_CAST); ++ write_exp_elt_type (&p->pstate, lookup_pointer_type (p->arg_type)); ++ write_exp_elt_opcode (&p->pstate, UNOP_CAST); ++ ++ write_exp_elt_opcode (&p->pstate, UNOP_IND); ++ ++ p->arg = tmp; ++ } ++ else ++ return 0; ++ ++ return 1; ++}*/ ++ ++/* AArch64 process record-replay constructs: syscall, signal etc. */ ++ ++struct linux_record_tdep sw_64_linux_record_tdep; ++ ++/* Enum that defines the AArch64 linux specific syscall identifiers used for ++ process record/replay. */ ++//rewrite ++/* ++enum sw_64_syscall{ ++ ++sw_64_sys_exit =1, ++sw_64_sys_fork =2, ++sw_64_sys_read =3, ++sw_64_sys_write =4, ++sw_64_sys_close =6, ++sw_64_sys_osf_wait4 =7, ++sw_64_sys_link =9, ++sw_64_sys_unlink =10, ++sw_64_sys_chdir =12, ++sw_64_sys_fchdir =13, ++sw_64_sys_mknod =14, ++sw_64_sys_chmod =15, ++sw_64_sys_chown =16, ++sw_64_sys_brk =17, ++sw_64_sys_lseek =19, ++sw_64_sys_getxpid =20, ++sw_64_sys_osf_mount =21, ++sw_64_sys_umount2 =22, ++sw_64_sys_setuid =23, ++sw_64_sys_getxuid =24, ++sw_64_sys_ptrace =26, ++sw_64_sys_access =33, ++sw_64_sys_sync =36, ++sw_64_sys_kill =37, ++sw_64_sys_setpgid =39, ++sw_64_sys_dup =41, ++sw_64_sys_pipe =42, ++sw_64_sys_osf_set_program_attributes =43, ++sw_64_sys_open =45, ++sw_64_sys_getxgid =47, ++sw_64_sys_osf_sigprocmask =48, ++sw_64_sys_acct =51, ++sw_64_sys_sigpending =52, ++sw_64_sys_ioctl =54, ++sw_64_sys_symlink =57, ++sw_64_sys_readlink =58, ++sw_64_sys_execve =59, ++sw_64_sys_umask =60, ++sw_64_sys_chroot =61, ++sw_64_sys_getpgrp =63, ++sw_64_sys_getpagesize =64, ++sw_64_sys_vfork =66, ++sw_64_sys_stat =67, ++sw_64_sys_lstat =68, ++sw_64_sys_mmap =71, ++sw_64_sys_munmap =73, ++sw_64_sys_mprotect =74, ++sw_64_sys_madvise =75, ++sw_64_sys_vhangup =76, ++sw_64_sys_getgroups =79, ++sw_64_sys_setgroups =80, ++sw_64_sys_setpgrp =82, ++sw_64_sys_osf_setitimer =83, ++sw_64_sys_osf_getitimer =86, ++sw_64_sys_gethostname =87, ++sw_64_sys_sethostname =88, ++sw_64_sys_getdtablesize =89, ++sw_64_sys_dup2 =90, ++sw_64_sys_fstat =91, ++sw_64_sys_fcntl =92, ++sw_64_sys_osf_select =93, ++sw_64_sys_poll =94, ++sw_64_sys_fsync =95, ++sw_64_sys_setpriority =96, ++sw_64_sys_socket =97, ++sw_64_sys_connect =98, ++sw_64_sys_accept =99, ++sw_64_sys_getpriority =100, ++sw_64_sys_send =101, ++sw_64_sys_recv =102, ++sw_64_sys_sigreturn =103, ++sw_64_sys_bind =104, ++sw_64_sys_setsockopt =105, ++sw_64_sys_listen =106, ++sw_64_sys_sigsuspend =111, ++sw_64_sys_osf_sigstack =112, ++sw_64_sys_recvmsg =113, ++sw_64_sys_sendmsg =114, ++sw_64_sys_osf_gettimeofday =116, ++sw_64_sys_osf_getrusage =117, ++sw_64_sys_getsockopt =118, ++sw_64_sys_socketcall =119, ++sw_64_sys_readv =120, ++sw_64_sys_writev =121, ++sw_64_sys_osf_settimeofday =122, ++sw_64_sys_fchown =123, ++sw_64_sys_fchmod =124, ++sw_64_sys_recvfrom =125, ++sw_64_sys_setreuid =126, ++sw_64_sys_setregid =127, ++sw_64_sys_rename =128, ++sw_64_sys_truncate =129, ++sw_64_sys_ftruncate =130, ++sw_64_sys_flock =131, ++sw_64_sys_setgid =132, ++sw_64_sys_sendto =133, ++sw_64_sys_shutdown =134, ++sw_64_sys_socketpair =135, ++sw_64_sys_mkdir =136, ++sw_64_sys_rmdir =137, ++sw_64_sys_osf_utimes =138, ++sw_64_sys_getpeername =141, ++sw_64_sys_getrlimit =144, ++sw_64_sys_setrlimit =145, ++sw_64_sys_setsid =147, ++sw_64_sys_quotactl =148, ++sw_64_sys_getsockname =150, ++sw_64_sys_sigaction =156, ++sw_64_sys_osf_getdirentries =159, ++sw_64_sys_osf_statfs =160, ++sw_64_sys_osf_fstatfs =161, ++sw_64_sys_osf_getdomainname =165, ++sw_64_sys_setdomainname =166, ++sw_64_sys_bpf =170, ++sw_64_sys_userfaultfd =171, ++sw_64_sys_membarrier =172, ++sw_64_sys_mlock2 =173, ++sw_64_sys_getpid =174, ++sw_64_sys_getppid =175, ++sw_64_sys_getuid =176, ++sw_64_sys_geteuid =177, ++sw_64_sys_getgid =178, ++sw_64_sys_getegid =179, ++sw_64_sys_osf_swapon =199, ++sw_64_sys_msgctl =200, ++sw_64_sys_msgget =201, ++sw_64_sys_msgrcv =202, ++sw_64_sys_msgsnd =203, ++sw_64_sys_semctl =204, ++sw_64_sys_semget =205, ++sw_64_sys_semop =206, ++sw_64_sys_osf_utsname =207, ++sw_64_sys_lchown =208, ++sw_64_sys_shmat =209, ++sw_64_sys_shmctl =210, ++sw_64_sys_shmdt =211, ++sw_64_sys_shmget =212, ++sw_64_sys_msync =217, ++sw_64_sys_osf_stat =224, ++sw_64_sys_osf_lstat =225, ++sw_64_sys_osf_fstat =226, ++sw_64_sys_osf_statfs64 =227, ++sw_64_sys_osf_fstatfs64 =228, ++sw_64_sys_statfs64 =229, ++sw_64_sys_fstatfs64 =230, ++sw_64_sys_getpgid =233, ++sw_64_sys_getsid =234, ++sw_64_sys_sigaltstack =235, ++sw_64_sys_osf_sysinfo =241, ++sw_64_sys_osf_proplist_syscall =244, ++sw_64_sys_osf_usleep_thread =251, ++sw_64_sys_sysfs =254, ++sw_64_sys_osf_getsysinfo =256, ++sw_64_sys_osf_setsysinfo =257, ++sw_64_sys_bdflush =300, ++sw_64_sys_sethae =301, ++sw_64_sys_mount =302, ++sw_64_sys_old_adjtimex =303, ++sw_64_sys_swapoff =304, ++sw_64_sys_getdents =305, ++sw_64_sys_create_module =306, ++sw_64_sys_init_module =307, ++sw_64_sys_delete_module =308, ++sw_64_sys_get_kernel_syms =309, ++sw_64_sys_syslog =310, ++sw_64_sys_reboot =311, ++sw_64_sys_clone =312, ++sw_64_sys_uselib =313, ++sw_64_sys_mlock =314, ++sw_64_sys_munlock =315, ++sw_64_sys_mlockall =316, ++sw_64_sys_munlockall =317, ++sw_64_sys_sysinfo =318, ++sw_64_sys__sysctl =319, ++sw_64_sys_oldumount =321, ++sw_64_sys_swapon =322, ++sw_64_sys_times =323, ++sw_64_sys_personality =324, ++sw_64_sys_setfsuid =325, ++sw_64_sys_setfsgid =326, ++sw_64_sys_ustat =327, ++sw_64_sys_statfs =328, ++sw_64_sys_fstatfs =329, ++sw_64_sys_sched_setparam =330, ++sw_64_sys_sched_getparam =331, ++sw_64_sys_sched_setscheduler =332, ++sw_64_sys_sched_getscheduler =333, ++sw_64_sys_sched_yield =334, ++sw_64_sys_sched_get_priority_max =335, ++sw_64_sys_sched_get_priority_min =336, ++sw_64_sys_sched_rr_get_interval =337, ++sw_64_sys_afs_syscall =338, ++sw_64_sys_uname =339, ++sw_64_sys_nanosleep =340, ++sw_64_sys_mremap =341, ++sw_64_sys_nfsservctl =342, ++sw_64_sys_setresuid =343, ++sw_64_sys_getresuid =344, ++sw_64_sys_pciconfig_read =345, ++sw_64_sys_pciconfig_write =346, ++sw_64_sys_query_module =347, ++sw_64_sys_prctl =348, ++sw_64_sys_pread64 =349, ++sw_64_sys_pwrite64 =350, ++sw_64_sys_rt_sigreturn =351, ++sw_64_sys_rt_sigaction =352, ++sw_64_sys_rt_sigprocmask =353, ++sw_64_sys_rt_sigpending =354, ++sw_64_sys_rt_sigtimedwait =355, ++sw_64_sys_rt_sigqueueinfo =356, ++sw_64_sys_rt_sigsuspend =357, ++sw_64_sys_select =358, ++sw_64_sys_gettimeofday =359, ++sw_64_sys_settimeofday =360, ++sw_64_sys_getitimer =361, ++sw_64_sys_setitimer =362, ++sw_64_sys_utimes =363, ++sw_64_sys_getrusage =364, ++sw_64_sys_wait4 =365, ++sw_64_sys_adjtimex =366, ++sw_64_sys_getcwd =367, ++sw_64_sys_capget =368, ++sw_64_sys_capset =369, ++sw_64_sys_sendfile =370, ++sw_64_sys_setresgid =371, ++sw_64_sys_getresgid =372, ++sw_64_sys_dipc =373, ++sw_64_sys_pivot_root =374, ++sw_64_sys_mincore =375, ++sw_64_sys_pciconfig_iobase =376, ++sw_64_sys_getdents64 =377, ++sw_64_sys_gettid =378, ++sw_64_sys_readahead =379, ++sw_64_sys_tkill =381, ++sw_64_sys_setxattr =382, ++sw_64_sys_lsetxattr =383, ++sw_64_sys_fsetxattr =384, ++sw_64_sys_getxattr =385, ++sw_64_sys_lgetxattr =386, ++sw_64_sys_fgetxattr =387, ++sw_64_sys_listxattr =388, ++sw_64_sys_llistxattr =389, ++sw_64_sys_flistxattr =390, ++sw_64_sys_removexattr =391, ++sw_64_sys_lremovexattr =392, ++sw_64_sys_fremovexattr =393, ++sw_64_sys_futex =394, ++sw_64_sys_sched_setaffinity =395, ++sw_64_sys_sched_getaffinity =396, ++sw_64_sys_tuxcall =397, ++sw_64_sys_io_setup =398, ++sw_64_sys_io_destroy =399, ++sw_64_sys_io_getevents =400, ++sw_64_sys_io_submit =401, ++sw_64_sys_io_cancel =402, ++sw_64_sys_io_pgetevents =403, ++sw_64_sys_rseq =404, ++sw_64_sys_exit_group =405, ++sw_64_sys_lookup_dcookie =406, ++sw_64_sys_epoll_create =407, ++sw_64_sys_epoll_ctl =408, ++sw_64_sys_epoll_wait =409, ++sw_64_sys_remap_file_pages =410, ++sw_64_sys_set_tid_address =411, ++sw_64_sys_restart_syscall =412, ++sw_64_sys_fadvise64 =413, ++sw_64_sys_timer_create =414, ++sw_64_sys_timer_settime =415, ++sw_64_sys_timer_gettime =416, ++sw_64_sys_timer_getoverrun =417, ++sw_64_sys_timer_delete =418, ++sw_64_sys_clock_settime =419, ++sw_64_sys_clock_gettime =420, ++sw_64_sys_clock_getres =421, ++sw_64_sys_clock_nanosleep =422, ++sw_64_sys_semtimedop =423, ++sw_64_sys_tgkill =424, ++sw_64_sys_stat64 =425, ++sw_64_sys_lstat64 =426, ++sw_64_sys_fstat64 =427, ++sw_64_sys_vserver =428, ++sw_64_sys_mbind =429, ++sw_64_sys_get_mempolicy =430, ++sw_64_sys_set_mempolicy =431, ++sw_64_sys_mq_open =432, ++sw_64_sys_mq_unlink =433, ++sw_64_sys_mq_timedsend =434, ++sw_64_sys_mq_timedreceive =435, ++sw_64_sys_mq_notify =436, ++sw_64_sys_mq_getsetattr =437, ++sw_64_sys_waitid =438, ++sw_64_sys_add_key =439, ++sw_64_sys_request_key =440, ++sw_64_sys_keyctl =441, ++sw_64_sys_ioprio_set =442, ++sw_64_sys_ioprio_get =443, ++sw_64_sys_inotify_init =444, ++sw_64_sys_inotify_add_watch =445, ++sw_64_sys_inotify_rm_watch =446, ++sw_64_sys_fdatasync =447, ++sw_64_sys_kexec_load =448, ++sw_64_sys_migrate_pages =449, ++sw_64_sys_openat =450, ++sw_64_sys_mkdirat =451, ++sw_64_sys_mknodat =452, ++sw_64_sys_fchownat =453, ++sw_64_sys_futimesat =454, ++sw_64_sys_fstatat64 =455, ++sw_64_sys_unlinkat =456, ++sw_64_sys_renameat =457, ++sw_64_sys_linkat =458, ++sw_64_sys_symlinkat =459, ++sw_64_sys_readlinkat =460, ++sw_64_sys_fchmodat =461, ++sw_64_sys_faccessat =462, ++sw_64_sys_pselect6 =463, ++sw_64_sys_ppoll =464, ++sw_64_sys_unshare =465, ++sw_64_sys_set_robust_list =466, ++sw_64_sys_get_robust_list =467, ++sw_64_sys_splice =468, ++sw_64_sys_sync_file_range =469, ++sw_64_sys_tee =470, ++sw_64_sys_vmsplice =471, ++sw_64_sys_move_pages =472, ++sw_64_sys_getcpu =473, ++sw_64_sys_epoll_pwait =474, ++sw_64_sys_utimensat =475, ++sw_64_sys_signalfd =476, ++sw_64_sys_timerfd =477, ++sw_64_sys_eventfd =478, ++sw_64_sys_recvmmsg =479, ++sw_64_sys_fallocate =480, ++sw_64_sys_timerfd_create =481, ++sw_64_sys_timerfd_settime =482, ++sw_64_sys_timerfd_gettime =483, ++sw_64_sys_signalfd4 =484, ++sw_64_sys_eventfd2 =485, ++sw_64_sys_epoll_create1 =486, ++sw_64_sys_dup3 =487, ++sw_64_sys_pipe2 =488, ++sw_64_sys_inotify_init1 =489, ++sw_64_sys_preadv =490, ++sw_64_sys_pwritev =491, ++sw_64_sys_rt_tgsigqueueinfo =492, ++sw_64_sys_perf_event_open =493, ++sw_64_sys_fanotify_init =494, ++sw_64_sys_fanotify_mark =495, ++sw_64_sys_prlimit64 =496, ++sw_64_sys_name_to_handle_at =497, ++sw_64_sys_open_by_handle_at =498, ++sw_64_sys_clock_adjtime =499, ++sw_64_sys_syncfs =500, ++sw_64_sys_setns =501, ++sw_64_sys_accept4 =502, ++sw_64_sys_sendmmsg =503, ++sw_64_sys_process_vm_readv =504, ++sw_64_sys_process_vm_writev 505, ++sw_64_sys_kcmp =506, ++sw_64_sys_finit_module =507, ++sw_64_sys_sched_setattr =508, ++sw_64_sys_sched_getattr =509, ++sw_64_sys_renameat2 =510, ++sw_64_sys_getrandom =511, ++sw_64_sys_memfd_create =512, ++sw_64_sys_execveat =513, ++sw_64_sys_seccomp =514, ++sw_64_sys_copy_file_range =515, ++sw_64_sys_preadv2 =516, ++sw_64_sys_pwritev2 =517, ++sw_64_sys_statx = 518, ++};*/ ++enum sw_64_syscall{ ++ ++sw_64_sys_exit =1, ++sw_64_sys_fork =2, ++sw_64_sys_read =3, ++sw_64_sys_write =4, ++sw_64_sys_close =6, ++sw_64_sys_wait4 =7, ++sw_64_sys_link =9, ++sw_64_sys_unlink =10, ++sw_64_sys_chdir =12, ++sw_64_sys_fchdir =13, ++sw_64_sys_mknod =14, ++sw_64_sys_chmod =15, ++sw_64_sys_chown =16, ++sw_64_sys_brk =17, ++sw_64_sys_lseek =19, ++sw_64_sys_getpid =20,//getxpid ++sw_64_sys_mount =21, ++sw_64_sys_umount2 =22, ++sw_64_sys_setuid =23, ++sw_64_sys_getuid =24,//getxuid ++sw_64_sys_ptrace =26, ++sw_64_sys_access =33, ++sw_64_sys_sync =36, ++sw_64_sys_kill =37, ++sw_64_sys_setpgid =39, ++sw_64_sys_dup =41, ++sw_64_sys_pipe =42, ++sw_64_sys_set_program_attributes =43, ++sw_64_sys_open =45, ++sw_64_sys_getgid =47,//getxgid ++sw_64_sys_sigprocmask =48, ++sw_64_sys_acct =51, ++sw_64_sys_sigpending =52, ++sw_64_sys_ioctl =54, ++sw_64_sys_symlink =57, ++sw_64_sys_readlink =58, ++sw_64_sys_execve =59, ++sw_64_sys_umask =60, ++sw_64_sys_chroot =61, ++sw_64_sys_getpgrp =63, ++sw_64_sys_getpagesize =64, ++sw_64_sys_vfork =66, ++sw_64_sys_stat =67, ++sw_64_sys_lstat =68, ++sw_64_sys_mmap =71, ++sw_64_sys_munmap =73, ++sw_64_sys_mprotect =74, ++sw_64_sys_madvise =75, ++sw_64_sys_vhangup =76, ++sw_64_sys_getgroups =79, ++sw_64_sys_setgroups =80, ++sw_64_sys_setpgrp =82, ++sw_64_sys_setitimer =83, ++sw_64_sys_getitimer =86, ++sw_64_sys_gethostname =87, ++sw_64_sys_sethostname =88, ++sw_64_sys_getdtablesize =89, ++sw_64_sys_dup2 =90, ++sw_64_sys_fstat =91, ++sw_64_sys_fcntl =92, ++sw_64_sys_select =93, ++sw_64_sys_poll =94, ++sw_64_sys_fsync =95, ++sw_64_sys_setpriority =96, ++sw_64_sys_socket =97, ++sw_64_sys_connect =98, ++sw_64_sys_accept =99, ++sw_64_sys_getpriority =100, ++sw_64_sys_send =101, ++sw_64_sys_recv =102, ++sw_64_sys_sigreturn =103, ++sw_64_sys_bind =104, ++sw_64_sys_setsockopt =105, ++sw_64_sys_listen =106, ++sw_64_sys_sigsuspend =111, ++sw_64_sysi_sigstack =112, ++sw_64_sys_recvmsg =113, ++sw_64_sys_sendmsg =114, ++sw_64_sys_gettimeofday =116, ++sw_64_sys_getrusage =117, ++sw_64_sys_getsockopt =118, ++sw_64_sys_socketcall =119, ++sw_64_sys_readv =120, ++sw_64_sys_writev =121, ++sw_64_sys_settimeofday =122, ++sw_64_sys_fchown =123, ++sw_64_sys_fchmod =124, ++sw_64_sys_recvfrom =125, ++sw_64_sys_setreuid =126, ++sw_64_sys_setregid =127, ++sw_64_sys_rename =128, ++sw_64_sys_truncate =129, ++sw_64_sys_ftruncate =130, ++sw_64_sys_flock =131, ++sw_64_sys_setgid =132, ++sw_64_sys_sendto =133, ++sw_64_sys_shutdown =134, ++sw_64_sys_socketpair =135, ++sw_64_sys_mkdir =136, ++sw_64_sys_rmdir =137, ++sw_64_sys_utimes =138, ++sw_64_sys_getpeername =141, ++sw_64_sys_getrlimit =144, ++sw_64_sys_setrlimit =145, ++sw_64_sys_setsid =147, ++sw_64_sys_quotactl =148, ++sw_64_sys_getsockname =150, ++sw_64_sys_sigaction =156, ++sw_64_sys_getdirentries =159, ++sw_64_sys_statfs =160, ++sw_64_sys_fstatfs =161, ++sw_64_sys_getdomainname =165, ++sw_64_sys_setdomainname =166, ++sw_64_sys_bpf =170, ++sw_64_sys_userfaultfd =171, ++sw_64_sys_membarrier =172, ++sw_64_sys_mlock2 =173, ++//sw_64_sys_getpid =174,//REPITATION ++sw_64_sys_getppid =175, ++//sw_64_sys_getuid =176,//REPITATION ++sw_64_sys_geteuid =177, ++//sw_64_sys_getgid =178,//REPITATION ++sw_64_sys_getegid =179, ++sw_64_sys_swapon =199, ++sw_64_sys_msgctl =200, ++sw_64_sys_msgget =201, ++sw_64_sys_msgrcv =202, ++sw_64_sys_msgsnd =203, ++sw_64_sys_semctl =204, ++sw_64_sys_semget =205, ++sw_64_sys_semop =206, ++sw_64_sys_utsname =207, ++sw_64_sys_lchown =208, ++sw_64_sys_shmat =209, ++sw_64_sys_shmctl =210, ++sw_64_sys_shmdt =211, ++sw_64_sys_shmget =212, ++sw_64_sys_msync =217, ++sw_64_sysi_stat =224, ++sw_64_sys_statfs64 =227, ++sw_64_sys_fstatfs64 =230, ++sw_64_sys_getpgid =233, ++sw_64_sys_getsid =234, ++sw_64_sys_sigaltstack =235, ++//sw_64_sys_osf_sysinfo =241,// ++sw_64_sys_proplist_syscall =244, ++sw_64_sys_usleep_thread =251, ++sw_64_sys_sysfs =254, ++sw_64_sys_getsysinfo =256, ++sw_64_sys_setsysinfo =257, ++sw_64_sys_bdflush =300, ++sw_64_sys_sethae =301, ++sw_64_sys_old_adjtimex =303, ++sw_64_sys_swapoff =304, ++sw_64_sys_getdents =305, ++sw_64_sys_create_module =306, ++sw_64_sys_init_module =307, ++sw_64_sys_delete_module =308, ++sw_64_sys_get_kernel_syms =309, ++sw_64_sys_syslog =310, ++sw_64_sys_reboot =311, ++sw_64_sys_clone =312, ++sw_64_sys_uselib =313, ++sw_64_sys_mlock =314, ++sw_64_sys_munlock =315, ++sw_64_sys_mlockall =316, ++sw_64_sys_munlockall =317, ++sw_64_sys_sysinfo =318, ++sw_64_sys_sysctl =319, ++sw_64_sys_oldumount =321, ++sw_64_sys_times =323, ++sw_64_sys_personality =324, ++sw_64_sys_setfsuid =325, ++sw_64_sys_setfsgid =326, ++sw_64_sys_ustat =327, ++sw_64_sys_sched_setparam =330, ++sw_64_sys_sched_getparam =331, ++sw_64_sys_sched_setscheduler =332, ++sw_64_sys_sched_getscheduler =333, ++sw_64_sys_sched_yield =334, ++sw_64_sys_sched_get_priority_max =335, ++sw_64_sys_sched_get_priority_min =336, ++sw_64_sys_sched_rr_get_interval =337, ++sw_64_sys_afs_syscall =338, ++sw_64_sys_uname =339, ++sw_64_sys_nanosleep =340, ++sw_64_sys_mremap =341, ++sw_64_sys_nfsservctl =342, ++sw_64_sys_setresuid =343, ++sw_64_sys_getresuid =344, ++sw_64_sys_pciconfig_read =345, ++sw_64_sys_pciconfig_write =346, ++sw_64_sys_query_module =347, ++sw_64_sys_prctl =348, ++sw_64_sys_pread64 =349, ++sw_64_sys_pwrite64 =350, ++sw_64_sys_rt_sigreturn =351, ++sw_64_sys_rt_sigaction =352, ++sw_64_sys_rt_sigprocmask =353, ++sw_64_sys_rt_sigpending =354, ++sw_64_sys_rt_sigtimedwait =355, ++sw_64_sys_rt_sigqueueinfo =356, ++sw_64_sys_rt_sigsuspend =357, ++sw_64_sys_adjtimex =366, ++sw_64_sys_getcwd =367, ++sw_64_sys_capget =368, ++sw_64_sys_capset =369, ++sw_64_sys_sendfile =370, ++sw_64_sys_setresgid =371, ++sw_64_sys_getresgid =372, ++sw_64_sys_dipc =373, ++sw_64_sys_pivot_root =374, ++sw_64_sys_mincore =375, ++sw_64_sys_pciconfig_iobase =376, ++sw_64_sys_getdents64 =377, ++sw_64_sys_gettid =378, ++sw_64_sys_readahead =379, ++sw_64_sys_tkill =381, ++sw_64_sys_setxattr =382, ++sw_64_sys_lsetxattr =383, ++sw_64_sys_fsetxattr =384, ++sw_64_sys_getxattr =385, ++sw_64_sys_lgetxattr =386, ++sw_64_sys_fgetxattr =387, ++sw_64_sys_listxattr =388, ++sw_64_sys_llistxattr =389, ++sw_64_sys_flistxattr =390, ++sw_64_sys_removexattr =391, ++sw_64_sys_lremovexattr =392, ++sw_64_sys_fremovexattr =393, ++sw_64_sys_futex =394, ++sw_64_sys_sched_setaffinity =395, ++sw_64_sys_sched_getaffinity =396, ++sw_64_sys_tuxcall =397, ++sw_64_sys_io_setup =398, ++sw_64_sys_io_destroy =399, ++sw_64_sys_io_getevents =400, ++sw_64_sys_io_submit =401, ++sw_64_sys_io_cancel =402, ++sw_64_sys_io_pgetevents =403, ++sw_64_sys_rseq =404, ++sw_64_sys_exit_group =405, ++sw_64_sys_lookup_dcookie =406, ++sw_64_sys_epoll_create =407, ++sw_64_sys_epoll_ctl =408, ++sw_64_sys_epoll_wait =409, ++sw_64_sys_remap_file_pages =410, ++sw_64_sys_set_tid_address =411, ++sw_64_sys_restart_syscall =412, ++sw_64_sys_fadvise64 =413, ++sw_64_sys_timer_create =414, ++sw_64_sys_timer_settime =415, ++sw_64_sys_timer_gettime =416, ++sw_64_sys_timer_getoverrun =417, ++sw_64_sys_timer_delete =418, ++sw_64_sys_clock_settime =419, ++sw_64_sys_clock_gettime =420, ++sw_64_sys_clock_getres =421, ++sw_64_sys_clock_nanosleep =422, ++sw_64_sys_semtimedop =423, ++sw_64_sys_tgkill =424, ++sw_64_sys_stat64 =425, ++sw_64_sys_lstat64 =426, ++sw_64_sys_fstat64 =427, ++sw_64_sys_vserver =428, ++sw_64_sys_mbind =429, ++sw_64_sys_get_mempolicy =430, ++sw_64_sys_set_mempolicy =431, ++sw_64_sys_mq_open =432, ++sw_64_sys_mq_unlink =433, ++sw_64_sys_mq_timedsend =434, ++sw_64_sys_mq_timedreceive =435, ++sw_64_sys_mq_notify =436, ++sw_64_sys_mq_getsetattr =437, ++sw_64_sys_waitid =438, ++sw_64_sys_add_key =439, ++sw_64_sys_request_key =440, ++sw_64_sys_keyctl =441, ++sw_64_sys_ioprio_set =442, ++sw_64_sys_ioprio_get =443, ++sw_64_sys_inotify_init =444, ++sw_64_sys_inotify_add_watch =445, ++sw_64_sys_inotify_rm_watch =446, ++sw_64_sys_fdatasync =447, ++sw_64_sys_kexec_load =448, ++sw_64_sys_migrate_pages =449, ++sw_64_sys_openat =450, ++sw_64_sys_mkdirat =451, ++sw_64_sys_mknodat =452, ++sw_64_sys_fchownat =453, ++sw_64_sys_futimesat =454, ++sw_64_sys_fstatat64 =455, ++sw_64_sys_unlinkat =456, ++sw_64_sys_renameat =457, ++sw_64_sys_linkat =458, ++sw_64_sys_symlinkat =459, ++sw_64_sys_readlinkat =460, ++sw_64_sys_fchmodat =461, ++sw_64_sys_faccessat =462, ++sw_64_sys_pselect6 =463, ++sw_64_sys_ppoll =464, ++sw_64_sys_unshare =465, ++sw_64_sys_set_robust_list =466, ++sw_64_sys_get_robust_list =467, ++sw_64_sys_splice =468, ++sw_64_sys_sync_file_range =469, ++sw_64_sys_tee =470, ++sw_64_sys_vmsplice =471, ++sw_64_sys_move_pages =472, ++sw_64_sys_getcpu =473, ++sw_64_sys_epoll_pwait =474, ++sw_64_sys_utimensat =475, ++sw_64_sys_signalfd =476, ++sw_64_sys_timerfd =477, ++sw_64_sys_eventfd =478, ++sw_64_sys_recvmmsg =479, ++sw_64_sys_fallocate =480, ++sw_64_sys_timerfd_create =481, ++sw_64_sys_timerfd_settime =482, ++sw_64_sys_timerfd_gettime =483, ++sw_64_sys_signalfd4 =484, ++sw_64_sys_eventfd2 =485, ++sw_64_sys_epoll_create1 =486, ++sw_64_sys_dup3 =487, ++sw_64_sys_pipe2 =488, ++sw_64_sys_inotify_init1 =489, ++sw_64_sys_preadv =490, ++sw_64_sys_pwritev =491, ++sw_64_sys_rt_tgsigqueueinfo =492, ++sw_64_sys_perf_event_open =493, ++sw_64_sys_fanotify_init =494, ++sw_64_sys_fanotify_mark =495, ++sw_64_sys_prlimit64 =496, ++sw_64_sys_name_to_handle_at =497, ++sw_64_sys_open_by_handle_at =498, ++sw_64_sys_clock_adjtime =499, ++sw_64_sys_syncfs =500, ++sw_64_sys_setns =501, ++sw_64_sys_accept4 =502, ++sw_64_sys_sendmmsg =503, ++sw_64_sys_process_vm_readv =504, ++sw_64_sys_process_vm_writev= 505, ++sw_64_sys_kcmp =506, ++sw_64_sys_finit_module =507, ++sw_64_sys_sched_setattr =508, ++sw_64_sys_sched_getattr =509, ++sw_64_sys_renameat2 =510, ++sw_64_sys_getrandom =511, ++sw_64_sys_memfd_create =512, ++sw_64_sys_execveat =513, ++sw_64_sys_seccomp =514, ++sw_64_sys_copy_file_range =515, ++sw_64_sys_preadv2 =516, ++sw_64_sys_pwritev2 =517, ++sw_64_sys_statx = 518, ++}; ++/*enum sw_64_syscall{ ++ sw_64_sys_osf_syscall =0, ++ sw_64_sys_exit =1, ++ sw_64_sys_fork =2, ++ sw_64_sys_read =3, ++ sw_64_sys_write =4, ++ sw_64_sys_osf_old_open =5, ++ sw_64_sys_close =6, ++ sw_64_sys_osf_wait4 =7, ++ sw_64_sys_osf_old_creat =8, ++ sw_64_sys_link =9, ++ sw_64_sys_unlink =10, ++ sw_64_sys_osf_execve =11, ++ sw_64_sys_chdir =12, ++ sw_64_sys_fchdir =13, ++ sw_64_sys_mknod =14, ++ sw_64_sys_chmod =15, ++ sw_64_sys_chown =16, ++ sw_64_sys_brk =17, ++ sw_64_sys_osf_getfsstat =18, ++ sw_64_sys_lseek =19, ++ sw_64_sys_getxpid =20, ++ sw_64_sys_osf_mount =21, ++ sw_64_sys_umount =22, ++ sw_64_sys_setuid =23, ++ sw_64_sys_getxuid =24, ++ sw_64_sys_exec_with_loader =25, ++ sw_64_sys_ptrace =26, ++ sw_64_sys_osf_nrecvmsg =27, ++ sw_64_sys_osf_nsendmsg =28, ++ sw_64_sys_osf_nrecvfrom =29, ++ sw_64_sys_osf_naccept =30, ++ sw_64_sys_osf_ngetpeername =31, ++ sw_64_sys_osf_ngetsockname =32, ++ sw_64_sys_access =33, ++ sw_64_sys_osf_chflags =34, ++ sw_64_sys_osf_fchflags =35, ++ sw_64_sys_sync =36, ++ sw_64_sys_kill =37, ++ sw_64_sys_osf_old_stat =38, ++ sw_64_sys_setpgid =39, ++ sw_64_sys_osf_old_lstat =40, ++ sw_64_sys_dup =41, ++ sw_64_sys_pipe =42, ++ sw_64_sys_osf_set_program_attributes =43, ++ sw_64_sys_osf_profil =44, ++ sw_64_sys_open =45, ++ sw_64_sys_osf_old_sigaction =46, ++ sw_64_sys_getxgid =47, ++ sw_64_sys_osf_sigprocmask =48, ++ sw_64_sys_osf_getlogin =49, ++ sw_64_sys_osf_setlogin =50, ++ sw_64_sys_acct =51, ++ sw_64_sys_sigpending =52, ++ ++ sw_64_sys_ioctl =54, ++ sw_64_sys_osf_reboot =55, ++ sw_64_sys_osf_revoke =56, ++ sw_64_sys_symlink =57, ++ sw_64_sys_readlink =58, ++ sw_64_sys_execve =59, ++ sw_64_sys_umask =60, ++ sw_64_sys_chroot =61, ++ sw_64_sys_osf_old_fstat =62, ++ sw_64_sys_getpgrp =63, ++ sw_64_sys_getpagesize =64, ++ sw_64_sys_osf_mremap =65, ++ sw_64_sys_vfork =66, ++ sw_64_sys_stat =67, ++ sw_64_sys_lstat =68, ++ sw_64_sys_osf_sbrk =69, ++ sw_64_sys_osf_sstk =70, ++ sw_64_sys_mmap =71, ++ sw_64_sys_osf_old_vadvise =72, ++ sw_64_sys_munmap =73, ++ sw_64_sys_mprotect =74, ++ sw_64_sys_madvise =75, ++ sw_64_sys_vhangup =76, ++ sw_64_sys_osf_kmodcall =77, ++ sw_64_sys_osf_mincore =78, ++ sw_64_sys_getgroups =79, ++ sw_64_sys_setgroups =80, ++ sw_64_sys_osf_old_getpgrp =81, ++ sw_64_sys_setpgrp =82, ++ sw_64_sys_osf_setitimer =83, ++ sw_64_sys_osf_old_wait =84, ++ sw_64_sys_osf_table =85, ++ sw_64_sys_osf_getitimer =86, ++ sw_64_sys_gethostname =87, ++ sw_64_sys_sethostname =88, ++ sw_64_sys_getdtablesize =89, ++ sw_64_sys_dup2 =90, ++ sw_64_sys_fstat =91, ++ sw_64_sys_fcntl =92, ++ sw_64_sys_osf_select =93, ++ sw_64_sys_poll =94, ++ sw_64_sys_fsync =95, ++ sw_64_sys_setpriority =96, ++ sw_64_sys_socket =97, ++ sw_64_sys_connect =98, ++ sw_64_sys_accept =99, ++ sw_64_sys_getpriority =100, ++ sw_64_sys_send =101, ++ sw_64_sys_recv =102, ++ sw_64_sys_sigreturn =103, ++ sw_64_sys_bind =104, ++ sw_64_sys_setsockopt =105, ++ sw_64_sys_listen =106, ++ sw_64_sys_osf_plock =107, ++ sw_64_sys_osf_old_sigvec =108, ++ sw_64_sys_osf_old_sigblock =109, ++ sw_64_sys_osf_old_sigsetmask =110, ++ sw_64_sys_sigsuspend =111, ++ sw_64_sys_osf_sigstack =112, ++ sw_64_sys_recvmsg =113, ++ sw_64_sys_sendmsg =114, ++ sw_64_sys_osf_old_vtrace =115, ++ sw_64_sys_osf_gettimeofday =116, ++ sw_64_sys_osf_getrusage =117, ++ sw_64_sys_getsockopt =118, ++ sw_64_sys_socketcall =119, ++ sw_64_sys_readv =120, ++ sw_64_sys_writev =121, ++ sw_64_sys_osf_settimeofday =122, ++ sw_64_sys_fchown =123, ++ sw_64_sys_fchmod =124, ++ sw_64_sys_recvfrom =125, ++ sw_64_sys_setreuid =126, ++ sw_64_sys_setregid =127, ++ sw_64_sys_rename =128, ++ sw_64_sys_truncate =129, ++ sw_64_sys_ftruncate =130, ++ sw_64_sys_flock =131, ++ sw_64_sys_setgid =132, ++ sw_64_sys_sendto =133, ++ sw_64_sys_shutdown =134, ++ sw_64_sys_socketpair =135, ++ sw_64_sys_mkdir =136, ++ sw_64_sys_rmdir =137, ++ sw_64_sys_osf_utimes =138, ++ sw_64_sys_osf_old_sigreturn =139, ++ sw_64_sys_osf_adjtime =140, ++ sw_64_sys_getpeername =141, ++ sw_64_sys_osf_gethostid =142, ++ sw_64_sys_osf_sethostid =143, ++ sw_64_sys_getrlimit =144, ++ sw_64_sys_setrlimit =145, ++ sw_64_sys_osf_old_killpg =146, ++ sw_64_sys_setsid =147, ++ sw_64_sys_quotactl =148, ++ sw_64_sys_osf_oldquota =149, ++ sw_64_sys_getsockname =150, ++ ++ sw_64_sys_osf_pid_block =153, ++ sw_64_sys_osf_pid_unblock =154, ++ ++ sw_64_sys_sigaction =156, ++ sw_64_sys_osf_sigwaitprim =157, ++ sw_64_sys_osf_nfssvc =158, ++ sw_64_sys_osf_getdirentries =159, ++ sw_64_sys_osf_statfs =160, ++ sw_64_sys_osf_fstatfs =161, ++ ++ sw_64_sys_osf_asynch_daemon =163, ++ sw_64_sys_osf_getfh =164, ++ sw_64_sys_osf_getdomainname =165, ++ sw_64_sys_setdomainname =166, ++ ++ sw_64_sys_osf_exportfs =169, ++ sw_64_sys_bpf =170, ++ sw_64_sys_userfaultfd =171, ++ sw_64_sys_membarrier =172, ++ sw_64_sys_mlock2 =173, ++ sw_64_sys_getpid=174, ++ sw_64_sys_getppid=175, ++ sw_64_sys_getuid=176, ++ sw_64_sys_geteuid=177, ++ sw_64_sys_getgid=178, ++ sw_64_sys_getegid=179, ++ sw_64_sys_osf_alt_plock =181, ++ ++ sw_64_sys_osf_getmnt =184, ++ ++ sw_64_sys_osf_alt_sigpending =187, ++ sw_64_sys_osf_alt_setsid =188, ++ ++ sw_64_sys_osf_swapon =199, ++ sw_64_sys_msgctl =200, ++ sw_64_sys_msgget =201, ++ sw_64_sys_msgrcv =202, ++ sw_64_sys_msgsnd =203, ++ sw_64_sys_semctl =204, ++ sw_64_sys_semget =205, ++ sw_64_sys_semop =206, ++ sw_64_sys_osf_utsname =207, ++ sw_64_sys_lchown =208, ++ sw_64_sys_osf_shmat =209, ++ sw_64_sys_shmctl =210, ++ sw_64_sys_shmdt =211, ++ sw_64_sys_shmget =212, ++ sw_64_sys_osf_mvalid =213, ++ sw_64_sys_osf_getaddressconf =214, ++ sw_64_sys_osf_msleep =215, ++ sw_64_sys_osf_mwakeup =216, ++ sw_64_sys_msync =217, ++ sw_64_sys_osf_signal =218, ++ sw_64_sys_osf_utc_gettime =219, ++ sw_64_sys_osf_utc_adjtime =220, ++ ++ sw_64_sys_osf_security =222, ++ sw_64_sys_osf_kloadcall =223, ++ sw_64_sys_osf_stat =224, ++ sw_64_sys_osf_lstat =225, ++ sw_64_sys_osf_fstat =226, ++ sw_64_sys_osf_statfs64 =227, ++ sw_64_sys_osf_fstatfs64 =228, ++ ++ sw_64_sys_getpgid =233, ++ sw_64_sys_getsid =234, ++ sw_64_sys_sigaltstack =235, ++ sw_64_sys_osf_waitid =236, ++ sw_64_sys_osf_priocntlset =237, ++ sw_64_sys_osf_sigsendset =238, ++ sw_64_sys_osf_set_speculative =239, ++ sw_64_sys_osf_msfs_syscall =240, ++ sw_64_sys_osf_sysinfo =241, ++ sw_64_sys_osf_uadmin =242, ++ sw_64_sys_osf_fuser =243, ++ sw_64_sys_osf_proplist_syscall =244, ++ sw_64_sys_osf_ntp_adjtime =245, ++ sw_64_sys_osf_ntp_gettime =246, ++ sw_64_sys_osf_pathconf =247, ++ sw_64_sys_osf_fpathconf =248, ++ ++ sw_64_sys_osf_uswitch =250, ++ sw_64_sys_osf_usleep_thread =251, ++ sw_64_sys_osf_audcntl =252, ++ sw_64_sys_osf_audgen =253, ++ sw_64_sys_sysfs =254, ++ sw_64_sys_osf_subsys_info =255, ++ sw_64_sys_osf_getsysinfo =256, ++ sw_64_sys_osf_setsysinfo =257, ++ sw_64_sys_osf_afs_syscall =258, ++ sw_64_sys_osf_swapctl =259, ++ sw_64_sys_osf_memcntl =260, ++ sw_64_sys_osf_fdatasync =261, ++ ++ sw_64_sys_bdflush =300, ++ sw_64_sys_sethae =301, ++ sw_64_sys_mount =302, ++ sw_64_sys_old_adjtimex =303, ++ sw_64_sys_swapoff =304, ++ sw_64_sys_getdents =305, ++ sw_64_sys_create_module =306, ++ sw_64_sys_init_module =307, ++ sw_64_sys_delete_module =308, ++ sw_64_sys_get_kernel_syms =309, ++ sw_64_sys_syslog =310, ++ sw_64_sys_reboot =311, ++ sw_64_sys_clone =312, ++ sw_64_sys_uselib =313, ++ sw_64_sys_mlock =314, ++ sw_64_sys_munlock =315, ++ sw_64_sys_mlockall =316, ++ sw_64_sys_munlockall =317, ++ sw_64_sys_sysinfo =318, ++ sw_64_sys__sysctl =319, ++ ++ sw_64_sys_oldumount =321, ++ sw_64_sys_swapon =322, ++ sw_64_sys_times =323, ++ sw_64_sys_personality =324, ++ sw_64_sys_setfsuid =325, ++ sw_64_sys_setfsgid =326, ++ sw_64_sys_ustat =327, ++ sw_64_sys_statfs =328, ++ sw_64_sys_fstatfs =329, ++ sw_64_sys_sched_setparam =330, ++ sw_64_sys_sched_getparam =331, ++ sw_64_sys_sched_setscheduler =332, ++ sw_64_sys_sched_getscheduler =333, ++ sw_64_sys_sched_yield =334, ++ sw_64_sys_sched_get_priority_max =335, ++ sw_64_sys_sched_get_priority_min =336, ++ sw_64_sys_sched_rr_get_interval =337, ++ sw_64_sys_afs_syscall =338, ++ sw_64_sys_uname =339, ++ sw_64_sys_nanosleep =340, ++ sw_64_sys_mremap =341, ++ sw_64_sys_nfsservctl =342, ++ sw_64_sys_setresuid =343, ++ sw_64_sys_getresuid =344, ++ sw_64_sys_pciconfig_read =345, ++ sw_64_sys_pciconfig_write =346, ++ sw_64_sys_query_module =347, ++ sw_64_sys_prctl =348, ++ sw_64_sys_pread64 =349, ++ sw_64_sys_pwrite64 =350, ++ sw_64_sys_rt_sigreturn =351, ++ sw_64_sys_rt_sigaction =352, ++ sw_64_sys_rt_sigprocmask =353, ++ sw_64_sys_rt_sigpending =354, ++ sw_64_sys_rt_sigtimedwait =355, ++ sw_64_sys_rt_sigqueueinfo =356, ++ sw_64_sys_rt_sigsuspend =357, ++ sw_64_sys_select =358, ++ sw_64_sys_gettimeofday =359, ++ sw_64_sys_settimeofday =360, ++ sw_64_sys_getitimer =361, ++ sw_64_sys_setitimer =362, ++ sw_64_sys_utimes =363, ++ sw_64_sys_getrusage =364, ++ sw_64_sys_wait4 =365, ++ sw_64_sys_adjtimex =366, ++ sw_64_sys_getcwd =367, ++ sw_64_sys_capget =368, ++ sw_64_sys_capset =369, ++ sw_64_sys_sendfile =370, ++ sw_64_sys_setresgid =371, ++ sw_64_sys_getresgid =372, ++ sw_64_sys_dipc =373, ++ sw_64_sys_pivot_root =374, ++ sw_64_sys_mincore =375, ++ sw_64_sys_pciconfig_iobase =376, ++ sw_64_sys_getdents64 =377, ++ sw_64_sys_gettid =378, ++ sw_64_sys_readahead =379, ++ ++ sw_64_sys_tkill =381, ++ sw_64_sys_setxattr =382, ++ sw_64_sys_lsetxattr =383, ++ sw_64_sys_fsetxattr =384, ++ sw_64_sys_getxattr =385, ++ sw_64_sys_lgetxattr =386, ++ sw_64_sys_fgetxattr =387, ++ sw_64_sys_listxattr =388, ++ sw_64_sys_llistxattr =389, ++ sw_64_sys_flistxattr =390, ++ sw_64_sys_removexattr =391, ++ sw_64_sys_lremovexattr =392, ++ sw_64_sys_fremovexattr =393, ++ sw_64_sys_futex =394, ++ sw_64_sys_sched_setaffinity =395, ++ sw_64_sys_sched_getaffinity =396, ++ sw_64_sys_tuxcall =397, ++ sw_64_sys_io_setup =398, ++ sw_64_sys_io_destroy =399, ++ sw_64_sys_io_getevents =400, ++ ++ sw_64_sys_io_submit =401, ++ sw_64_sys_io_cancel =402, ++ ++ sw_64_sys_exit_group =405, ++ sw_64_sys_lookup_dcookie =406, ++ sw_64_sys_epoll_create =407, ++ sw_64_sys_epoll_ctl =408, ++ sw_64_sys_epoll_wait =409, ++ ++ sw_64_sys_remap_file_pages =410, ++ sw_64_sys_set_tid_address =411, ++ sw_64_sys_restart_syscall =412, ++ sw_64_sys_fadvise64 =413, ++ sw_64_sys_timer_create =414, ++ sw_64_sys_timer_settime =415, ++ sw_64_sys_timer_gettime =416, ++ sw_64_sys_timer_getoverrun =417, ++ sw_64_sys_timer_delete =418, ++ sw_64_sys_clock_settime =419, ++ sw_64_sys_clock_gettime =420, ++ sw_64_sys_clock_getres =421, ++ sw_64_sys_clock_nanosleep =422, ++ sw_64_sys_semtimedop =423, ++ sw_64_sys_tgkill =424, ++ sw_64_sys_stat64 =425, ++ sw_64_sys_lstat64 =426, ++ sw_64_sys_fstat64 =427, ++ sw_64_sys_vserver =428, ++ sw_64_sys_mbind =429, ++ sw_64_sys_get_mempolicy =430, ++ sw_64_sys_set_mempolicy =431, ++ sw_64_sys_mq_open =432, ++ sw_64_sys_mq_unlink =433, ++ sw_64_sys_mq_timedsend =434, ++ sw_64_sys_mq_timedreceive =435, ++ sw_64_sys_mq_notify =436, ++ sw_64_sys_mq_getsetattr =437, ++ sw_64_sys_waitid =438, ++ sw_64_sys_add_key =439, ++ sw_64_sys_request_key =440, ++ sw_64_sys_keyctl =441, ++ sw_64_sys_ioprio_set =442, ++ sw_64_sys_ioprio_get =443, ++ sw_64_sys_inotify_init =444, ++ sw_64_sys_inotify_add_watch =445, ++ sw_64_sys_inotify_rm_watch =446, ++ sw_64_sys_fdatasync =447, ++ sw_64_sys_kexec_load =448, ++ sw_64_sys_migrate_pages =449, ++ sw_64_sys_openat =450, ++ sw_64_sys_mkdirat =451, ++ sw_64_sys_mknodat =452, ++ sw_64_sys_fchownat =453, ++ sw_64_sys_futimesat =454, ++ sw_64_sys_fstatat64 =455, ++ sw_64_sys_unlinkat =456, ++ sw_64_sys_renameat =457, ++ sw_64_sys_linkat =458, ++ sw_64_sys_symlinkat =459, ++ sw_64_sys_readlinkat =460, ++ sw_64_sys_fchmodat =461, ++ sw_64_sys_faccessat =462, ++ sw_64_sys_pselect6 =463, ++ sw_64_sys_ppoll =464, ++ sw_64_sys_unshare =465, ++ sw_64_sys_set_robust_list =466, ++ sw_64_sys_get_robust_list =467, ++ sw_64_sys_splice =468, ++ sw_64_sys_sync_file_range =469, ++ sw_64_sys_tee =470, ++ sw_64_sys_vmsplice =471, ++ sw_64_sys_move_pages =472, ++ sw_64_sys_getcpu =473, ++ sw_64_sys_epoll_pwait =474, ++ //sw_64_sys_utimensat =475, ++ //sw_64_sys_signalfd =476, ++ //sw_64_sys_timerfd =477, ++ sw_64_sys_eventfd =478, ++ sw_64_sys_recvmmsg =479,// ++ sw_64_sys_fallocate =480, ++ sw_64_sys_timerfd_create =481, ++ sw_64_sys_timerfd_settime =482, ++ sw_64_sys_timerfd_gettime =483, ++ sw_64_sys_signalfd4 =484, ++ sw_64_sys_eventfd2 =485, ++ sw_64_sys_epoll_create1 =486, ++ sw_64_sys_dup3 =487, ++ sw_64_sys_pipe2 =488, ++ sw_64_sys_inotify_init1 =489, ++ sw_64_sys_preadv =490,// ++ //sw_64_sys_pwritev =491, ++ sw_64_sys_rt_tgsigqueueinfo =492,//unsupport ++ sw_64_sys_perf_event_open =493,//unsupport ++ sw_64_sys_fanotify_init =494,// ++ sw_64_sys_fanotify_mark =495,// ++ sw_64_sys_prlimit64 =496,/// ++ sw_64_sys_name_to_handle_at =497,// ++ sw_64_sys_open_by_handle_at =498,// ++ sw_64_sys_clock_adjtime =499,// ++ sw_64_sys_syncfs =500,// ++ sw_64_sys_setns =501,// ++ sw_64_sys_accept4 =502,//unsupport ++ sw_64_sys_sendmmsg =503,// ++ sw_64_sys_process_vm_readv =504,// ++ sw_64_sys_process_vm_writev =505,// ++ sw_64_sys_kcmp =506,// ++ sw_64_sys_finit_module =507,// ++ sw_64_sys_sched_setattr =508,// ++ sw_64_sys_sched_getattr =509,// ++ //sw_64_sys_renameat2 =510, ++ //sw_64_sys_getrandom =511, ++ //sw_64_sys_memfd_create =512, ++ //sw_64_sys_execveat =513, ++ //sw_64_sys_seccomp =514, ++ //sw_64_sys_copy_file_range =515, ++ //sw_64_sys_preadv2 =516, ++ //sw_64_sys_pwritev2 =517, ++ //sw_64_sys_statx =518, ++ ++};*/ ++ ++/* sw_64_canonicalize_syscall maps syscall ids from the native AArch64 ++ linux set of syscall ids into a canonical set of syscall ids used by ++ process record. */ ++ ++static enum gdb_syscall ++sw_64_canonicalize_syscall (enum sw_64_syscall syscall_number) ++{ ++#define SYSCALL_MAP(SYSCALL) case sw_64_sys_##SYSCALL: \ ++ return gdb_sys_##SYSCALL ++ ++#define UNSUPPORTED_SYSCALL_MAP(SYSCALL) case sw_64_sys_##SYSCALL: \ ++ return gdb_sys_no_syscall ++ ++ switch (syscall_number) ++ { ++ //sw syscall ++ //UNSUPPORTED_SYSCALL_MAP(SYSCALL) (execveat); ++ //UNSUPPORTED_SYSCALL_MAP (userfaultfd); ++ //UNSUPPORTED_SYSCALL_MAP (mlock2); ++ //UNSUPPORTED_SYSCALL_MAP (copy_file_range); ++ //UNSUPPORTED_SYSCALL_MAP (preadv2); ++ //UNSUPPORTED_SYSCALL_MAP (pwritev2); ++ //UNSUPPORTED_SYSCALL_MAP (renameat2); ++ //UNSUPPORTED_SYSCALL_MAP (seccomp); ++ //UNSUPPORTED_SYSCALL_MAP (getrandom); ++ //UNSUPPORTED_SYSCALL_MAP (memfd_create); ++ //UNSUPPORTED_SYSCALL_MAP (bpf); ++ //UNSUPPORTED_SYSCALL_MAP(syscalls); ++ // arm syscall ++ SYSCALL_MAP (fstatat64); ++ SYSCALL_MAP (io_setup); ++ SYSCALL_MAP (io_destroy); ++ SYSCALL_MAP (io_submit); ++ SYSCALL_MAP (io_cancel); ++ SYSCALL_MAP (io_getevents); ++ ++ SYSCALL_MAP (setxattr); ++ SYSCALL_MAP (lsetxattr); ++ SYSCALL_MAP (fsetxattr); ++ SYSCALL_MAP (getxattr); ++ SYSCALL_MAP (lgetxattr); ++ SYSCALL_MAP (fgetxattr); ++ SYSCALL_MAP (listxattr); ++ SYSCALL_MAP (llistxattr); ++ SYSCALL_MAP (flistxattr); ++ SYSCALL_MAP (removexattr); ++ SYSCALL_MAP (lremovexattr); ++ SYSCALL_MAP (fremovexattr); ++ SYSCALL_MAP (getcwd); ++ SYSCALL_MAP (lookup_dcookie); ++ SYSCALL_MAP (eventfd2); ++ SYSCALL_MAP (epoll_create1); ++ SYSCALL_MAP (epoll_ctl); ++ SYSCALL_MAP (epoll_pwait); ++ SYSCALL_MAP (dup); ++ SYSCALL_MAP (dup3); ++ SYSCALL_MAP (fcntl); ++ SYSCALL_MAP (inotify_init1); ++ SYSCALL_MAP (inotify_add_watch); ++ SYSCALL_MAP (inotify_rm_watch); ++ SYSCALL_MAP (ioctl); ++ SYSCALL_MAP (ioprio_set); ++ SYSCALL_MAP (ioprio_get); ++ SYSCALL_MAP (flock); ++ SYSCALL_MAP (mknodat); ++ SYSCALL_MAP (mkdirat); ++ SYSCALL_MAP (unlinkat); ++ SYSCALL_MAP (symlinkat); ++ SYSCALL_MAP (linkat); ++ SYSCALL_MAP (renameat); ++ UNSUPPORTED_SYSCALL_MAP (umount2); ++ SYSCALL_MAP (mount); ++ SYSCALL_MAP (pivot_root); ++ SYSCALL_MAP (nfsservctl); ++ SYSCALL_MAP (statfs); ++ SYSCALL_MAP (truncate); ++ SYSCALL_MAP (ftruncate); ++ SYSCALL_MAP (fallocate); ++ SYSCALL_MAP (faccessat); ++ SYSCALL_MAP (fchdir); ++ SYSCALL_MAP (chroot); ++ SYSCALL_MAP (fchmod); ++ SYSCALL_MAP (fchmodat); ++ SYSCALL_MAP (fchownat); ++ SYSCALL_MAP (fchown); ++ SYSCALL_MAP (openat); ++ SYSCALL_MAP (close); ++ SYSCALL_MAP (vhangup); ++ SYSCALL_MAP (pipe); ++ SYSCALL_MAP (pipe2); ++ SYSCALL_MAP (quotactl); ++ SYSCALL_MAP (getdents64); ++ SYSCALL_MAP (lseek); ++ SYSCALL_MAP (read); ++ SYSCALL_MAP (write); ++ SYSCALL_MAP (readv); ++ SYSCALL_MAP (writev); ++ SYSCALL_MAP (pread64); ++ SYSCALL_MAP (pwrite64); ++ UNSUPPORTED_SYSCALL_MAP (preadv); ++ UNSUPPORTED_SYSCALL_MAP (pwritev); ++ SYSCALL_MAP (sendfile); ++ SYSCALL_MAP (pselect6); ++ SYSCALL_MAP (ppoll); ++ UNSUPPORTED_SYSCALL_MAP (signalfd4); ++ SYSCALL_MAP (vmsplice); ++ SYSCALL_MAP (splice); ++ SYSCALL_MAP (tee); ++ SYSCALL_MAP (readlinkat); ++ //SYSCALL_MAP (newfstatat); ++ ++ SYSCALL_MAP (fstat); ++ SYSCALL_MAP (sync); ++ SYSCALL_MAP (fsync); ++ SYSCALL_MAP (fdatasync); ++ SYSCALL_MAP (sync_file_range); ++ UNSUPPORTED_SYSCALL_MAP (timerfd_create); ++ UNSUPPORTED_SYSCALL_MAP (timerfd_settime); ++ UNSUPPORTED_SYSCALL_MAP (timerfd_gettime); ++ UNSUPPORTED_SYSCALL_MAP (utimensat); ++ SYSCALL_MAP (acct); ++ SYSCALL_MAP (capget); ++ SYSCALL_MAP (capset); ++ SYSCALL_MAP (personality); ++ SYSCALL_MAP (exit); ++ SYSCALL_MAP (exit_group); ++ SYSCALL_MAP (waitid); ++ SYSCALL_MAP (set_tid_address); ++ SYSCALL_MAP (unshare); ++ SYSCALL_MAP (futex); ++ SYSCALL_MAP (set_robust_list); ++ SYSCALL_MAP (get_robust_list); ++ SYSCALL_MAP (nanosleep); ++ ++ SYSCALL_MAP (getitimer); ++ SYSCALL_MAP (setitimer); ++ SYSCALL_MAP (kexec_load); ++ SYSCALL_MAP (init_module); ++ SYSCALL_MAP (delete_module); ++ SYSCALL_MAP (timer_create); ++ SYSCALL_MAP (timer_settime); ++ SYSCALL_MAP (timer_gettime); ++ SYSCALL_MAP (timer_getoverrun); ++ SYSCALL_MAP (timer_delete); ++ SYSCALL_MAP (clock_settime); ++ SYSCALL_MAP (clock_gettime); ++ SYSCALL_MAP (clock_getres); ++ SYSCALL_MAP (clock_nanosleep); ++ SYSCALL_MAP (syslog); ++ SYSCALL_MAP (ptrace); ++ SYSCALL_MAP (sched_setparam); ++ SYSCALL_MAP (sched_setscheduler); ++ SYSCALL_MAP (sched_getscheduler); ++ SYSCALL_MAP (sched_getparam); ++ SYSCALL_MAP (sched_setaffinity); ++ SYSCALL_MAP (sched_getaffinity); ++ SYSCALL_MAP (sched_yield); ++ SYSCALL_MAP (sched_get_priority_max); ++ SYSCALL_MAP (sched_get_priority_min); ++ SYSCALL_MAP (sched_rr_get_interval); ++ SYSCALL_MAP (kill); ++ SYSCALL_MAP (tkill); ++ SYSCALL_MAP (tgkill); ++ SYSCALL_MAP (sigaltstack); ++ SYSCALL_MAP (rt_sigsuspend); ++ SYSCALL_MAP (rt_sigaction); ++ SYSCALL_MAP (sigprocmask); ++ SYSCALL_MAP (rt_sigprocmask); ++ SYSCALL_MAP (rt_sigpending); ++ SYSCALL_MAP (rt_sigtimedwait); ++ SYSCALL_MAP (rt_sigqueueinfo); ++ SYSCALL_MAP (sigreturn); ++ SYSCALL_MAP (rt_sigreturn); ++ SYSCALL_MAP (setpriority); ++ SYSCALL_MAP (getpriority); ++ SYSCALL_MAP (reboot); ++ SYSCALL_MAP (setregid); ++ SYSCALL_MAP (setgid); ++ SYSCALL_MAP (setreuid); ++ SYSCALL_MAP (setuid); ++ SYSCALL_MAP (setresuid); ++ SYSCALL_MAP (getresuid); ++ SYSCALL_MAP (setresgid); ++ SYSCALL_MAP (getresgid); ++ SYSCALL_MAP (setfsuid); ++ SYSCALL_MAP (setfsgid); ++ SYSCALL_MAP (times); ++ SYSCALL_MAP (setpgid); ++ SYSCALL_MAP (getpgid); ++ SYSCALL_MAP (getsid); ++ SYSCALL_MAP (setsid); ++ SYSCALL_MAP (getgroups); ++ SYSCALL_MAP (setgroups); ++ SYSCALL_MAP (uname); ++ SYSCALL_MAP (sethostname); ++ SYSCALL_MAP (setdomainname); ++ SYSCALL_MAP (getrlimit); ++ SYSCALL_MAP (setrlimit); ++ SYSCALL_MAP (getrusage); ++ SYSCALL_MAP (umask); ++ SYSCALL_MAP (prctl); ++ SYSCALL_MAP (getcpu); ++ SYSCALL_MAP (gettimeofday); ++ SYSCALL_MAP (settimeofday); ++ SYSCALL_MAP (adjtimex); ++ SYSCALL_MAP (getpid); ++ SYSCALL_MAP (getppid); ++ SYSCALL_MAP (getuid); ++ SYSCALL_MAP (geteuid); ++ SYSCALL_MAP (getgid); ++ SYSCALL_MAP (getegid); ++ SYSCALL_MAP (gettid); ++ SYSCALL_MAP (sysinfo); ++ SYSCALL_MAP (mq_open); ++ SYSCALL_MAP (mq_unlink); ++ SYSCALL_MAP (mq_timedsend); ++ SYSCALL_MAP (mq_timedreceive); ++ SYSCALL_MAP (mq_notify); ++ SYSCALL_MAP (mq_getsetattr); ++ SYSCALL_MAP (msgget); ++ SYSCALL_MAP (msgctl); ++ SYSCALL_MAP (msgrcv); ++ SYSCALL_MAP (msgsnd); ++ SYSCALL_MAP (semget); ++ SYSCALL_MAP (semctl); ++ SYSCALL_MAP (semtimedop); ++ SYSCALL_MAP (semop); ++ SYSCALL_MAP (shmget); ++ SYSCALL_MAP (shmctl); ++ SYSCALL_MAP (shmat); ++ SYSCALL_MAP (shmdt); ++ SYSCALL_MAP (socket); ++ SYSCALL_MAP (socketpair); ++ SYSCALL_MAP (bind); ++ SYSCALL_MAP (listen); ++ SYSCALL_MAP (accept); ++ SYSCALL_MAP (connect); ++ SYSCALL_MAP (getsockname); ++ SYSCALL_MAP (getpeername); ++ SYSCALL_MAP (sendto); ++ SYSCALL_MAP (recvfrom); ++ SYSCALL_MAP (setsockopt); ++ SYSCALL_MAP (getsockopt); ++ SYSCALL_MAP (shutdown); ++ SYSCALL_MAP (sendmsg); ++ SYSCALL_MAP (recvmsg); ++ SYSCALL_MAP (readahead); ++ SYSCALL_MAP (brk); ++ SYSCALL_MAP (munmap); ++ SYSCALL_MAP (mremap); ++ SYSCALL_MAP (add_key); ++ SYSCALL_MAP (request_key); ++ SYSCALL_MAP (keyctl); ++ SYSCALL_MAP (clone); ++ SYSCALL_MAP (execve); ++ ++ case sw_64_sys_mmap: ++ return gdb_sys_mmap2; ++ ++ SYSCALL_MAP (fadvise64); ++ SYSCALL_MAP (swapon); ++ SYSCALL_MAP (swapoff); ++ SYSCALL_MAP (mprotect); ++ SYSCALL_MAP (msync); ++ SYSCALL_MAP (mlock); ++ SYSCALL_MAP (munlock); ++ SYSCALL_MAP (mlockall); ++ SYSCALL_MAP (munlockall); ++ SYSCALL_MAP (mincore); ++ SYSCALL_MAP (madvise); ++ SYSCALL_MAP (remap_file_pages); ++ SYSCALL_MAP (mbind); ++ SYSCALL_MAP (get_mempolicy); ++ SYSCALL_MAP (set_mempolicy); ++ SYSCALL_MAP (migrate_pages); ++ SYSCALL_MAP (move_pages); ++ UNSUPPORTED_SYSCALL_MAP (rt_tgsigqueueinfo); ++ UNSUPPORTED_SYSCALL_MAP (perf_event_open); ++ UNSUPPORTED_SYSCALL_MAP (accept4); ++ UNSUPPORTED_SYSCALL_MAP (recvmmsg); ++ ++ SYSCALL_MAP (wait4); ++ ++ UNSUPPORTED_SYSCALL_MAP (prlimit64); ++ UNSUPPORTED_SYSCALL_MAP (fanotify_init); ++ UNSUPPORTED_SYSCALL_MAP (fanotify_mark); ++ UNSUPPORTED_SYSCALL_MAP (name_to_handle_at); ++ UNSUPPORTED_SYSCALL_MAP (open_by_handle_at); ++ UNSUPPORTED_SYSCALL_MAP (clock_adjtime); ++ UNSUPPORTED_SYSCALL_MAP (syncfs); ++ UNSUPPORTED_SYSCALL_MAP (setns); ++ UNSUPPORTED_SYSCALL_MAP (sendmmsg); ++ UNSUPPORTED_SYSCALL_MAP (process_vm_readv); ++ UNSUPPORTED_SYSCALL_MAP (process_vm_writev); ++ UNSUPPORTED_SYSCALL_MAP (kcmp); ++ UNSUPPORTED_SYSCALL_MAP (finit_module); ++ UNSUPPORTED_SYSCALL_MAP (sched_setattr); ++ UNSUPPORTED_SYSCALL_MAP (sched_getattr); ++ default: ++ return gdb_sys_no_syscall; ++ } ++} ++ ++/* Record all registers but PC register for process-record. */ ++ ++static int ++sw_64_all_but_pc_registers_record (struct regcache *regcache) ++{ ++ int i; ++ ++ for (i = SW_A0_REGNUM; i < SW_PC_REGNUM; i++) ++ if (record_full_arch_list_add_reg (regcache, i)) ++ return -1; ++ ++ if (record_full_arch_list_add_reg (regcache, SW_CSR_REGNUM)) ++ return -1; ++ ++ return 0; ++} ++ ++/* Handler for sw_64 system call instruction recording. */ ++ ++static int ++sw_64_linux_syscall_record (struct regcache *regcache) ++{ ++ int ret = 0; ++ enum gdb_syscall syscall_gdb; ++ ULONGEST svc_number; ++ regcache_raw_read_unsigned (regcache, SW_V0_REGNUM, &svc_number);//_ASM_ get regbuf ++ syscall_gdb = ++ sw_64_canonicalize_syscall ((enum sw_64_syscall) svc_number); ++ ++ if (syscall_gdb < 0) ++ { ++ printf_unfiltered (_("Process record and replay target doesn't " ++ "support syscall number %s\n"), ++ plongest (svc_number)); ++ return -1; ++ } ++ ++ if (syscall_gdb == gdb_sys_sigreturn ++ || syscall_gdb == gdb_sys_rt_sigreturn) ++ { ++ if (sw_64_all_but_pc_registers_record (regcache)) ++ return -1; ++ return 0; ++ } ++ ++ ret = record_linux_system_call (syscall_gdb, regcache, &sw_64_linux_record_tdep); ++ ++ if (ret != 0) ++ return ret; ++ ++ /* Record the return value of the system call. */ ++ if (record_full_arch_list_add_reg (regcache, SW_V0_REGNUM)) ++ return -1; ++ ++ return 0; ++} ++ ++/* Implement the "gcc_target_options" gdbarch method. */ ++ ++static std::string ++sw_64_linux_gcc_target_options (struct gdbarch *gdbarch) ++{ ++ /* GCC doesn't know "-m64". */ ++ return {}; ++} ++ ++static void ++sw_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ static const char *const stap_integer_prefixes[] = { "i", NULL }; ++ static const char *const stap_register_indirection_prefixes[] = { "(", ++ NULL }; ++ static const char *const stap_register_indirection_suffixes[] = { ")", ++ NULL }; ++ ++ linux_init_abi (info, gdbarch); ++ ++#ifndef LHX20210326 ++ //set_xml_syscall_file_name (gdbarch, "syscalls/sw_64-linux.xml"); ++ /* Get the syscall number from the arch's register. */ ++ //set_gdbarch_get_syscall_number (gdbarch, sw_64_linux_get_syscall_number); ++#endif ++ ++ /* Hook into the DWARF CFI frame unwinder. */ ++ sw_64_dwarf2_init_abi (info, gdbarch); ++ ++ /* Hook into the MDEBUG frame unwinder. */ ++ sw_64_mdebug_init_abi (info, gdbarch); ++ ++ tdep->dynamic_sigtramp_offset = sw_64_linux_sigtramp_offset; ++ tdep->sigcontext_addr = sw_64_linux_sigcontext_addr; ++ tdep->pc_in_sigtramp = sw_64_linux_pc_in_sigtramp; ++ tdep->jb_pc = 2; ++ tdep->jb_elt_size = 8; ++ ++ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); ++ ++ set_solib_svr4_fetch_link_map_offsets ++ (gdbarch, svr4_lp64_fetch_link_map_offsets); ++ //set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description); ++ // set_gdbarch_iterate_over_regset_sections (gdbarch, ++ // ppc_linux_iterate_over_regset_sections); ++ ++ /* Enable TLS support. */ ++ set_gdbarch_fetch_tls_load_module_address (gdbarch, ++ svr4_fetch_objfile_link_map); ++ ++ set_gdbarch_iterate_over_regset_sections ++ (gdbarch, sw_64_linux_iterate_over_regset_sections); ++ ++ set_gdbarch_gdb_signal_from_target (gdbarch, ++ sw_64_linux_gdb_signal_from_target); ++ set_gdbarch_gdb_signal_to_target (gdbarch, ++ sw_64_linux_gdb_signal_to_target); ++ /* SystemTap functions. */ ++ set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); ++ set_gdbarch_stap_register_indirection_prefixes (gdbarch, ++ stap_register_indirection_prefixes); ++ set_gdbarch_stap_register_indirection_suffixes (gdbarch, ++ stap_register_indirection_suffixes); ++ set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); ++ //set_gdbarch_stap_is_single_operand (gdbarch, sw_64_stap_is_single_operand); ++ //set_gdbarch_stap_parse_special_token (gdbarch, ++ // sw_64_stap_parse_special_token); ++ /* Shared library handling. */ ++ // set_gdbarch_skip_trampoline_code (gdbarch, sw_64_skip_trampoline_code); ++ set_solib_svr4_fetch_link_map_offsets ++ (gdbarch, svr4_lp64_fetch_link_map_offsets); ++ /* Reversible debugging, process record. */ ++ set_gdbarch_process_record (gdbarch, sw_64_process_record); ++ /* Syscall record. */ ++ tdep->sw_64_syscall_record = sw_64_linux_syscall_record; ++ /* Displaced stepping. */ ++ //set_gdbarch_displaced_step_location (gdbarch, ++ // linux_displaced_step_location); ++ sw_64_init_linux_record_tdep (&sw_64_linux_record_tdep, 8); ++ ++} ++ ++void _initialize_aarch64_linux_tdep (); ++void ++_initialize_sw_64_linux_tdep (void) ++{ ++ gdbarch_register_osabi (bfd_arch_sw_64, 0, GDB_OSABI_LINUX, ++ sw_64_linux_init_abi); ++} +diff -Nuar gdb-10.2/gdb/sw_64-linux-tdep.h gdb-10.2/gdb/sw_64-linux-tdep.h +--- gdb-10.2/gdb/sw_64-linux-tdep.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-linux-tdep.h 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,43 @@ ++/* GNU/Linux on SW_64 target support, prototypes. ++ ++ Copyright (C) 2012-2020 Free Software Foundation, Inc. ++ Contributed by ARM Ltd. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef SW_64_LINUX_TDEP_H ++#define SW_64_LINUX_TDEP_H ++ ++#include "regset.h" ++ ++/* The general-purpose regset consists of 31 X registers, plus SP, PC, ++ and PSTATE registers, as defined in the SW_64 port of the Linux ++ kernel. */ ++#define SW_64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE) ++ ++/* The fp regset consists of 32 V registers, plus FPCR and FPSR which ++ are 4 bytes wide each, and the whole structure is padded to 128 bit ++ alignment. */ ++#define SW_64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE) ++ ++/* The pauth regset consists of 2 X sized registers. */ ++#define SW_64_LINUX_SIZEOF_PAUTH (2 * X_REGISTER_SIZE) ++ ++ ++/* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h. */ ++#define SW_64_HWCAP_PACA (1 << 30) ++ ++#endif /* SW_64_LINUX_TDEP_H */ +diff -Nuar gdb-10.2/gdb/sw_64-linux.xml gdb-10.2/gdb/sw_64-linux.xml +--- gdb-10.2/gdb/sw_64-linux.xml 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-linux.xml 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,18 @@ ++ ++ ++ ++ ++ ++ sw_64 ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/sw_64-mdebug-tdep.c gdb-10.2/gdb/sw_64-mdebug-tdep.c +--- gdb-10.2/gdb/sw_64-mdebug-tdep.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-mdebug-tdep.c 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,408 @@ ++/* Target-dependent mdebug code for the SW_64 architecture. ++ Copyright (C) 1993-2018 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "defs.h" ++#include "frame.h" ++#include "frame-unwind.h" ++#include "frame-base.h" ++#include "symtab.h" ++#include "gdbcore.h" ++#include "block.h" ++#include "trad-frame.h" ++ ++#include "sw_64-tdep.h" ++#include "mdebugread.h" ++#include "gdbarch.h" ++ ++/* FIXME: Some of this code should perhaps be merged with mips. */ ++ ++/* *INDENT-OFF* */ ++/* Layout of a stack frame on the alpha: ++ ++ | | ++ pdr members: | 7th ... nth arg, | ++ | `pushed' by caller. | ++ | | ++----------------|-------------------------------|<-- old_sp == vfp ++ ^ ^ ^ ^ | | ++ | | | | | | ++ | |localoff | Copies of 1st .. 6th | ++ | | | | | argument if necessary. | ++ | | | v | | ++ | | | --- |-------------------------------|<-- LOCALS_ADDRESS ++ | | | | | ++ | | | | Locals and temporaries. | ++ | | | | | ++ | | | |-------------------------------| ++ | | | | | ++ |-fregoffset | Saved float registers. | ++ | | | | F9 | ++ | | | | . | ++ | | | | . | ++ | | | | F2 | ++ | | v | | ++ | | -------|-------------------------------| ++ | | | | ++ | | | Saved registers. | ++ | | | S6 | ++ |-regoffset | . | ++ | | | . | ++ | | | S0 | ++ | | | pdr.pcreg | ++ | v | | ++ | ----------|-------------------------------| ++ | | | ++ frameoffset | Argument build area, gets | ++ | | 7th ... nth arg for any | ++ | | called procedure. | ++ v | | ++ -------------|-------------------------------|<-- sp ++ | | ++*/ ++/* *INDENT-ON* */ ++ ++#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) ++#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) ++#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) ++#define PROC_REG_MASK(proc) ((proc)->pdr.regmask) ++#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) ++#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) ++#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) ++#define PROC_PC_REG(proc) ((proc)->pdr.pcreg) ++#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff) ++ ++/* Locate the mdebug PDR for the given PC. Return null if one can't ++ be found; you'll have to fall back to other methods in that case. */ ++ ++static struct mdebug_extra_func_info * ++find_proc_desc (CORE_ADDR pc) ++{ ++ const struct block *b = block_for_pc (pc); ++ struct mdebug_extra_func_info *proc_desc = NULL; ++ struct symbol *sym = NULL; ++ const char *sh_name = NULL; ++ ++ if (b) ++ { ++ CORE_ADDR startaddr; ++ find_pc_partial_function (pc, &sh_name, &startaddr, NULL); ++ ++ if (startaddr > BLOCK_START (b)) ++ /* This is the "pathological" case referred to in a comment in ++ print_frame_info. It might be better to move this check into ++ symbol reading. */ ++ sym = NULL; ++ else ++ sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, ++ 0).symbol; ++ } ++ ++ if (sym) ++ { ++ proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym); ++ ++ /* Correct incorrect setjmp procedure descriptor from the library ++ to make backtrace through setjmp work. */ ++ if (proc_desc->pdr.pcreg == 0 ++ && strcmp (sh_name, "setjmp") == 0) ++ { ++ proc_desc->pdr.pcreg = SW_RA_REGNUM; ++ proc_desc->pdr.regmask = 0x80000000; ++ proc_desc->pdr.regoffset = -4; ++ } ++ ++ /* If we never found a PDR for this function in symbol reading, ++ then examine prologues to find the information. */ ++ if (proc_desc->pdr.framereg == -1) ++ proc_desc = NULL; ++ } ++ ++ return proc_desc; ++} ++ ++/* Return a non-zero result if the function is frameless; zero otherwise. */ ++ ++static int ++sw_64_mdebug_frameless (struct mdebug_extra_func_info *proc_desc) ++{ ++ return (PROC_FRAME_REG (proc_desc) == SW_SP_REGNUM ++ && PROC_FRAME_OFFSET (proc_desc) == 0); ++} ++ ++/* This returns the PC of the first inst after the prologue. If we can't ++ find the prologue, then return 0. */ ++ ++static CORE_ADDR ++sw_64_mdebug_after_prologue (CORE_ADDR pc, ++ struct mdebug_extra_func_info *proc_desc) ++{ ++ if (proc_desc) ++ { ++ /* If function is frameless, then we need to do it the hard way. I ++ strongly suspect that frameless always means prologueless... */ ++ if (sw_64_mdebug_frameless (proc_desc)) ++ return 0; ++ } ++ ++ return sw_64_after_prologue (pc); ++} ++ ++/* Return non-zero if we *might* be in a function prologue. Return zero ++ if we are definitively *not* in a function prologue. */ ++ ++static int ++sw_64_mdebug_in_prologue (CORE_ADDR pc, ++ struct mdebug_extra_func_info *proc_desc) ++{ ++ CORE_ADDR after_prologue_pc = sw_64_mdebug_after_prologue (pc, proc_desc); ++ return (after_prologue_pc == 0 || pc < after_prologue_pc); ++} ++ ++ ++/* Frame unwinder that reads mdebug PDRs. */ ++ ++struct sw_64_mdebug_unwind_cache ++{ ++ struct mdebug_extra_func_info *proc_desc; ++ CORE_ADDR vfp; ++ struct trad_frame_saved_reg *saved_regs; ++}; ++ ++/* Extract all of the information about the frame from PROC_DESC ++ and store the resulting register save locations in the structure. */ ++ ++static struct sw_64_mdebug_unwind_cache * ++sw_64_mdebug_frame_unwind_cache (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_mdebug_unwind_cache *info; ++ struct mdebug_extra_func_info *proc_desc; ++ ULONGEST vfp; ++ CORE_ADDR pc, reg_position; ++ unsigned long mask; ++ int ireg, returnreg; ++ ++ if (*this_prologue_cache) ++ return (struct sw_64_mdebug_unwind_cache *) *this_prologue_cache; ++ ++ info = FRAME_OBSTACK_ZALLOC (struct sw_64_mdebug_unwind_cache); ++ *this_prologue_cache = info; ++ pc = get_frame_address_in_block (this_frame); ++ ++ /* ??? We don't seem to be able to cache the lookup of the PDR ++ from sw_64_mdebug_frame_p. It'd be nice if we could change ++ the arguments to that function. Oh well. */ ++ proc_desc = find_proc_desc (pc); ++ info->proc_desc = proc_desc; ++ gdb_assert (proc_desc != NULL); ++ ++ info->saved_regs = trad_frame_alloc_saved_regs (this_frame); ++ ++ /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */ ++ vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc)); ++ vfp += PROC_FRAME_OFFSET (info->proc_desc); ++ info->vfp = vfp; ++ ++ /* Fill in the offsets for the registers which gen_mask says were saved. */ ++ ++ reg_position = vfp + PROC_REG_OFFSET (proc_desc); ++ mask = PROC_REG_MASK (proc_desc); ++ returnreg = PROC_PC_REG (proc_desc); ++ ++ /* Note that RA is always saved first, regardless of its actual ++ register number. */ ++ if (mask & (1 << returnreg)) ++ { ++ /* Clear bit for RA so we don't save it again later. */ ++ mask &= ~(1 << returnreg); ++ ++ info->saved_regs[returnreg].addr = reg_position; ++ reg_position += 8; ++ } ++ ++ for (ireg = 0; ireg <= 31; ++ireg) ++ if (mask & (1 << ireg)) ++ { ++ info->saved_regs[ireg].addr = reg_position; ++ reg_position += 8; ++ } ++ ++ reg_position = vfp + PROC_FREG_OFFSET (proc_desc); ++ mask = PROC_FREG_MASK (proc_desc); ++ ++ for (ireg = 0; ireg <= 31; ++ireg) ++ if (mask & (1 << ireg)) ++ { ++ info->saved_regs[SW_FP0_REGNUM + ireg].addr = reg_position; ++ reg_position += 8; ++ } ++ ++ /* The stack pointer of the previous frame is computed by popping ++ the current stack frame. */ ++ if (!trad_frame_addr_p (info->saved_regs, SW_SP_REGNUM)) ++ trad_frame_set_value (info->saved_regs, SW_SP_REGNUM, vfp); ++ ++ return info; ++} ++ ++/* Given a GDB frame, determine the address of the calling function's ++ frame. This will be used to create a new GDB frame struct. */ ++ ++static void ++sw_64_mdebug_frame_this_id (struct frame_info *this_frame, ++ void **this_prologue_cache, ++ struct frame_id *this_id) ++{ ++ struct sw_64_mdebug_unwind_cache *info ++ = sw_64_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); ++ ++ *this_id = frame_id_build (info->vfp, get_frame_func (this_frame)); ++} ++ ++/* Retrieve the value of REGNUM in FRAME. Don't give up! */ ++ ++static struct value * ++sw_64_mdebug_frame_prev_register (struct frame_info *this_frame, ++ void **this_prologue_cache, int regnum) ++{ ++ struct sw_64_mdebug_unwind_cache *info ++ = sw_64_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); ++ ++ /* The PC of the previous frame is stored in the link register of ++ the current frame. Frob regnum so that we pull the value from ++ the correct place. */ ++ if (regnum == SW_PC_REGNUM) ++ regnum = PROC_PC_REG (info->proc_desc); ++ ++ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); ++} ++ ++/* Return a non-zero result if the size of the stack frame exceeds the ++ maximum debuggable frame size (512 Kbytes); zero otherwise. */ ++ ++static int ++sw_64_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc) ++{ ++ /* If frame offset is null, we can be in two cases: either the ++ function is frameless (the stack frame is null) or its ++ frame exceeds the maximum debuggable frame size (512 Kbytes). */ ++ ++ return (PROC_FRAME_OFFSET (proc_desc) == 0 ++ && !sw_64_mdebug_frameless (proc_desc)); ++} ++ ++static int ++sw_64_mdebug_frame_sniffer (const struct frame_unwind *self, ++ struct frame_info *this_frame, ++ void **this_cache) ++{ ++ CORE_ADDR pc = get_frame_address_in_block (this_frame); ++ struct mdebug_extra_func_info *proc_desc; ++ ++ /* If this PC does not map to a PDR, then clearly this isn't an ++ mdebug frame. */ ++ proc_desc = find_proc_desc (pc); ++ if (proc_desc == NULL) ++ return 0; ++ ++ /* If we're in the prologue, the PDR for this frame is not yet valid. ++ Say no here and we'll fall back on the heuristic unwinder. */ ++ if (sw_64_mdebug_in_prologue (pc, proc_desc)) ++ return 0; ++ ++ /* If the maximum debuggable frame size has been exceeded, the ++ proc desc is bogus. Fall back on the heuristic unwinder. */ ++ if (sw_64_mdebug_max_frame_size_exceeded (proc_desc)) ++ return 0; ++ ++ return 1; ++} ++ ++static const struct frame_unwind sw_64_mdebug_frame_unwind = { ++ NORMAL_FRAME, ++ default_frame_unwind_stop_reason, ++ sw_64_mdebug_frame_this_id, ++ sw_64_mdebug_frame_prev_register, ++ NULL, ++ sw_64_mdebug_frame_sniffer ++}; ++ ++static CORE_ADDR ++sw_64_mdebug_frame_base_address (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_mdebug_unwind_cache *info ++ = sw_64_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); ++ ++ return info->vfp; ++} ++ ++static CORE_ADDR ++sw_64_mdebug_frame_locals_address (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_mdebug_unwind_cache *info ++ = sw_64_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); ++ ++ return info->vfp - PROC_LOCALOFF (info->proc_desc); ++} ++ ++static CORE_ADDR ++sw_64_mdebug_frame_args_address (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_mdebug_unwind_cache *info ++ = sw_64_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); ++ ++ return info->vfp - SW_NUM_ARG_REGS * 8; ++} ++ ++static const struct frame_base sw_64_mdebug_frame_base = { ++ &sw_64_mdebug_frame_unwind, ++ sw_64_mdebug_frame_base_address, ++ sw_64_mdebug_frame_locals_address, ++ sw_64_mdebug_frame_args_address ++}; ++ ++static const struct frame_base * ++sw_64_mdebug_frame_base_sniffer (struct frame_info *this_frame) ++{ ++ CORE_ADDR pc = get_frame_address_in_block (this_frame); ++ struct mdebug_extra_func_info *proc_desc; ++ ++ /* If this PC does not map to a PDR, then clearly this isn't an ++ mdebug frame. */ ++ proc_desc = find_proc_desc (pc); ++ if (proc_desc == NULL) ++ return NULL; ++ ++ /* If the maximum debuggable frame size has been exceeded, the ++ proc desc is bogus. Fall back on the heuristic unwinder. */ ++ if (sw_64_mdebug_max_frame_size_exceeded (proc_desc)) ++ return 0; ++ ++ return &sw_64_mdebug_frame_base; ++} ++ ++ ++void ++sw_64_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) ++{ ++ frame_unwind_append_unwinder (gdbarch, &sw_64_mdebug_frame_unwind); ++ frame_base_append_sniffer (gdbarch, sw_64_mdebug_frame_base_sniffer); ++} +diff -Nuar gdb-10.2/gdb/sw_64-tdep.c gdb-10.2/gdb/sw_64-tdep.c +--- gdb-10.2/gdb/sw_64-tdep.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-tdep.c 2025-04-16 17:06:52.012086800 +0800 +@@ -0,0 +1,2739 @@ ++/* Target-dependent code for the SW_64 architecture, for GDB, the GNU Debugger. ++ ++ Copyright (C) 1993-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "defs.h" ++#include "frame.h" ++#include "frame-unwind.h" ++#include "frame-base.h" ++#include "dwarf2/frame.h" ++#include "inferior.h" ++#include "symtab.h" ++#include "value.h" ++#include "gdbcmd.h" ++#include "gdbcore.h" ++#include "dis-asm.h" ++#include "symfile.h" ++#include "objfiles.h" ++#include "linespec.h" ++#include "regcache.h" ++#include "reggroups.h" ++#include "arch-utils.h" ++#include "osabi.h" ++#include "block.h" ++#include "infcall.h" ++#include "trad-frame.h" ++#include ++#include "elf-bfd.h" ++ ++#include "sw_64-tdep.h" ++#include ++#include "record.h" ++#include "record-full.h" ++ ++/* Instruction decoding. The notations for registers, immediates and ++ opcodes are the same as the one used in Compaq's SW_64 architecture ++ handbook. */ ++#define submask(x) ((1L << ((x) + 1)) - 1) ++#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) ++#define INSN_OPCODE(insn) ((insn & 0xfc000000) >> 26) ++#define bit(obj,st) (((obj) >> (st)) & 1) ++#define rigg(obj,st) ((obj) >> (st)) ++enum sw_64_record_result ++{ ++ SW_64_RECORD_SUCCESS, ++ SW_64_RECORD_UNSUPPORTED, ++ SW_64_RECORD_UNKNOWN ++}; ++ ++/* Memory instruction format */ ++#define MEM_RA(insn) ((insn & 0x03e00000) >> 21) ++#define MEM_RB(insn) ((insn & 0x001f0000) >> 16) ++#define MEM_DISP(insn) \ ++ (((insn & 0x8000) == 0) ? (insn & 0xffff) : -((-insn) & 0xffff)) ++ ++#ifdef LHX20201102 ++static const int lda_opcode = 0x08; ++static const int stq_opcode = 0x2d; ++#else ++ ++static const int lda_opcode = 0x3e; ++static const int stq_opcode = 0x2d; ++#endif ++ ++/* Branch instruction format */ ++#define BR_RA(insn) MEM_RA(insn) ++ ++static const int br_opcode = 0x30; ++static const int bne_opcode = 0x3d; ++ ++/* Operate instruction format */ ++#define OPR_FUNCTION(insn) ((insn & 0xfe0) >> 5) ++#define OPR_HAS_IMMEDIATE(insn) ((insn & 0x1000) == 0x1000) ++#define OPR_RA(insn) MEM_RA(insn) ++#define OPR_RC(insn) ((insn & 0x1f)) ++#define OPR_LIT(insn) ((insn & 0x1fe000) >> 13) ++ ++static const int subq_opcode = 0x10; ++static const int subq_function = 0x29; ++ ++extern int pc_in_section (CORE_ADDR , char *); ++ ++ ++/* Return the name of the REGNO register. ++ ++ 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 sw_64 targets. */ ++ ++static const char * ++sw_64_register_name (struct gdbarch *gdbarch, int regno) ++{ ++ static const char * const register_names[] = ++ { ++#ifndef LHX20201026 ++ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", ++ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "fp", ++ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", ++ "r24", "r25", "ra", "r27", "r28", "r29", "sp", "r31", ++#else ++ "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", ++#endif ++ "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", ++ "ef0", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef1", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef2", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef3", "ef", "ef", "ef", "ef", "ef", "ef", "ef", /* ef0 */ ++ "ef4", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef5", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef6", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef7", "ef", "ef", "ef", "ef", "ef", "ef", "ef", /* ef1 */ ++ "ef8", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef9", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef10", "ef", "ef", "ef", "ef", "ef", "ef", "ef", ++ "ef11", "ef", "ef", "ef", "ef", "ef", "ef", "ef", /* ef2 */ ++ "", "", "", "", /*"DA_MATCH", "DA_MASK", "DV__MATCH", "DV_MASK",*/ ++ "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", ++ "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", ++ "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", ++ "V24", "V25", "V26", "V27", "V28", "V29", "V30", "V31", ++ "" ++ }; ++ ++ if (regno < 0) ++ return NULL; ++ if (regno >= ARRAY_SIZE(register_names)) ++ return NULL; ++ return register_names[regno]; ++} ++ ++static int ++sw_64_cannot_fetch_register (struct gdbarch *gdbarch, int regno) ++{ ++ return (strlen (sw_64_register_name (gdbarch, regno)) == 0); ++} ++ ++static int ++sw_64_cannot_store_register (struct gdbarch *gdbarch, int regno) ++{ ++ return (regno == SW_ZERO_REGNUM ++ || strlen (sw_64_register_name (gdbarch, regno)) == 0); ++} ++/* Construct vector type for ext registers. */ ++static struct type * ++sw_64_vec_type (struct gdbarch *gdbarch) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ if (!tdep->sw_64_vec_type) ++ { ++ struct type *t,*elem; ++ ++ t = arch_composite_type(gdbarch, "__gdb_builtin_type_vec256", TYPE_CODE_UNION); ++ ++ elem = builtin_type (gdbarch)->builtin_long_long; ++ append_composite_type_field (t, "v4_int64", ++ init_vector_type (elem, 4)); ++ elem = builtin_type (gdbarch)->builtin_double; ++ append_composite_type_field (t, "v4_double", ++ init_vector_type (elem, 4)); ++ ++ TYPE_VECTOR(t) = 1; ++ const char a[20]="builtin_type_vec256"; ++ t->set_name (&a[0]);//SBW ++ tdep->sw_64_vec_type = t; ++ } ++ ++ return tdep->sw_64_vec_type; ++} ++static struct type * ++sw_64_register_type (struct gdbarch *gdbarch, int regno) ++{ ++ if (regno == SW_SP_REGNUM || regno == SW_GP_REGNUM) ++ return builtin_type (gdbarch)->builtin_data_ptr; ++ if (regno == SW_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 sw_64-unicosmk. */ ++ if (regno >= SW_FP0_REGNUM && regno < SW_FP0_REGNUM + NFP_REGS - 1) ++ return builtin_type (gdbarch)->builtin_double; ++ ++if (regno >= SW64_VEC0 && regno < SW64_VEC0 + NVEC_REGS - 1 ) ++ return sw_64_vec_type(gdbarch); ++#ifndef LHX20201102 ++ if (regno >= 67 && regno <= 131 + 31) ++ return builtin_type (gdbarch)->builtin_double; ++#endif ++ ++ return builtin_type (gdbarch)->builtin_int64; ++} ++ ++/* Is REGNUM a member of REGGROUP? */ ++ ++static int ++sw_64_register_reggroup_p (struct gdbarch *gdbarch, int regnum, ++ struct reggroup *group) ++{ ++ /* Filter out any registers eliminated, but whose regnum is ++ reserved for backward compatibility, e.g. the vfp. */ ++ if (gdbarch_register_name (gdbarch, regnum) == NULL ++ || *gdbarch_register_name (gdbarch, regnum) == '\0') ++ return 0; ++ ++ if (group == all_reggroup) ++ return 1; ++ ++ /* Zero should not be saved or restored. Technically it is a general ++ register (just as $f31 would be a float if we represented it), but ++ there's no point displaying it during "info regs", so leave it out ++ of all groups except for "all". */ ++ if (regnum == SW_ZERO_REGNUM) ++ return 0; ++ ++ /* All other registers are saved and restored. */ ++ if (group == save_reggroup || group == restore_reggroup) ++ return 1; ++ ++ /* All other groups are non-overlapping. */ ++ ++ /* Since this is really a PALcode memory slot... */ ++ if (regnum == SW_UNIQUE_REGNUM) ++ return group == system_reggroup; ++ ++ /* Force the FPCR to be considered part of the floating point state. */ ++ if (regnum == SW_FPCR_REGNUM) ++ return group == float_reggroup; ++ ++#ifndef LHX20201102 ++ if (regnum >= SW_FP0_REGNUM && regnum < SW_FP0_REGNUM + NFP_REGS - 1) ++ return group == float_reggroup; ++ if (regnum >= SW64_VEC0 && regnum < SW64_VEC0 + NVEC_REGS - 1) ++ return group == vector_reggroup; ++#endif ++ if (regnum < SW_ZERO_REGNUM ) ++ return group == general_reggroup; ++ else ++ return 0; ++} ++ ++static enum register_status ++sw_64_vec_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, ++ int regnum, gdb_byte *buf) ++{ ++#ifndef LHX20201102 ++//printf("[sw_64_vec_register_read] REG: read $V%d\n", regnum); ++#endif ++#ifndef LHX20201102 ++ int i,fpnum; ++ enum register_status status; ++ // ULONGEST addr; ++ gdb_byte fp_buf[SW_REGISTER_SIZE]; ++ if (regnum >= SW2_V0_REGNUM && regnum < SW2_V0_REGNUM + 31) ++ { ++ fpnum = regnum - SW2_V0_REGNUM + SW_FP0_REGNUM; ++ //status = regcache->raw_read(fpnum, &addr); ++ status = regcache->raw_read(fpnum, fp_buf); ++ if (status != REG_VALID) ++ return status; ++ //read_memory (addr, buf+24, SW_REGISTER_SIZE); ++ memcpy (buf+24, fp_buf, SW_REGISTER_SIZE); ++ fpnum = regnum - SW2_V0_REGNUM + SW2_V0F3_REGNUM; ++ for (i=0; i<3; ++ i++, fpnum -= 32 ) { ++ //status = regcache->raw_read(fpnum, &addr); ++ status = regcache->raw_read(fpnum, fp_buf); ++ if (status != REG_VALID) ++ return status; ++ //read_memory(addr, buf+(i<<3), SW_REGISTER_SIZE); ++ memcpy (buf+(i<<3), fp_buf, SW_REGISTER_SIZE); ++ ++ } ++ } ++ return REG_VALID; ++#else ++ int i,fpnum; ++ enum register_status status; ++ ULONGEST addr; ++ ++ if ( regnum < SW64_VEC0 || regnum >= SW64_VEC0 + NVEC_REGS) { ++ warning("REG: read $V%d\n", regnum); ++ return REG_VALID; ++ } ++ fpnum = regnum - SW64_VEC0 + SW_FP0_REGNUM; ++ status = regcache->raw_read(fpnum, &addr); ++ read_memory (addr, buf+24, SW_REGISTER_SIZE); ++ ++ fpnum += NVEC_REGS*3; ++ for (i=0; i<3; i++, fpnum -= NVEC_REGS) ++ { ++ status = regcache->raw_read(fpnum, &addr); ++ read_memory(addr, buf+(i<<3), SW_REGISTER_SIZE); ++ } ++ return status; ++#endif ++} ++ ++static void ++sw_64_vec_register_write (struct gdbarch *gdbarch, struct regcache *regcache, ++ int regnum, const gdb_byte *buf) ++{ ++#ifndef LHX20201102 ++//printf("[sw_64_vec_register_write] REG: write $V%d\n", regnum); ++#endif ++#ifndef LHX20201102 ++ if (regnum >= SW2_V0_REGNUM && regnum < SW2_V0_REGNUM + 31) { ++ int i,fpnum; ++ ++ fpnum = regnum - SW2_V0_REGNUM + SW_FP0_REGNUM; ++ regcache->raw_write (fpnum, buf+24); ++ ++ fpnum = regnum - SW2_V0_REGNUM + SW2_V0F3_REGNUM; ++ for (i=0; i<3; ++ i++, fpnum -= 32 ) { ++ regcache->raw_write (fpnum, buf+(i<<3)); ++ } ++ } ++#else ++ int i,fpnum; ++ enum register_status status; ++ if ( regnum < SW64_VEC0 || regnum >= SW64_VEC0 + NVEC_REGS) ++ { ++ warning("REG: write $V%d\n", regnum); ++ return ; ++ } ++ ++ fpnum = regnum - SW64_VEC0 + SW_FP0_REGNUM; ++ //regcache_raw_write (regcache, fpnum, buf+24); ++ regcache->raw_write (fpnum, buf+24); ++ ++ fpnum += NVEC_REGS*3; ++ for (i=0; i<3; i++, fpnum -= NVEC_REGS ) ++ //regcache_raw_write (regcache, fpnum, buf+(i<<3)); ++ regcache->raw_write (fpnum, buf+(i<<3)); ++#endif ++} ++#ifndef LHX20201026 ++/* Read an instruction from memory at PC, looking through breakpoints. */ ++/* n is power of 2, over 0 */ ++ ++unsigned int* ++sw_64_read_insns (struct gdbarch *gdbarch, CORE_ADDR pc, int n) ++{ ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ ++ /* alloc from stack frame, freed on return */ ++ gdb_byte *buf = (gdb_byte *)XALLOCAVEC(int, n); ++ unsigned int *ibuf = XCNEWVEC(unsigned int, n); ++ gdb_byte *p; ++ int res, i; ++ ++ ++ res = target_read_memory (pc, buf, sizeof (int)*n); ++ if (res != 0) ++ memory_error (TARGET_XFER_E_IO, pc); ++ ++ n >>= 1; ++ for (i=0, p=buf; i> 0) & 0x7fffff; ++ ULONGEST sign = (mem >> 31) & 1; ++ ULONGEST exp_msb = (mem >> 30) & 1; ++ ULONGEST exp_low = (mem >> 23) & 0x7f; ++ ULONGEST exp, reg; ++ ++ exp = (exp_msb << 10) | exp_low; ++ if (exp_msb) ++ { ++ if (exp_low == 0x7f) ++ exp = 0x7ff; ++ } ++ else ++ { ++ if (exp_low != 0x00) ++ exp |= 0x380; ++ } ++ ++ reg = (sign << 63) | (exp << 52) | (frac << 29); ++ store_unsigned_integer ((gdb_byte *) out, 8, byte_order, reg); ++} ++ ++/* Similarly, this represents exactly the conversion performed by ++ the STS instruction. */ ++ ++static void ++sw_64_sts (struct gdbarch *gdbarch, void *out, const void *in) ++{ ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ ULONGEST reg, mem; ++ ++ reg = extract_unsigned_integer ((const gdb_byte *) in, 8, byte_order); ++ mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff); ++ store_unsigned_integer ((gdb_byte *) out, 4, byte_order, mem); ++} ++ ++/* The sw_64 needs a conversion between register and memory format if the ++ register is a floating point register and memory format is float, as the ++ register format must be double or memory format is an integer with 4 ++ bytes, as the representation of integers in floating point ++ registers is different. */ ++ ++static int ++sw_64_convert_register_p (struct gdbarch *gdbarch, int regno, ++ struct type *type) ++{ ++ return (regno >= SW_FP0_REGNUM && regno < SW_FP0_REGNUM + 31 ++ && TYPE_LENGTH (type) == 4); ++} ++ ++static int ++sw_64_register_to_value (struct frame_info *frame, int regnum, ++ struct type *valtype, gdb_byte *out, ++ int *optimizedp, int *unavailablep) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (frame); ++ struct value *value = get_frame_register_value (frame, regnum); ++ ++ gdb_assert (value != NULL); ++ *optimizedp = value_optimized_out (value); ++ *unavailablep = !value_entirely_available (value); ++ ++ if (*optimizedp || *unavailablep) ++ { ++ release_value (value); ++ return 0; ++ } ++ ++ /* Convert to VALTYPE. */ ++ ++ gdb_assert (TYPE_LENGTH (valtype) == 4); ++ sw_64_sts (gdbarch, out, value_contents_all (value)); ++ ++ release_value (value); ++ return 1; ++} ++ ++static void ++sw_64_value_to_register (struct frame_info *frame, int regnum, ++ struct type *valtype, const gdb_byte *in) ++{ ++ gdb_byte out[SW_REGISTER_SIZE]; ++ ++ gdb_assert (TYPE_LENGTH (valtype) == 4); ++ gdb_assert (register_size (get_frame_arch (frame), regnum) ++ <= SW_REGISTER_SIZE); ++ sw_64_lds (get_frame_arch (frame), out, in); ++ ++ put_frame_register (frame, regnum, out); ++} ++ ++ ++/* The sw_64 passes the first six arguments in the registers, the rest on ++ the stack. The register arguments are stored in ARG_REG_BUFFER, and ++ then moved into the register file; this simplifies the passing of a ++ large struct which extends from the registers to the stack, plus avoids ++ three ptrace invocations per word. ++ ++ We don't bother tracking which register values should go in integer ++ regs or fp regs; we load the same values into both. ++ ++ If the called function is returning a structure, the address of the ++ structure to be returned is passed as a hidden first argument. */ ++ ++static CORE_ADDR ++sw_64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, ++ struct regcache *regcache, CORE_ADDR bp_addr, ++ int nargs, struct value **args, CORE_ADDR sp, ++ function_call_return_method return_method, ++ CORE_ADDR struct_addr) ++{ ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ int i; ++ int accumulate_size = (return_method == return_method_struct) ? 8 : 0; ++ struct sw_64_arg ++ { ++ const gdb_byte *contents; ++ int len; ++ int offset; ++ }; ++ struct sw_64_arg *sw_64_args = XALLOCAVEC (struct sw_64_arg, nargs); ++ struct sw_64_arg *m_arg; ++ gdb_byte arg_reg_buffer[SW_REGISTER_SIZE * SW_NUM_ARG_REGS]; ++ int required_arg_regs; ++ CORE_ADDR func_addr = find_function_addr (function, NULL); ++ ++ /* The ABI places the address of the called function in T12. */ ++ regcache_cooked_write_signed (regcache, SW_T12_REGNUM, func_addr); ++ ++ /* Set the return address register to point to the entry point ++ of the program, where a breakpoint lies in wait. */ ++ regcache_cooked_write_signed (regcache, SW_RA_REGNUM, bp_addr); ++ ++ /* Lay out the arguments in memory. */ ++ for (i = 0, m_arg = sw_64_args; i < nargs; i++, m_arg++) ++ { ++ struct value *arg = args[i]; ++ struct type *arg_type = check_typedef (value_type (arg)); ++ ++ /* Cast argument to long if necessary as the compiler does it too. */ ++ switch (arg_type->code ()) ++ { ++ case TYPE_CODE_INT: ++ case TYPE_CODE_BOOL: ++ case TYPE_CODE_CHAR: ++ case TYPE_CODE_RANGE: ++ case TYPE_CODE_ENUM: ++ if (TYPE_LENGTH (arg_type) == 4) ++ { ++ /* 32-bit values must be sign-extended to 64 bits ++ even if the base data type is unsigned. */ ++ arg_type = builtin_type (gdbarch)->builtin_int32; ++ arg = value_cast (arg_type, arg); ++ } ++ if (TYPE_LENGTH (arg_type) < SW_REGISTER_SIZE) ++ { ++ arg_type = builtin_type (gdbarch)->builtin_int64; ++ arg = value_cast (arg_type, arg); ++ } ++ break; ++ ++ case TYPE_CODE_FLT: ++ /* "float" arguments loaded in registers must be passed in ++ register format, aka "double". */ ++ if (accumulate_size < sizeof (arg_reg_buffer) ++ && TYPE_LENGTH (arg_type) == 4) ++ { ++ arg_type = builtin_type (gdbarch)->builtin_double; ++ arg = value_cast (arg_type, arg); ++ } ++ /* Tru64 5.1 has a 128-bit long double, and passes this by ++ invisible reference. No one else uses this data type. */ ++ else if (TYPE_LENGTH (arg_type) == 16) ++ { ++ /* Allocate aligned storage. */ ++ sp = (sp & -16) - 16; ++ ++ /* Write the real data into the stack. */ ++ write_memory (sp, value_contents (arg), 16); ++ ++ /* Construct the indirection. */ ++ arg_type = lookup_pointer_type (arg_type); ++ arg = value_from_pointer (arg_type, sp); ++ } ++ break; ++ ++ case TYPE_CODE_COMPLEX: ++ /* ??? The ABI says that complex values are passed as two ++ separate scalar values. This distinction only matters ++ for complex float. However, GCC does not implement this. */ ++ ++ /* Tru64 5.1 has a 128-bit long double, and passes this by ++ invisible reference. */ ++ if (TYPE_LENGTH (arg_type) == 32) ++ { ++ /* Allocate aligned storage. */ ++ sp = (sp & -16) - 16; ++ ++ /* Write the real data into the stack. */ ++ write_memory (sp, value_contents (arg), 32); ++ ++ /* Construct the indirection. */ ++ arg_type = lookup_pointer_type (arg_type); ++ arg = value_from_pointer (arg_type, sp); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ m_arg->len = TYPE_LENGTH (arg_type); ++ m_arg->offset = accumulate_size; ++ accumulate_size = (accumulate_size + m_arg->len + 7) & ~7; ++ m_arg->contents = value_contents (arg); ++ } ++ ++ /* Determine required argument register loads, loading an argument register ++ is expensive as it uses three ptrace calls. */ ++ required_arg_regs = accumulate_size / 8; ++ if (required_arg_regs > SW_NUM_ARG_REGS) ++ required_arg_regs = SW_NUM_ARG_REGS; ++ ++ /* Make room for the arguments on the stack. */ ++ if (accumulate_size < sizeof(arg_reg_buffer)) ++ accumulate_size = 0; ++ else ++ accumulate_size -= sizeof(arg_reg_buffer); ++ sp -= accumulate_size; ++ ++ /* Keep sp aligned to a multiple of 16 as the ABI requires. */ ++ sp &= ~15; ++ ++ /* `Push' arguments on the stack. */ ++ for (i = nargs; m_arg--, --i >= 0;) ++ { ++ const gdb_byte *contents = m_arg->contents; ++ int offset = m_arg->offset; ++ int len = m_arg->len; ++ ++ /* Copy the bytes destined for registers into arg_reg_buffer. */ ++ if (offset < sizeof(arg_reg_buffer)) ++ { ++ if (offset + len <= sizeof(arg_reg_buffer)) ++ { ++ memcpy (arg_reg_buffer + offset, contents, len); ++ continue; ++ } ++ else ++ { ++ int tlen = sizeof(arg_reg_buffer) - offset; ++ memcpy (arg_reg_buffer + offset, contents, tlen); ++ offset += tlen; ++ contents += tlen; ++ len -= tlen; ++ } ++ } ++ ++ /* Everything else goes to the stack. */ ++ write_memory (sp + offset - sizeof(arg_reg_buffer), contents, len); ++ } ++ if (return_method == return_method_struct) ++ store_unsigned_integer (arg_reg_buffer, SW_REGISTER_SIZE, ++ byte_order, struct_addr); ++ ++ /* Load the argument registers. */ ++ for (i = 0; i < required_arg_regs; i++) ++ { ++ regcache->cooked_write (SW_A0_REGNUM + i, ++ arg_reg_buffer + i * SW_REGISTER_SIZE); ++ regcache->cooked_write (SW_FPA0_REGNUM + i, ++ arg_reg_buffer + i * SW_REGISTER_SIZE); ++ } ++ ++ /* Finally, update the stack pointer. */ ++ regcache_cooked_write_signed (regcache, SW_SP_REGNUM, sp); ++ ++ return sp; ++} ++ ++/* Extract from REGCACHE the value about to be returned from a function ++ and copy it into VALBUF. */ ++ ++static void ++sw_64_extract_return_value (struct type *valtype, struct regcache *regcache, ++ gdb_byte *valbuf) ++{ ++ struct gdbarch *gdbarch = regcache->arch (); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte raw_buffer[SW_REGISTER_SIZE]; ++ ULONGEST l; ++ ++ switch (valtype->code ()) ++ { ++ case TYPE_CODE_FLT: ++ switch (TYPE_LENGTH (valtype)) ++ { ++ case 4: ++ regcache->cooked_read (SW_FP0_REGNUM, raw_buffer); ++ sw_64_sts (gdbarch, valbuf, raw_buffer); ++ break; ++ ++ case 8: ++ regcache->cooked_read (SW_FP0_REGNUM, valbuf); ++ break; ++ ++ case 16: ++ regcache_cooked_read_unsigned (regcache, SW_V0_REGNUM, &l); ++ read_memory (l, valbuf, 16); ++ break; ++ ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("unknown floating point width")); ++ } ++ break; ++ ++ case TYPE_CODE_COMPLEX: ++ switch (TYPE_LENGTH (valtype)) ++ { ++ case 8: ++ /* ??? This isn't correct wrt the ABI, but it's what GCC does. */ ++ regcache->cooked_read (SW_FP0_REGNUM, valbuf); ++ break; ++ ++ case 16: ++ regcache->cooked_read (SW_FP0_REGNUM, valbuf); ++ regcache->cooked_read (SW_FP0_REGNUM + 1, valbuf + 8); ++ break; ++ ++ case 32: ++ regcache_cooked_read_unsigned (regcache, SW_V0_REGNUM, &l); ++ read_memory (l, valbuf, 32); ++ break; ++ ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("unknown floating point width")); ++ } ++ break; ++ ++ default: ++ /* Assume everything else degenerates to an integer. */ ++ regcache_cooked_read_unsigned (regcache, SW_V0_REGNUM, &l); ++ store_unsigned_integer (valbuf, TYPE_LENGTH (valtype), byte_order, l); ++ break; ++ } ++} ++ ++/* Insert the given value into REGCACHE as if it was being ++ returned by a function. */ ++ ++static void ++sw_64_store_return_value (struct type *valtype, struct regcache *regcache, ++ const gdb_byte *valbuf) ++{ ++ struct gdbarch *gdbarch = regcache->arch (); ++ gdb_byte raw_buffer[SW_REGISTER_SIZE]; ++ ULONGEST l; ++ ++ switch (valtype->code ()) ++ { ++ case TYPE_CODE_FLT: ++ switch (TYPE_LENGTH (valtype)) ++ { ++ case 4: ++ sw_64_lds (gdbarch, raw_buffer, valbuf); ++ regcache->cooked_write (SW_FP0_REGNUM, raw_buffer); ++ break; ++ ++ case 8: ++ regcache->cooked_write (SW_FP0_REGNUM, valbuf); ++ break; ++ ++ case 16: ++ /* FIXME: 128-bit long doubles are returned like structures: ++ by writing into indirect storage provided by the caller ++ as the first argument. */ ++ error (_("Cannot set a 128-bit long double return value.")); ++ ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("unknown floating point width")); ++ } ++ break; ++ ++ case TYPE_CODE_COMPLEX: ++ switch (TYPE_LENGTH (valtype)) ++ { ++ case 8: ++ /* ??? This isn't correct wrt the ABI, but it's what GCC does. */ ++ regcache->cooked_write (SW_FP0_REGNUM, valbuf); ++ break; ++ ++ case 16: ++ regcache->cooked_write (SW_FP0_REGNUM, valbuf); ++ regcache->cooked_write (SW_FP0_REGNUM + 1, valbuf + 8); ++ break; ++ ++ case 32: ++ /* FIXME: 128-bit long doubles are returned like structures: ++ by writing into indirect storage provided by the caller ++ as the first argument. */ ++ error (_("Cannot set a 128-bit long double return value.")); ++ ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("unknown floating point width")); ++ } ++ break; ++ ++ default: ++ /* Assume everything else degenerates to an integer. */ ++ /* 32-bit values must be sign-extended to 64 bits ++ even if the base data type is unsigned. */ ++ if (TYPE_LENGTH (valtype) == 4) ++ valtype = builtin_type (gdbarch)->builtin_int32; ++ l = unpack_long (valtype, valbuf); ++ regcache_cooked_write_unsigned (regcache, SW_V0_REGNUM, l); ++ break; ++ } ++} ++ ++static enum return_value_convention ++sw_64_return_value (struct gdbarch *gdbarch, struct value *function, ++ struct type *type, struct regcache *regcache, ++ gdb_byte *readbuf, const gdb_byte *writebuf) ++{ ++ enum type_code code = type->code (); ++ ++ if ((code == TYPE_CODE_STRUCT ++ || code == TYPE_CODE_UNION ++ || code == TYPE_CODE_ARRAY) ++ && gdbarch_tdep (gdbarch)->return_in_memory (type)) ++ { ++ if (readbuf) ++ { ++ ULONGEST addr; ++ regcache_raw_read_unsigned (regcache, SW_V0_REGNUM, &addr); ++ read_memory (addr, readbuf, TYPE_LENGTH (type)); ++ } ++ ++ return RETURN_VALUE_ABI_RETURNS_ADDRESS; ++ } ++ ++ if (readbuf) ++ sw_64_extract_return_value (type, regcache, readbuf); ++ if (writebuf) ++ sw_64_store_return_value (type, regcache, writebuf); ++ ++ return RETURN_VALUE_REGISTER_CONVENTION; ++} ++ ++static int ++sw_64_return_in_memory_always (struct type *type) ++{ ++ return 1; ++} ++ ++ ++constexpr gdb_byte sw_64_break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */ ++ ++typedef BP_MANIPULATION (sw_64_break_insn) sw_64_breakpoint; ++ ++ ++/* This returns the PC of the first insn after the prologue. ++ If we can't find the prologue, then return 0. */ ++ ++CORE_ADDR ++sw_64_after_prologue (CORE_ADDR pc) ++{ ++ struct symtab_and_line sal; ++ CORE_ADDR func_addr, func_end; ++ ++ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) ++ return 0; ++ ++ sal = find_pc_line (func_addr, 0); ++ if (sal.end < func_end) ++ return sal.end; ++ ++ /* The line after the prologue is after the end of the function. In this ++ case, tell the caller to find the prologue the hard way. */ ++ return 0; ++} ++ ++/* Read an instruction from memory at PC, looking through breakpoints. */ ++ ++unsigned int ++sw_64_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte buf[SW_INSN_SIZE]; ++ int res; ++ ++ res = target_read_memory (pc, buf, sizeof (buf)); ++ if (res != 0) ++ memory_error (TARGET_XFER_E_IO, pc); ++ return extract_unsigned_integer (buf, sizeof (buf), byte_order); ++} ++ ++/* To skip prologues, I use this predicate. Returns either PC itself ++ if the code at PC does not look like a function prologue; otherwise ++ returns an address that (if we're lucky) follows the prologue. If ++ LENIENT, then we must skip everything which is involved in setting ++ up the frame (it's OK to skip more, just so long as we don't skip ++ anything which might clobber the registers which are being saved. */ ++ ++static CORE_ADDR ++sw_64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ unsigned long inst; ++ int offset; ++ CORE_ADDR post_prologue_pc; ++ gdb_byte buf[SW_INSN_SIZE]; ++ ++ /* Silently return the unaltered pc upon memory errors. ++ This could happen on OSF/1 if decode_line_1 tries to skip the ++ prologue for quickstarted shared library functions when the ++ shared library is not yet mapped in. ++ Reading target memory is slow over serial lines, so we perform ++ this check only if the target has shared libraries (which all ++ SW_64 targets do). */ ++ if (target_read_memory (pc, buf, sizeof (buf))) ++ return pc; ++ ++ /* See if we can determine the end of the prologue via the symbol table. ++ If so, then return either PC, or the PC after the prologue, whichever ++ is greater. */ ++ ++ post_prologue_pc = sw_64_after_prologue (pc); ++ if (post_prologue_pc != 0) ++ return std::max (pc, post_prologue_pc); ++ ++ /* Can't determine prologue from the symbol table, need to examine ++ instructions. */ ++ ++ /* Skip the typical prologue instructions. These are the stack adjustment ++ instruction and the instructions that save registers on the stack ++ or in the gcc frame. */ ++ for (offset = 0; offset < 100; offset += SW_INSN_SIZE) ++ { ++ inst = sw_64_read_insn (gdbarch, pc + offset); ++ ++ if ((inst & 0xffff0000) == 0xffbb0000) /* ldah $gp,n($t12) */ ++ continue; ++ if ((inst & 0xffff0000) == 0xfbbd0000) /* lda $gp,n($gp) */ ++ continue; ++ if ((inst & 0xffff0000) == 0x8f7d0000) /* lda $sp,n($sp) */ ++ continue; ++ if ((inst & 0xfffff000) == 0xfbde8000) /* subq $sp,n,$sp */ ++ continue; ++ ++ if ((inst & 0xffe01fff) == 0x43c0153e) /* stq reg,n($sp) */ ++ continue; ++ if ((inst & 0xfc1f0000) == 0xac1e0000) /* stl reg,n($sp) */ ++ continue; ++ ++ if (inst == 0x43de074f) /* bis sp,sp,fp */ ++ continue; ++ if (inst == 0x43fe074f) /* bis zero,sp,fp */ ++ continue; ++ ++ break; ++ } ++ return pc + offset; ++} ++ ++ ++#ifdef LHX20201026 ++static const int ldl_l_opcode = 0x2a; ++static const int ldq_l_opcode = 0x2b; ++static const int stl_c_opcode = 0x2e; ++static const int stq_c_opcode = 0x2f; ++#else ++static const int ldq_l_opcode = 0x23; //ldi ++static const int ldl_l_opcode = 0x3e; // ldl ++static const int stl_c_opcode = 0x2b; ++static const int stq_c_opcode = 0x2b; // stl ++#endif ++ ++/* Checks for an atomic sequence of instructions beginning with a LDL_L/LDQ_L ++ instruction and ending with a STL_C/STQ_C instruction. If such a sequence ++ is found, attempt to step through it. A breakpoint is placed at the end of ++ the sequence. */ ++ ++static std::vector ++sw_64_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX}; ++ CORE_ADDR loc = pc; ++ CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */ ++ unsigned int insn = sw_64_read_insn (gdbarch, loc); ++ int insn_count; ++ int index; ++ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ ++ const int atomic_sequence_length = 16; /* Instruction sequence length. */ ++ int bc_insn_count = 0; /* Conditional branch instruction count. */ ++ unsigned int func_opcode = (insn>>12)&0xf; ++ /* Assume all atomic sequences start with a LDL_L/LDQ_L instruction. */ ++ if (!((INSN_OPCODE (insn) == 0x8 ) && ++ (func_opcode == 0 || func_opcode == 1))) ++ return {}; ++ ++ /* Assume that no atomic sequence is longer than "atomic_sequence_length" ++ instructions. */ ++ for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) ++ { ++ loc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, loc); ++ ++ /* Assume that there is at most one branch in the atomic ++ sequence. If a branch is found, put a breakpoint in ++ its destination address. */ ++ if (INSN_OPCODE (insn) >= 0x30 && ++ INSN_OPCODE (insn) <= 0x3d) ++ { ++ int immediate = (insn & 0x001fffff) << 2; ++ ++ immediate = (immediate ^ 0x400000) - 0x400000; ++ ++ if (bc_insn_count >= 1) ++ return {}; /* More than one branch found, fallback ++ to the standard single-step code. */ ++ ++ breaks[1] = loc + SW_INSN_SIZE + immediate; ++ ++ bc_insn_count++; ++ last_breakpoint++; ++ } ++ ++ if (INSN_OPCODE (insn) >= 0x20 && INSN_OPCODE (insn) <= 0x2c) ++ { ++ loc -= SW_INSN_SIZE; ++ break; ++ } ++ func_opcode = (insn>>12)&0xf; ++ if (INSN_OPCODE (insn) == 0x6 && ++ func_opcode == 0) ++ break; ++ } ++#if 0 ++ /* Assume that the atomic sequence ends with a STL_C/STQ_C instruction. */ ++ if (INSN_OPCODE (insn) != stl_c_opcode ++ && INSN_OPCODE (insn) != stq_c_opcode) ++ return {}; ++#endif ++ closing_insn = loc; ++ loc += SW_INSN_SIZE; ++ ++ /* Insert a breakpoint right after the end of the atomic sequence. */ ++ breaks[0] = loc; ++ ++ /* Check for duplicated breakpoints. Check also for a breakpoint ++ placed (branch instruction's destination) anywhere in sequence. */ ++ if (last_breakpoint ++ && (breaks[1] == breaks[0] ++ || (breaks[1] >= pc && breaks[1] <= closing_insn))) ++ last_breakpoint = 0; ++ ++ std::vector next_pcs; ++ ++ for (index = 0; index <= last_breakpoint; index++) ++ next_pcs.push_back (breaks[index]); ++ ++ return next_pcs; ++} ++ ++#ifndef XWB20200903 ++static void ++sw_64_skip_permanent_breakpoint (struct regcache *regcache) ++{ ++ CORE_ADDR current_pc = regcache_read_pc (regcache); ++ ++ current_pc += 4; ++ regcache_write_pc (regcache, current_pc); } ++#endif ++ ++ ++/* Figure out where the longjmp will land. ++ We expect the first arg to be a pointer to the jmp_buf structure from ++ which we extract the PC (JB_PC) that we will land at. The PC is copied ++ into the "pc". This routine returns true on success. */ ++ ++static int ++sw_64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (frame); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ CORE_ADDR jb_addr; ++ gdb_byte raw_buffer[SW_REGISTER_SIZE]; ++ ++ jb_addr = get_frame_register_unsigned (frame, SW_A0_REGNUM); ++ ++ if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size), ++ raw_buffer, tdep->jb_elt_size)) ++ return 0; ++ ++ *pc = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size, byte_order); ++ return 1; ++} ++ ++ ++/* Frame unwinder for signal trampolines. We use sw_64 tdep bits that ++ describe the location and shape of the sigcontext structure. After ++ that, all registers are in memory, so it's easy. */ ++/* ??? Shouldn't we be able to do this generically, rather than with ++ OSABI data specific to SW_64? */ ++ ++struct sw_64_sigtramp_unwind_cache ++{ ++ CORE_ADDR sigcontext_addr; ++}; ++ ++static struct sw_64_sigtramp_unwind_cache * ++sw_64_sigtramp_frame_unwind_cache (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_sigtramp_unwind_cache *info; ++ struct gdbarch_tdep *tdep; ++ ++ if (*this_prologue_cache) ++ return (struct sw_64_sigtramp_unwind_cache *) *this_prologue_cache; ++ ++ info = FRAME_OBSTACK_ZALLOC (struct sw_64_sigtramp_unwind_cache); ++ *this_prologue_cache = info; ++ ++ tdep = gdbarch_tdep (get_frame_arch (this_frame)); ++ info->sigcontext_addr = tdep->sigcontext_addr (this_frame); ++ ++ return info; ++} ++ ++/* Return the address of REGNUM in a sigtramp frame. Since this is ++ all arithmetic, it doesn't seem worthwhile to cache it. */ ++ ++static CORE_ADDR ++sw_64_sigtramp_register_address (struct gdbarch *gdbarch, ++ CORE_ADDR sigcontext_addr, int regnum) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ if (regnum >= 0 && regnum < 32) ++ return sigcontext_addr + tdep->sc_regs_offset + regnum * 8; ++ else if (regnum >= SW_FP0_REGNUM && regnum < SW_FP0_REGNUM + 32) ++ return sigcontext_addr + tdep->sc_fpregs_offset + regnum * 8; ++ else if (regnum == SW_PC_REGNUM) ++ return sigcontext_addr + tdep->sc_pc_offset; ++ ++ return 0; ++} ++ ++/* Given a GDB frame, determine the address of the calling function's ++ frame. This will be used to create a new GDB frame struct. */ ++ ++static void ++sw_64_sigtramp_frame_this_id (struct frame_info *this_frame, ++ void **this_prologue_cache, ++ struct frame_id *this_id) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ struct sw_64_sigtramp_unwind_cache *info ++ = sw_64_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache); ++ CORE_ADDR stack_addr, code_addr; ++ ++ /* If the OSABI couldn't locate the sigcontext, give up. */ ++ if (info->sigcontext_addr == 0) ++ return; ++ ++ /* If we have dynamic signal trampolines, find their start. ++ If we do not, then we must assume there is a symbol record ++ that can provide the start address. */ ++ if (tdep->dynamic_sigtramp_offset) ++ { ++ int offset; ++ code_addr = get_frame_pc (this_frame); ++ offset = tdep->dynamic_sigtramp_offset (gdbarch, code_addr); ++ if (offset >= 0) ++ code_addr -= offset; ++ else ++ code_addr = 0; ++ } ++ else ++ code_addr = get_frame_func (this_frame); ++ ++ /* The stack address is trivially read from the sigcontext. */ ++ stack_addr = sw_64_sigtramp_register_address (gdbarch, info->sigcontext_addr, ++ SW_SP_REGNUM); ++ stack_addr = get_frame_memory_unsigned (this_frame, stack_addr, ++ SW_REGISTER_SIZE); ++ ++ *this_id = frame_id_build (stack_addr, code_addr); ++} ++ ++/* Retrieve the value of REGNUM in FRAME. Don't give up! */ ++ ++static struct value * ++sw_64_sigtramp_frame_prev_register (struct frame_info *this_frame, ++ void **this_prologue_cache, int regnum) ++{ ++ struct sw_64_sigtramp_unwind_cache *info ++ = sw_64_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache); ++ CORE_ADDR addr; ++ ++ if (info->sigcontext_addr != 0) ++ { ++ /* All integer and fp registers are stored in memory. */ ++ addr = sw_64_sigtramp_register_address (get_frame_arch (this_frame), ++ info->sigcontext_addr, regnum); ++ if (addr != 0) ++ return frame_unwind_got_memory (this_frame, regnum, addr); ++ } ++ ++ /* This extra register may actually be in the sigcontext, but our ++ current description of it in sw_64_sigtramp_frame_unwind_cache ++ doesn't include it. Too bad. Fall back on whatever's in the ++ outer frame. */ ++ return frame_unwind_got_register (this_frame, regnum, regnum); ++} ++ ++static int ++sw_64_sigtramp_frame_sniffer (const struct frame_unwind *self, ++ struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ CORE_ADDR pc = get_frame_pc (this_frame); ++ const char *name; ++ ++ /* NOTE: cagney/2004-04-30: Do not copy/clone this code. Instead ++ look at tramp-frame.h and other simpler per-architecture ++ sigtramp unwinders. */ ++ ++ /* We shouldn't even bother to try if the OSABI didn't register a ++ sigcontext_addr handler or pc_in_sigtramp handler. */ ++ if (gdbarch_tdep (gdbarch)->sigcontext_addr == NULL) ++ return 0; ++ if (gdbarch_tdep (gdbarch)->pc_in_sigtramp == NULL) ++ return 0; ++ ++ /* Otherwise we should be in a signal frame. */ ++ find_pc_partial_function (pc, &name, NULL, NULL); ++ if (gdbarch_tdep (gdbarch)->pc_in_sigtramp (gdbarch, pc, name)) ++ return 1; ++ ++ return 0; ++} ++ ++static const struct frame_unwind sw_64_sigtramp_frame_unwind = { ++ SIGTRAMP_FRAME, ++ default_frame_unwind_stop_reason, ++ sw_64_sigtramp_frame_this_id, ++ sw_64_sigtramp_frame_prev_register, ++ NULL, ++ sw_64_sigtramp_frame_sniffer ++}; ++ ++ ++ ++/* Heuristic_proc_start may hunt through the text section for a long ++ time across a 2400 baud serial line. Allows the user to limit this ++ search. */ ++#ifndef _SW64_ ++static int heuristic_fence_post = 40; ++#else ++static int heuristic_fence_post = 0; ++#endif ++/* Attempt to locate the start of the function containing PC. We assume that ++ the previous function ends with an about_to_return insn. Not foolproof by ++ any means, since gcc is happy to put the epilogue in the middle of a ++ function. But we're guessing anyway... */ ++ ++static CORE_ADDR ++sw_64_heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ CORE_ADDR last_non_nop = pc; ++ CORE_ADDR fence = pc - heuristic_fence_post; ++ CORE_ADDR orig_pc = pc; ++ CORE_ADDR func; ++ struct inferior *inf; ++ ++ if (pc == 0) ++ return 0; ++ ++ /* First see if we can find the start of the function from minimal ++ symbol information. This can succeed with a binary that doesn't ++ have debug info, but hasn't been stripped. */ ++ func = get_pc_function_start (pc); ++ if (func) ++ return func; ++ ++ if (heuristic_fence_post == -1 ++ || fence < tdep->vm_min_address) ++ fence = tdep->vm_min_address; ++ ++ /* Search back for previous return; also stop at a 0, which might be ++ seen for instance before the start of a code section. Don't include ++ nops, since this usually indicates padding between functions. */ ++#ifdef LHX20201102 ++ i = 0; ++ insns = sw_64_read_insns (gdbarch, pc, heuristic_fence_post>>2) ++ for (pc -= SW_INSN_SIZE; pc >= fence; i++, pc -= SW_INSN_SIZE) ++ { ++ unsigned int insn = insns[i]; ++ /* The above is unreliable, sometime other unexpacted insn ex ist. */ ++ /* ldih gp,17(t12) ;0xffbb0011 ++ * ldi gp,18728(gp) ;0xfbbd4928 */ ++ /* swxrun */ ++ if ((insn & 0xffff0000) == 0xfbbd0000) ++ flag = 1; ++ else ++ if ((insn & 0xffff0000) == 0xffbb0000) ++ { ++ if ((flag == 1) && ++ ((last_non_nop-SW_INSN_SIZE) == pc)) ++ return pc; ++ } ++ switch (insn) ++ { ++ case 0: /* invalid insn */ ++// case 0x6bfa8001: /* ret $31,($26),1 */ ++ case 0x07da6001: /* slave ret */ ++ case 0x0bfa0001: /* mater ret */ ++ //debug("ret before proc_start"); ++ return last_non_nop; ++ ++ case 0x2ffe0000: /* unop: ldq_u $31,0($30) */ ++ case 0x47ff041f: /* nop: bis $31,$31,$31 */ ++ break; ++ ++ default: ++ last_non_nop = pc; ++ break; ++ } ++ } ++ XDELETEVEC(insns); ++#else ++ for (pc -= SW_INSN_SIZE; pc >= fence; pc -= SW_INSN_SIZE) ++ { ++ unsigned int insn = sw_64_read_insn (gdbarch, pc); ++ ++ switch (insn) ++ { ++ case 0: /* invalid insn */ ++ case 0x6bfa8001: /* ret $31,($26),1 */ ++ case 0x0bfa0001: /* mater ret */ ++ return last_non_nop; ++ ++ case 0x2ffe0000: /* unop: ldq_u $31,0($30) */ ++ case 0x47ff041f: /* nop: bis $31,$31,$31 */ ++ break; ++ ++ default: ++ last_non_nop = pc; ++ break; ++ } ++ } ++#endif ++ inf = current_inferior (); ++ ++ /* It's not clear to me why we reach this point when stopping quietly, ++ but with this test, at least we don't print out warnings for every ++ child forked (eg, on decstation). 22apr93 rich@cygnus.com. */ ++ if (inf->control.stop_soon == NO_STOP_QUIETLY) ++ { ++ static int blurb_printed = 0; ++ ++ if (fence == tdep->vm_min_address) ++ warning (_("Hit beginning of text section without finding \ ++enclosing function for address %s"), paddress (gdbarch, orig_pc)); ++ else ++ warning (_("Hit heuristic-fence-post without finding \ ++enclosing function for address %s"), paddress (gdbarch, orig_pc)); ++ ++ if (!blurb_printed) ++ { ++ printf_filtered (_("\ ++This warning occurs if you are debugging a function without any symbols\n\ ++(for example, in a stripped executable). In that case, you may wish to\n\ ++increase the size of the search with the `set heuristic-fence-post' command.\n\ ++\n\ ++Otherwise, you told GDB there was a function where there isn't one, or\n\ ++(more likely) you have encountered a bug in GDB.\n")); ++ blurb_printed = 1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++/* Fallback sw_64 frame unwinder. Uses instruction scanning and knows ++ something about the traditional layout of sw_64 stack frames. */ ++ ++struct sw_64_heuristic_unwind_cache ++{ ++ CORE_ADDR vfp; ++ CORE_ADDR start_pc; ++ struct trad_frame_saved_reg *saved_regs; ++ int return_reg; ++}; ++ ++/* If a probing loop sequence starts at PC, simulate it and compute ++ FRAME_SIZE and PC after its execution. Otherwise, return with PC and ++ FRAME_SIZE unchanged. */ ++ ++static void ++sw_64_heuristic_analyze_probing_loop (struct gdbarch *gdbarch, CORE_ADDR *pc, ++ int *frame_size) ++{ ++ CORE_ADDR cur_pc = *pc; ++ int cur_frame_size = *frame_size; ++ int nb_of_iterations, reg_index, reg_probe; ++ unsigned int insn; ++ ++ /* The following pattern is recognized as a probing loop: ++ ++ lda REG_INDEX,NB_OF_ITERATIONS ++ lda REG_PROBE,(sp) ++ ++ LOOP_START: ++ stq zero,(REG_PROBE) ++ subq REG_INDEX,0x1,REG_INDEX ++ lda REG_PROBE,(REG_PROBE) ++ bne REG_INDEX, LOOP_START ++ ++ lda sp,(REG_PROBE) ++ ++ If anything different is found, the function returns without ++ changing PC and FRAME_SIZE. Otherwise, PC will point immediately ++ after this sequence, and FRAME_SIZE will be updated. */ ++ ++ /* lda REG_INDEX,NB_OF_ITERATIONS */ ++ ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != lda_opcode) ++ return; ++ reg_index = MEM_RA (insn); ++ nb_of_iterations = MEM_DISP (insn); ++ ++ /* lda REG_PROBE,(sp) */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != lda_opcode ++ || MEM_RB (insn) != SW_SP_REGNUM) ++ return; ++ reg_probe = MEM_RA (insn); ++ cur_frame_size -= MEM_DISP (insn); ++ ++ /* stq zero,(REG_PROBE) */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != stq_opcode ++ || MEM_RA (insn) != 0x1f ++ || MEM_RB (insn) != reg_probe) ++ return; ++ ++ /* subq REG_INDEX,0x1,REG_INDEX */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != subq_opcode ++ || !OPR_HAS_IMMEDIATE (insn) ++ || OPR_FUNCTION (insn) != subq_function ++ || OPR_LIT(insn) != 1 ++ || OPR_RA (insn) != reg_index ++ || OPR_RC (insn) != reg_index) ++ return; ++ ++ /* lda REG_PROBE,(REG_PROBE) */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != lda_opcode ++ || MEM_RA (insn) != reg_probe ++ || MEM_RB (insn) != reg_probe) ++ return; ++ cur_frame_size -= MEM_DISP (insn) * nb_of_iterations; ++ ++ /* bne REG_INDEX, LOOP_START */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != bne_opcode ++ || MEM_RA (insn) != reg_index) ++ return; ++ ++ /* lda sp,(REG_PROBE) */ ++ ++ cur_pc += SW_INSN_SIZE; ++ insn = sw_64_read_insn (gdbarch, cur_pc); ++ if (INSN_OPCODE (insn) != lda_opcode ++ || MEM_RA (insn) != SW_SP_REGNUM ++ || MEM_RB (insn) != reg_probe) ++ return; ++ cur_frame_size -= MEM_DISP (insn); ++ ++ *pc = cur_pc; ++ *frame_size = cur_frame_size; ++} ++ ++static struct sw_64_heuristic_unwind_cache * ++sw_64_heuristic_frame_unwind_cache (struct frame_info *this_frame, ++ void **this_prologue_cache, ++ CORE_ADDR start_pc) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ struct sw_64_heuristic_unwind_cache *info; ++ ULONGEST val; ++ CORE_ADDR limit_pc, cur_pc; ++ int frame_reg, frame_size, return_reg, reg; ++ ++ if (*this_prologue_cache) ++ return (struct sw_64_heuristic_unwind_cache *) *this_prologue_cache; ++ ++ info = FRAME_OBSTACK_ZALLOC (struct sw_64_heuristic_unwind_cache); ++ *this_prologue_cache = info; ++ info->saved_regs = trad_frame_alloc_saved_regs (this_frame); ++ ++ limit_pc = get_frame_pc (this_frame); ++ if (start_pc == 0) ++ start_pc = sw_64_heuristic_proc_start (gdbarch, limit_pc); ++ info->start_pc = start_pc; ++ ++ frame_reg = SW_SP_REGNUM; ++ frame_size = 0; ++ return_reg = -1; ++ ++ /* If we've identified a likely place to start, do code scanning. */ ++ if (start_pc != 0) ++ { ++ /* Limit the forward search to 50 instructions. */ ++ if (start_pc + 200 < limit_pc) ++ limit_pc = start_pc + 200; ++ ++ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += SW_INSN_SIZE) ++ { ++ unsigned int word = sw_64_read_insn (gdbarch, cur_pc); ++ ++ if ((word & 0xffff8000) == 0xfbde8000) /* lda $sp,n($sp) */ ++ { ++ if (word & 0x8000) ++ { ++ /* Consider only the first stack allocation instruction ++ to contain the static size of the frame. */ ++ if (frame_size == 0) ++ frame_size = (-word) & 0xffff; ++ } ++ else ++ { ++ /* Exit loop if a positive stack adjustment is found, which ++ usually means that the stack cleanup code in the function ++ epilogue is reached. */ ++ break; ++ } ++ } ++ else if ((word & 0xfc1f8000) == 0xac1e0000 || (word & 0xfc1f8000) ==0xac0f0000 ) /* stq reg,n($sp) */ ++ { ++ reg = (word & 0x03e00000) >> 21; ++ ++ /* Ignore this instruction if we have already encountered ++ an instruction saving the same register earlier in the ++ function code. The current instruction does not tell ++ us where the original value upon function entry is saved. ++ All it says is that the function we are scanning reused ++ that register for some computation of its own, and is now ++ saving its result. */ ++ if (trad_frame_addr_p(info->saved_regs, reg)) ++ continue; ++ ++ if (reg == 31) ++ continue; ++ ++ /* Do not compute the address where the register was saved yet, ++ because we don't know yet if the offset will need to be ++ relative to $sp or $fp (we can not compute the address ++ relative to $sp if $sp is updated during the execution of ++ the current subroutine, for instance when doing some alloca). ++ So just store the offset for the moment, and compute the ++ address later when we know whether this frame has a frame ++ pointer or not. */ ++ /* Hack: temporarily add one, so that the offset is non-zero ++ and we can tell which registers have save offsets below. */ ++ info->saved_regs[reg].addr = (word & 0xffff) + 1; ++ ++ /* Starting with OSF/1-3.2C, the system libraries are shipped ++ without local symbols, but they still contain procedure ++ descriptors without a symbol reference. GDB is currently ++ unable to find these procedure descriptors and uses ++ heuristic_proc_desc instead. ++ As some low level compiler support routines (__div*, __add*) ++ use a non-standard return address register, we have to ++ add some heuristics to determine the return address register, ++ or stepping over these routines will fail. ++ Usually the return address register is the first register ++ saved on the stack, but assembler optimization might ++ rearrange the register saves. ++ So we recognize only a few registers (t7, t9, ra) within ++ the procedure prologue as valid return address registers. ++ If we encounter a return instruction, we extract the ++ return address register from it. ++ ++ FIXME: Rewriting GDB to access the procedure descriptors, ++ e.g. via the minimal symbol table, might obviate this ++ hack. */ ++ if (return_reg == -1 ++ && cur_pc < (start_pc + 80) ++ && (reg == SW_T7_REGNUM ++ || reg == SW_T9_REGNUM ++ || reg == SW_RA_REGNUM)) ++ return_reg = reg; ++ } ++ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ ++ return_reg = (word >> 16) & 0x1f; ++#ifndef XWB20200903 ++ else if (word == 0x43de074f) /* bis sp,sp,fp */ ++ frame_reg = SW_GCC_FP_REGNUM; ++ else if (word == 0x43fe074f) /* bis zero,sp,fp */ ++ frame_reg = SW_GCC_FP_REGNUM; ++#else ++ else if (word == 0x47de040f) /* bis sp,sp,fp */ ++ frame_reg = SW_GCC_FP_REGNUM; ++ else if (word == 0x47fe040f) /* bis zero,sp,fp */ ++ frame_reg = SW_GCC_FP_REGNUM; ++#endif ++ sw_64_heuristic_analyze_probing_loop (gdbarch, &cur_pc, &frame_size); ++ } ++ ++ /* If we haven't found a valid return address register yet, keep ++ searching in the procedure prologue. */ ++ if (return_reg == -1) ++ { ++ while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80)) ++ { ++ unsigned int word = sw_64_read_insn (gdbarch, cur_pc); ++ ++ ++#ifndef XWB20200903 ++ if ((word & 0xfc1f0000) ==0xac1e0000 /* stl reg,n($sp) */ ++ || (word & 0xfc1f0000) == 0xac0f0000 /* stl reg,n($fp) */ ++ || (word & 0xfc1f0000) == 0xa80f0000 /* stw reg,n($fp) */ ++ || (word & 0xfc1f0000) == 0xa81e0000) /* stw reg,n($sp) */ ++#else ++ if ((word & 0xfc1f0000) == 0xb41e0000) /* stq reg,n($sp) */ ++#endif ++ ++ { ++ reg = (word & 0x03e00000) >> 21; ++ if (reg == SW_T7_REGNUM ++ || reg == SW_T9_REGNUM ++ || reg == SW_RA_REGNUM) ++ { ++ return_reg = reg; ++ break; ++ } ++ } ++#ifndef XWB20200903 ++ else if ((word & 0xffe0ffff) == 0x0be00001) /* ret zero,reg,1 */ ++#else ++ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ ++#endif ++ ++ { ++ return_reg = (word >> 16) & 0x1f; ++ break; ++ } ++ ++ cur_pc += SW_INSN_SIZE; ++ } ++ } ++ } ++ ++ /* Failing that, do default to the customary RA. */ ++ if (return_reg == -1) ++ return_reg = SW_RA_REGNUM; ++ info->return_reg = return_reg; ++ ++ val = get_frame_register_unsigned (this_frame, frame_reg); ++ info->vfp = val + frame_size; ++ ++ /* Convert offsets to absolute addresses. See above about adding ++ one to the offsets to make all detected offsets non-zero. */ ++ for (reg = 0; reg < SW_NUM_REGS; ++reg) ++ if (trad_frame_addr_p(info->saved_regs, reg)) ++ info->saved_regs[reg].addr += val - 1; ++ ++ /* The stack pointer of the previous frame is computed by popping ++ the current stack frame. */ ++ if (!trad_frame_addr_p (info->saved_regs, SW_SP_REGNUM)) ++ trad_frame_set_value (info->saved_regs, SW_SP_REGNUM, info->vfp); ++ ++#ifndef XWB20200903 ++ if (frame_reg != SW_SP_REGNUM ) ++ info->saved_regs[SW_SP_REGNUM].addr = info->saved_regs[frame_reg].addr; ++#endif ++ return info; ++} ++ ++/* Given a GDB frame, determine the address of the calling function's ++ frame. This will be used to create a new GDB frame struct. */ ++ ++static void ++sw_64_heuristic_frame_this_id (struct frame_info *this_frame, ++ void **this_prologue_cache, ++ struct frame_id *this_id) ++{ ++ struct sw_64_heuristic_unwind_cache *info ++ = sw_64_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0); ++ ++ *this_id = frame_id_build (info->vfp, info->start_pc); ++} ++ ++/* Retrieve the value of REGNUM in FRAME. Don't give up! */ ++ ++static struct value * ++sw_64_heuristic_frame_prev_register (struct frame_info *this_frame, ++ void **this_prologue_cache, int regnum) ++{ ++ struct sw_64_heuristic_unwind_cache *info ++ = sw_64_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0); ++ ++ /* The PC of the previous frame is stored in the link register of ++ the current frame. Frob regnum so that we pull the value from ++ the correct place. */ ++ if (regnum == SW_PC_REGNUM) ++ regnum = info->return_reg; ++ ++ return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); ++} ++ ++static const struct frame_unwind sw_64_heuristic_frame_unwind = { ++ NORMAL_FRAME, ++ default_frame_unwind_stop_reason, ++ sw_64_heuristic_frame_this_id, ++ sw_64_heuristic_frame_prev_register, ++ NULL, ++ default_frame_sniffer ++}; ++ ++static CORE_ADDR ++sw_64_heuristic_frame_base_address (struct frame_info *this_frame, ++ void **this_prologue_cache) ++{ ++ struct sw_64_heuristic_unwind_cache *info ++ = sw_64_heuristic_frame_unwind_cache (this_frame, this_prologue_cache, 0); ++ ++ return info->vfp; ++} ++ ++static const struct frame_base sw_64_heuristic_frame_base = { ++ &sw_64_heuristic_frame_unwind, ++ sw_64_heuristic_frame_base_address, ++ sw_64_heuristic_frame_base_address, ++ sw_64_heuristic_frame_base_address ++}; ++ ++/* Just like reinit_frame_cache, but with the right arguments to be ++ callable as an sfunc. Used by the "set heuristic-fence-post" command. */ ++ ++static void ++reinit_frame_cache_sfunc (const char *args, ++ int from_tty, struct cmd_list_element *c) ++{ ++ reinit_frame_cache (); ++} ++ ++/* Helper routines for sw_64*-nat.c files to move register sets to and ++ from core files. The UNIQUE pointer is allowed to be NULL, as most ++ targets don't supply this value in their core files. */ ++ ++void ++sw_64_supply_int_regs (struct regcache *regcache, int regno, ++ const void *r0_r30, const void *pc, const void *unique) ++{ ++ const gdb_byte *regs = (const gdb_byte *) r0_r30; ++ int i; ++ ++ for (i = 0; i < 31; ++i) ++ if (regno == i || regno == -1) ++ regcache->raw_supply (i, regs + i * 8); ++ ++ if (regno == SW_ZERO_REGNUM || regno == -1) ++ { ++ const gdb_byte zero[8] = { 0 }; ++ ++ regcache->raw_supply (SW_ZERO_REGNUM, zero); ++ } ++ ++ if (regno == SW_PC_REGNUM || regno == -1) ++ regcache->raw_supply (SW_PC_REGNUM, pc); ++ ++ if (regno == SW_UNIQUE_REGNUM || regno == -1) ++ regcache->raw_supply (SW_UNIQUE_REGNUM, unique); ++} ++ ++void ++sw_64_fill_int_regs (const struct regcache *regcache, ++ int regno, void *r0_r30, void *pc, void *unique) ++{ ++ gdb_byte *regs = (gdb_byte *) r0_r30; ++ int i; ++ ++ for (i = 0; i < 31; ++i) ++ if (regno == i || regno == -1) ++ regcache->raw_collect (i, regs + i * 8); ++ ++ if (regno == SW_PC_REGNUM || regno == -1) ++ regcache->raw_collect (SW_PC_REGNUM, pc); ++ ++ if (unique && (regno == SW_UNIQUE_REGNUM || regno == -1)) ++ regcache->raw_collect (SW_UNIQUE_REGNUM, unique); ++} ++ ++void ++sw_64_supply_fp_regs (struct regcache *regcache, int regno, ++ const void *f0_f30, const void *fpcr) ++{ ++ const gdb_byte *regs = (const gdb_byte *) f0_f30; ++ int i; ++ ++ for (i = SW_FP0_REGNUM; i < SW_FP0_REGNUM + 31; ++i) ++ if (regno == i || regno == -1) ++ regcache->raw_supply (i, regs + (i - SW_FP0_REGNUM) * 8); ++ ++ if (regno == SW_FPCR_REGNUM || regno == -1) ++ regcache->raw_supply (SW_FPCR_REGNUM, fpcr); ++} ++ ++void ++sw_64_fill_fp_regs (const struct regcache *regcache, ++ int regno, void *f0_f30, void *fpcr) ++{ ++ gdb_byte *regs = (gdb_byte *) f0_f30; ++ int i; ++ ++ for (i = SW_FP0_REGNUM; i < SW_FP0_REGNUM + 31; ++i) ++ if (regno == i || regno == -1) ++ regcache->raw_collect (i, regs + (i - SW_FP0_REGNUM) * 8); ++ ++ if (regno == SW_FPCR_REGNUM || regno == -1) ++ regcache->raw_collect (SW_FPCR_REGNUM, fpcr); ++} ++ ++ ++ ++/* Return nonzero if the G_floating register value in REG is equal to ++ zero for FP control instructions. */ ++ ++static int ++fp_register_zero_p (LONGEST reg) ++{ ++ /* Check that all bits except the sign bit are zero. */ ++ const LONGEST zero_mask = ((LONGEST) 1 << 63) ^ -1; ++ ++ return ((reg & zero_mask) == 0); ++} ++ ++/* Return the value of the sign bit for the G_floating register ++ value held in REG. */ ++ ++static int ++fp_register_sign_bit (LONGEST reg) ++{ ++ const LONGEST sign_mask = (LONGEST) 1 << 63; ++ ++ return ((reg & sign_mask) != 0); ++} ++ ++/* sw_64_software_single_step() is called just before we want to resume ++ the inferior, if we want to single-step it but there is no hardware ++ or kernel single-step support (NetBSD on SW_64, for example). We find ++ the target of the coming instruction and breakpoint it. */ ++ ++static CORE_ADDR ++sw_64_next_pc (struct regcache *regcache, CORE_ADDR pc) ++{ ++ struct gdbarch *gdbarch = regcache->arch (); ++ unsigned int insn; ++ unsigned int op; ++ int regno; ++ int offset; ++ LONGEST rav; ++ ++ insn = sw_64_read_insn (gdbarch, pc); ++ ++ /* Opcode is top 6 bits. */ ++ op = (insn >> 26) & 0x3f; ++ ++#if 1 ++ ++ switch (op) { ++ case 0x1: ++ case 0x2: ++ case 0x3: ++ return (regcache_raw_get_unsigned (regcache, (insn >> 16) & 0x1f) & ~3); ++ case 0x4: /* BR */ ++ case 0x5: /* BSR */ ++#else ++ if (op == 0x1a) ++ { ++ /* Jump format: target PC is: ++ RB & ~3 */ ++ return (regcache_raw_get_unsigned (regcache, (insn >> 16) & 0x1f) & ~3); ++ } ++ ++ if ((op & 0x30) == 0x30) ++ { ++ /* Branch format: target PC is: ++ (new PC) + (4 * sext(displacement)) */ ++ if (op == 0x30 /* BR */ ++ || op == 0x34) /* BSR */ ++ { ++#endif ++ ++branch_taken: ++ offset = (insn & 0x001fffff); ++ if (offset & 0x00100000) ++ offset |= 0xffe00000; ++ offset *= SW_INSN_SIZE; ++ return (pc + SW_INSN_SIZE + offset); ++ } ++#ifndef XWB20200903 ++ if ((op & 0x30) == 0x30){ ++#endif ++ regno = (insn >> 21) & 0x1f; ++ switch (op) ++ { ++ case 0x38: /* FBEQ */ ++ case 0x39: /* FBGE */ ++ case 0x3a: /* FBGT */ ++ case 0x3b: /* FBLE */ ++ case 0x3c: /* FBLT */ ++ case 0x3d: /* FBNE */ ++ regno += gdbarch_fp0_regnum (gdbarch); ++ } ++ ++ rav = regcache_raw_get_signed (regcache, regno); ++ switch (op) ++ { ++ case 0x36: /* BLBC */ ++ if ((rav & 1) == 0) ++ goto branch_taken; ++ break; ++ case 0x37: /* BLBS */ ++ if (rav & 1) ++ goto branch_taken; ++ break; ++ case 0x30: /* BEQ */ ++ if (rav == 0) ++ goto branch_taken; ++ break; ++ case 0x31: /* BNE */ ++ if (rav != 0) ++ goto branch_taken; ++ break; ++ case 0x32: /* BLT */ ++ if (rav < 0) ++ goto branch_taken; ++ break; ++ case 0x33: /* BLE */ ++ if (rav <= 0) ++ goto branch_taken; ++ break; ++ case 0x34: /* BGT */ ++ if (rav > 0) ++ goto branch_taken; ++ break; ++ case 0x35: /* BGE */ ++ if (rav >= 0) ++ goto branch_taken; ++ break; ++ ++ /* Floating point branches. */ ++ ++ case 0x38: /* FBEQ */ ++ if (fp_register_zero_p (rav)) ++ goto branch_taken; ++ break; ++ case 0x3d: /* FBGE */ ++ if (fp_register_sign_bit (rav) == 0 || fp_register_zero_p (rav)) ++ goto branch_taken; ++ break; ++ case 0x3c: /* FBGT */ ++ if (fp_register_sign_bit (rav) == 0 && ! fp_register_zero_p (rav)) ++ goto branch_taken; ++ break; ++ case 0x3b: /* FBLE */ ++ if (fp_register_sign_bit (rav) == 1 || fp_register_zero_p (rav)) ++ goto branch_taken; ++ break; ++ case 0x3a: /* FBLT */ ++ if (fp_register_sign_bit (rav) == 1 && ! fp_register_zero_p (rav)) ++ goto branch_taken; ++ break; ++ case 0x39: /* FBNE */ ++#ifndef LHX20201026 ++ if (! fp_register_zero_p (rav)) ++#else ++ if ( fp_register_zero_p (rav)) ++#endif ++ goto branch_taken; ++ break; ++ } ++#ifndef _SW64_ ++ } ++#endif ++ ++ /* Not a branch or branch not taken; target PC is: ++ pc + 4 */ ++ return (pc + SW_INSN_SIZE); ++ ++} ++ ++ ++std::vector ++sw_64_software_single_step (struct regcache *regcache) ++{ ++ struct gdbarch *gdbarch = regcache->arch (); ++ ++ CORE_ADDR pc = regcache_read_pc (regcache); ++ ++ std::vector next_pcs ++ = sw_64_deal_with_atomic_sequence (gdbarch, pc); ++ if (!next_pcs.empty ()) ++ return next_pcs; ++ ++ CORE_ADDR next_pc = sw_64_next_pc (regcache, pc); ++ return {next_pc}; ++} ++ ++ ++/* Initialize the current architecture based on INFO. If possible, re-use an ++ architecture from ARCHES, which is a list of architectures already created ++ during this debugging session. ++ ++ Called e.g. at program startup, when reading a core file, and when reading ++ a binary file. */ ++ ++static struct gdbarch * ++sw_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) ++{ ++ struct gdbarch_tdep *tdep; ++ struct gdbarch *gdbarch; ++ ++ /* Find a candidate among extant architectures. */ ++ arches = gdbarch_list_lookup_by_info (arches, &info); ++ if (arches != NULL) ++ return arches->gdbarch; ++ ++ tdep = XCNEW (struct gdbarch_tdep); ++ gdbarch = gdbarch_alloc (&info, tdep); ++ ++ /* Lowest text address. This is used by heuristic_proc_start() ++ to decide when to stop looking. */ ++ tdep->vm_min_address = (CORE_ADDR) 0x120000000LL; ++ ++ tdep->dynamic_sigtramp_offset = NULL; ++ tdep->sigcontext_addr = NULL; ++ tdep->sc_pc_offset = 2 * 8; ++ tdep->sc_regs_offset = 4 * 8; ++ tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8; ++ ++ tdep->jb_pc = -1; /* longjmp support not enabled by default. */ ++ ++ tdep->return_in_memory = sw_64_return_in_memory_always; ++ ++ /* Type sizes */ ++ set_gdbarch_short_bit (gdbarch, 16); ++ set_gdbarch_int_bit (gdbarch, 32); ++ set_gdbarch_long_bit (gdbarch, 64); ++ set_gdbarch_long_long_bit (gdbarch, 64); ++ set_gdbarch_wchar_bit (gdbarch, 64); ++ set_gdbarch_wchar_signed (gdbarch, 0); ++ set_gdbarch_float_bit (gdbarch, 32); ++ set_gdbarch_double_bit (gdbarch, 64); ++ set_gdbarch_long_double_bit (gdbarch, 64); ++ set_gdbarch_ptr_bit (gdbarch, 64); ++ ++ /* Register info */ ++ set_gdbarch_num_regs (gdbarch, SW_NUM_REGS); ++ set_gdbarch_sp_regnum (gdbarch, SW_SP_REGNUM); ++ set_gdbarch_pc_regnum (gdbarch, SW_PC_REGNUM); ++ set_gdbarch_fp0_regnum (gdbarch, SW_FP0_REGNUM); ++ ++ set_gdbarch_register_name (gdbarch, sw_64_register_name); ++ set_gdbarch_register_type (gdbarch, sw_64_register_type); ++ ++ set_gdbarch_cannot_fetch_register (gdbarch, sw_64_cannot_fetch_register); ++ set_gdbarch_cannot_store_register (gdbarch, sw_64_cannot_store_register); ++ ++ set_gdbarch_convert_register_p (gdbarch, sw_64_convert_register_p); ++ set_gdbarch_register_to_value (gdbarch, sw_64_register_to_value); ++ set_gdbarch_value_to_register (gdbarch, sw_64_value_to_register); ++ ++ set_gdbarch_register_reggroup_p (gdbarch, sw_64_register_reggroup_p); ++ ++ /* Prologue heuristics. */ ++ set_gdbarch_skip_prologue (gdbarch, sw_64_skip_prologue); ++#ifndef _SW64_ //2017-11 ++ set_gdbarch_skip_entrypoint (gdbarch, sw_64_skip_prologue); ++#endif ++ ++ ++ //set_gdbarch_skip_entrypoint (gdbarch, sw_64_skip_prologue); ++ set_gdbarch_num_pseudo_regs (gdbarch, NVEC_REGS); ++ set_gdbarch_pseudo_register_read (gdbarch, sw_64_vec_register_read); ++ set_gdbarch_pseudo_register_write (gdbarch, sw_64_vec_register_write); ++ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); //2012 ++ /* Call info. */ ++ ++ set_gdbarch_return_value (gdbarch, sw_64_return_value); ++ ++ /* Settings for calling functions in the inferior. */ ++ set_gdbarch_push_dummy_call (gdbarch, sw_64_push_dummy_call); ++ ++ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); ++ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); ++ ++#ifndef XWB20200903 ++ set_gdbarch_skip_permanent_breakpoint (gdbarch, sw_64_skip_permanent_breakpoint); ++#endif ++ set_gdbarch_breakpoint_kind_from_pc (gdbarch, ++ sw_64_breakpoint::kind_from_pc); ++ set_gdbarch_sw_breakpoint_from_kind (gdbarch, ++ sw_64_breakpoint::bp_from_kind); ++ set_gdbarch_decr_pc_after_break (gdbarch, SW_INSN_SIZE); ++ set_gdbarch_cannot_step_breakpoint (gdbarch, 1); ++#ifndef _SW64_ ++ tdep->sw_64_vec_type = 0; ++ //tdep->slave_vec_type = 0; ++ ++ set_gdbarch_num_pseudo_regs (gdbarch, NVEC_REGS); ++ set_gdbarch_pseudo_register_read (gdbarch, sw_64_vec_register_read); ++ set_gdbarch_pseudo_register_write (gdbarch, sw_64_vec_register_write); ++ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); //2012 ++#endif ++ /* Handles single stepping of atomic sequences. */ ++ set_gdbarch_software_single_step (gdbarch, sw_64_software_single_step); ++ ++ /* Hook in ABI-specific overrides, if they have been registered. */ ++ gdbarch_init_osabi (info, gdbarch); ++ ++ /* Now that we have tuned the configuration, set a few final things ++ based on what the OS ABI has told us. */ ++ ++ if (tdep->jb_pc >= 0) ++ set_gdbarch_get_longjmp_target (gdbarch, sw_64_get_longjmp_target); ++ ++ frame_unwind_append_unwinder (gdbarch, &sw_64_sigtramp_frame_unwind); ++ frame_unwind_append_unwinder (gdbarch, &sw_64_heuristic_frame_unwind); ++ ++ frame_base_set_default (gdbarch, &sw_64_heuristic_frame_base); ++ ++ return gdbarch; ++} ++/* SW_64 process record-replay related structures, defines etc. */ ++ ++#define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \ ++ do \ ++ { \ ++ unsigned int reg_len = LENGTH; \ ++ if (reg_len) \ ++ { \ ++ REGS = XNEWVEC (uint32_t, reg_len); \ ++ memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \ ++ } \ ++ } \ ++ while (0) ++ ++ ++#define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \ ++ do \ ++ { \ ++ unsigned int mem_len = LENGTH; \ ++ if (mem_len) \ ++ { \ ++ MEMS = XNEWVEC (struct sw_64_mem_r, mem_len); \ ++ memcpy(&MEMS->len, &RECORD_BUF[0], \ ++ sizeof(struct sw_64_mem_r) * LENGTH); \ ++ } \ ++ } \ ++ while (0) ++void ++sw_64_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) ++{ ++ dwarf2_append_unwinders (gdbarch); ++ frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); ++} ++ ++extern initialize_file_ftype _initialize_sw_64_tdep; /* -Wmissing-prototypes */ ++ ++void _initialize_sw_64_tdep (); ++void ++_initialize_sw_64_tdep () ++{ ++ ++ gdbarch_register (bfd_arch_sw_64, sw_64_gdbarch_init, NULL); ++ ++ /* Let the user set the fence post for heuristic_proc_start. */ ++ ++ /* We really would like to have both "0" and "unlimited" work, but ++ command.c doesn't deal with that. So make it a var_zinteger ++ because the user can always use "999999" or some such for unlimited. */ ++ /* We need to throw away the frame cache when we set this, since it ++ might change our ability to get backtraces. */ ++ add_setshow_zinteger_cmd ("heuristic-fence-post", class_support, ++ &heuristic_fence_post, _("\ ++Set the distance searched for the start of a function."), _("\ ++Show the distance searched for the start of a function."), _("\ ++If you are debugging a stripped executable, GDB needs to search through the\n\ ++program for the start of a function. This command sets the distance of the\n\ ++search. The only need to set it is when debugging a stripped executable."), ++ reinit_frame_cache_sfunc, ++ NULL, /* FIXME: i18n: The distance searched for ++ the start of a function is \"%d\". */ ++ &setlist, &showlist); ++} ++ ++struct sw_64_mem_r ++{ ++ uint64_t len; /* Record length. */ ++ uint64_t addr; /* Memory address. */ ++}; ++ ++typedef struct insn_decode_record_t ++{ ++ struct gdbarch *gdbarch; ++ struct regcache *regcache; ++ CORE_ADDR this_addr; /* Address of insn to be recorded. */ ++ uint32_t sw_64_insn; /* Insn to be recorded. */ ++ uint32_t mem_rec_count; /* Count of memory records. */ ++ uint32_t reg_rec_count; /* Count of register records. */ ++ uint32_t *sw_64_regs; /* Registers to be recorded. */ ++ struct sw_64_mem_r *sw_64_mems; /* Memory locations to be recorded. */ ++} insn_decode_record; ++ ++unsigned int ++sw_64_record_data_proc_reg (insn_decode_record *sw_64_insn_r) ++{ ++ uint8_t insn_bits21_25; ++ insn_bits21_25 = (rigg (sw_64_insn_r->sw_64_insn, 21) & 0x1F); ++ uint8_t ins_bits5_12; ++ ins_bits5_12 = (rigg(sw_64_insn_r->sw_64_insn,5) & 0xff); ++ uint32_t ins_bit31_26; ++ ins_bit31_26 = rigg (sw_64_insn_r->sw_64_insn,26); ++ uint8_t ins_bits0_4; ++ ins_bits0_4 = (sw_64_insn_r->sw_64_insn & 0x1F); ++ uint32_t record_buf[4]; ++ record_buf[0] = ins_bits0_4; ++ if(ins_bit31_26 == 0x18) ++ { ++ if(ins_bits5_12 == 0x50) ++ { ++ record_buf[0] = insn_bits21_25+31; ++ } ++ else if(ins_bits5_12 == 0x51 || (0x54 <= ins_bits5_12 && ins_bits5_12 <= 0x57)) ++ { ++ record_buf[0] = SW_FPCR_REGNUM; ++ } ++ else ++ { ++ record_buf[0] = ins_bits0_4+32; ++ } ++ } ++ if(0x14 <= ins_bit31_26 && ins_bit31_26<= 0x17) ++ { ++ record_buf[0] = ins_bits0_4;//+167; ++ } ++ if(ins_bit31_26 == 0x1a) ++ { ++ if(ins_bits5_12 == 0x2 || ins_bits5_12 == 0x22 || ins_bits5_12 == 0x18 || ins_bits5_12 == 0x19) ++ { ++ record_buf[0] = ins_bits0_4+32; ++ } ++ else ++ { ++ record_buf[0] = ins_bits0_4;//+167; ++ } ++ } ++ if(ins_bit31_26 == 0x1b) ++ { ++ if(ins_bits5_12 == 0x22 || ins_bits5_12 == 0x23) ++ { ++ record_buf[0] = ins_bits0_4+32; ++ } ++ record_buf[0] = ins_bits0_4;//+167; ++ } ++ sw_64_insn_r->reg_rec_count = 1; ++ REG_ALLOC (sw_64_insn_r->sw_64_regs, sw_64_insn_r->reg_rec_count,record_buf); ++ return SW_64_RECORD_SUCCESS; ++} ++ ++static unsigned int ++sw_64_record_data_proc_imm (insn_decode_record *sw_64_insn_r) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (sw_64_insn_r->gdbarch); ++ int ret; ++ if(sw_64_insn_r->sw_64_insn == 0x200009e) ++ { ++ for(int i=0;i<32;i++) ++ { ++ record_full_arch_list_add_reg(sw_64_insn_r->regcache,i); ++ } ++ return SW_64_RECORD_SUCCESS; ++ } ++ if (tdep->sw_64_syscall_record != NULL) ++ { ++ ret=tdep->sw_64_syscall_record (sw_64_insn_r->regcache); ++ ++ } ++ else ++ printf_unfiltered (_("Process record does not support instruction syscall.\n")); ++ if (ret==0) ++ return ret; ++ else ++ return SW_64_RECORD_UNSUPPORTED; ++} ++ ++static unsigned int ++sw_64_record_branch_except_sys (insn_decode_record *sw_64_insn_r) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (sw_64_insn_r->gdbarch); ++ uint32_t ins_bit31_26; ++ ins_bit31_26 = rigg (sw_64_insn_r->sw_64_insn, 26); ++ uint32_t record_buf[4]; ++ uint8_t insn_bits21_25; ++ insn_bits21_25 = (rigg (sw_64_insn_r->sw_64_insn, 21) & 0x1F); ++ /*Test & branch*/ ++ if (0x30 <= ins_bit31_26 && ins_bit31_26<= 0x3D) ++ { ++ record_buf[sw_64_insn_r->reg_rec_count++] = SW_PC_REGNUM; ++ } ++ else ++ { record_buf[sw_64_insn_r->reg_rec_count++] = SW_PC_REGNUM; ++ record_buf[sw_64_insn_r->reg_rec_count++] = insn_bits21_25; ++ } ++ REG_ALLOC (sw_64_insn_r->sw_64_regs, sw_64_insn_r->reg_rec_count, ++ record_buf); ++ return SW_64_RECORD_SUCCESS; ++} ++ ++static unsigned int ++sw_64_record_load_store (insn_decode_record *sw_64_insn_r) ++{ ++ uint8_t bit12; ++ bit12=bit(sw_64_insn_r->sw_64_insn, 12); ++ uint8_t insn_bits12_15; ++ insn_bits12_15=(rigg(sw_64_insn_r->sw_64_insn, 12) & 0x1f); ++ uint8_t insn_bits21_25; ++ uint8_t insn_bits16_20; ++ uint8_t insn_bits8_15; ++ insn_bits8_15 = (rigg(sw_64_insn_r->sw_64_insn, 8) & 0xff); ++ uint32_t ins_bit31_26; ++ ins_bit31_26 = rigg (sw_64_insn_r->sw_64_insn, 26); ++ insn_bits16_20 = (rigg(sw_64_insn_r->sw_64_insn, 16) & 0x1f); ++ uint8_t insn_bit0_16; ++ insn_bit0_16=(sw_64_insn_r->sw_64_insn & 0xffff); ++ uint32_t record_buf[8]; ++ uint64_t record_buf_mem[8]; ++ CORE_ADDR address; ++ int save_size; ++ insn_bits21_25 = (rigg (sw_64_insn_r->sw_64_insn, 21) & 0x1F);// ++ int Byte4_len; ++ int disp15,disp11; ++ disp15 = sw_64_insn_r->sw_64_insn & 0xffff; ++ disp11 = sw_64_insn_r->sw_64_insn & 0xfff; ++ if(sw_64_insn_r->sw_64_insn & 0x8000) ++ { ++ disp15 |= 0xffff0000; ++ } ++ if(sw_64_insn_r->sw_64_insn & 0x800) ++ { ++ disp11 |= 0xfffff000; ++ } ++ /*load imme , transfer*/ ++ if ((0x3E <= ins_bit31_26 && ins_bit31_26<= 0x3F) || ins_bit31_26 ==0x07 || ins_bit31_26 == 0x25) ++ { ++ if (record_debug) ++ debug_printf ("Process record: load register (literal)\n"); ++ record_buf[0] = insn_bits21_25; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ else if((0x09 <= ins_bit31_26 && ins_bit31_26<= 0x0F) || ins_bit31_26 == 0x1C)//simd save and load ++ { ++ if(0x09 <= ins_bit31_26 && ins_bit31_26<= 0x0D) ++ { ++ record_buf[0] = insn_bits21_25;//+167; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ if(0x0E == ins_bit31_26 || ins_bit31_26 == 0x0F || ins_bit31_26 == 0x1C) ++ { ++ if(ins_bit31_26 == 0x1C && insn_bits12_15 == 0xe) ++ { ++ regcache_raw_read_unsigned (sw_64_insn_r->regcache, insn_bits16_20, ++ &address); ++ address+=disp11; ++ record_buf_mem[0] = 32; ++ record_buf_mem[1] = address; ++ sw_64_insn_r->mem_rec_count = 1; ++ } ++ regcache_raw_read_unsigned (sw_64_insn_r->regcache, insn_bits16_20, ++ &address); ++ if(ins_bit31_26 == 0xe && ins_bit31_26 == 0xf) ++ { ++ address+=disp15; ++ } ++ address+=(sw_64_insn_r->sw_64_insn & 0xfff); ++ if(ins_bit31_26 == 0x1C) ++ { ++ switch(insn_bits12_15) ++ { ++ case 0x9: ++ case 0x8: ++ case 0x1: ++ Byte4_len = ((address & 0x1f) >> 2); ++ address=address & 0xffffffffffffffe0; ++ break; ++ case 0xb: ++ case 0xa: ++ case 0x3: ++ Byte4_len = ((address & 0xf) >> 2); ++ address=address & 0xfffffffffffffff0; ++ break; ++ case 0xf: ++ save_size=32; ++ break; ++ case 0xd: ++ case 0xc: ++ case 0x5: ++ Byte4_len = ((address & 0x1f) >> 3); ++ address=address & 0xffffffffffffffe0; ++ break; ++ default: ++ goto simdsave; ++ break; ++ } ++ } ++ switch(ins_bit31_26) ++ { ++ case 0x0e: ++ save_size=16; ++ break; ++ case 0xf: ++ save_size=32; ++ break; ++ case 0x1C: ++ switch(insn_bits12_15) ++ { ++ case 0x01: ++ save_size=32; ++ break; ++ case 0x03: ++ case 0x05: ++ save_size=16; ++ break; ++ case 0x8: ++ save_size=32-4*Byte4_len; ++ address+=Byte4_len*4; ++ break; ++ case 0xf: ++ save_size=32; ++ break; ++ case 0xc: ++ case 0xA: ++ save_size=4*(4-Byte4_len); ++ address+=Byte4_len*4; ++ break; ++ case 0xB: ++ case 0x9: ++ case 0xd: ++ if(Byte4_len == 0) ++ { ++ return SW_64_RECORD_UNSUPPORTED; ++ } ++ else ++ { ++ save_size = Byte4_len*4; ++ } ++ break; ++ default: ++ goto simdsave; ++ break; ++ } ++ default: ++ return SW_64_RECORD_UNSUPPORTED; ++ } ++ record_buf_mem[0] = save_size; ++ record_buf_mem[1] = address; ++ sw_64_insn_r->mem_rec_count = 1; ++ } ++ } ++ else if(0x01 <= ins_bit31_26 && ins_bit31_26<= 0x03) ++ { ++ record_buf[sw_64_insn_r->reg_rec_count++] = SW_PC_REGNUM; ++ record_buf[sw_64_insn_r->reg_rec_count++] = insn_bits21_25; ++ goto log; ++ } ++ else if(ins_bit31_26 == 0x06 || ins_bit31_26 == 0x08 || ins_bit31_26 == 0x2D)//misc ++ { ++ if(ins_bit31_26 == 0x06 && (insn_bits8_15 == 0xff || insn_bits8_15 == 0xfe)) ++ { ++ if(insn_bits8_15 == 0xff) ++ { ++ record_buf[0] = SW_CSR_REGNUM; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ else ++ { ++ record_buf[0] = insn_bits21_25; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ } ++ if(ins_bit31_26 == 0x08 && insn_bits12_15 == 0xc) ++ { ++ record_buf[0] = insn_bits21_25+32; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ if(insn_bit0_16 == 0x20 || insn_bit0_16 == 0x40 || insn_bit0_16 == 0x1040) ++ { ++ record_buf[0] = insn_bits21_25; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ if((ins_bit31_26 == 0x2D) || (ins_bit31_26 == 0x08 && ((0x2 <=insn_bits12_15 && insn_bits12_15 <= 0x7) || (0xd <=insn_bits12_15 && insn_bits12_15 <= 0xf)))) ++ { ++ switch(insn_bits12_15) ++ { ++ case 0x2: ++ case 0x4: ++ case 0x6: ++ case 0xd: ++ save_size=4; ++ break; ++ case 0x3: ++ case 0x5: ++ case 0x7: ++ case 0xe: ++ case 0xf: ++ save_size=8; ++ break; ++ } ++ if(bit12 == 0) ++ { ++ save_size=4; ++ } ++ else ++ { ++ save_size=8; ++ } ++ regcache_raw_read_unsigned (sw_64_insn_r->regcache, insn_bits16_20, ++ &address); ++ address+=disp11; ++ record_buf_mem[0] = save_size; ++ record_buf_mem[1] = address; ++ sw_64_insn_r->mem_rec_count = 1; ++ } ++ } ++ else if(ins_bit31_26 == 0x26 || ins_bit31_26 == 0x27)//float save ++ { ++ record_buf[0] = insn_bits21_25+32; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ else ++ { ++ if (record_debug) ++ debug_printf ("Process record: load/store exclusive\n"); ++ ++ if (0x20 <= ins_bit31_26 && ins_bit31_26<= 0x24) ++ { ++ record_buf[0] = insn_bits21_25; ++ sw_64_insn_r->reg_rec_count = 1; ++ } ++ else ++ { ++ switch(ins_bit31_26) ++ { ++ case 0x28: ++ save_size=1; ++ break; ++ case 0x29: ++ save_size=2; ++ break; ++ case 0x2A: ++ case 0x2E: ++ save_size=4; ++ break; ++ case 0x2B: ++ case 0x2F: ++ case 0x24: ++ save_size=8; ++ break; ++ } ++ regcache_raw_read_unsigned (sw_64_insn_r->regcache, insn_bits16_20, ++ &address); ++ address+=disp15; ++ switch(ins_bit31_26) ++ { ++ case 0x24: ++ address&=0xfffffffffffffff8; ++ } ++ record_buf_mem[0] = save_size; ++ record_buf_mem[1] = address; ++ sw_64_insn_r->mem_rec_count = 1; ++ } ++ } ++simdsave: ++ record_buf[0] = insn_bits21_25;//+167; ++ sw_64_insn_r->reg_rec_count = 1; ++log: ++ MEM_ALLOC (sw_64_insn_r->sw_64_mems, sw_64_insn_r->mem_rec_count, ++ record_buf_mem); ++ REG_ALLOC (sw_64_insn_r->sw_64_regs, sw_64_insn_r->reg_rec_count, ++ record_buf); ++ return SW_64_RECORD_SUCCESS; ++} ++ ++static unsigned int ++sw_64_record_data_proc_simd_fp (insn_decode_record *sw_64_insn_r) ++{ ++ uint8_t ins_bits0_4; ++ ins_bits0_4 = (sw_64_insn_r->sw_64_insn & 0x1F); ++ uint32_t record_buf[4]; ++ record_buf[0] = ins_bits0_4; ++ sw_64_insn_r->reg_rec_count = 1; ++ REG_ALLOC (sw_64_insn_r->sw_64_regs, sw_64_insn_r->reg_rec_count,record_buf); ++ return SW_64_RECORD_SUCCESS; ++} ++ ++/* Decodes insns type and invokes its record handler. */ ++static unsigned int ++sw_64_record_decode_insn_handler (insn_decode_record *sw_64_insn_r) ++{ ++ uint32_t ins_bit31_26; ++ ins_bit31_26 = rigg (sw_64_insn_r->sw_64_insn, 26); ++ /*five differrent instruction format*/ ++/* system format. */ ++ if (ins_bit31_26 == 0) ++ return sw_64_record_data_proc_imm (sw_64_insn_r); ++ ++ /* transfer format */ ++ if (ins_bit31_26 == 0x04 || ins_bit31_26 == 0x05 || (0x30 <= ins_bit31_26 && ins_bit31_26<= 0x3D)) ++ return sw_64_record_branch_except_sys (sw_64_insn_r); ++ ++ /* Load and store format. */ ++ if ((0x01 <= ins_bit31_26 && ins_bit31_26<= 0x03)/*jump*/|| (0x28 <= ins_bit31_26 && ins_bit31_26<= 0x2C)//save and load ++ || (0x20 <= ins_bit31_26 && ins_bit31_26<= 0x24) ++ || (ins_bit31_26 == 0x25)//PRI_LD ++ || (0x26 <= ins_bit31_26 && ins_bit31_26<= 0x27) ++ || (0x2D == ins_bit31_26)//PRI_ST ++ || (0x2E <= ins_bit31_26 && ins_bit31_26<= 0x2F) ++ || (0x3E <= ins_bit31_26 && ins_bit31_26<= 0x3F)//load immedia ++ || (ins_bit31_26 == 0x06)//PRI_RWCSR ++ || (ins_bit31_26 == 0x07)//PRI_RET:W ++ || (ins_bit31_26 == 0x08)//misc ++ || (0x09 <= ins_bit31_26 && ins_bit31_26<= 0x0F)//simd load and save ++ || (ins_bit31_26 == 0x1c)) ++ return sw_64_record_load_store (sw_64_insn_r); ++ ++ /* simple calculate format */ ++ if (ins_bit31_26 == 0x10 || ins_bit31_26 == 0x12//integer calculate ++ || ins_bit31_26 == 0x18//float calculate ++ || ins_bit31_26 == 0x1A//integer or float simd calculate ++ || (0x14 <= ins_bit31_26 && ins_bit31_26<= 0x17))//reconfig ++ return sw_64_record_data_proc_reg (sw_64_insn_r); ++ ++ /* combination calculate format */ ++ if (ins_bit31_26 == 0x1B || ins_bit31_26 == 0x19 || ins_bit31_26 == 0x11 || ins_bit31_26 == 0x13) ++ return sw_64_record_data_proc_simd_fp (sw_64_insn_r); ++ ++ return SW_64_RECORD_UNSUPPORTED; ++} ++ ++static void ++deallocate_reg_mem (insn_decode_record *record) ++{ ++ xfree (record->sw_64_regs); ++ xfree (record->sw_64_mems); ++} ++ ++int ++sw_64_process_record (struct gdbarch *gdbarch, struct regcache *regcache, ++ CORE_ADDR insn_addr) ++{ ++ uint32_t rec_no = 0; ++ uint8_t insn_size = 4; ++ uint32_t ret = 0; ++ gdb_byte buf[insn_size]; ++ insn_decode_record sw_64_record; ++ ++ memset (&buf[0], 0, insn_size); ++ memset (&sw_64_record, 0, sizeof (insn_decode_record)); ++ target_read_memory (insn_addr, &buf[0], insn_size); ++ sw_64_record.sw_64_insn ++ = (uint32_t) extract_unsigned_integer (&buf[0], ++ insn_size, ++ gdbarch_byte_order (gdbarch)); ++ sw_64_record.regcache = regcache; ++ sw_64_record.this_addr = insn_addr; ++ sw_64_record.gdbarch = gdbarch; ++ ++ ret = sw_64_record_decode_insn_handler (&sw_64_record); ++ if (ret == SW_64_RECORD_UNSUPPORTED) ++ { ++ printf_unfiltered (_("Process record does not support instruction " ++ "0x%0x at address %s.\n"), ++ sw_64_record.sw_64_insn, ++ paddress (gdbarch, insn_addr)); ++ ret = -1; ++ } ++ ++ if (0 == ret) ++ { ++ /* Record registers. */ ++ record_full_arch_list_add_reg (sw_64_record.regcache, ++ SW_PC_REGNUM); ++ /* Always record register CPSR. */ ++ record_full_arch_list_add_reg (sw_64_record.regcache, ++ SW_CSR_REGNUM); ++ if (sw_64_record.sw_64_regs) ++ for (rec_no = 0; rec_no < sw_64_record.reg_rec_count; rec_no++) ++ if (record_full_arch_list_add_reg (sw_64_record.regcache, ++ sw_64_record.sw_64_regs[rec_no])) ++ ret = -1; ++ ++ /* Record memories. */ ++ if (sw_64_record.sw_64_mems) ++ for (rec_no = 0; rec_no < sw_64_record.mem_rec_count; rec_no++) ++ if (record_full_arch_list_add_mem ++ ((CORE_ADDR)sw_64_record.sw_64_mems[rec_no].addr, ++ sw_64_record.sw_64_mems[rec_no].len)) ++ ret = -1; ++ ++ if (record_full_arch_list_add_end ()) ++ ret = -1; ++ } ++ ++ deallocate_reg_mem (&sw_64_record); ++ return ret; ++} +diff -Nuar gdb-10.2/gdb/sw_64-tdep.h gdb-10.2/gdb/sw_64-tdep.h +--- gdb-10.2/gdb/sw_64-tdep.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/sw_64-tdep.h 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,174 @@ ++/* Common target dependent code for GDB on SW_64 systems. ++ Copyright (C) 1993-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef SW_64_TDEP_H ++#define SW_64_TDEP_H ++ ++struct regcache; ++ ++/* Say how long (ordinary) registers are. This is a piece of bogosity ++ used in push_word and a few other places; register_size() is the ++ real way to know how big a register is. */ ++#define SW_REGISTER_SIZE 8 ++ ++/* Number of machine registers. */ ++#ifndef LHX20201026 ++#define SW_NUM_REGS 167 ++#else ++#define SW_NUM_REGS 165 ++#endif ++ ++/* Register numbers of various important registers. Note that most of ++ these values are "real" register numbers, and correspond to the ++ general registers of the machine. */ ++enum sw_64_regnum{ ++ SW_V0_REGNUM, ++ SW_T7_REGNUM=8, ++ SW_S0_REGNUM=9, ++ SW_GCC_FP_REGNUM=15, ++ SW_A0_REGNUM=16, ++ SW_T9_REGNUM=23, ++ SW_RA_REGNUM=26, ++ SW_T12_REGNUM, ++ SW_GP_REGNUM=29, ++ SW_SP_REGNUM, ++ SW_ZERO_REGNUM, ++ SW_FP0_REGNUM, ++ SW_FPA0_REGNUM=48, ++ SW_FPCR_REGNUM=63, ++ SW_UNIQUE_REGNUM=66 ++}; ++//#define SW_V0_REGNUM 0 /* Function integer return value */ ++#define SW_T7_REGNUM 8 /* Return address register for OSF/1 __add* */ ++#define SW_S0_REGNUM 9 /* First saved register */ ++#define SW_GCC_FP_REGNUM 15 /* Used by gcc as frame register */ ++#define SW_A0_REGNUM 16 /* Loc of first arg during a subr call */ ++#define SW_T9_REGNUM 23 /* Return address register for OSF/1 __div* */ ++#define SW_RA_REGNUM 26 /* Contains return address value */ ++#define SW_T12_REGNUM 27 /* Contains start addr of current proc */ ++#define SW_GP_REGNUM 29 /* Contains the global pointer */ ++#define SW_SP_REGNUM 30 /* Contains address of top of stack */ ++#define SW_ZERO_REGNUM 31 /* Read-only register, always 0 */ ++#define SW_FP0_REGNUM 32 /* Floating point register 0 */ ++#define SW_FPA0_REGNUM 48 /* First float arg during a subr call */ ++#define SW_FPCR_REGNUM 63 /* Floating point control register */ ++#define SW_PC_REGNUM 64 /* Contains program counter */ ++#define SW_UNIQUE_REGNUM 66 /* PAL_rduniq value */ ++#define SW_CSR_REGNUM 66 /* Current Program Status Register. *///rewrite ++ ++#ifndef LHX20201026 ++ #define SW2_V0F1_REGNUM 67 ++ #define SW2_V0F2_REGNUM 99 ++ #define SW2_V0F3_REGNUM 131 ++ #define SW2_V0_REGNUM 167 ++#endif ++ ++/* Instruction size. */ ++#define SW_INSN_SIZE 4 ++ ++/* The sw_64 has two different virtual pointers for arguments and locals. ++ ++ The virtual argument pointer is pointing to the bottom of the argument ++ transfer area, which is located immediately below the virtual frame ++ pointer. Its size is fixed for the native compiler, it is either zero ++ (for the no arguments case) or large enough to hold all argument registers. ++ gcc uses a variable sized argument transfer area. As it has ++ to stay compatible with the native debugging tools it has to use the same ++ virtual argument pointer and adjust the argument offsets accordingly. ++ ++ The virtual local pointer is localoff bytes below the virtual frame ++ pointer, the value of localoff is obtained from the PDR. */ ++#define SW_NUM_ARG_REGS 6 ++ ++/* Target-dependent structure in gdbarch. */ ++struct gdbarch_tdep ++{ ++ CORE_ADDR vm_min_address; /* Used by sw_64_heuristic_proc_start. */ ++ ++ /* If PC is inside a dynamically-generated signal trampoline function ++ (i.e. one copied onto the user stack at run-time), return how many ++ bytes PC is beyond the start of that function. Otherwise, return -1. */ ++ LONGEST (*dynamic_sigtramp_offset) (struct gdbarch *, CORE_ADDR); ++ ++ /* Translate a signal handler stack base address into the address of ++ the sigcontext structure for that signal handler. */ ++ CORE_ADDR (*sigcontext_addr) (struct frame_info *); ++ ++ /* Does the PC fall in a signal trampoline. */ ++ /* NOTE: cagney/2004-04-30: Do not copy/clone this code. Instead ++ look at tramp-frame.h and other simplier per-architecture ++ sigtramp unwinders. */ ++ int (*pc_in_sigtramp) (struct gdbarch *gdbarch, CORE_ADDR pc, ++ const char *name); ++ ++ /* If TYPE will be returned in memory, return true. */ ++ int (*return_in_memory) (struct type *type); ++ ++ /* Offset of registers in `struct sigcontext'. */ ++ int sc_pc_offset; ++ uint64_t vq; ++ bool has_sve () const ++ { ++ return vq != 0; ++ } ++ int sc_regs_offset; ++ int sc_fpregs_offset; ++ ++ int jb_pc; /* Offset to PC value in jump buffer. ++ If htis is negative, longjmp support ++ will be disabled. */ ++ size_t jb_elt_size; /* And the size of each entry in the buf. */ ++#ifndef LHX20201026 ++ struct type *sw_64_vec_type; ++#else ++ struct type *master_vec_type; ++#endif ++/* syscall record. */ ++ int (*sw_64_syscall_record) (struct regcache *regcache); ++}; ++ ++extern unsigned int sw_64_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc); ++extern std::vector sw_64_software_single_step ++ (struct regcache *regcache); ++extern CORE_ADDR sw_64_after_prologue (CORE_ADDR pc); ++ ++extern void sw_64_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); ++extern void sw_64_dwarf2_init_abi (struct gdbarch_info, struct gdbarch *); ++ ++extern void sw_64_supply_int_regs (struct regcache *, int, const void *, ++ const void *, const void *); ++extern int aarch64_process_record (struct gdbarch *gdbarch, ++ struct regcache *regcache, CORE_ADDR addr); ++extern void sw_64_fill_int_regs (const struct regcache *, int, ++ void *, void *, void *); ++extern void sw_64_supply_fp_regs (struct regcache *, int, ++ const void *, const void *); ++extern void sw_64_fill_fp_regs (const struct regcache *, ++ int, void *, void *); ++extern int sw_64_process_record (struct gdbarch *gdbarch, ++ struct regcache *regcache, CORE_ADDR addr); ++ ++#define SW64_VEC0 SW_NUM_REGS ++#define REG_BASE 0 ++#define NGP_REGS 32 ++#define NFP_REGS 32 ++#define NVEC_REGS 32 ++#define GPR_BASE REG_BASE ++#define FPR_BASE (GPR_BASE+NGP_REGS) ++ ++#endif /* SW_64_TDEP_H */ +diff -Nuar gdb-10.2/gdb/symfile.c gdb-10.2/gdb/symfile.c +--- gdb-10.2/gdb/symfile.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/symfile.c 2025-04-16 17:06:41.922086800 +0800 +@@ -652,7 +652,26 @@ + for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) + /* We do not expect this to happen; just skip this step if the + relocatable file has a section with an assigned VMA. */ +- if (bfd_section_vma (cur_sec) != 0) ++ if (bfd_section_vma (cur_sec) != 0 ++ /* ++ * Kernel modules may have some non-zero VMAs, i.e., like the ++ * __ksymtab and __ksymtab_gpl sections in this example: ++ * ++ * Section Headers: ++ * [Nr] Name Type Address Offset ++ * Size EntSize Flags Link Info Align ++ * ... ++ * [ 8] __ksymtab PROGBITS 0000000000000060 0000ad90 ++ * 0000000000000010 0000000000000000 A 0 0 16 ++ * [ 9] .rela__ksymtab RELA 0000000000000000 0000ada0 ++ * 0000000000000030 0000000000000018 43 8 8 ++ * [10] __ksymtab_gpl PROGBITS 0000000000000070 0000add0 ++ * 00000000000001a0 0000000000000000 A 0 0 16 ++ * ... ++ * ++ * but they should be treated as if they are NULL. ++ */ ++ && strncmp (bfd_section_name (cur_sec), "__k", 3) != 0) + break; + + if (cur_sec == NULL) +@@ -1083,6 +1102,12 @@ + if (mainline) + flags |= OBJF_MAINLINE; + objfile = objfile::make (abfd, name, flags, parent); ++#ifdef CRASH_MERGE ++ if (add_flags & SYMFILE_MAINLINE) { ++ extern struct objfile *gdb_kernel_objfile; ++ gdb_kernel_objfile = objfile; ++ } ++#endif + + /* We either created a new mapped symbol table, mapped an existing + symbol table file which has not had initial symbol reading +@@ -1375,6 +1400,10 @@ + #if ! defined (DEBUG_SUBDIRECTORY) + #define DEBUG_SUBDIRECTORY ".debug" + #endif ++#ifdef CRASH_MERGE ++extern "C" int check_specified_module_tree(const char *, const char *); ++extern "C" char *check_specified_kernel_debug_file(); ++#endif + + /* Find a separate debuginfo file for OBJFILE, using DIR as the directory + where the original file resides (may not be the same as +@@ -1410,6 +1439,15 @@ + if (separate_debug_file_exists (debugfile, crc32, objfile)) + return debugfile; + ++#ifdef CRASH_MERGE ++{ ++ if (check_specified_module_tree(objfile_name (objfile), debugfile.c_str()) && ++ separate_debug_file_exists(debugfile, crc32, objfile)) { ++ return debugfile; ++ } ++} ++#endif ++ + /* Then try in the global debugfile directories. + + Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will +@@ -1568,6 +1606,14 @@ + } + } + ++#ifdef CRASH_MERGE ++ if (debugfile.empty ()) { ++ char *name_copy; ++ name_copy = check_specified_kernel_debug_file(); ++ return name_copy ? std::string (name_copy) : std::string (); ++ } ++#endif ++ + return debugfile; + } + +@@ -2334,8 +2380,10 @@ + else if (section_addrs.empty ()) + printf_unfiltered ("\n"); + ++#ifndef CRASH_MERGE + if (from_tty && (!query ("%s", ""))) + error (_("Not confirmed.")); ++#endif + + objf = symbol_file_add (filename.get (), add_flags, §ion_addrs, + flags); +@@ -3622,6 +3670,15 @@ + symfile_relocate_debug_section (struct objfile *objfile, + asection *sectp, bfd_byte *buf) + { ++#ifdef CRASH_MERGE ++ /* Executable files have all the relocations already resolved. ++ * Handle files linked with --emit-relocs. ++ * http://sources.redhat.com/ml/gdb/2006-08/msg00137.html ++ */ ++ bfd *abfd = objfile->obfd; ++ if ((abfd->flags & EXEC_P) != 0) ++ return NULL; ++#endif + gdb_assert (objfile->sf->sym_relocate); + + return (*objfile->sf->sym_relocate) (objfile, sectp, buf); +diff -Nuar gdb-10.2/gdb/symtab.c gdb-10.2/gdb/symtab.c +--- gdb-10.2/gdb/symtab.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/symtab.c 2025-04-16 17:06:41.952086800 +0800 +@@ -1870,27 +1870,46 @@ + variable and thus can probably assume it will never hit the C++ + code). */ + ++#ifdef CRASH_MERGE ++static void gdb_bait_and_switch(char *, struct symbol *); ++#endif ++ + struct block_symbol + lookup_symbol_in_language (const char *name, const struct block *block, + const domain_enum domain, enum language lang, + struct field_of_this_result *is_a_field_of_this) + { ++ struct block_symbol result; + demangle_result_storage storage; + const char *modified_name = demangle_for_lookup (name, lang, storage); + +- return lookup_symbol_aux (modified_name, ++ result = lookup_symbol_aux (modified_name, + symbol_name_match_type::FULL, + block, domain, lang, + is_a_field_of_this); ++#ifdef CRASH_MERGE ++ if (result.symbol && (domain == VAR_DOMAIN)) ++ gdb_bait_and_switch((char *)modified_name, result.symbol); ++#endif ++ return result; + } + + /* See symtab.h. */ + ++#ifdef CRASH_MERGE ++static const struct block *gdb_get_crash_block(void); ++#endif ++ + struct block_symbol + lookup_symbol (const char *name, const struct block *block, + domain_enum domain, + struct field_of_this_result *is_a_field_of_this) + { ++#ifdef CRASH_MERGE ++ if (!block) ++ block = gdb_get_crash_block(); ++#endif ++ + return lookup_symbol_in_language (name, block, domain, + current_language->la_language, + is_a_field_of_this); +@@ -6886,3 +6905,902 @@ + gdb::observers::new_objfile.attach (symtab_new_objfile_observer); + gdb::observers::free_objfile.attach (symtab_free_objfile_observer); + } ++ ++#ifdef CRASH_MERGE ++#include "gdb-stabs.h" ++#include "gdbsupport/version.h" ++#define GDB_COMMON ++#include "../../defs.h" ++ ++static void get_member_data(struct gnu_request *, struct type *, long, int); ++static void walk_enum(struct type *, struct gnu_request *); ++static void eval_enum(struct type *, struct gnu_request *); ++static void gdb_get_line_number(struct gnu_request *); ++static void gdb_get_datatype(struct gnu_request *); ++static void gdb_get_symbol_type(struct gnu_request *); ++static void gdb_command_exists(struct gnu_request *); ++static void gdb_debug_command(struct gnu_request *); ++static void gdb_function_numargs(struct gnu_request *); ++static void gdb_add_symbol_file(struct gnu_request *); ++static void gdb_delete_symbol_file(struct gnu_request *); ++static void gdb_patch_symbol_values(struct gnu_request *); ++static void get_user_print_option_address(struct gnu_request *); ++extern int get_frame_offset(CORE_ADDR); ++static void gdb_set_crash_block(struct gnu_request *); ++extern "C" void gdb_command_funnel(struct gnu_request *); ++void gdb_command_funnel_1(struct gnu_request *); ++static long lookup_struct_contents(struct gnu_request *); ++static void iterate_datatypes(struct gnu_request *); ++ ++struct objfile *gdb_kernel_objfile = { 0 }; ++ ++static ulong gdb_merge_flags = 0; ++#define KERNEL_SYMBOLS_PATCHED (0x1) ++ ++#undef STREQ ++#define STREQ(A, B) (A && B && (strcmp(A, B) == 0)) ++#define TYPE_CODE(t) (t->code ()) ++#define TYPE_TAG_NAME(t) (TYPE_MAIN_TYPE(t)->name) ++#define TYPE_NFIELDS(t) (t->num_fields ()) ++#define TYPE_NAME(t) (t->name ()) ++ ++/* ++ * All commands from above come through here. ++ */ ++void ++gdb_command_funnel(struct gnu_request *req) ++{ ++ try { ++ gdb_command_funnel_1(req); ++ } catch (const gdb_exception &ex) { ++ if (req->flags & GNU_RETURN_ON_ERROR) ++ req->flags |= GNU_COMMAND_FAILED; ++ else ++ throw ex; ++ } ++} ++ ++void ++gdb_command_funnel_1(struct gnu_request *req) ++{ ++ struct symbol *sym; ++ ++ if (req->command != GNU_VERSION && req->command != GNU_USER_PRINT_OPTION) { ++ (dynamic_castgdb_stdout)->set_stream(req->fp); ++ (dynamic_castgdb_stderr)->set_stream(req->fp); ++ } ++ ++ switch (req->command) ++ { ++ case GNU_VERSION: ++ req->buf = (char *)version; ++ break; ++ ++ case GNU_PASS_THROUGH: ++ execute_command(req->buf, ++ req->flags & GNU_FROM_TTY_OFF ? FALSE : TRUE); ++ break; ++ ++ case GNU_USER_PRINT_OPTION: ++ get_user_print_option_address(req); ++ break; ++ ++ case GNU_RESOLVE_TEXT_ADDR: ++ sym = find_pc_function(req->addr); ++ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) ++ req->flags |= GNU_COMMAND_FAILED; ++ break; ++ ++ case GNU_DISASSEMBLE: ++ if (req->addr2) ++ sprintf(req->buf, "disassemble 0x%lx 0x%lx", ++ req->addr, req->addr2); ++ else ++ sprintf(req->buf, "disassemble 0x%lx", req->addr); ++ execute_command(req->buf, TRUE); ++ break; ++ ++ case GNU_ADD_SYMBOL_FILE: ++ gdb_add_symbol_file(req); ++ break; ++ ++ case GNU_DELETE_SYMBOL_FILE: ++ gdb_delete_symbol_file(req); ++ break; ++ ++ case GNU_GET_LINE_NUMBER: ++ gdb_get_line_number(req); ++ break; ++ ++ case GNU_GET_DATATYPE: ++ gdb_get_datatype(req); ++ break; ++ ++ case GNU_GET_SYMBOL_TYPE: ++ gdb_get_symbol_type(req); ++ break; ++ ++ case GNU_COMMAND_EXISTS: ++ gdb_command_exists(req); ++ break; ++ ++ case GNU_ALPHA_FRAME_OFFSET: ++ req->value = 0; ++ break; ++ ++ case GNU_FUNCTION_NUMARGS: ++ gdb_function_numargs(req); ++ break; ++ ++ case GNU_DEBUG_COMMAND: ++ gdb_debug_command(req); ++ break; ++ ++ case GNU_PATCH_SYMBOL_VALUES: ++ gdb_patch_symbol_values(req); ++ break; ++ ++ case GNU_SET_CRASH_BLOCK: ++ gdb_set_crash_block(req); ++ break; ++ ++ case GNU_GET_FUNCTION_RANGE: ++ { ++ CORE_ADDR start, end; ++ if (!find_pc_partial_function(req->pc, NULL, &start, &end)) ++ req->flags |= GNU_COMMAND_FAILED; ++ else { ++ req->addr = (ulong)start; ++ req->addr2 = (ulong)end; ++ } ++ } ++ break; ++ ++ case GNU_LOOKUP_STRUCT_CONTENTS: ++ req->value = lookup_struct_contents(req); ++ break; ++ ++ case GNU_ITERATE_DATATYPES: ++ iterate_datatypes(req); ++ break; ++ ++ default: ++ req->flags |= GNU_COMMAND_FAILED; ++ break; ++ } ++} ++ ++/* ++ * Given a PC value, return the file and line number. ++ */ ++static void ++gdb_get_line_number(struct gnu_request *req) ++{ ++ struct symtab_and_line sal; ++ struct objfile *objfile; ++ CORE_ADDR pc; ++ ++#define LASTCHAR(s) (s[strlen(s)-1]) ++ ++ /* ++ * Prime the addrmap pump. ++ */ ++ pc = req->addr; ++ ++ sal = find_pc_line(pc, 0); ++ ++ if (!sal.symtab) { ++ /* ++ * If a module address line number can't be found, it's typically ++ * due to its addrmap still containing offset values because its ++ * objfile doesn't have full symbols loaded. ++ */ ++ if (req->lm) { ++ objfile = req->lm->loaded_objfile; ++ if (!objfile_has_full_symbols(objfile) && objfile->sf) { ++ objfile->sf->qf->expand_all_symtabs(objfile); ++ sal = find_pc_line(pc, 0); ++ } ++ } ++ if (!sal.symtab) { ++ req->buf[0] = '\0'; ++ return; ++ } ++ } ++ ++ if (sal.symtab->filename && SYMTAB_DIRNAME(sal.symtab)) { ++ if (sal.symtab->filename[0] == '/') ++ sprintf(req->buf, "%s: %d", ++ sal.symtab->filename, sal.line); ++ else ++ sprintf(req->buf, "%s%s%s: %d", ++ SYMTAB_DIRNAME(sal.symtab), ++ LASTCHAR(SYMTAB_DIRNAME(sal.symtab)) == '/' ? "" : "/", ++ sal.symtab->filename, sal.line); ++ } ++} ++ ++ ++/* ++ * Follow the type linkage for full member and value type resolution, with callback ++ */ ++static void drillDownType(struct gnu_request *req, struct type *type) ++{ ++ while (type) ++ { ++ /* check out for stub types and pull in the definition instead */ ++ if (TYPE_STUB(type) && TYPE_TAG_NAME(type)) { ++ struct symbol *sym; ++ sym = lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0).symbol; ++ if (sym) ++ type = sym->type; ++ } ++ switch (TYPE_CODE(type)) { ++ drill_ops_t op; ++ long l1, l2; ++ int typecode; ++ ++ case TYPE_CODE_PTR: ++ req->tcb(EOP_POINTER, req, 0, 0, 0, 0); ++ break; ++ ++ case TYPE_CODE_TYPEDEF: ++ req->is_typedef = 1; ++ req->typecode = TYPE_CODE(type); ++ if (!req->tcb(EOP_TYPEDEF, req, TYPE_NAME(type), 0, 0, 0)) ++ return; ++ break; ++ ++ case TYPE_CODE_FUNC: ++ req->tcb(EOP_FUNCTION, req, 0, 0, 0, 0); ++ break; ++ ++ case TYPE_CODE_ARRAY: ++ l1 = TYPE_LENGTH (type); ++ l2 = TYPE_LENGTH (check_typedef(TYPE_TARGET_TYPE (type))); ++ req->tcb(EOP_ARRAY, req, &l1, &l2, 0, 0); ++ break; ++ ++ case TYPE_CODE_VOID: ++ case TYPE_CODE_INT: ++ case TYPE_CODE_BOOL: ++ l1 = TYPE_LENGTH(type); ++ req->tcb(EOP_INT, req, &l1, 0, 0, 0); ++ break; ++ ++ case TYPE_CODE_UNION: ++ op = EOP_UNION; ++ goto label; ++ ++ case TYPE_CODE_ENUM: ++ op = EOP_ENUM; ++ goto label; ++ ++ case TYPE_CODE_STRUCT: ++ op = EOP_STRUCT; ++ goto label; ++ ++ default: ++ typecode = TYPE_CODE(type); ++ req->tcb(EOP_OOPS, req, &typecode, "Unknown typecode", 0, 0); ++ return; /* not reached */ ++ ++ label: ++ l1 = TYPE_LENGTH(type); ++ req->tcb(op, req, &l1, type, TYPE_TAG_NAME(type), 0); ++ } ++ type = TYPE_TARGET_TYPE(type); ++ } ++ req->tcb(EOP_DONE, req, 0, 0, 0, 0); ++} ++ ++/* ++ * General purpose routine for determining datatypes. ++ */ ++ ++static void ++gdb_get_datatype(struct gnu_request *req) ++{ ++ struct type *type; ++ struct type *typedef_type; ++ expression_up expr; ++ struct symbol *sym; ++ struct value *val; ++ ++ if (gdb_CRASHDEBUG(2)) ++ console("gdb_get_datatype [%s] (a)\n", req->name); ++ ++ req->typecode = TYPE_CODE_UNDEF; ++ ++ /* ++ * lookup_symbol() will pick up struct and union names. ++ */ ++ sym = lookup_symbol(req->name, 0, STRUCT_DOMAIN, 0).symbol; ++ if (sym) { ++ req->typecode = TYPE_CODE(sym->type); ++ req->length = TYPE_LENGTH(sym->type); ++ if (req->member) ++ get_member_data(req, sym->type, 0, 1); ++ ++ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) ++ walk_enum(sym->type, req); ++ ++ return; ++ } ++ ++ /* ++ * Otherwise parse the expression. ++ */ ++ if (gdb_CRASHDEBUG(2)) ++ console("gdb_get_datatype [%s] (b)\n", req->name); ++ ++ expr = parse_expression(req->name); ++ ++ ++ switch (expr.get()->elts[0].opcode) ++ { ++ case OP_VAR_VALUE: ++ if (gdb_CRASHDEBUG(2)) ++ console("expr->elts[0].opcode: OP_VAR_VALUE\n"); ++ type = expr.get()->elts[2].symbol->type; ++ if (req->tcb) { ++ long value = SYMBOL_VALUE(expr->elts[2].symbol); ++ /* callback with symbol value */ ++ req->typecode = TYPE_CODE(type); ++ req->tcb(EOP_VALUE, req, &value, 0, 0, 0); ++ drillDownType(req, type); ++ } else { ++ if (req->flags & GNU_VAR_LENGTH_TYPECODE) { ++ req->typecode = TYPE_CODE(type); ++ req->length = TYPE_LENGTH(type); ++ } ++ if (TYPE_CODE(type) == TYPE_CODE_ENUM) { ++ req->typecode = TYPE_CODE(type); ++ req->value = SYMBOL_VALUE(expr->elts[2].symbol); ++ req->tagname = (char *)TYPE_TAG_NAME(type); ++ if (!req->tagname) { ++ val = evaluate_type(expr.get()); ++ eval_enum(value_type(val), req); ++ } ++ } ++ } ++ break; ++ ++ case OP_TYPE: ++ if (gdb_CRASHDEBUG(2)) ++ console("expr->elts[0].opcode: OP_TYPE\n"); ++ type = expr.get()->elts[1].type; ++ ++ if (req->tcb) { ++ drillDownType(req, type); ++ } else { ++ req->typecode = TYPE_CODE(type); ++ req->length = TYPE_LENGTH(type); ++ if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) { ++ req->is_typedef = TYPE_CODE_TYPEDEF; ++ if ((typedef_type = check_typedef(type))) { ++ req->typecode = TYPE_CODE(typedef_type); ++ req->length = TYPE_LENGTH(typedef_type); ++ type = typedef_type; ++ } ++ } ++ if (TYPE_CODE(type) == TYPE_CODE_ENUM) ++ walk_enum(type, req); ++ } ++ ++ if (req->member) ++ get_member_data(req, type, 0, 1); ++ ++ break; ++ ++ default: ++ if (gdb_CRASHDEBUG(2)) ++ console("expr.get()->elts[0].opcode: %d (?)\n", ++ expr.get()->elts[0].opcode); ++ break; ++ ++ } ++} ++ ++/* ++ * More robust enum list dump that gdb's, showing the value of each ++ * identifier, each on its own line. ++ */ ++static void ++walk_enum(struct type *type, struct gnu_request *req) ++{ ++ int i; ++ int len, print = (req->flags & GNU_PRINT_ENUMERATORS); ++ long long lastval; ++ ++ if (print) { ++ if (req->is_typedef) ++ fprintf_filtered(gdb_stdout, "typedef "); ++ if (TYPE_TAG_NAME(type)) ++ fprintf_filtered(gdb_stdout, "enum %s {\n", TYPE_TAG_NAME (type)); ++ else ++ fprintf_filtered(gdb_stdout, "enum {\n"); ++ } ++ ++ len = TYPE_NFIELDS (type); ++ for (i = 0; i < len; i++) { ++ if (print) ++ fprintf_filtered(gdb_stdout, " %s", TYPE_FIELD_NAME (type, i)); ++ lastval = TYPE_FIELD_ENUMVAL (type, i); ++ if (print) { ++ fprintf_filtered(gdb_stdout, " = %s", plongest(lastval)); ++ fprintf_filtered(gdb_stdout, "\n"); ++ } else if (req->tcb) ++ req->tcb(EOP_ENUMVAL, req, TYPE_FIELD_NAME (type, i), &lastval, 0, 0); ++ } ++ if (print) { ++ if (TYPE_TAG_NAME(type)) ++ fprintf_filtered(gdb_stdout, "};\n"); ++ else ++ fprintf_filtered(gdb_stdout, "} %s;\n", req->name); ++ } ++} ++ ++/* ++ * Given an enum type with no tagname, determine its value. ++ */ ++static void ++eval_enum(struct type *type, struct gnu_request *req) ++{ ++ int i; ++ int len; ++ long long lastval; ++ ++ len = TYPE_NFIELDS (type); ++ lastval = 0; ++ ++ for (i = 0; i < len; i++) { ++ if (lastval != TYPE_FIELD_ENUMVAL (type, i)) ++ lastval = TYPE_FIELD_ENUMVAL (type, i); ++ ++ if (STREQ(TYPE_FIELD_NAME(type, i), req->name)) { ++ req->tagname = "(unknown)"; ++ req->value = lastval; ++ return; ++ } ++ lastval++; ++ } ++} ++ ++/* ++ * Walk through a struct type's list of fields looking for the desired ++ * member field, and when found, return its relevant data. ++ */ ++static void ++get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first) ++{ ++ short i; ++ struct field *nextfield; ++ short nfields; ++ struct type *typedef_type, *target_type; ++ ++ req->member_offset = -1; ++ ++ nfields = TYPE_MAIN_TYPE(type)->nfields; ++ nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields; ++ ++ if (nfields == 0 && is_first /* The first call */) { ++ struct type *newtype; ++ newtype = lookup_transparent_type(req->name); ++ if (newtype) { ++ console("get_member_data(%s.%s): switching type from %lx to %lx\n", ++ req->name, req->member, type, newtype); ++ nfields = TYPE_MAIN_TYPE(newtype)->nfields; ++ nextfield = TYPE_MAIN_TYPE(newtype)->flds_bnds.fields; ++ } ++ } ++ ++ for (i = 0; i < nfields; i++) { ++ if (*nextfield->name == 0) { /* Anonymous struct/union */ ++ get_member_data(req, nextfield->type(), ++ offset + nextfield->loc.bitpos, 0); ++ if (req->member_offset != -1) ++ return; ++ } else { ++ /* callback may be just looking for a specific member name */ ++ if (req->tcb) { ++ if (req->tcb(EOP_MEMBER_NAME, req, nextfield->name, 0, 0, 0)) { ++ long bitpos = FIELD_BITPOS(*nextfield); ++ long bitsize = FIELD_BITSIZE(*nextfield); ++ long len = TYPE_LENGTH(nextfield->type()); ++ long byteOffset; ++ offset += nextfield->loc.bitpos; ++ byteOffset = offset/8; ++ console("EOP_MEMBER_SIZES\n"); ++ req->tcb(EOP_MEMBER_SIZES, req, &byteOffset, &len, &bitpos, &bitsize); ++ /* callback with full type info */ ++ drillDownType(req, nextfield->type()); ++ } ++ } else if (STREQ(req->member, nextfield->name)) { ++ req->member_offset = offset + nextfield->loc.bitpos; ++ req->member_length = TYPE_LENGTH(nextfield->type()); ++ req->member_typecode = TYPE_CODE(nextfield->type()); ++ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type()); ++ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type()); ++ target_type = TYPE_TARGET_TYPE(nextfield->type()); ++ if (target_type) { ++ req->member_target_type_name = (char *)TYPE_NAME(target_type); ++ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type); ++ } ++ if ((req->member_typecode == TYPE_CODE_TYPEDEF) && ++ (typedef_type = check_typedef(nextfield->type()))) { ++ req->member_length = TYPE_LENGTH(typedef_type); ++ } ++ return; ++ } ++ } ++ nextfield++; ++ } ++} ++ ++/* ++ * Check whether a command exists. If it doesn't, the command will be ++ * returned indirectly via the error_hook. ++ */ ++static void ++gdb_command_exists(struct gnu_request *req) ++{ ++ extern struct cmd_list_element *cmdlist; ++ ++ req->value = FALSE; ++ lookup_cmd((const char **)&req->name, cmdlist, "", NULL, 0, 1); ++ req->value = TRUE; ++} ++ ++static void ++gdb_function_numargs(struct gnu_request *req) ++{ ++ struct symbol *sym; ++ ++ sym = find_pc_function(req->pc); ++ ++ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) { ++ req->flags |= GNU_COMMAND_FAILED; ++ return; ++ } ++ ++ req->value = (ulong)TYPE_NFIELDS(sym->type); ++} ++ ++struct load_module *gdb_current_load_module = NULL; ++ ++static void ++gdb_add_symbol_file(struct gnu_request *req) ++{ ++ struct load_module *lm; ++ int i; ++ int allsect = 0; ++ char *secname; ++ char buf[96]; ++ ++ gdb_current_load_module = lm = (struct load_module *)req->addr; ++ ++ req->name = lm->mod_namelist; ++ gdb_delete_symbol_file(req); ++ lm->loaded_objfile = NULL; ++ ++ if ((lm->mod_flags & MOD_NOPATCH) == 0) { ++ for (i = 0 ; i < lm->mod_sections; i++) { ++ if (STREQ(lm->mod_section_data[i].name, ".text") && ++ (lm->mod_section_data[i].flags & SEC_FOUND)) ++ allsect = 1; ++ } ++ ++ if (!allsect) { ++ sprintf(req->buf, "add-symbol-file %s 0x%lx %s", lm->mod_namelist, ++ lm->mod_text_start ? lm->mod_text_start : lm->mod_base, ++ lm->mod_flags & MOD_DO_READNOW ? "-readnow" : ""); ++ if (lm->mod_data_start) { ++ sprintf(buf, " -s .data 0x%lx", lm->mod_data_start); ++ strcat(req->buf, buf); ++ } ++ if (lm->mod_bss_start) { ++ sprintf(buf, " -s .bss 0x%lx", lm->mod_bss_start); ++ strcat(req->buf, buf); ++ } ++ if (lm->mod_rodata_start) { ++ sprintf(buf, " -s .rodata 0x%lx", lm->mod_rodata_start); ++ strcat(req->buf, buf); ++ } ++ } else { ++ sprintf(req->buf, "add-symbol-file %s 0x%lx %s", lm->mod_namelist, ++ lm->mod_text_start, lm->mod_flags & MOD_DO_READNOW ? ++ "-readnow" : ""); ++ for (i = 0; i < lm->mod_sections; i++) { ++ secname = lm->mod_section_data[i].name; ++ if ((lm->mod_section_data[i].flags & SEC_FOUND) && ++ !STREQ(secname, ".text")) { ++ if (lm->mod_section_data[i].addr) ++ sprintf(buf, " -s %s 0x%lx", secname, lm->mod_section_data[i].addr); ++ else ++ sprintf(buf, " -s %s 0x%lx", secname, ++ lm->mod_section_data[i].offset + lm->mod_base); ++ strcat(req->buf, buf); ++ } ++ } ++ } ++ } + -+ crash_target_init(); ++ if (gdb_CRASHDEBUG(1)) ++ fprintf_filtered(gdb_stdout, "%s\n", req->buf); + -+ /* Back to crash. */ -+ main_loop(); -+#endif ++ execute_command(req->buf, FALSE); ++ ++ for (objfile *objfile : current_program_space->objfiles ()) { ++ if (same_file((char *)objfile_name(objfile), lm->mod_namelist)) { ++ if (objfile->separate_debug_objfile) ++ lm->loaded_objfile = objfile->separate_debug_objfile; ++ else ++ lm->loaded_objfile = objfile; ++ break; ++ } ++ } ++ ++ if (!lm->loaded_objfile) ++ req->flags |= GNU_COMMAND_FAILED; ++} ++ ++static void ++gdb_delete_symbol_file(struct gnu_request *req) ++{ ++ for (objfile *objfile : current_program_space->objfiles ()) { ++ if (STREQ(objfile_name(objfile), req->name) || ++ same_file((char *)objfile_name(objfile), req->name)) { ++ objfile->unlink (); ++ break; ++ } ++ } ++ ++ if (gdb_CRASHDEBUG(2)) { ++ fprintf_filtered(gdb_stdout, "current object files:\n"); ++ for (objfile *objfile : current_program_space->objfiles ()) ++ fprintf_filtered(gdb_stdout, " %s\n", objfile_name(objfile)); ++ } ++} + - /* NOTE: cagney/1999-11-07: There is probably no reason for not - moving this loop and the code found in captured_command_loop() - into the command_loop() proper. The main thing holding back that -@@ -1256,6 +1298,9 @@ captured_main (void *data) - { - exception_print (gdb_stderr, ex); - } -+#ifdef CRASH_MERGE -+ console("\n"); -+#endif - } - /* No exit -- exit is through quit_command. */ - } -@@ -1277,6 +1322,22 @@ gdb_main (struct captured_main_args *args) - return 1; - } - -+#ifdef CRASH_MERGE +/* -+ * NOTE: adapted from gdb.c, which is no longer built in; changed name of -+ * original main() to gdb_main_entry() for use as crash entry point ++ * Walk through all minimal_symbols, patching their values with the ++ * correct addresses. + */ -+int -+gdb_main_entry (int argc, char **argv) ++static void ++gdb_patch_symbol_values(struct gnu_request *req) +{ -+ struct captured_main_args args; -+ memset (&args, 0, sizeof args); -+ args.argc = argc; -+ args.argv = argv; -+ args.interpreter_p = INTERP_CONSOLE; -+ return gdb_main (&args); ++ req->name = PATCH_KERNEL_SYMBOLS_START; ++ patch_kernel_symbol(req); ++ ++ for (objfile *objfile : current_program_space->objfiles ()) ++ for (minimal_symbol *msymbol : objfile->msymbols ()) ++ { ++ req->name = (char *)msymbol->m_name; ++ req->addr = (ulong)(&MSYMBOL_VALUE(msymbol)); ++ if (!patch_kernel_symbol(req)) { ++ req->flags |= GNU_COMMAND_FAILED; ++ break; ++ } ++ } ++ ++ req->name = PATCH_KERNEL_SYMBOLS_STOP; ++ patch_kernel_symbol(req); ++ ++ clear_symtab_users(0); ++ gdb_merge_flags |= KERNEL_SYMBOLS_PATCHED; +} -+#endif - - /* Don't use *_filtered for printing help. We don't want to prompt - for continue no matter how small the screen or how much we're going ---- gdb-10.2/gdb/objfiles.h.orig -+++ gdb-10.2/gdb/objfiles.h -@@ -747,9 +747,9 @@ extern int objfile_has_full_symbols (struct objfile *objfile); - - extern int objfile_has_symbols (struct objfile *objfile); - --extern int have_partial_symbols (void); -+extern "C" int have_partial_symbols (void); - --extern int have_full_symbols (void); -+extern "C" int have_full_symbols (void); - - extern void objfile_set_sym_fns (struct objfile *objfile, - const struct sym_fns *sf); ---- gdb-10.2/gdb/printcmd.c.orig -+++ gdb-10.2/gdb/printcmd.c -@@ -524,6 +524,9 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr) - form. However note that DO_DEMANGLE can be overridden by the specific - settings of the demangle and asm_demangle variables. Returns - non-zero if anything was printed; zero otherwise. */ -+#ifdef CRASH_MERGE -+extern "C" int gdb_print_callback(unsigned long); -+#endif - - int - print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, -@@ -535,6 +538,12 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, - int offset = 0; - int line = 0; - -+#ifdef CRASH_MERGE -+ if (!gdb_print_callback(addr)) { -+ return 0; -+ } -+#endif + - if (build_address_symbolic (gdbarch, addr, do_demangle, false, &name, - &offset, &filename, &line, &unmapped)) - return 0; -@@ -1221,6 +1230,43 @@ print_command_1 (const char *args, int voidprint) - print_value (val, print_opts); - } - -+static void -+print_command_2 (const char *args, int voidprint) -+{ -+ struct value *val; -+ value_print_options print_opts; ++static void ++gdb_get_symbol_type(struct gnu_request *req) ++{ ++ expression_up expr; ++ struct value *val; ++ struct type *type; ++ struct type *target_type; ++ ++ req->typecode = TYPE_CODE_UNDEF; ++ ++ expr = parse_expression (req->name); ++ val = evaluate_type (expr.get()); ++ ++ type = value_type(val); ++ ++ req->type_name = (char *)TYPE_MAIN_TYPE(type)->name; ++ req->typecode = TYPE_MAIN_TYPE(type)->code; ++ req->length = type->length; ++ req->type_tag_name = (char *)TYPE_TAG_NAME(type); ++ target_type = TYPE_MAIN_TYPE(type)->target_type; ++ ++ if (target_type) { ++ req->target_typename = (char *)TYPE_MAIN_TYPE(target_type)->name; ++ req->target_typecode = TYPE_MAIN_TYPE(target_type)->code; ++ req->target_length = target_type->length; ++ } ++ ++ if (req->member) ++ get_member_data(req, type, 0, 1); ++} ++ ++static void ++gdb_debug_command(struct gnu_request *req) ++{ ++ ++} ++ ++/* ++ * Only necessary on "patched" kernel symbol sessions, and called only by ++ * lookup_symbol(), pull a symbol value bait-and-switch operation by altering ++ * either a data symbol's address value or a text symbol's block start address. ++ */ ++static void ++gdb_bait_and_switch(char *name, struct symbol *sym) ++{ ++ struct bound_minimal_symbol msym; ++ struct block *block; ++ ++ if ((gdb_merge_flags & KERNEL_SYMBOLS_PATCHED) && ++ (msym = lookup_minimal_symbol(name, NULL, gdb_kernel_objfile)).minsym) { ++ if (SYMBOL_CLASS(sym) == LOC_BLOCK) { ++ block = (struct block *)SYMBOL_BLOCK_VALUE(sym); ++ BLOCK_START(block) = BMSYMBOL_VALUE_ADDRESS(msym); ++ } else ++ SET_SYMBOL_VALUE_ADDRESS(sym, BMSYMBOL_VALUE_ADDRESS(msym)); ++ } ++} ++ ++#include "valprint.h" ++ ++void ++get_user_print_option_address(struct gnu_request *req) ++{ ++ extern struct value_print_options user_print_options; ++ ++ req->addr = 0; ++ ++ if (strcmp(req->name, "output_format") == 0) ++ req->addr = (ulong)&user_print_options.output_format; ++ if (strcmp(req->name, "print_max") == 0) ++ req->addr = (ulong)&user_print_options.print_max; ++ if (strcmp(req->name, "prettyprint_structs") == 0) ++ req->addr = (ulong)&user_print_options.prettyformat_structs; ++ if (strcmp(req->name, "prettyprint_arrays") == 0) ++ req->addr = (ulong)&user_print_options.prettyformat_arrays; ++ if (strcmp(req->name, "repeat_count_threshold") == 0) ++ req->addr = (ulong)&user_print_options.repeat_count_threshold; ++ if (strcmp(req->name, "stop_print_at_null") == 0) ++ req->addr = (ulong)&user_print_options.stop_print_at_null; ++ if (strcmp(req->name, "output_radix") == 0) ++ req->addr = (ulong)&output_radix; ++} ++ ++CORE_ADDR crash_text_scope; ++ ++static void ++gdb_set_crash_block(struct gnu_request *req) ++{ ++ if (!req->addr) { /* debug */ ++ crash_text_scope = 0; ++ return; ++ } ++ ++ if ((req->addr2 = (ulong)block_for_pc(req->addr))) ++ crash_text_scope = req->addr; ++ else { ++ crash_text_scope = 0; ++ req->flags |= GNU_COMMAND_FAILED; ++ } ++} ++ ++static const struct block * ++gdb_get_crash_block(void) ++{ ++ if (crash_text_scope) ++ return block_for_pc(crash_text_scope); ++ else ++ return NULL; ++} ++ ++static long ++lookup_struct_contents(struct gnu_request *req) ++{ ++ int i; ++ long r; ++ struct field *f; ++ struct main_type *m; ++ const char *n; ++ struct main_type *top_m = (struct main_type *)req->addr; ++ char *type_name = req->type_name; ++ ++ if (!top_m || !type_name) ++ return 0; ++ ++ for (i = 0; i < top_m->nfields; i++) ++ { ++ f = top_m->flds_bnds.fields + i; ++ if (!f->type()) ++ continue; ++ m = f->type()->main_type; + -+ get_user_print_options (&print_opts); -+ /* Override global settings with explicit options, if any. */ -+ auto group = make_value_print_options_def_group (&print_opts); -+ gdb::option::process_options -+ (&args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group); ++ // If the field is an array, check the target type - ++ // it might be structure, or might not be. ++ // - struct request_sock *syn_table[0]; ++ // here m->target_type->main_type->code is expected ++ // to be TYPE_CODE_PTR ++ // - struct list_head vec[TVN_SIZE]; ++ // here m->target_type->main_type->code should be ++ // TYPE_CODE_STRUCT ++ if (m->code == TYPE_CODE_ARRAY && m->target_type) ++ m = m->target_type->main_type; + -+ print_command_parse_format (&args, "print", &print_opts); ++ /* Here is a recursion. ++ * If we have struct variable (not pointer), ++ * scan this inner structure ++ */ ++ if (m->code == TYPE_CODE_STRUCT) { ++ req->addr = (ulong)m; ++ r = lookup_struct_contents(req); ++ req->addr = (ulong)top_m; ++ if (r) ++ return 1; ++ } + -+ const char *exp = args; ++ if (m->code == TYPE_CODE_PTR && m->target_type) ++ m = m->target_type->main_type; ++ if (m->name) ++ n = m->name; ++ else ++ continue; + -+ if (exp != nullptr && *exp) -+ { -+ expression_up expr = parse_expression (exp); -+ val = evaluate_expression (expr.get ()); ++ if (strstr(n, type_name)) ++ return 1; + } -+ else -+ val = access_value_history (0); + -+ printf_filtered ("%d %d %ld %ld %ld %ld\n", -+ check_typedef(value_type (val))->code(), -+ TYPE_UNSIGNED (check_typedef(value_type (val))), -+ TYPE_LENGTH (check_typedef(value_type(val))), -+ value_offset (val), value_bitpos (val), value_bitsize(val)); ++ return 0; +} + +static void -+printm_command (const char *exp, int from_tty) ++iterate_datatypes (struct gnu_request *req) +{ -+ print_command_2 (exp, 1); -+} ++ for (objfile *objfile : current_program_space->objfiles ()) ++ { ++ if (objfile->sf) ++ objfile->sf->qf->expand_all_symtabs(objfile); + - /* See valprint.h. */ - - void -@@ -2855,6 +2901,12 @@ but no count or size letter (see \"x\" command)."), - c = add_com ("print", class_vars, print_command, print_help.c_str ()); - set_cmd_completer_handle_brkchars (c, print_command_completer); - add_com_alias ("p", "print", class_vars, 1); ++ for (compunit_symtab *cust : objfile->compunits ()) ++ { ++ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); + -+ c = add_com ("printm", class_vars, printm_command, _("\ -+Similar to \"print\" command, but it used to print the type, size, offset,\n\ -+bitpos and bitsize of the expression EXP.")); -+ set_cmd_completer (c, expression_completer); ++ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i) ++ { ++ const struct block *b = BLOCKVECTOR_BLOCK (bv, i); ++ struct block_iterator iter; ++ struct symbol *sym; + - add_com_alias ("inspect", "print", class_vars, 1); - - add_setshow_uinteger_cmd ("max-symbolic-offset", no_class, ---- gdb-10.2/gdb/psymtab.c.orig -+++ gdb-10.2/gdb/psymtab.c -@@ -283,6 +283,9 @@ find_pc_sect_psymtab_closer (struct objfile *objfile, - return best_pst; - } - -+#ifdef CRASH_MERGE -+ extern "C" int gdb_line_number_callback(unsigned long, unsigned long, unsigned long); -+#endif - /* Find which partial symtab contains PC and SECTION. Return NULL if - none. We return the psymtab that contains a symbol whose address - exactly matches PC, or, if we cannot find an exact match, the -@@ -363,7 +366,12 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, - - best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst, - msymbol); -+#ifdef CRASH_MERGE -+ if ((best_pst != NULL) && -+ gdb_line_number_callback(pc, pst->text_low (objfile), pst->text_high (objfile))) -+#else - if (best_pst != NULL) -+#endif - return best_pst; - } - ---- gdb-10.2/gdb/symfile.c.orig -+++ gdb-10.2/gdb/symfile.c -@@ -652,7 +652,26 @@ default_symfile_offsets (struct objfile *objfile, - for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) - /* We do not expect this to happen; just skip this step if the - relocatable file has a section with an assigned VMA. */ -- if (bfd_section_vma (cur_sec) != 0) -+ if (bfd_section_vma (cur_sec) != 0 -+ /* -+ * Kernel modules may have some non-zero VMAs, i.e., like the -+ * __ksymtab and __ksymtab_gpl sections in this example: -+ * -+ * Section Headers: -+ * [Nr] Name Type Address Offset -+ * Size EntSize Flags Link Info Align -+ * ... -+ * [ 8] __ksymtab PROGBITS 0000000000000060 0000ad90 -+ * 0000000000000010 0000000000000000 A 0 0 16 -+ * [ 9] .rela__ksymtab RELA 0000000000000000 0000ada0 -+ * 0000000000000030 0000000000000018 43 8 8 -+ * [10] __ksymtab_gpl PROGBITS 0000000000000070 0000add0 -+ * 00000000000001a0 0000000000000000 A 0 0 16 -+ * ... -+ * -+ * but they should be treated as if they are NULL. -+ */ -+ && strncmp (bfd_section_name (cur_sec), "__k", 3) != 0) - break; - - if (cur_sec == NULL) -@@ -1083,6 +1102,12 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, - if (mainline) - flags |= OBJF_MAINLINE; - objfile = objfile::make (abfd, name, flags, parent); -+#ifdef CRASH_MERGE -+ if (add_flags & SYMFILE_MAINLINE) { -+ extern struct objfile *gdb_kernel_objfile; -+ gdb_kernel_objfile = objfile; -+ } -+#endif - - /* We either created a new mapped symbol table, mapped an existing - symbol table file which has not had initial symbol reading -@@ -1375,6 +1400,10 @@ show_debug_file_directory (struct ui_file *file, int from_tty, - #if ! defined (DEBUG_SUBDIRECTORY) - #define DEBUG_SUBDIRECTORY ".debug" - #endif -+#ifdef CRASH_MERGE -+extern "C" int check_specified_module_tree(const char *, const char *); -+extern "C" char *check_specified_kernel_debug_file(); -+#endif - - /* Find a separate debuginfo file for OBJFILE, using DIR as the directory - where the original file resides (may not be the same as -@@ -1410,6 +1439,15 @@ find_separate_debug_file (const char *dir, - if (separate_debug_file_exists (debugfile, crc32, objfile)) - return debugfile; - -+#ifdef CRASH_MERGE -+{ -+ if (check_specified_module_tree(objfile_name (objfile), debugfile.c_str()) && -+ separate_debug_file_exists(debugfile, crc32, objfile)) { -+ return debugfile; -+ } ++ ALL_BLOCK_SYMBOLS (b, iter, sym) ++ { ++ QUIT; ++ ++ if (SYMBOL_CLASS (sym) != LOC_TYPEDEF) ++ continue; ++ ++ if (req->highest && ++ !(req->lowest <= sym->type->length && sym->type->length <= req->highest)) ++ continue; ++ ++ req->addr = (ulong)(sym->type->main_type); ++ req->name = (char *)(sym->m_name); ++ req->length = sym->type->length; ++ ++ if (req->member) { ++ req->value = lookup_struct_contents(req); ++ if (!req->value) ++ continue; ++ } ++ req->callback(req, req->callback_data); ++ } ++ } ++ } ++ } +} +#endif +diff -Nuar gdb-10.2/gdb/syscalls/sw_64-linux.xml gdb-10.2/gdb/syscalls/sw_64-linux.xml +--- gdb-10.2/gdb/syscalls/sw_64-linux.xml 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/syscalls/sw_64-linux.xml 2025-04-16 17:06:51.982086800 +0800 +@@ -0,0 +1,478 @@ ++ ++ + - return debugfile; - } - -@@ -2334,8 +2380,10 @@ add_symbol_file_command (const char *args, int from_tty) - else if (section_addrs.empty ()) - printf_unfiltered ("\n"); - -+#ifndef CRASH_MERGE - if (from_tty && (!query ("%s", ""))) - error (_("Not confirmed.")); -+#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/syscalls/sw_64-linux.xml.in gdb-10.2/gdb/syscalls/sw_64-linux.xml.in +--- gdb-10.2/gdb/syscalls/sw_64-linux.xml.in 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdb/syscalls/sw_64-linux.xml.in 2025-04-16 17:06:51.992086800 +0800 +@@ -0,0 +1,479 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nuar gdb-10.2/gdb/ui-file.h gdb-10.2/gdb/ui-file.h +--- gdb-10.2/gdb/ui-file.h 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdb/ui-file.h 2025-04-16 17:06:41.912086800 +0800 +@@ -195,10 +195,10 @@ - objf = symbol_file_add (filename.get (), add_flags, §ion_addrs, - flags); -@@ -3622,6 +3670,15 @@ bfd_byte * - symfile_relocate_debug_section (struct objfile *objfile, - asection *sectp, bfd_byte *buf) - { -+#ifdef CRASH_MERGE -+ /* Executable files have all the relocations already resolved. -+ * Handle files linked with --emit-relocs. -+ * http://sources.redhat.com/ml/gdb/2006-08/msg00137.html -+ */ -+ bfd *abfd = objfile->obfd; -+ if ((abfd->flags & EXEC_P) != 0) -+ return NULL; -+#endif - gdb_assert (objfile->sf->sym_relocate); + bool can_emit_style_escape () override; - return (*objfile->sf->sym_relocate) (objfile, sectp, buf); ---- gdb-10.2/gdb/symtab.c.orig -+++ gdb-10.2/gdb/symtab.c -@@ -1870,27 +1870,46 @@ search_name_hash (enum language language, const char *search_name) - variable and thus can probably assume it will never hit the C++ - code). */ +-private: + /* Sets the internal stream to FILE, and saves the FILE's file + descriptor in M_FD. */ + void set_stream (FILE *file); ++private: -+#ifdef CRASH_MERGE -+static void gdb_bait_and_switch(char *, struct symbol *); -+#endif -+ - struct block_symbol - lookup_symbol_in_language (const char *name, const struct block *block, - const domain_enum domain, enum language lang, - struct field_of_this_result *is_a_field_of_this) + /* The file. */ + FILE *m_file; +diff -Nuar gdb-10.2/gdb/xml-syscall.c gdb-10.2/gdb/xml-syscall.c +--- gdb-10.2/gdb/xml-syscall.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdb/xml-syscall.c 2025-04-16 17:06:41.912086800 +0800 +@@ -37,7 +37,11 @@ + static void + syscall_warn_user (void) { -+ struct block_symbol result; - demangle_result_storage storage; - const char *modified_name = demangle_for_lookup (name, lang, storage); - -- return lookup_symbol_aux (modified_name, -+ result = lookup_symbol_aux (modified_name, - symbol_name_match_type::FULL, - block, domain, lang, - is_a_field_of_this); +#ifdef CRASH_MERGE -+ if (result.symbol && (domain == VAR_DOMAIN)) -+ gdb_bait_and_switch((char *)modified_name, result.symbol); ++ static int have_warned = 1; ++#else + static int have_warned = 0; +#endif -+ return result; - } - - /* See symtab.h. */ - -+#ifdef CRASH_MERGE -+static const struct block *gdb_get_crash_block(void); + if (!have_warned) + { + have_warned = 1; +diff -Nuar gdb-10.2/gdbserver/configure.srv gdb-10.2/gdbserver/configure.srv +--- gdb-10.2/gdbserver/configure.srv 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdbserver/configure.srv 2025-04-16 17:06:51.992086800 +0800 +@@ -372,8 +372,31 @@ + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; ++# sw_64*-*-linux*) srv_regobj="sw_64-linux.o" ++# srv_regobj="${srv_regobj} sw_64-linux.o" ++# srv_tgtobj="$srv_linux_obj linux-sw_64-low.o" ++# srv_tgtobj="${srv_tgtobj} nat/sw_64-linux-watch.o" ++# srv_xmlfiles="sw_64-linux.xml" ++# srv_xmlfiles="${srv_xmlfiles} sw_64-linux.xml" ++# srv_xmlfiles="${srv_xmlfiles} sw_64-cpu.xml" ++# srv_xmlfiles="${srv_xmlfiles} sw_64-fpu.xml" ++# srv_xmlfiles="${srv_xmlfiles} sw_64-efu.xml" ++# srv_xmlfiles="${srv_xmlfiles} sw_64-vec.xml" ++# srv_linux_regsets=yes ++# srv_linux_usrregs=yes ++# srv_linux_thread_db=yes ++# ;; ++ ++# alpha*-*-linux* | sw_64*-*-linux*) srv_regobj="sw_64-linux.o" ++# srv_tgtobj="linux-sw_64-low.o sw_64-linux-watch.o" ++# srv_tgtobj="${srv_tgtobj} $srv_linux_obj " ++# srv_linux_usrregs=yes ++# srv_linux_regsets=no ++# srv_linux_thread_db=yes ++# srv_xmlfiles="sw_64-linux.xml" ++# ;; + *) +- # Who are you? ++ # Who are you? SBW_ + UNSUPPORTED=1 + ;; + esac +diff -Nuar gdb-10.2/gdbserver/linux-sw_64-low.cc gdb-10.2/gdbserver/linux-sw_64-low.cc +--- gdb-10.2/gdbserver/linux-sw_64-low.cc 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/gdbserver/linux-sw_64-low.cc 2025-04-16 17:06:51.992086800 +0800 +@@ -0,0 +1,958 @@ ++/* GNU/Linux/sw_64 specific low level interface, for the remote server for GDB. ++ Copyright (C) 1995-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#include "server.h" ++#include "linux-low.h" ++#include "tdesc.h" ++#include "nat/gdb_ptrace.h" ++#include ++ ++#include "nat/sw_64-linux-watch.h" ++#include "gdb_proc_service.h" ++ ++ ++/* Linux target op definitions for the MIPS architecture. */ ++ ++class sw_64_target : public linux_process_target ++{ ++public: ++ ++ const regs_info *get_regs_info () override; ++ ++ const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override; ++ ++ bool supports_z_point_type (char z_type) override; ++ ++protected: ++ ++ void low_arch_setup () override; ++ ++ bool low_cannot_fetch_register (int regno) override; ++ ++ bool low_cannot_store_register (int regno) override; ++ ++ bool low_fetch_register (regcache *regcache, int regno) override; ++ ++ bool low_supports_breakpoints () override; ++ ++ CORE_ADDR low_get_pc (regcache *regcache) override; ++ ++ void low_set_pc (regcache *regcache, CORE_ADDR newpc) override; ++ ++ bool low_breakpoint_at (CORE_ADDR pc) override; ++ ++ int low_insert_point (raw_bkpt_type type, CORE_ADDR addr, ++ int size, raw_breakpoint *bp) override; ++ ++ int low_remove_point (raw_bkpt_type type, CORE_ADDR addr, ++ int size, raw_breakpoint *bp) override; ++ ++ bool low_stopped_by_watchpoint () override; ++ ++ CORE_ADDR low_stopped_data_address () override; ++ ++ void low_collect_ptrace_register (regcache *regcache, int regno, ++ char *buf) override; ++ ++ void low_supply_ptrace_register (regcache *regcache, int regno, ++ const char *buf) override; ++ ++ arch_process_info *low_new_process () override; ++ ++ void low_delete_process (arch_process_info *info) override; ++ ++ void low_new_thread (lwp_info *) override; ++ ++ void low_delete_thread (arch_lwp_info *) override; ++ ++ void low_new_fork (process_info *parent, process_info *child) override; ++ ++ void low_prepare_to_resume (lwp_info *lwp) override; ++}; ++ ++/* The singleton target ops object. */ ++ ++static sw_64_target the_sw_64_target; ++ ++/* Defined in auto-generated file sw_64-linux.c. */ ++void init_registers_sw_64_linux (void); ++extern const struct target_desc *tdesc_sw_64_linux; ++ ++ ++#ifndef PTRACE_GET_THREAD_AREA ++#define PTRACE_GET_THREAD_AREA 25 +#endif + - struct block_symbol - lookup_symbol (const char *name, const struct block *block, - domain_enum domain, - struct field_of_this_result *is_a_field_of_this) - { -+#ifdef CRASH_MERGE -+ if (!block) -+ block = gdb_get_crash_block(); ++#ifdef HAVE_SYS_REG_H ++#include +#endif ++//#define sw_64_num_regs 73 ++#include ++#include + - return lookup_symbol_in_language (name, block, domain, - current_language->la_language, - is_a_field_of_this); -@@ -6886,3 +6905,806 @@ If zero then the symbol cache is disabled."), - gdb::observers::new_objfile.attach (symtab_new_objfile_observer); - gdb::observers::free_objfile.attach (symtab_free_objfile_observer); - } + -+#ifdef CRASH_MERGE -+#include "gdb-stabs.h" -+#include "gdbsupport/version.h" -+#define GDB_COMMON -+#include "../../defs.h" ++union sw_64_register ++{ ++ unsigned char buf[8]; + -+static void get_member_data(struct gnu_request *, struct type *, long, int); -+static void dump_enum(struct type *, struct gnu_request *); -+static void eval_enum(struct type *, struct gnu_request *); -+static void gdb_get_line_number(struct gnu_request *); -+static void gdb_get_datatype(struct gnu_request *); -+static void gdb_get_symbol_type(struct gnu_request *); -+static void gdb_command_exists(struct gnu_request *); -+static void gdb_debug_command(struct gnu_request *); -+static void gdb_function_numargs(struct gnu_request *); -+static void gdb_add_symbol_file(struct gnu_request *); -+static void gdb_delete_symbol_file(struct gnu_request *); -+static void gdb_patch_symbol_values(struct gnu_request *); -+static void get_user_print_option_address(struct gnu_request *); -+extern int get_frame_offset(CORE_ADDR); -+static void gdb_set_crash_block(struct gnu_request *); -+extern "C" void gdb_command_funnel(struct gnu_request *); -+void gdb_command_funnel_1(struct gnu_request *); -+static long lookup_struct_contents(struct gnu_request *); -+static void iterate_datatypes(struct gnu_request *); ++ /* Deliberately signed, for proper sign extension. */ ++ int reg32; ++ long long reg64; ++}; + -+struct objfile *gdb_kernel_objfile = { 0 }; ++int gcc_backtrace(); ++void exc_handler(int, siginfo_t*, void*); ++extern int tohex (int nib); ++extern int bin2hex (const gdb_byte *bin, char *hex, int count); ++extern long dva_match_addr; ++extern long status_cg[]; ++extern struct lwp_info *add_lwp (ptid_t ptid); + -+static ulong gdb_merge_flags = 0; -+#define KERNEL_SYMBOLS_PATCHED (0x1) ++/* Return the ptrace ``address'' of register REGNO. */ ++#define FPR_BASE 32 + -+#undef STREQ -+#define STREQ(A, B) (A && B && (strcmp(A, B) == 0)) -+#define TYPE_CODE(t) (t->code ()) -+#define TYPE_TAG_NAME(t) (TYPE_MAIN_TYPE(t)->name) -+#define TYPE_NFIELDS(t) (t->num_fields ()) -+#define TYPE_NAME(t) (t->name ()) ++/* 0~63 general, 64 pc, 65-69 hwbpt/da_match,70-101 simd */ ++static int sw_64_regmap[] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, ++ 24, 25, 26, 27, 28, 29, 30, 31, ++ FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, ++ FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, ++ FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, ++ FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, ++ FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, ++ FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, ++ FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, ++ FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, ++ REG_PC, -1,-1, /* NULL and unique */ ++ REG_V0F1, REG_V0F1 + 1, REG_V0F1 + 2, REG_V0F1 + 3, ++ REG_V0F1 + 4, REG_V0F1 + 5, REG_V0F1 + 6, REG_V0F1 + 7, ++ REG_V0F1 + 8, REG_V0F1 + 9, REG_V0F1 + 10, REG_V0F1 + 11, ++ REG_V0F1 + 12, REG_V0F1 + 13, REG_V0F1 + 14, REG_V0F1 + 15, ++ REG_V0F1 + 16, REG_V0F1 + 17, REG_V0F1 + 18, REG_V0F1 + 19, ++ REG_V0F1 + 20, REG_V0F1 + 21, REG_V0F1 + 22, REG_V0F1 + 23, ++ REG_V0F1 + 24, REG_V0F1 + 25, REG_V0F1 + 26, REG_V0F1 + 27, ++ REG_V0F1 + 28, REG_V0F1 + 29, REG_V0F1 + 30, REG_V0F1 + 31, ++ REG_V0F2, REG_V0F2 + 1, REG_V0F2 + 2, REG_V0F2 + 3, ++ REG_V0F2 + 4, REG_V0F2 + 5, REG_V0F2 + 6, REG_V0F2 + 7, ++ REG_V0F2 + 8, REG_V0F2 + 9, REG_V0F2 + 10, REG_V0F2 + 11, ++ REG_V0F2 + 12, REG_V0F2 + 13, REG_V0F2 + 14, REG_V0F2 + 15, ++ REG_V0F2 + 16, REG_V0F2 + 17, REG_V0F2 + 18, REG_V0F2 + 19, ++ REG_V0F2 + 20, REG_V0F2 + 21, REG_V0F2 + 22, REG_V0F2 + 23, ++ REG_V0F2 + 24, REG_V0F2 + 25, REG_V0F2 + 26, REG_V0F2 + 27, ++ REG_V0F2 + 28, REG_V0F2 + 29, REG_V0F2 + 30, REG_V0F2 + 31, ++ REG_V0F3, REG_V0F3 + 1, REG_V0F3 + 2, REG_V0F3 + 3, ++ REG_V0F3 + 4, REG_V0F3 + 5, REG_V0F3 + 6, REG_V0F3 + 7, ++ REG_V0F3 + 8, REG_V0F3 + 9, REG_V0F3 + 10, REG_V0F3 + 11, ++ REG_V0F3 + 12, REG_V0F3 + 13, REG_V0F3 + 14, REG_V0F3 + 15, ++ REG_V0F3 + 16, REG_V0F3 + 17, REG_V0F3 + 18, REG_V0F3 + 19, ++ REG_V0F3 + 20, REG_V0F3 + 21, REG_V0F3 + 22, REG_V0F3 + 23, ++ REG_V0F3 + 24, REG_V0F3 + 25, REG_V0F3 + 26, REG_V0F3 + 27, ++ REG_V0F3 + 28, REG_V0F3 + 29, REG_V0F3 + 30, REG_V0F3 + 31, ++ -1, ++}; + -+/* -+ * All commands from above come through here. -+ */ -+void -+gdb_command_funnel(struct gnu_request *req) ++ ++/* Try peeking at an arbitrarily chosen DSP register and pick the available ++ user register set accordingly. */ ++ ++static const struct target_desc * ++sw_64_read_description (void) +{ -+ try { -+ gdb_command_funnel_1(req); -+ } catch (const gdb_exception &ex) { -+ if (req->flags & GNU_RETURN_ON_ERROR) -+ req->flags |= GNU_COMMAND_FAILED; -+ else -+ throw ex; -+ } ++ return tdesc_sw_64_linux; +} + +void -+gdb_command_funnel_1(struct gnu_request *req) ++sw_64_target::low_arch_setup () +{ -+ struct symbol *sym; -+ -+ if (req->command != GNU_VERSION && req->command != GNU_USER_PRINT_OPTION) { -+ (dynamic_castgdb_stdout)->set_stream(req->fp); -+ (dynamic_castgdb_stderr)->set_stream(req->fp); -+ } ++ current_process ()->tdesc = sw_64_read_description (); ++} + -+ switch (req->command) -+ { -+ case GNU_VERSION: -+ req->buf = (char *)version; -+ break; ++/* Per-process arch-specific data we want to keep. */ + -+ case GNU_PASS_THROUGH: -+ execute_command(req->buf, -+ req->flags & GNU_FROM_TTY_OFF ? FALSE : TRUE); -+ break; ++struct arch_process_info ++{ ++//#if 0 ++/* -1 if the kernel and/or CPU do not support watch registers. ++ 1 if watch_readback is valid and we can read style, num_valid ++ and the masks. ++ 0 if we need to read the watch_readback. */ + -+ case GNU_USER_PRINT_OPTION: -+ get_user_print_option_address(req); -+ break; ++ int watch_readback_valid; + -+ case GNU_RESOLVE_TEXT_ADDR: -+ sym = find_pc_function(req->addr); -+ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) -+ req->flags |= GNU_COMMAND_FAILED; -+ break; ++ /* Cached watch register read values. */ + -+ case GNU_DISASSEMBLE: -+ if (req->addr2) -+ sprintf(req->buf, "disassemble 0x%lx 0x%lx", -+ req->addr, req->addr2); -+ else -+ sprintf(req->buf, "disassemble 0x%lx", req->addr); -+ execute_command(req->buf, TRUE); -+ break; ++ struct pt_watch_regs watch_readback; + -+ case GNU_ADD_SYMBOL_FILE: -+ gdb_add_symbol_file(req); -+ break; ++ /* Current watchpoint requests for this process. */ + -+ case GNU_DELETE_SYMBOL_FILE: -+ gdb_delete_symbol_file(req); -+ break; ++ struct sw_64_watchpoint *current_watches; + -+ case GNU_GET_LINE_NUMBER: -+ gdb_get_line_number(req); -+ break; ++ /* The current set of watch register values for writing the ++ registers. */ + -+ case GNU_GET_DATATYPE: -+ gdb_get_datatype(req); -+ break; ++ struct pt_watch_regs watch_mirror; ++//#endif ++}; + -+ case GNU_GET_SYMBOL_TYPE: -+ gdb_get_symbol_type(req); -+ break; ++/* Per-thread arch-specific data we want to keep. */ ++/* ++struct arch_lwp_info ++{ ++ Non-zero if our copy differs from what's recorded in the thread. */ ++ //int watch_registers_changed; ++//}; + -+ case GNU_COMMAND_EXISTS: -+ gdb_command_exists(req); -+ break; ++/* From sw_64-linux-nat.c. */ + -+ case GNU_ALPHA_FRAME_OFFSET: -+ req->value = 0; -+ break; ++/* Pseudo registers can not be read. ptrace does not provide a way to ++ read (or set) PS_REGNUM, and there's no point in reading or setting ++ ZERO_REGNUM, it's always 0. We also can not set BADVADDR, CAUSE, ++ or FCRIR via ptrace(). */ ++bool ++sw_64_target::low_cannot_fetch_register (int regno) ++{ ++ const struct target_desc *tdesc; + -+ case GNU_FUNCTION_NUMARGS: -+ gdb_function_numargs(req); -+ break; ++ if (get_regs_info ()->usrregs->regmap[regno] == -1) ++ return true; + -+ case GNU_DEBUG_COMMAND: -+ gdb_debug_command(req); -+ break; ++} ++bool ++sw_64_target::low_cannot_store_register (int regno) ++{ + -+ case GNU_PATCH_SYMBOL_VALUES: -+ gdb_patch_symbol_values(req); -+ break; ++ if (get_regs_info ()->usrregs->regmap[regno] == -1) ++ return true; + -+ case GNU_SET_CRASH_BLOCK: -+ gdb_set_crash_block(req); -+ break; ++ return false; ++} + -+ case GNU_GET_FUNCTION_RANGE: -+ { -+ CORE_ADDR start, end; -+ if (!find_pc_partial_function(req->pc, NULL, &start, &end)) -+ req->flags |= GNU_COMMAND_FAILED; -+ else { -+ req->addr = (ulong)start; -+ req->addr2 = (ulong)end; -+ } -+ } -+ break; ++bool ++sw_64_target::low_fetch_register (regcache *regcache, int regno) ++{ ++ const struct target_desc *tdesc = current_process ()->tdesc; + -+ case GNU_LOOKUP_STRUCT_CONTENTS: -+ req->value = lookup_struct_contents(req); -+ break; ++ if (find_regno (tdesc, "r0") == regno) ++ { ++ supply_register_zeroed (regcache, regno); ++ return true; ++ } + -+ case GNU_ITERATE_DATATYPES: -+ iterate_datatypes(req); -+ break; ++ return false; ++} + -+ default: -+ req->flags |= GNU_COMMAND_FAILED; -+ break; -+ } ++bool ++sw_64_target::low_supports_breakpoints () ++{ ++ return true; +} + -+/* -+ * Given a PC value, return the file and line number. -+ */ -+static void -+gdb_get_line_number(struct gnu_request *req) ++CORE_ADDR ++sw_64_target::low_get_pc (regcache *regcache) +{ -+ struct symtab_and_line sal; -+ struct objfile *objfile; -+ CORE_ADDR pc; ++ union sw_64_register pc; ++ collect_register_by_name (regcache, "pc", pc.buf); ++ return pc.reg64; ++} + -+#define LASTCHAR(s) (s[strlen(s)-1]) ++void ++sw_64_target::low_set_pc (regcache *regcache, CORE_ADDR pc) ++{ ++ union sw_64_register newpc; ++ newpc.reg64 = pc; + -+ /* -+ * Prime the addrmap pump. -+ */ -+ pc = req->addr; ++ supply_register_by_name (regcache, "pc", newpc.buf); ++} + -+ sal = find_pc_line(pc, 0); ++/* Correct in either endianness. */ ++static const unsigned int sw_64_breakpoint = 0x00000080; ++#define sw_64_breakpoint_len 4 + -+ if (!sal.symtab) { -+ /* -+ * If a module address line number can't be found, it's typically -+ * due to its addrmap still containing offset values because its -+ * objfile doesn't have full symbols loaded. -+ */ -+ if (req->lm) { -+ objfile = req->lm->loaded_objfile; -+ if (!objfile_has_full_symbols(objfile) && objfile->sf) { -+ objfile->sf->qf->expand_all_symtabs(objfile); -+ sal = find_pc_line(pc, 0); -+ } -+ } -+ if (!sal.symtab) { -+ req->buf[0] = '\0'; -+ return; -+ } -+ } ++/* Implementation of target ops method "sw_breakpoint_from_kind". */ + -+ if (sal.symtab->filename && SYMTAB_DIRNAME(sal.symtab)) { -+ if (sal.symtab->filename[0] == '/') -+ sprintf(req->buf, "%s: %d", -+ sal.symtab->filename, sal.line); -+ else -+ sprintf(req->buf, "%s%s%s: %d", -+ SYMTAB_DIRNAME(sal.symtab), -+ LASTCHAR(SYMTAB_DIRNAME(sal.symtab)) == '/' ? "" : "/", -+ sal.symtab->filename, sal.line); -+ } ++const gdb_byte * ++sw_64_target::sw_breakpoint_from_kind (int kind, int *size) ++{ ++ *size = sw_64_breakpoint_len; ++ return (const gdb_byte *) &sw_64_breakpoint; +} + ++bool ++sw_64_target::low_breakpoint_at (CORE_ADDR where) ++{ ++ unsigned int insn; + -+/* -+ * General purpose routine for determining datatypes. -+ */ ++ read_memory (where, (unsigned char *) &insn, 4); ++ if (insn == sw_64_breakpoint) ++ return true; ++ ++ /* If necessary, recognize more trap instructions here. GDB only uses the ++ one. */ ++ return false; ++} ++ ++/* Mark the watch registers of lwp, represented by ENTRY, as changed. */ + +static void -+gdb_get_datatype(struct gnu_request *req) ++update_watch_registers_callback (thread_info *thread) +{ -+ register struct type *type; -+ register struct type *typedef_type; -+ expression_up expr; -+ struct symbol *sym; -+ struct value *val; ++ struct lwp_info *lwp = get_thread_lwp (thread); + -+ if (gdb_CRASHDEBUG(2)) -+ console("gdb_get_datatype [%s] (a)\n", req->name); ++ /* The actual update is done later just before resuming the lwp, ++ we just mark that the registers need updating. */ ++ lwp->arch_private->watch_registers_changed = 1; + -+ req->typecode = TYPE_CODE_UNDEF; ++ /* If the lwp isn't stopped, force it to momentarily pause, so ++ we can update its watch registers. */ ++ if (!lwp->stopped) ++ linux_stop_lwp (lwp); ++} + -+ /* -+ * lookup_symbol() will pick up struct and union names. -+ */ -+ sym = lookup_symbol(req->name, 0, STRUCT_DOMAIN, 0).symbol; -+ if (sym) { -+ req->typecode = TYPE_CODE(sym->type); -+ req->length = TYPE_LENGTH(sym->type); -+ if (req->member) -+ get_member_data(req, sym->type, 0, 1); ++/* This is the implementation of linux target ops method ++ low_new_process. */ + -+ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) { -+ if (req->flags & GNU_PRINT_ENUMERATORS) -+ dump_enum(sym->type, req); -+ } ++arch_process_info * ++sw_64_target::low_new_process () ++{ ++ struct arch_process_info *info = XCNEW (struct arch_process_info); + -+ return; -+ } ++ return info; ++} + -+ /* -+ * Otherwise parse the expression. -+ */ -+ if (gdb_CRASHDEBUG(2)) -+ console("gdb_get_datatype [%s] (b)\n", req->name); ++/* This is the implementation of linux target ops method ++ low_delete_process. */ + -+ expr = parse_expression(req->name); ++void ++sw_64_target::low_delete_process (arch_process_info *info) ++{ ++ xfree (info); ++} + ++/* This is the implementation of linux target ops method low_new_thread. ++ Mark the watch registers as changed, so the threads' copies will ++ be updated. */ + -+ switch (expr.get()->elts[0].opcode) -+ { -+ case OP_VAR_VALUE: -+ if (gdb_CRASHDEBUG(2)) -+ console("expr->elts[0].opcode: OP_VAR_VALUE\n"); -+ type = expr.get()->elts[2].symbol->type; -+ if (req->flags & GNU_VAR_LENGTH_TYPECODE) { -+ req->typecode = TYPE_CODE(type); -+ req->length = TYPE_LENGTH(type); -+ } -+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) { -+ req->typecode = TYPE_CODE(type); -+ req->value = SYMBOL_VALUE(expr.get()->elts[2].symbol); -+ req->tagname = (char *)TYPE_TAG_NAME(type); -+ if (!req->tagname) { -+ val = evaluate_type(expr.get()); -+ eval_enum(value_type(val), req); -+ } -+ } -+ break; ++void ++sw_64_target::low_new_thread (lwp_info *lwp) ++{ ++ struct arch_lwp_info *info = XCNEW (struct arch_lwp_info); + -+ case OP_TYPE: -+ if (gdb_CRASHDEBUG(2)) -+ console("expr->elts[0].opcode: OP_TYPE\n"); -+ type = expr.get()->elts[1].type; ++ info->watch_registers_changed = 1; + -+ req->typecode = TYPE_CODE(type); -+ req->length = TYPE_LENGTH(type); ++ lwp->arch_private = info; ++} + -+ if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) { -+ req->is_typedef = TYPE_CODE_TYPEDEF; -+ if ((typedef_type = check_typedef(type))) { -+ req->typecode = TYPE_CODE(typedef_type); -+ req->length = TYPE_LENGTH(typedef_type); -+ type = typedef_type; -+ } -+ } ++/* Function to call when a thread is being deleted. */ + -+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) { -+ if (req->is_typedef) -+ if (req->flags & GNU_PRINT_ENUMERATORS) { -+ if (req->is_typedef) -+ fprintf_filtered(gdb_stdout, -+ "typedef "); -+ dump_enum(type, req); -+ } -+ } ++void ++sw_64_target::low_delete_thread (arch_lwp_info *arch_lwp) ++{ ++ xfree (arch_lwp); ++} + -+ if (req->member) -+ get_member_data(req, type, 0, 1); ++//#if 0 ++/* Create a new sw_64_watchpoint and add it to the list. */ + -+ break; ++static void ++sw_64_add_watchpoint (struct arch_process_info *priv, CORE_ADDR addr, int len, ++ enum target_hw_bp_type watch_type) ++{ ++ struct sw_64_watchpoint *new_watch; ++ struct sw_64_watchpoint **pw; + -+ default: -+ if (gdb_CRASHDEBUG(2)) -+ console("expr.get()->elts[0].opcode: %d (?)\n", -+ expr.get()->elts[0].opcode); -+ break; ++ new_watch = XNEW (struct sw_64_watchpoint); ++ new_watch->addr = addr; ++ new_watch->len = len; ++ new_watch->type = watch_type; ++ new_watch->next = NULL; + -+ } ++ pw = &priv->current_watches; ++ while (*pw != NULL) ++ pw = &(*pw)->next; ++ *pw = new_watch; +} ++//#endif ++/* Hook to call when a new fork is attached. */ + -+/* -+ * More robust enum list dump that gdb's, showing the value of each -+ * identifier, each on its own line. -+ */ -+static void -+dump_enum(struct type *type, struct gnu_request *req) ++void ++sw_64_target::low_new_fork (process_info *parent, ++ process_info *child) +{ -+ register int i; -+ int len; -+ long long lastval; ++ // struct arch_process_info *parent_private; ++ // struct arch_process_info *child_private; ++// struct sw_64_watchpoint *wp; + -+ len = TYPE_NFIELDS (type); -+ lastval = 0; -+ if (TYPE_TAG_NAME(type)) -+ fprintf_filtered(gdb_stdout, -+ "enum %s {\n", TYPE_TAG_NAME (type)); -+ else -+ fprintf_filtered(gdb_stdout, "enum {\n"); ++ /* These are allocated by linux_add_process. */ ++ gdb_assert (parent->priv != NULL ++ && parent->priv->arch_private != NULL); ++ gdb_assert (child->priv != NULL ++ && child->priv->arch_private != NULL); + -+ for (i = 0; i < len; i++) { -+ fprintf_filtered(gdb_stdout, " %s", -+ TYPE_FIELD_NAME (type, i)); -+ if (lastval != TYPE_FIELD_ENUMVAL (type, i)) { -+ fprintf_filtered (gdb_stdout, " = %s", -+ plongest(TYPE_FIELD_ENUMVAL (type, i))); -+ lastval = TYPE_FIELD_ENUMVAL (type, i); -+ } else -+ fprintf_filtered(gdb_stdout, " = %s", plongest(lastval)); -+ fprintf_filtered(gdb_stdout, "\n"); -+ lastval++; ++ /* Linux kernel before 2.6.33 commit ++ 72f674d203cd230426437cdcf7dd6f681dad8b0d ++ will inherit hardware debug registers from parent ++ on fork/vfork/clone. Newer Linux kernels create such tasks with ++ zeroed debug registers. ++ ++ GDB core assumes the child inherits the watchpoints/hw ++ breakpoints of the parent, and will remove them all from the ++ forked off process. Copy the debug registers mirrors into the ++ new process so that all breakpoints and watchpoints can be ++ removed together. The debug registers mirror will become zeroed ++ in the end before detaching the forked off process, thus making ++ this compatible with older Linux kernels too. */ ++ ++ /* parent_private = parent->priv->arch_private; ++ child_private = child->priv->arch_private; ++ ++ child_private->watch_readback_valid = parent_private->watch_readback_valid; ++ child_private->watch_readback = parent_private->watch_readback; ++ ++ for (wp = parent_private->current_watches; wp != NULL; wp = wp->next) ++ sw_64_add_watchpoint (child_private, wp->addr, wp->len, wp->type); ++ ++ child_private->watch_mirror = parent_private->watch_mirror; ++*/ ++} ++/* This is the implementation of linux target ops method ++ low_prepare_to_resume. If the watch regs have changed, update the ++ thread's copies. */ ++ ++enum sw_64_hw_bp_type ++sw_64_hw_bp_type_from_raw_type (enum raw_bkpt_type raw_type) ++{ ++ switch (raw_type) ++ { ++ case raw_bkpt_type_hw: ++ return sw_64_none; ++ case raw_bkpt_type_write_wp: ++ return sw_64_write; ++ case raw_bkpt_type_read_wp: ++ return sw_64_read; ++ case raw_bkpt_type_access_wp: ++ return sw_64_access; ++ case raw_bkpt_type_value_wp: ++ return sw_64_vstore; ++ default: ++ internal_error (__FILE__, __LINE__, ++ "bad raw breakpoint type %d", (int) raw_type); + } -+ if (TYPE_TAG_NAME(type)) -+ fprintf_filtered(gdb_stdout, "};\n"); -+ else -+ fprintf_filtered(gdb_stdout, "} %s;\n", req->name); +} + -+/* -+ * Given an enum type with no tagname, determine its value. -+ */ -+static void -+eval_enum(struct type *type, struct gnu_request *req) ++void ++sw_64_target::low_prepare_to_resume (lwp_info *lwp) +{ -+ register int i; -+ int len; -+ long long lastval; ++ int i; ++ ptid_t ptid = ptid_of (get_lwp_thread (lwp)); ++ struct arch_lwp_info *priv = lwp->arch_private; ++ //pid_t lwpid = ptid_of_lwp(ptid); ++ pid_t lwpid = ptid.lwp (); + -+ len = TYPE_NFIELDS (type); -+ lastval = 0; ++ if (!lwp->arch_private->watch_registers_changed) ++ return; + -+ for (i = 0; i < len; i++) { -+ if (lastval != TYPE_FIELD_ENUMVAL (type, i)) -+ lastval = TYPE_FIELD_ENUMVAL (type, i); ++ if ( priv->wpt[1].valid ) ++ { ++ store_debug_register (lwpid, M_DV_MATCH, priv->wpt[1].match); ++ store_debug_register (lwpid, M_DV_MATCH+1, priv->wpt[1].mask); ++ } ++ if ( priv->wpt[0].valid ) ++ { ++ store_debug_register (lwpid, M_DA_MATCH, priv->wpt->match); ++ store_debug_register (lwpid, M_DA_MASK, priv->wpt->mask); ++ } + -+ if (STREQ(TYPE_FIELD_NAME(type, i), req->name)) { -+ req->tagname = "(unknown)"; -+ req->value = lastval; -+ return; ++ i = (priv->wpt[1].valid<<1) | priv->wpt[0].valid; ++ ++ // setting dv_ctl ++ switch (i) ++ { ++ //da_match ++ case 0: ++ case 1: ++ //store_debug_register (lwpid, M_DV_MATCH+2, 0L); ++ break; ++ //dv_match ++ case 2: ++ store_debug_register (lwpid, M_DV_MATCH+2, 1); ++ break; ++ //dva_match ++ case 3: ++ store_debug_register (lwpid, M_DV_MATCH+2, 3); ++ break; ++ default: ++ ;; + } -+ lastval++; -+ } ++ ++ lwp->arch_private->watch_registers_changed = 0; +} + -+/* -+ * Walk through a struct type's list of fields looking for the desired -+ * member field, and when found, return its relevant data. -+ */ -+static void -+get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first) ++bool ++sw_64_target::supports_z_point_type (char z_type) +{ -+ register short i; -+ struct field *nextfield; -+ short nfields; -+ struct type *typedef_type, *target_type; ++ switch (z_type) ++ { ++ case Z_PACKET_SW_BP: ++ case Z_PACKET_HW_BP: ++ case Z_PACKET_WRITE_WP: ++ case Z_PACKET_READ_WP: ++ case Z_PACKET_ACCESS_WP: ++ case Z_PACKET_DV_WP: ++ return true; ++ default: ++ return false; ++ } ++} + -+ req->member_offset = -1; ++/* This is the implementation of linux target ops method ++ low_insert_point. */ + -+ nfields = TYPE_MAIN_TYPE(type)->nfields; -+ nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields; ++int ++sw_64_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr, ++ int len, raw_breakpoint *bp) ++{ ++int pid, i; ++ long lwpid, data; ++ enum sw_64_hw_bp_type watch_type; ++ struct lwp_info *lwp = get_thread_lwp (current_thread); ++ struct arch_lwp_info *priv = lwp->arch_private; + -+ if (nfields == 0 && is_first /* The first call */) { -+ struct type *newtype; -+ newtype = lookup_transparent_type(req->name); -+ if (newtype) { -+ console("get_member_data(%s.%s): switching type from %lx to %lx\n", -+ req->name, req->member, type, newtype); -+ nfields = TYPE_MAIN_TYPE(newtype)->nfields; -+ nextfield = TYPE_MAIN_TYPE(newtype)->flds_bnds.fields; -+ } -+ } ++ if (!addr) ++ return 0; + -+ for (i = 0; i < nfields; i++) { -+ if (STREQ(req->member, nextfield->name)) { -+ req->member_offset = offset + nextfield->loc.bitpos; -+ req->member_length = TYPE_LENGTH(nextfield->type()); -+ req->member_typecode = TYPE_CODE(nextfield->type()); -+ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type()); -+ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type()); -+ target_type = TYPE_TARGET_TYPE(nextfield->type()); -+ if (target_type) { -+ req->member_target_type_name = (char *)TYPE_NAME(target_type); -+ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type); -+ } -+ if ((req->member_typecode == TYPE_CODE_TYPEDEF) && -+ (typedef_type = check_typedef(nextfield->type()))) -+ req->member_length = TYPE_LENGTH(typedef_type); -+ return; -+ } else if (*nextfield->name == 0) { /* Anonymous struct/union */ -+ get_member_data(req, nextfield->type(), -+ offset + nextfield->loc.bitpos, 0); -+ if (req->member_offset != -1) -+ return; -+ } -+ nextfield++; ++ lwpid = lwpid_of (current_thread); ++ pid = pid_of (current_thread); ++ ++ if ( len <= 0 || !is_power_of_2 (len)) ++ return 0; ++ ++ /* Now try to add the new watch. */ ++ watch_type = sw_64_hw_bp_type_from_raw_type(type); ++ ++ if (sw_64_linux_try_one_watch(lwpid, priv, watch_type,addr,len)) ++ //find_inferior (&all_threads, update_watch_registers_callback, &pid); ++/* Only update the threads of this process. */ ++ for_each_thread (pid, update_watch_registers_callback); ++ return 0; ++} ++ ++/* This is the implementation of linux_target_ops method ++ stopped_by_watchpoint. The watchhi R and W bits indicate ++ the watch register triggered. */ ++/* Check master wp only now */ ++ ++static int ++sw_64_stopped_by_watchpoint (void) ++{ ++ pid_t lwpid = lwpid_of(current_thread); ++ struct lwp_info *lwp = get_thread_lwp (current_thread); ++ siginfo_t siginfo; ++ ++ /* Retrieve siginfo. */ ++ errno = 0; ++ ptrace (PTRACE_GETSIGINFO, lwpid, 0, &siginfo); ++ if (errno != 0) ++ { ++ warning("%s:%d GETSIGINFO return %d\n", __FILE__, __LINE__, errno); ++ return 0; } debug("GETSIGINFO %#x si_code=%#x si_signo=%d si_errno = %x", lwpid, siginfo.si_code, siginfo.si_signo,siginfo.si_errno); /* This must be a hardware breakpoint. */ ++ if (siginfo.si_signo != SIGTRAP ++ || (siginfo.si_code & 0xffff) != M_DA_MATCH_TRAP/* TRAP_HWBKPT */) ++ return 0; ++ debug("si_code=%#x si_signo=%d si_errno = %x pc=%#lx, data_address %#lx", siginfo.si_code, siginfo.si_signo,siginfo.si_errno,(long)siginfo.si_value.sival_ptr, (long)siginfo.si_addr); /* siginfo should return the accessed data address, not pc */ ++ if (siginfo.si_errno == 1) ++ lwp->arch_private->stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (lwp->arch_private->wpt->match & ((1L<<53)-1)); ++ else ++ lwp->arch_private->stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (lwp->arch_private->value_address); // get the saved ++ return 1; ++} ++ ++#define BTSIZE 20 ++int gcc_backtrace() ++{ ++ int j, nptrs; ++ void *buffer[BTSIZE]; ++ char **strings; ++ ++ nptrs = backtrace(buffer, BTSIZE); ++ ++ /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) ++ would produce similar output to the following: */ ++ ++ strings = backtrace_symbols(buffer, nptrs); ++ if (strings == NULL) { ++ perror("backtrace_symbols"); ++ return (EXIT_FAILURE); + } ++ ++ for (j = 0; j < nptrs; j++) ++ printf(" %s", strings[j]); ++ printf("\n"); ++ ++ free(strings); ++ return 0; +} + -+/* -+ * Check whether a command exists. If it doesn't, the command will be -+ * returned indirectly via the error_hook. -+ */ -+static void -+gdb_command_exists(struct gnu_request *req) ++void exc_handler(int sig, siginfo_t* info, void *arg) +{ -+ extern struct cmd_list_element *cmdlist; ++ //unsigned long ra; ++ //unsigned long sp, pc; ++ //ucontext_t *uc = (ucontext_t *)arg; ++#if 0 ++ register unsigned long __ra __asm__("$26"); ++ pc = uc->uc_mcontext.sc_pc; ++ ra = uc->uc_mcontext.sc_regs[26]; ++ sp = uc->uc_mcontext.sc_regs[30]; ++ printf("pc = %#lx, ra = %#lx, sp=%#lx, called from %#lx\n", pc, ra, sp, *(unsigned long*)sp); fflush(stdout); ++#else ++ gcc_backtrace(); ++#endif ++ exit(1); ++} ++/* This is the implementation of linux target ops method ++ low_remove_point. */ + -+ req->value = FALSE; -+ lookup_cmd((const char **)&req->name, cmdlist, "", NULL, 0, 1); -+ req->value = TRUE; ++int ++sw_64_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr, ++ int len, raw_breakpoint *bp) ++{ ++ int pid, i; ++ uint64_t match; ++ uint64_t data; ++ enum sw_64_hw_bp_type watch_type; ++ long lwpid; ++ struct lwp_info *lwp = get_thread_lwp (current_thread); ++ struct arch_lwp_info *priv = lwp->arch_private; ++ ++ /* Search for a known watch that matches. Then unlink and free it. */ ++ watch_type = sw_64_hw_bp_type_from_raw_type(type); ++ ++ pid = pid_of (current_thread); ++ lwpid = lwpid_of(current_thread); ++ if (!sw_64_linux_del_one_watch(lwpid, priv, watch_type,addr,len)) ++ { ++ warning("none wp about %#lx\n", (long)addr); ++ return -1; /* We don't know about it, fail doing nothing. */ ++ } ++ /* Only update the threads of this process. */ ++ //find_inferior (&all_threads, update_watch_registers_callback, &pid); ++ for_each_thread (pid, update_watch_registers_callback); ++ return 0; +} + -+static void -+gdb_function_numargs(struct gnu_request *req) -+{ -+ struct symbol *sym; ++/* This is the implementation of linux target ops method ++ low_stopped_by_watchpoint. The watchhi R and W bits indicate ++ the watch register triggered. */ + -+ sym = find_pc_function(req->pc); -+ -+ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) { -+ req->flags |= GNU_COMMAND_FAILED; -+ return; -+ } ++bool ++sw_64_target::low_stopped_by_watchpoint () ++{ ++ pid_t lwpid = lwpid_of(current_thread); ++ struct lwp_info *lwp = get_thread_lwp (current_thread); ++ siginfo_t siginfo; + -+ req->value = (ulong)TYPE_NFIELDS(sym->type); ++ /* Retrieve siginfo. */ ++ errno = 0; ++ ptrace (PTRACE_GETSIGINFO, lwpid, 0, &siginfo); ++ if (errno != 0) ++ { ++ warning("%s:%d GETSIGINFO return %d\n", __FILE__, __LINE__, errno); ++ return 0; } debug("GETSIGINFO %#x si_code=%#x si_signo=%d si_errno = %x", lwpid, siginfo.si_code, siginfo.si_signo,siginfo.si_errno); ++ /* This must be a hardware breakpoint. */ ++ if (siginfo.si_signo != SIGTRAP ++ || (siginfo.si_code & 0xffff) != M_DA_MATCH_TRAP/* TRAP_HWBKPT */) ++ return 0; ++ debug("si_code=%#x si_signo=%d si_errno = %x pc=%#lx, data_address %#lx", siginfo.si_code, siginfo.si_signo,siginfo.si_errno,(long)siginfo.si_value.sival_ptr, (long)siginfo.si_addr); ++ /* siginfo should return the accessed data address, not pc */ ++ if (siginfo.si_errno == 1) ++ lwp->arch_private->stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (lwp->arch_private->wpt->match & ((1L<<53)-1)); ++ else ++ lwp->arch_private->stopped_data_address ++ = (CORE_ADDR) (uintptr_t) (lwp->arch_private->value_address); // get the saved ++ return 1; +} ++/* This is the implementation of linux target ops method ++ low_stopped_data_address. */ + -+struct load_module *gdb_current_load_module = NULL; -+ -+static void -+gdb_add_symbol_file(struct gnu_request *req) ++CORE_ADDR ++sw_64_target::low_stopped_data_address () +{ -+ struct load_module *lm; -+ int i; -+ int allsect = 0; -+ char *secname; -+ char buf[80]; ++ struct lwp_info *lwp; + -+ gdb_current_load_module = lm = (struct load_module *)req->addr; ++ lwp = get_thread_lwp (current_thread); ++ sw_64_stopped_by_watchpoint(); + -+ req->name = lm->mod_namelist; -+ gdb_delete_symbol_file(req); -+ lm->loaded_objfile = NULL; ++ return lwp->arch_private->stopped_data_address; ++} + -+ if ((lm->mod_flags & MOD_NOPATCH) == 0) { -+ for (i = 0 ; i < lm->mod_sections; i++) { -+ if (STREQ(lm->mod_section_data[i].name, ".text") && -+ (lm->mod_section_data[i].flags & SEC_FOUND)) -+ allsect = 1; -+ } + -+ if (!allsect) { -+ sprintf(req->buf, "add-symbol-file %s 0x%lx %s", lm->mod_namelist, -+ lm->mod_text_start ? lm->mod_text_start : lm->mod_base, -+ lm->mod_flags & MOD_DO_READNOW ? "-readnow" : ""); -+ if (lm->mod_data_start) { -+ sprintf(buf, " -s .data 0x%lx", lm->mod_data_start); -+ strcat(req->buf, buf); -+ } -+ if (lm->mod_bss_start) { -+ sprintf(buf, " -s .bss 0x%lx", lm->mod_bss_start); -+ strcat(req->buf, buf); -+ } -+ if (lm->mod_rodata_start) { -+ sprintf(buf, " -s .rodata 0x%lx", lm->mod_rodata_start); -+ strcat(req->buf, buf); -+ } -+ } else { -+ sprintf(req->buf, "add-symbol-file %s 0x%lx %s", lm->mod_namelist, -+ lm->mod_text_start, lm->mod_flags & MOD_DO_READNOW ? -+ "-readnow" : ""); -+ for (i = 0; i < lm->mod_sections; i++) { -+ secname = lm->mod_section_data[i].name; -+ if ((lm->mod_section_data[i].flags & SEC_FOUND) && -+ !STREQ(secname, ".text")) { -+ sprintf(buf, " -s %s 0x%lx", secname, -+ lm->mod_section_data[i].offset + lm->mod_base); -+ strcat(req->buf, buf); -+ } -+ } -+ } -+ } ++/* Fetch the thread-local storage pointer for libthread_db. */ + -+ if (gdb_CRASHDEBUG(1)) -+ fprintf_filtered(gdb_stdout, "%s\n", req->buf); ++ps_err_e ++ps_get_thread_area (struct ps_prochandle *ph, ++ lwpid_t lwpid, int idx, void **base) ++{ ++ if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) ++ return PS_ERR; + -+ execute_command(req->buf, FALSE); ++ /* IDX is the bias from the thread pointer to the beginning of the ++ thread descriptor. It has to be subtracted due to implementation ++ quirks in libthread_db. */ ++ *base = (void *) ((char *)*base - idx); + -+ for (objfile *objfile : current_program_space->objfiles ()) { -+ if (same_file((char *)objfile_name(objfile), lm->mod_namelist)) { -+ if (objfile->separate_debug_objfile) -+ lm->loaded_objfile = objfile->separate_debug_objfile; -+ else -+ lm->loaded_objfile = objfile; -+ break; -+ } -+ } ++ return PS_OK; ++} + -+ if (!lm->loaded_objfile) -+ req->flags |= GNU_COMMAND_FAILED; ++/* Fetch the thread-local storage pointer for libthread_db. */ ++ ++#ifdef HAVE_PTRACE_GETREGS ++static void ++sw_64_collect_register (struct regcache *regcache, ++ int use_64bit, int regno, union sw_64_register *reg) ++{ ++ union sw_64_register tmp_reg; ++ ++ if (use_64bit) ++ { ++ collect_register (regcache, regno, &tmp_reg.reg64); ++ *reg = tmp_reg; ++ } ++ else ++ { ++ collect_register (regcache, regno, &tmp_reg.reg32); ++ reg->reg64 = tmp_reg.reg32; ++ } +} + +static void -+gdb_delete_symbol_file(struct gnu_request *req) ++sw_64_supply_register (struct regcache *regcache, ++ int use_64bit, int regno, const union sw_64_register *reg) +{ -+ for (objfile *objfile : current_program_space->objfiles ()) { -+ if (STREQ(objfile_name(objfile), req->name) || -+ same_file((char *)objfile_name(objfile), req->name)) { -+ objfile->unlink (); -+ break; -+ } -+ } ++ int offset = 0; + -+ if (gdb_CRASHDEBUG(2)) { -+ fprintf_filtered(gdb_stdout, "current object files:\n"); -+ for (objfile *objfile : current_program_space->objfiles ()) -+ fprintf_filtered(gdb_stdout, " %s\n", objfile_name(objfile)); -+ } ++ /* For big-endian 32-bit targets, ignore the high four bytes of each ++ eight-byte slot. */ ++ if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit) ++ offset = 4; ++ ++ supply_register (regcache, regno, reg->buf + offset); +} + -+/* -+ * Walk through all minimal_symbols, patching their values with the -+ * correct addresses. -+ */ ++//#ifdef HAVE_PTRACE_GETREGS ++ ++ +static void -+gdb_patch_symbol_values(struct gnu_request *req) ++sw_64_fill_gregset (struct regcache *regcache, void *buf) +{ -+ req->name = PATCH_KERNEL_SYMBOLS_START; -+ patch_kernel_symbol(req); ++ union sw_64_register *regset = (union sw_64_register *) buf; ++ int i, use_64bit; ++ const struct target_desc *tdesc = regcache->tdesc; + -+ for (objfile *objfile : current_program_space->objfiles ()) -+ for (minimal_symbol *msymbol : objfile->msymbols ()) -+ { -+ req->name = (char *)msymbol->m_name; -+ req->addr = (ulong)(&MSYMBOL_VALUE(msymbol)); -+ if (!patch_kernel_symbol(req)) { -+ req->flags |= GNU_COMMAND_FAILED; -+ break; -+ } -+ } ++ use_64bit = (register_size (tdesc, 0) == 8); + -+ req->name = PATCH_KERNEL_SYMBOLS_STOP; -+ patch_kernel_symbol(req); ++ for (i = 1; i < 32; i++) ++ sw_64_collect_register (regcache, use_64bit, i, regset + i); + -+ clear_symtab_users(0); -+ gdb_merge_flags |= KERNEL_SYMBOLS_PATCHED; ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "lo"), regset + 32); ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "hi"), regset + 33); ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "pc"), regset + 34); ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "badvaddr"), regset + 35); ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "status"), regset + 36); ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "cause"), regset + 37); ++ ++ sw_64_collect_register (regcache, use_64bit, ++ find_regno (tdesc, "restart"), regset + 0); +} + +static void -+gdb_get_symbol_type(struct gnu_request *req) ++sw_64_store_gregset (struct regcache *regcache, const void *buf) +{ -+ expression_up expr; -+ struct value *val; -+ struct type *type; -+ struct type *target_type; -+ -+ req->typecode = TYPE_CODE_UNDEF; ++ const union sw_64_register *regset = (const union sw_64_register *) buf; ++ int i, use_64bit; + -+ expr = parse_expression (req->name); -+ val = evaluate_type (expr.get()); ++ use_64bit = (register_size (regcache->tdesc, 0) == 8); + -+ type = value_type(val); ++ supply_register_by_name_zeroed (regcache, "r0"); + -+ req->type_name = (char *)TYPE_MAIN_TYPE(type)->name; -+ req->typecode = TYPE_MAIN_TYPE(type)->code; -+ req->length = type->length; -+ req->type_tag_name = (char *)TYPE_TAG_NAME(type); -+ target_type = TYPE_MAIN_TYPE(type)->target_type; ++ for (i = 1; i < 32; i++) ++ sw_64_supply_register (regcache, use_64bit, i, regset + i); + -+ if (target_type) { -+ req->target_typename = (char *)TYPE_MAIN_TYPE(target_type)->name; -+ req->target_typecode = TYPE_MAIN_TYPE(target_type)->code; -+ req->target_length = target_type->length; -+ } ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "lo"), regset + 32); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "hi"), regset + 33); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "pc"), regset + 34); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "badvaddr"), regset + 35); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "status"), regset + 36); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "cause"), regset + 37); + -+ if (req->member) -+ get_member_data(req, type, 0, 1); ++ sw_64_supply_register (regcache, use_64bit, ++ find_regno (regcache->tdesc, "restart"), regset + 0); +} + +static void -+gdb_debug_command(struct gnu_request *req) ++sw_64_fill_fpregset (struct regcache *regcache, void *buf) +{ ++ union sw_64_register *regset = (union sw_64_register *) buf; ++ int i, use_64bit, first_fp, big_endian; + ++ use_64bit = (register_size (regcache->tdesc, 0) == 8); ++ first_fp = find_regno (regcache->tdesc, "f0"); ++ big_endian = (__BYTE_ORDER == __BIG_ENDIAN); ++ ++ /* See GDB for a discussion of this peculiar layout. */ ++ for (i = 0; i < 32; i++) ++ if (use_64bit) ++ collect_register (regcache, first_fp + i, regset[i].buf); ++ else ++ collect_register (regcache, first_fp + i, ++ regset[i & ~1].buf + 4 * (big_endian != (i & 1))); ++ ++ //sw_64_collect_register_32bit (regcache, use_64bit, ++ // find_regno (regcache->tdesc, "fcsr"), regset[32].buf); ++ //sw_64_collect_register_32bit (regcache, use_64bit, ++ // find_regno (regcache->tdesc, "fir"), ++ // regset[32].buf + 4); +} + -+/* -+ * Only necessary on "patched" kernel symbol sessions, and called only by -+ * lookup_symbol(), pull a symbol value bait-and-switch operation by altering -+ * either a data symbol's address value or a text symbol's block start address. -+ */ +static void -+gdb_bait_and_switch(char *name, struct symbol *sym) ++sw_64_store_fpregset (struct regcache *regcache, const void *buf) +{ -+ struct bound_minimal_symbol msym; -+ struct block *block; ++ const union sw_64_register *regset = (const union sw_64_register *) buf; ++ int i, use_64bit, first_fp, big_endian; ++ ++ use_64bit = (register_size (regcache->tdesc, 0) == 8); ++ first_fp = find_regno (regcache->tdesc, "f0"); ++ big_endian = (__BYTE_ORDER == __BIG_ENDIAN); ++ ++ /* See GDB for a discussion of this peculiar layout. */ ++ for (i = 0; i < 32; i++) ++ if (use_64bit) ++ supply_register (regcache, first_fp + i, regset[i].buf); ++ else ++ supply_register (regcache, first_fp + i, ++ regset[i & ~1].buf + 4 * (big_endian != (i & 1))); + -+ if ((gdb_merge_flags & KERNEL_SYMBOLS_PATCHED) && -+ (msym = lookup_minimal_symbol(name, NULL, gdb_kernel_objfile)).minsym) { -+ if (SYMBOL_CLASS(sym) == LOC_BLOCK) { -+ block = (struct block *)SYMBOL_BLOCK_VALUE(sym); -+ BLOCK_START(block) = BMSYMBOL_VALUE_ADDRESS(msym); -+ } else -+ SET_SYMBOL_VALUE_ADDRESS(sym, BMSYMBOL_VALUE_ADDRESS(msym)); -+ } +} ++//#endif /* HAVE_PTRACE_GETREGS */ + -+#include "valprint.h" ++/* Take care of 32-bit registers with 64-bit ptrace, POKEUSER side. */ ++static struct regset_info sw_64_regsets[] = { ++ { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, ++ sw_64_fill_gregset, sw_64_store_gregset }, ++ { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, ++ sw_64_fill_fpregset, sw_64_store_fpregset }, ++ NULL_REGSET ++}; + ++static struct regsets_info sw_64_regsets_info = ++ { ++ sw_64_regsets, /* regsets */ ++ 0, /* num_regsets */ ++ NULL, /* disabled_regsets */ ++ }; ++#endif /* HAVE_PTRACE_GETREGS */ +void -+get_user_print_option_address(struct gnu_request *req) ++sw_64_target::low_collect_ptrace_register (regcache *regcache, int regno, ++ char *buf) +{ -+ extern struct value_print_options user_print_options; ++ int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8; + -+ req->addr = 0; ++ if (use_64bit && register_size (regcache->tdesc, regno) == 4) ++ { ++ union sw_64_register reg; + -+ if (strcmp(req->name, "output_format") == 0) -+ req->addr = (ulong)&user_print_options.output_format; -+ if (strcmp(req->name, "print_max") == 0) -+ req->addr = (ulong)&user_print_options.print_max; -+ if (strcmp(req->name, "prettyprint_structs") == 0) -+ req->addr = (ulong)&user_print_options.prettyformat_structs; -+ if (strcmp(req->name, "prettyprint_arrays") == 0) -+ req->addr = (ulong)&user_print_options.prettyformat_arrays; -+ if (strcmp(req->name, "repeat_count_threshold") == 0) -+ req->addr = (ulong)&user_print_options.repeat_count_threshold; -+ if (strcmp(req->name, "stop_print_at_null") == 0) -+ req->addr = (ulong)&user_print_options.stop_print_at_null; -+ if (strcmp(req->name, "output_radix") == 0) -+ req->addr = (ulong)&output_radix; ++ sw_64_collect_register (regcache, 0, regno, ®); ++ memcpy (buf, ®, sizeof (reg)); ++ } ++ else ++ collect_register (regcache, regno, buf); +} + -+CORE_ADDR crash_text_scope; ++/* Take care of 32-bit registers with 64-bit ptrace, PEEKUSER side. */ + -+static void -+gdb_set_crash_block(struct gnu_request *req) ++void ++sw_64_target::low_supply_ptrace_register (regcache *regcache, int regno, ++ const char *buf) +{ -+ if (!req->addr) { /* debug */ -+ crash_text_scope = 0; -+ return; -+ } ++ int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8; + -+ if ((req->addr2 = (ulong)block_for_pc(req->addr))) -+ crash_text_scope = req->addr; -+ else { -+ crash_text_scope = 0; -+ req->flags |= GNU_COMMAND_FAILED; -+ } -+} ++ if (use_64bit && register_size (regcache->tdesc, regno) == 4) ++ { ++ union sw_64_register reg; + -+static const struct block * -+gdb_get_crash_block(void) -+{ -+ if (crash_text_scope) -+ return block_for_pc(crash_text_scope); -+ else -+ return NULL; ++ memcpy (®, buf, sizeof (reg)); ++ sw_64_supply_register (regcache, 0, regno, ®); ++ } ++ else ++ supply_register (regcache, regno, buf); +} + -+static long -+lookup_struct_contents(struct gnu_request *req) -+{ -+ int i; -+ long r; -+ struct field *f; -+ struct main_type *m; -+ const char *n; -+ struct main_type *top_m = (struct main_type *)req->addr; -+ char *type_name = req->type_name; -+ -+ if (!top_m || !type_name) -+ return 0; + -+ for (i = 0; i < top_m->nfields; i++) -+ { -+ f = top_m->flds_bnds.fields + i; -+ if (!f->type()) -+ continue; -+ m = f->type()->main_type; ++static struct usrregs_info sw_64_usrregs_info = ++ { ++ 165, ++ sw_64_regmap, ++ }; + -+ // If the field is an array, check the target type - -+ // it might be structure, or might not be. -+ // - struct request_sock *syn_table[0]; -+ // here m->target_type->main_type->code is expected -+ // to be TYPE_CODE_PTR -+ // - struct list_head vec[TVN_SIZE]; -+ // here m->target_type->main_type->code should be -+ // TYPE_CODE_STRUCT -+ if (m->code == TYPE_CODE_ARRAY && m->target_type) -+ m = m->target_type->main_type; + -+ /* Here is a recursion. -+ * If we have struct variable (not pointer), -+ * scan this inner structure -+ */ -+ if (m->code == TYPE_CODE_STRUCT) { -+ req->addr = (ulong)m; -+ r = lookup_struct_contents(req); -+ req->addr = (ulong)top_m; -+ if (r) -+ return 1; -+ } ++static struct regs_info myregs_info = ++ { ++ NULL, /* regset_bitmap */ ++ &sw_64_usrregs_info, ++#ifdef HAVE_PTRACE_GETREGS ++ &sw_64_regsets_info ++#endif ++ }; + -+ if (m->code == TYPE_CODE_PTR && m->target_type) -+ m = m->target_type->main_type; -+ if (m->name) -+ n = m->name; -+ else -+ continue; ++static int have_dsp = -1; ++/* The linux target ops object. */ + -+ if (strstr(n, type_name)) -+ return 1; -+ } ++linux_process_target *the_linux_target = &the_sw_64_target; + -+ return 0; -+} + -+static void -+iterate_datatypes (struct gnu_request *req) ++void ++initialize_low_arch (void) +{ -+ for (objfile *objfile : current_program_space->objfiles ()) -+ { -+ if (objfile->sf) -+ objfile->sf->qf->expand_all_symtabs(objfile); ++ struct sigaction sa, old_sa; ++ /* Initialize the Linux target descriptions. */ ++ init_registers_sw_64_linux (); + -+ for (compunit_symtab *cust : objfile->compunits ()) -+ { -+ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); ++ // initialize_regsets_info (&mips_regsets_info); + -+ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i) -+ { -+ const struct block *b = BLOCKVECTOR_BLOCK (bv, i); -+ struct block_iterator iter; -+ struct symbol *sym; ++ sa.sa_sigaction = exc_handler; ++ sigemptyset (&sa.sa_mask); ++ sa.sa_flags = SA_RESTART|SA_SIGINFO; ++ sigaction (11, &sa, &old_sa); ++ sigaction (4, &sa, &old_sa); ++ sigaction (8, &sa, &old_sa); ++} +diff -Nuar gdb-10.2/gdbserver/mem-break.cc gdb-10.2/gdbserver/mem-break.cc +--- gdb-10.2/gdbserver/mem-break.cc 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdbserver/mem-break.cc 2025-04-16 17:06:51.992086800 +0800 +@@ -1,5 +1,5 @@ + /* Memory breakpoint operations for the remote server for GDB. +- Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ Copyright (C) 2002-2020 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + +@@ -252,6 +252,10 @@ + return hw_read; + case raw_bkpt_type_access_wp: + return hw_access; ++#ifndef XWB20200308 ++ case raw_bkpt_type_value_wp: ++ return hw_vstore; ++#endif + default: + internal_error (__FILE__, __LINE__, + "bad raw breakpoint type %d", (int) raw_type); +@@ -285,6 +289,10 @@ + return raw_bkpt_type_read_wp; + case Z_PACKET_ACCESS_WP: + return raw_bkpt_type_access_wp; ++#ifndef XWB20200308 ++ case Z_PACKET_DV_WP: ++ return raw_bkpt_type_value_wp; ++#endif + default: + gdb_assert_not_reached ("unhandled Z packet type."); + } +diff -Nuar gdb-10.2/gdbserver/mem-break.h gdb-10.2/gdbserver/mem-break.h +--- gdb-10.2/gdbserver/mem-break.h 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdbserver/mem-break.h 2025-04-16 17:06:51.992086800 +0800 +@@ -1,5 +1,5 @@ + /* Memory breakpoint interfaces for the remote server for GDB. +- Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ Copyright (C) 2002-2020 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + +@@ -35,6 +35,9 @@ + #define Z_PACKET_WRITE_WP '2' + #define Z_PACKET_READ_WP '3' + #define Z_PACKET_ACCESS_WP '4' ++#ifndef XWB20200308 ++#define Z_PACKET_DV_WP '5' ++#endif + + /* The low level breakpoint types. */ + +@@ -54,6 +57,9 @@ + + /* Hardware-assisted access watchpoint. */ + raw_bkpt_type_access_wp ++#ifndef XWB20200308 ++ ,raw_bkpt_type_value_wp ++#endif + }; + + /* Map the protocol breakpoint/watchpoint type Z_TYPE to the internal +diff -Nuar gdb-10.2/gdbserver/server.h gdb-10.2/gdbserver/server.h +--- gdb-10.2/gdbserver/server.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gdbserver/server.h 2025-04-16 17:06:52.022086800 +0800 +@@ -1,5 +1,5 @@ + /* Common definitions for remote server for GDB. +- Copyright (C) 1993-2021 Free Software Foundation, Inc. ++ Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -197,4 +197,16 @@ + #include "gdbthread.h" + #include "inferiors.h" + ++#ifndef _SW64_ ++#define debug(format, ... ) \ ++ do { \ ++ if (debug_threads) \ ++ { \ ++ debug_printf("%s:%d,%s:", __FILE__, __LINE__, __func__); \ ++ debug_printf(format, ##__VA_ARGS__); \ ++ debug_printf("\n"); \ ++ }\ ++ }while(0); ++#endif + -+ ALL_BLOCK_SYMBOLS (b, iter, sym) -+ { -+ QUIT; + #endif /* GDBSERVER_SERVER_H */ +diff -Nuar gdb-10.2/gdbsupport/break-common.h gdb-10.2/gdbsupport/break-common.h +--- gdb-10.2/gdbsupport/break-common.h 2021-04-25 12:04:35.000000000 +0800 ++++ gdb-10.2/gdbsupport/break-common.h 2025-04-16 17:06:51.992086800 +0800 +@@ -1,6 +1,6 @@ + /* Data structures associated with breakpoints shared in both GDB and + GDBserver. +- Copyright (C) 1992-2021 Free Software Foundation, Inc. ++ Copyright (C) 1992-2020 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -26,6 +26,9 @@ + hw_read = 1, /* Read HW watchpoint */ + hw_access = 2, /* Access HW watchpoint */ + hw_execute = 3 /* Execute HW breakpoint */ ++#ifndef XWB20200308 ++,hw_vstore = 4 ++#endif + }; + + #endif /* COMMON_BREAK_COMMON_H */ +diff -Nuar gdb-10.2/gnulib/configure gdb-10.2/gnulib/configure +--- gdb-10.2/gnulib/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gnulib/configure 2025-04-16 17:06:51.992086800 +0800 +@@ -6468,6 +6468,20 @@ + CPPFLAGS="$CPPFLAGS -ieee" + fi + ;; ++ sw_64*) ++ # On SW_64 systems, a compiler option provides the behaviour. ++ # See the ieee(3) manual page, also available at ++ # ++ if test -n "$GCC"; then ++ # GCC has the option -mieee. ++ # For full IEEE compliance (rarely needed), use option -mieee-with-inexact. ++ CPPFLAGS="$CPPFLAGS -mieee" ++ else ++ # Compaq (ex-DEC) C has the option -ieee, equivalent to -ieee_with_no_inexact. ++ # For full IEEE compliance (rarely needed), use option -ieee_with_inexact. ++ CPPFLAGS="$CPPFLAGS -ieee" ++ fi ++ ;; + sh*) + if test -n "$GCC"; then + # GCC has the option -mieee. +diff -Nuar gdb-10.2/gnulib/import/cdefs.h gdb-10.2/gnulib/import/cdefs.h +--- gdb-10.2/gnulib/import/cdefs.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gnulib/import/cdefs.h 2025-04-16 17:06:41.932086800 +0800 +@@ -1,17 +1,18 @@ +-/* Copyright (C) 1992-2020 Free Software Foundation, Inc. ++/* Copyright (C) 1992-2023 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU General Public ++ modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either +- version 3 of the License, or (at your option) any later version. ++ version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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. ++ Lesser General Public License for more details. + +- You should have received a copy of the GNU General Public ++ You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +@@ -25,16 +26,38 @@ + + /* The GNU libc does not support any K&R compilers or the traditional mode + of ISO C compilers anymore. Check for some of the combinations not +- anymore supported. */ +-#if defined __GNUC__ && !defined __STDC__ +-# error "You need a ISO C conforming compiler to use the glibc headers" ++ supported anymore. */ ++#if defined __GNUC__ && !defined __STDC__ && !defined __cplusplus ++# error "You need a ISO C or C++ conforming compiler to use the glibc headers" + #endif + + /* Some user header file might have defined this before. */ + #undef __P + #undef __PMT + +-#ifdef __GNUC__ ++/* Compilers that lack __has_attribute may object to ++ #if defined __has_attribute && __has_attribute (...) ++ even though they do not need to evaluate the right-hand side of the &&. ++ Similarly for __has_builtin, etc. */ ++#if (defined __has_attribute \ ++ && (!defined __clang_minor__ \ ++ || 3 < __clang_major__ + (5 <= __clang_minor__))) ++# define __glibc_has_attribute(attr) __has_attribute (attr) ++#else ++# define __glibc_has_attribute(attr) 0 ++#endif ++#ifdef __has_builtin ++# define __glibc_has_builtin(name) __has_builtin (name) ++#else ++# define __glibc_has_builtin(name) 0 ++#endif ++#ifdef __has_extension ++# define __glibc_has_extension(ext) __has_extension (ext) ++#else ++# define __glibc_has_extension(ext) 0 ++#endif + -+ if (SYMBOL_CLASS (sym) != LOC_TYPEDEF) -+ continue; ++#if defined __GNUC__ || defined __clang__ + + /* All functions, except those with callbacks or those that + synchronize memory, are leaf functions. */ +@@ -47,21 +70,26 @@ + # endif + + /* GCC can always grok prototypes. For C++ programs we add throw() +- to help it optimize the function calls. But this works only with +- gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions ++ to help it optimize the function calls. But this only works with ++ gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions + as non-throwing using a function attribute since programs can use + the -fexceptions options for C code as well. */ +-# if !defined __cplusplus && __GNUC_PREREQ (3, 3) ++# if !defined __cplusplus \ ++ && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__)) + # define __THROW __attribute__ ((__nothrow__ __LEAF)) + # define __THROWNL __attribute__ ((__nothrow__)) + # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct + # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct + # else +-# if defined __cplusplus && __GNUC_PREREQ (2,8) +-# define __THROW throw () +-# define __THROWNL throw () +-# define __NTH(fct) __LEAF_ATTR fct throw () +-# define __NTHNL(fct) fct throw () ++# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) ++# if __cplusplus >= 201103L ++# define __THROW noexcept (true) ++# else ++# define __THROW throw () ++# endif ++# define __THROWNL __THROW ++# define __NTH(fct) __LEAF_ATTR fct __THROW ++# define __NTHNL(fct) fct __THROW + # else + # define __THROW + # define __THROWNL +@@ -70,7 +98,7 @@ + # endif + # endif + +-#else /* Not GCC. */ ++#else /* Not GCC or clang. */ + + # if (defined __cplusplus \ + || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +@@ -83,16 +111,7 @@ + # define __THROWNL + # define __NTH(fct) fct + +-#endif /* GCC. */ +- +-/* Compilers that are not clang may object to +- #if defined __clang__ && __has_extension(...) +- even though they do not need to evaluate the right-hand side of the &&. */ +-#if defined __clang__ && defined __has_extension +-# define __glibc_clang_has_extension(ext) __has_extension (ext) +-#else +-# define __glibc_clang_has_extension(ext) 0 +-#endif ++#endif /* GCC || clang. */ + + /* These two macros are not used in glibc anymore. They are kept here + only because some other projects expect the macros to be defined. */ +@@ -123,14 +142,70 @@ + #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) + #define __bos0(ptr) __builtin_object_size (ptr, 0) + ++/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ ++#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ ++ || __GNUC_PREREQ (12, 0)) ++# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) ++# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) ++#else ++# define __glibc_objsize0(__o) __bos0 (__o) ++# define __glibc_objsize(__o) __bos (__o) ++#endif + -+ if (req->highest && -+ !(req->lowest <= sym->type->length && sym->type->length <= req->highest)) -+ continue; ++#if __USE_FORTIFY_LEVEL > 0 ++/* Compile time conditions to choose between the regular, _chk and _chk_warn ++ variants. These conditions should get evaluated to constant and optimized ++ away. */ + -+ req->addr = (ulong)(sym->type->main_type); -+ req->name = (char *)(sym->m_name); -+ req->length = sym->type->length; ++#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) ++#define __glibc_unsigned_or_positive(__l) \ ++ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ ++ || (__builtin_constant_p (__l) && (__l) > 0)) + -+ if (req->member) { -+ req->value = lookup_struct_contents(req); -+ if (!req->value) -+ continue; -+ } -+ req->callback(req, req->callback_data); -+ } -+ } -+ } -+ } -+} ++/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ ++ condition can be folded to a constant and if it is true, or unknown (-1) */ ++#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ ++ ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) \ ++ || (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ (__s), (__osz))) \ ++ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz)))) ++ ++/* Conversely, we know at compile time that the length is unsafe if the ++ __L * __S <= __OBJSZ condition can be folded to a constant and if it is ++ false. */ ++#define __glibc_unsafe_len(__l, __s, __osz) \ ++ (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ __s, __osz)) \ ++ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ++/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be ++ declared. */ ++ ++#define __glibc_fortify(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ ++ : __ ## f ## _chk (__VA_ARGS__, __osz))) ++ ++/* Fortify function f, where object size argument passed to f is the number of ++ elements and not total size. */ ++ ++#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ ++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +#endif ---- gdb-10.2/gdb/ui-file.h.orig -+++ gdb-10.2/gdb/ui-file.h -@@ -195,10 +195,10 @@ class stdio_file : public ui_file - - bool can_emit_style_escape () override; ++ + #if __GNUC_PREREQ (4,3) +-# define __warndecl(name, msg) \ +- extern void name (void) __attribute__((__warning__ (msg))) + # define __warnattr(msg) __attribute__((__warning__ (msg))) + # define __errordecl(name, msg) \ + extern void name (void) __attribute__((__error__ (msg))) + #else +-# define __warndecl(name, msg) extern void name (void) + # define __warnattr(msg) + # define __errordecl(name, msg) extern void name (void) + #endif +@@ -142,8 +217,8 @@ + #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc + # define __flexarr [] + # define __glibc_c99_flexarr_available 1 +-#elif __GNUC_PREREQ (2,97) +-/* GCC 2.97 supports C99 flexible array members as an extension, ++#elif __GNUC_PREREQ (2,97) || defined __clang__ ++/* GCC 2.97 and clang support C99 flexible array members as an extension, + even when in C89 mode or compiling C++ (any version). */ + # define __flexarr [] + # define __glibc_c99_flexarr_available 1 +@@ -169,7 +244,7 @@ + Example: + int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ --private: - /* Sets the internal stream to FILE, and saves the FILE's file - descriptor in M_FD. */ - void set_stream (FILE *file); -+private: +-#if defined __GNUC__ && __GNUC__ >= 2 ++#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4) - /* The file. */ - FILE *m_file; ---- gdb-10.2/gdb/xml-syscall.c.orig -+++ gdb-10.2/gdb/xml-syscall.c -@@ -37,7 +37,11 @@ - static void - syscall_warn_user (void) - { -+#ifdef CRASH_MERGE -+ static int have_warned = 1; -+#else - static int have_warned = 0; -+#endif - if (!have_warned) - { - have_warned = 1; ---- gdb-10.2/libiberty/Makefile.in.orig -+++ gdb-10.2/libiberty/Makefile.in -@@ -180,6 +180,7 @@ REQUIRED_OFILES = \ - ./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \ - ./lbasename.$(objext) ./lrealpath.$(objext) \ - ./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \ -+ ./mkstemps.$(objext) \ - ./objalloc.$(objext) \ - ./obstack.$(objext) \ - ./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \ -@@ -213,7 +214,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext) \ - ./index.$(objext) ./insque.$(objext) \ - ./memchr.$(objext) ./memcmp.$(objext) ./memcpy.$(objext) \ - ./memmem.$(objext) ./memmove.$(objext) \ -- ./mempcpy.$(objext) ./memset.$(objext) ./mkstemps.$(objext) \ -+ ./mempcpy.$(objext) ./memset.$(objext) \ - ./pex-djgpp.$(objext) ./pex-msdos.$(objext) \ - ./pex-unix.$(objext) ./pex-win32.$(objext) \ - ./putenv.$(objext) \ ---- gdb-10.2/opcodes/i386-dis.c.orig -+++ gdb-10.2/opcodes/i386-dis.c -@@ -9778,6 +9778,10 @@ print_insn (bfd_vma pc, disassemble_info *info) - threebyte = *codep; - dp = &dis386_twobyte[threebyte]; - need_modrm = twobyte_has_modrm[*codep]; -+ if (dp->name && ((strcmp(dp->name, "ud2a") == 0) || (strcmp(dp->name, "ud2") == 0))) { -+ extern int kernel_BUG_encoding_bytes(void); -+ codep += kernel_BUG_encoding_bytes(); -+ } - codep++; - } - else ---- gdb-10.2/readline/readline/misc.c.orig -+++ gdb-10.2/readline/readline/misc.c -@@ -403,7 +403,7 @@ _rl_history_set_point (void) + # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) + # ifdef __cplusplus +@@ -194,17 +269,17 @@ + */ + #endif - #if defined (VI_MODE) - if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap) -- rl_point = 0; -+ rl_point = rl_end; - #endif /* VI_MODE */ +-/* GCC has various useful declarations that can be made with the +- `__attribute__' syntax. All of the ways we use this do fine if +- they are omitted for compilers that don't understand it. */ +-#if !defined __GNUC__ || __GNUC__ < 2 ++/* GCC and clang have various useful declarations that can be made with ++ the '__attribute__' syntax. All of the ways we use this do fine if ++ they are omitted for compilers that don't understand it. */ ++#if !(defined __GNUC__ || defined __clang__) + # define __attribute__(xyz) /* Ignore */ + #endif - if (rl_editing_mode == emacs_mode) ---- gdb-10.2/readline/readline/readline.h.orig -+++ gdb-10.2/readline/readline/readline.h -@@ -395,7 +395,7 @@ extern int rl_crlf PARAMS((void)); - #if defined (USE_VARARGS) && defined (PREFER_STDARG) - extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); + /* At some point during the gcc 2.96 development the `malloc' attribute + for functions was introduced. We don't want to use it unconditionally + (although this would be possible) since it generates warnings. */ +-#if __GNUC_PREREQ (2,96) ++#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__) + # define __attribute_malloc__ __attribute__ ((__malloc__)) #else --extern int rl_message (); -+extern int rl_message (void); + # define __attribute_malloc__ /* Ignore */ +@@ -219,26 +294,41 @@ + # define __attribute_alloc_size__(params) /* Ignore. */ #endif - extern int rl_show_char PARAMS((int)); ---- gdb-10.2/readline/readline/rltypedefs.h.orig -+++ gdb-10.2/readline/readline/rltypedefs.h -@@ -32,10 +32,10 @@ extern "C" { - # define _FUNCTION_DEF ++/* Tell the compiler which argument to an allocation function ++ indicates the alignment of the allocation. */ ++#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__) ++# define __attribute_alloc_align__(param) \ ++ __attribute__ ((__alloc_align__ param)) ++#else ++# define __attribute_alloc_align__(param) /* Ignore. */ ++#endif ++ + /* At some point during the gcc 2.96 development the `pure' attribute + for functions was introduced. We don't want to use it unconditionally + (although this would be possible) since it generates warnings. */ +-#if __GNUC_PREREQ (2,96) ++#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__) + # define __attribute_pure__ __attribute__ ((__pure__)) + #else + # define __attribute_pure__ /* Ignore */ + #endif - #if defined(__GNUC__) || defined(__clang__) --typedef int Function () __attribute__ ((deprecated)); --typedef void VFunction () __attribute__ ((deprecated)); --typedef char *CPFunction () __attribute__ ((deprecated)); --typedef char **CPPFunction () __attribute__ ((deprecated)); -+typedef int Function (void) __attribute__ ((deprecated)); -+typedef void VFunction (void) __attribute__ ((deprecated)); -+typedef char *CPFunction (void) __attribute__ ((deprecated)); -+typedef char **CPPFunction (void) __attribute__ ((deprecated)); + /* This declaration tells the compiler that the value is constant. */ +-#if __GNUC_PREREQ (2,5) ++#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__) + # define __attribute_const__ __attribute__ ((__const__)) #else - typedef int Function (); - typedef void VFunction (); ---- gdb-10.2/readline/readline/util.c.orig -+++ gdb-10.2/readline/readline/util.c -@@ -487,10 +487,13 @@ _rl_trace (va_alist) + # define __attribute_const__ /* Ignore */ + #endif - if (_rl_tracefp == 0) - _rl_tropen (); -+ if (!_rl_tracefp) -+ goto out; - vfprintf (_rl_tracefp, format, args); - fprintf (_rl_tracefp, "\n"); - fflush (_rl_tracefp); ++#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__) ++# define __attribute_maybe_unused__ __attribute__ ((__unused__)) ++#else ++# define __attribute_maybe_unused__ /* Ignore */ ++#endif ++ + /* At some point during the gcc 3.1 development the `used' attribute + for functions was introduced. We don't want to use it unconditionally + (although this would be possible) since it generates warnings. */ +-#if __GNUC_PREREQ (3,1) ++#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__) + # define __attribute_used__ __attribute__ ((__used__)) + # define __attribute_noinline__ __attribute__ ((__noinline__)) + #else +@@ -247,7 +337,7 @@ + #endif -+out: - va_end (args); - } + /* Since version 3.2, gcc allows marking deprecated functions. */ +-#if __GNUC_PREREQ (3,2) ++#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__) + # define __attribute_deprecated__ __attribute__ ((__deprecated__)) + #else + # define __attribute_deprecated__ /* Ignore */ +@@ -256,8 +346,8 @@ + /* Since version 4.5, gcc also allows one to specify the message printed + when a deprecated function is used. clang claims to be gcc 4.2, but + may also support this feature. */ +-#if __GNUC_PREREQ (4,5) || \ +- __glibc_clang_has_extension (__attribute_deprecated_with_message__) ++#if __GNUC_PREREQ (4,5) \ ++ || __glibc_has_extension (__attribute_deprecated_with_message__) + # define __attribute_deprecated_msg__(msg) \ + __attribute__ ((__deprecated__ (msg))) + #else +@@ -270,7 +360,7 @@ + If several `format_arg' attributes are given for the same function, in + gcc-3.0 and older, all but the last one are ignored. In newer gccs, + all designated arguments are considered. */ +-#if __GNUC_PREREQ (2,8) ++#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__) + # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) + #else + # define __attribute_format_arg__(x) /* Ignore */ +@@ -280,7 +370,7 @@ + attribute for functions was introduced. We don't want to use it + unconditionally (although this would be possible) since it + generates warnings. */ +-#if __GNUC_PREREQ (2,97) ++#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__) + # define __attribute_format_strfmon__(a,b) \ + __attribute__ ((__format__ (__strfmon__, a, b))) + #else +@@ -288,19 +378,33 @@ + #endif -@@ -513,16 +516,17 @@ _rl_tropen (void) - sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long) getpid ()); + /* The nonnull function attribute marks pointer parameters that +- must not be NULL. Do not define __nonnull if it is already defined, +- for portability when this file is used in Gnulib. */ ++ must not be NULL. This has the name __nonnull in glibc, ++ and __attribute_nonnull__ in files shared with Gnulib to avoid ++ collision with a different __nonnull in DragonFlyBSD 5.9. */ ++#ifndef __attribute_nonnull__ ++# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) ++# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) ++# else ++# define __attribute_nonnull__(params) ++# endif ++#endif + #ifndef __nonnull +-# if __GNUC_PREREQ (3,3) +-# define __nonnull(params) __attribute__ ((__nonnull__ params)) ++# define __nonnull(params) __attribute_nonnull__ (params) ++#endif ++ ++/* The returns_nonnull function attribute marks the return type of the function ++ as always being non-null. */ ++#ifndef __returns_nonnull ++# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__) ++# define __returns_nonnull __attribute__ ((__returns_nonnull__)) + # else +-# define __nonnull(params) ++# define __returns_nonnull + # endif + #endif + + /* If fortification mode, we warn about unused results of certain + function calls which can lead to problems. */ +-#if __GNUC_PREREQ (3,4) ++#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__) + # define __attribute_warn_unused_result__ \ + __attribute__ ((__warn_unused_result__)) + # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 +@@ -314,7 +418,7 @@ #endif - unlink (fnbuf); -- _rl_tracefp = fopen (fnbuf, "w+"); -+ _rl_tracefp = fopen (fnbuf, "w+xe"); - return _rl_tracefp != 0; - } - int - _rl_trclose (void) - { -- int r; -+ int r = 0; + /* Forces a function to be always inlined. */ +-#if __GNUC_PREREQ (3,2) ++#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__) + /* The Linux kernel defines __always_inline in stddef.h (283d7573), and + it conflicts with this definition. Therefore undefine it first to + allow either header to be included first. */ +@@ -327,7 +431,7 @@ -- r = fclose (_rl_tracefp); -+ if (_rl_tracefp) -+ r = fclose (_rl_tracefp); - _rl_tracefp = 0; - return r; - } ---- gdb-10.2/gdb/completer.c.orig -+++ gdb-10.2/gdb/completer.c -@@ -2949,6 +2949,8 @@ + /* Associate error messages with the source location of the call site rather + than with the source location inside the function. */ +-#if __GNUC_PREREQ (4,3) ++#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__) + # define __attribute_artificial__ __attribute__ ((__artificial__)) + #else + # define __attribute_artificial__ /* Ignore */ +@@ -370,12 +474,14 @@ + run in pedantic mode if the uses are carefully marked using the + `__extension__' keyword. But this is not generally available before + version 2.8. */ +-#if !__GNUC_PREREQ (2,8) ++#if !(__GNUC_PREREQ (2,8) || defined __clang__) + # define __extension__ /* Ignore */ + #endif - /* How many items of MAX length can we fit in the screen window? */ - cols = gdb_complete_get_screenwidth (displayer); -+ rl_reset_screen_size(); -+ rl_get_screen_size(NULL, &cols); - max += 2; - limit = cols / max; - if (limit != 1 && (limit * max == cols)) ---- gdb-10.2/gdb/ada-lang.c.orig -+++ gdb-10.2/gdb/ada-lang.c -@@ -997,7 +997,7 @@ ada_fold_name (gdb::string_view name) - int len = name.size (); - GROW_VECT (fold_buffer, fold_buffer_size, len + 1); +-/* __restrict is known in EGCS 1.2 and above. */ +-#if !__GNUC_PREREQ (2,92) ++/* __restrict is known in EGCS 1.2 and above, and in clang. ++ It works also in C++ mode (outside of arrays), but only when spelled ++ as '__restrict', not 'restrict'. */ ++#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3) + # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L + # define __restrict restrict + # else +@@ -385,8 +491,9 @@ -- if (name[0] == '\'') -+ if (!name.empty () && name[0] == '\'') - { - strncpy (fold_buffer, name.data () + 1, len - 2); - fold_buffer[len - 2] = '\000'; -@@ -1006,8 +1006,9 @@ ada_fold_name (gdb::string_view name) - { - int i; + /* ISO C99 also allows to declare arrays as non-overlapping. The syntax is + array_name[restrict] +- GCC 3.1 supports this. */ +-#if __GNUC_PREREQ (3,1) && !defined __GNUG__ ++ GCC 3.1 and clang support this. ++ This syntax is not usable in C++ mode. */ ++#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus + # define __restrict_arr __restrict + #else + # ifdef __GNUC__ +@@ -401,7 +508,7 @@ + # endif + #endif -- for (i = 0; i <= len; i += 1) -+ for (i = 0; i < len; i += 1) - fold_buffer[i] = tolower (name[i]); -+ fold_buffer[i] = '\0'; - } +-#if __GNUC__ >= 3 ++#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect) + # define __glibc_unlikely(cond) __builtin_expect ((cond), 0) + # define __glibc_likely(cond) __builtin_expect ((cond), 1) + #else +@@ -409,15 +516,10 @@ + # define __glibc_likely(cond) (cond) + #endif - return fold_buffer; -@@ -13596,7 +13597,7 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name) - { - gdb::string_view user_name = lookup_name.name (); +-#ifdef __has_attribute +-# define __glibc_has_attribute(attr) __has_attribute (attr) +-#else +-# define __glibc_has_attribute(attr) 0 +-#endif +- + #if (!defined _Noreturn \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ +- && !__GNUC_PREREQ (4,7)) ++ && !(__GNUC_PREREQ (4,7) \ ++ || (3 < __clang_major__ + (5 <= __clang_minor__)))) + # if __GNUC_PREREQ (2,8) + # define _Noreturn __attribute__ ((__noreturn__)) + # else +@@ -434,22 +536,63 @@ + # define __attribute_nonstring__ + #endif -- if (user_name[0] == '<') -+ if (!user_name.empty () && user_name[0] == '<') - { - if (user_name.back () == '>') - m_encoded_name ---- gdb-10.2/gdb/Makefile.in.orig -+++ gdb-10.2/gdb/Makefile.in -@@ -1865,7 +1865,7 @@ libgdb.a: $(LIBGDB_OBS) - # Removing the old gdb first works better if it is running, at least on SunOS. - gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS) - $(SILENCE) rm -f gdb$(EXEEXT) -- @(cd ../..; make --no-print-directory GDB_FLAGS=-DGDB_10_2 library) -+ @$(MAKE) -C ../.. GDB_FLAGS=-DGDB_10_2 library - $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ - -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \ - $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs) ---- gdb-10.2/gdb/c-typeprint.c.orig -+++ gdb-10.2/gdb/c-typeprint.c -@@ -1202,6 +1202,9 @@ c_type_print_base_struct_union (struct t - = podata->end_bitpos - - TYPE_LENGTH (type->field (i).type ()) * TARGET_CHAR_BIT; - } -+ else if (strlen(TYPE_FIELD_NAME (type, i)) == 0) -+ /* crash: Print details for unnamed struct and union. */ -+ newshow = show; - - c_print_type_1 (type->field (i).type (), - TYPE_FIELD_NAME (type, i), ---- gdb-10.2/gdb/symfile.c.orig -+++ gdb-10.2/gdb/symfile.c -@@ -1610,7 +1610,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) - if (debugfile.empty ()) { - char *name_copy; - name_copy = check_specified_kernel_debug_file(); -- return std::string (name_copy); -+ return name_copy ? std::string (name_copy) : std::string (); - } ++/* Undefine (also defined in libc-symbols.h). */ ++#undef __attribute_copy__ ++#if __GNUC_PREREQ (9, 0) ++/* Copies attributes from the declaration or type referenced by ++ the argument. */ ++# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg))) ++#else ++# define __attribute_copy__(arg) ++#endif ++ + #if (!defined _Static_assert && !defined __cplusplus \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ +- && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__)) ++ && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \ ++ || defined __STRICT_ANSI__)) + # define _Static_assert(expr, diagnostic) \ + extern int (*__Static_assert_function (void)) \ + [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] #endif ---- gdb-10.2/gdb/printcmd.c.orig -+++ gdb-10.2/gdb/printcmd.c -@@ -576,6 +576,10 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, +-/* The #ifndef lets Gnulib avoid including these on non-glibc +- platforms, where the includes typically do not exist. */ +-#ifndef __WORDSIZE ++/* Gnulib avoids including these, as they don't work on non-glibc or ++ older glibc platforms. */ ++#ifndef __GNULIB_CDEFS + # include + # include + #endif - /* See valprint.h. */ +-#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH ++#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 ++# ifdef __REDIRECT ++ ++/* Alias name defined automatically. */ ++# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir ++# define __LDBL_REDIR_DECL(name) \ ++ extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128")); ++ ++/* Alias name defined automatically, with leading underscores. */ ++# define __LDBL_REDIR2_DECL(name) \ ++ extern __typeof (__##name) __##name \ ++ __asm (__ASMNAME ("__" #name "ieee128")); ++ ++/* Alias name defined manually. */ ++# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1 ++# define __LDBL_REDIR1_DECL(name, alias) \ ++ extern __typeof (name) name __asm (__ASMNAME (#alias)); ++ ++# define __LDBL_REDIR1_NTH(name, proto, alias) \ ++ __REDIRECT_NTH (name, proto, alias) ++# define __REDIRECT_NTH_LDBL(name, proto, alias) \ ++ __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128) ++ ++/* Unused. */ ++# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl ++# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth ++ ++# else ++_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform"); ++# endif ++#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH + # define __LDBL_COMPAT 1 + # ifdef __REDIRECT + # define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias) +@@ -458,6 +601,8 @@ + # define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias) + # define __LDBL_REDIR_NTH(name, proto) \ + __LDBL_REDIR1_NTH (name, proto, __nldbl_##name) ++# define __LDBL_REDIR2_DECL(name) \ ++ extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name)); + # define __LDBL_REDIR1_DECL(name, alias) \ + extern __typeof (name) name __asm (__ASMNAME (#alias)); + # define __LDBL_REDIR_DECL(name) \ +@@ -468,11 +613,13 @@ + __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) + # endif + #endif +-#if !defined __LDBL_COMPAT || !defined __REDIRECT ++#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \ ++ || !defined __REDIRECT + # define __LDBL_REDIR1(name, proto, alias) name proto + # define __LDBL_REDIR(name, proto) name proto + # define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW + # define __LDBL_REDIR_NTH(name, proto) name proto __THROW ++# define __LDBL_REDIR2_DECL(name) + # define __LDBL_REDIR_DECL(name) + # ifdef __REDIRECT + # define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias) +@@ -503,7 +650,7 @@ + check is required to enable the use of generic selection. */ + #if !defined __cplusplus \ + && (__GNUC_PREREQ (4, 9) \ +- || __glibc_clang_has_extension (c_generic_selections) \ ++ || __glibc_has_extension (c_generic_selections) \ + || (!defined __GNUC__ && defined __STDC_VERSION__ \ + && __STDC_VERSION__ >= 201112L)) + # define __HAVE_GENERIC_SELECTION 1 +@@ -511,4 +658,50 @@ + # define __HAVE_GENERIC_SELECTION 0 + #endif -+#ifdef CRASH_MERGE -+extern "C" char *gdb_lookup_module_symbol(unsigned long, unsigned long *); ++#if __GNUC_PREREQ (10, 0) ++/* Designates a 1-based positional argument ref-index of pointer type ++ that can be used to access size-index elements of the pointed-to ++ array according to access mode, or at least one element when ++ size-index is not provided: ++ access (access-mode, [, ]) */ ++# define __attr_access(x) __attribute__ ((__access__ x)) ++/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may ++ use the access attribute to get object sizes from function definition ++ arguments, so we can't use them on functions we fortify. Drop the object ++ size hints for such functions. */ ++# if __USE_FORTIFY_LEVEL == 3 ++# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) ++# else ++# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) ++# endif ++# if __GNUC_PREREQ (11, 0) ++# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno))) ++# else ++# define __attr_access_none(argno) ++# endif ++#else ++# define __fortified_attr_access(a, o, s) ++# define __attr_access(x) ++# define __attr_access_none(argno) ++#endif ++ ++#if __GNUC_PREREQ (11, 0) ++/* Designates dealloc as a function to call to deallocate objects ++ allocated by the declared function. */ ++# define __attr_dealloc(dealloc, argno) \ ++ __attribute__ ((__malloc__ (dealloc, argno))) ++# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1) ++#else ++# define __attr_dealloc(dealloc, argno) ++# define __attr_dealloc_free +#endif + - int - build_address_symbolic (struct gdbarch *gdbarch, - CORE_ADDR addr, /* IN */ -@@ -682,7 +686,19 @@ build_address_symbolic (struct gdbarch *gdbarch, - } - } - if (symbol == NULL && msymbol.minsym == NULL) -+#ifdef CRASH_MERGE -+ { -+ char *name_ptr = gdb_lookup_module_symbol(addr, (unsigned long *)offset); -+ if (name_ptr) { -+ *name = name_ptr; -+ return 0; -+ } else { -+ return 1; -+ } -+ } ++/* Specify that a function such as setjmp or vfork may return ++ twice. */ ++#if __GNUC_PREREQ (4, 1) ++# define __attribute_returns_twice__ __attribute__ ((__returns_twice__)) +#else - return 1; ++# define __attribute_returns_twice__ /* Ignore. */ +#endif ++ + #endif /* sys/cdefs.h */ +diff -Nuar gdb-10.2/gnulib/import/libc-config.h gdb-10.2/gnulib/import/libc-config.h +--- gdb-10.2/gnulib/import/libc-config.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gnulib/import/libc-config.h 2025-04-16 17:06:41.932086800 +0800 +@@ -79,13 +79,9 @@ + #ifndef _FEATURES_H + # define _FEATURES_H 1 + #endif +-/* Define __WORDSIZE so that does not attempt to include +- nonexistent files. Make it a syntax error, since Gnulib does not +- use __WORDSIZE now, and if Gnulib uses it later the syntax error +- will let us know that __WORDSIZE needs configuring. */ +-#ifndef __WORDSIZE +-# define __WORDSIZE %%% +-#endif ++/* Define __GNULIB_CDEFS so that does not attempt to include ++ nonexistent files. */ ++# define __GNULIB_CDEFS + /* Undef the macros unconditionally defined by our copy of glibc + , so that they do not clash with any system-defined + versions. */ +diff -Nuar gdb-10.2/gnulib/import/m4/fpieee.m4 gdb-10.2/gnulib/import/m4/fpieee.m4 +--- gdb-10.2/gnulib/import/m4/fpieee.m4 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gnulib/import/m4/fpieee.m4 2025-04-16 17:06:52.002086800 +0800 +@@ -44,6 +44,16 @@ + CPPFLAGS="$CPPFLAGS -ieee" + fi + ;; ++ sw_64*) ++ # On Sw_64 systems, a compiler option provides the behaviour. ++ # See the ieee(3) manual page, also available at ++ # if test -n "$GCC"; then ++ # GCC has the option -mieee. ++ # For full IEEE compliance (rarely needed), use option -mieee-with-inexact. CPPFLAGS="$CPPFLAGS -mieee" ++ else ++ # Compaq (ex-DEC) C has the option -ieee, equivalent to -ieee_with_no_inexact. # For full IEEE compliance (rarely needed), use option -ieee_with_inexact. ++ CPPFLAGS="$CPPFLAGS -ieee" fi ++ ;; + sh*) + if test -n "$GCC"; then + # GCC has the option -mieee. +diff -Nuar gdb-10.2/gnulib/import/unistd.in.h gdb-10.2/gnulib/import/unistd.in.h +--- gdb-10.2/gnulib/import/unistd.in.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/gnulib/import/unistd.in.h 2025-04-16 17:06:52.002086800 +0800 +@@ -947,7 +947,7 @@ + # endif + /* This is for older VMS. */ + # if !defined _gl_getpagesize && defined __VMS +-# ifdef __ALPHA ++# ifdef (__ALPHA_) || defined (__SW_64)//sbw + # define _gl_getpagesize() 8192 + # else + # define _gl_getpagesize() 512 +diff -Nuar gdb-10.2/include/coff/ecoff.h gdb-10.2/include/coff/ecoff.h +--- gdb-10.2/include/coff/ecoff.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/include/coff/ecoff.h 2025-04-16 17:06:52.002086800 +0800 +@@ -47,6 +47,12 @@ + /* A compressed version of an ALPHA_MAGIC file created by DEC's tools. */ + #define ALPHA_MAGIC_COMPRESSED 0x188 - /* If the nearest symbol is too far away, don't print anything symbolic. */ - ---- gdb-10.2/gdb/symtab.c.orig -+++ gdb-10.2/gdb/symtab.c -@@ -7128,8 +7128,8 @@ gdb_get_line_number(struct gnu_request * - static void - gdb_get_datatype(struct gnu_request *req) - { -- register struct type *type; -- register struct type *typedef_type; -+ struct type *type; -+ struct type *typedef_type; - expression_up expr; - struct symbol *sym; - struct value *val; -@@ -7235,7 +7235,7 @@ gdb_get_datatype(struct gnu_request *req - static void - dump_enum(struct type *type, struct gnu_request *req) - { -- register int i; -+ int i; - int len; - long long lastval; - -@@ -7271,7 +7271,7 @@ dump_enum(struct type *type, struct gnu_ - static void - eval_enum(struct type *type, struct gnu_request *req) - { -- register int i; -+ int i; - int len; - long long lastval; - -@@ -7298,7 +7298,7 @@ eval_enum(struct type *type, struct gnu_ - static void - get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first) - { -- register short i; -+ short i; - struct field *nextfield; - short nfields; - struct type *typedef_type, *target_type; ---- gdb-10.2/gdb/symtab.c.orig -+++ gdb-10.2/gdb/symtab.c -@@ -6913,7 +6913,7 @@ - #include "../../defs.h" - - static void get_member_data(struct gnu_request *, struct type *, long, int); --static void dump_enum(struct type *, struct gnu_request *); -+static void walk_enum(struct type *, struct gnu_request *); - static void eval_enum(struct type *, struct gnu_request *); - static void gdb_get_line_number(struct gnu_request *); - static void gdb_get_datatype(struct gnu_request *); -@@ -7122,6 +7122,79 @@ ++/* SW_64 magic numbers used in filehdr. */ ++#define SW_64_MAGIC 0x184 ++#define SW_64_MAGIC_BSD 0x186 ++/* A compressed version of an SW_64_MAGIC file created by DEC's tools. */ ++#define SW_64_MAGIC_COMPRESSED 0x189 ++ + /* Magic numbers used in a.out header. */ + #define ECOFF_AOUT_OMAGIC 0407 /* not demand paged (ld -N). */ + #define ECOFF_AOUT_ZMAGIC 0413 /* demand load format, eg normal ld output */ +diff -Nuar gdb-10.2/include/coff/sw_64.h gdb-10.2/include/coff/sw_64.h +--- gdb-10.2/include/coff/sw_64.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/include/coff/sw_64.h 2025-04-16 17:06:52.022086800 +0800 +@@ -0,0 +1,391 @@ ++/* ECOFF support on SW_64 machines. ++ coff/ecoff.h must be included before this file. ++ ++ Copyright (C) 2001-2019 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/********************** FILE HEADER **********************/ ++ ++struct external_filehdr ++{ ++ unsigned char f_magic[2]; /* magic number */ ++ unsigned char f_nscns[2]; /* number of sections */ ++ unsigned char f_timdat[4]; /* time & date stamp */ ++ unsigned char f_symptr[8]; /* file pointer to symtab */ ++ unsigned char f_nsyms[4]; /* number of symtab entries */ ++ unsigned char f_opthdr[2]; /* sizeof(optional hdr) */ ++ unsigned char f_flags[2]; /* flags */ ++}; ++ ++/* Magic numbers are defined in coff/ecoff.h. */ ++#define SW_64_ECOFF_BADMAG(x) \ ++ ((x).f_magic != SW_64_MAGIC && (x).f_magic != SW_64_MAGIC_BSD) ++ ++#define SW_64_ECOFF_COMPRESSEDMAG(x) \ ++ ((x).f_magic == SW_64_MAGIC_COMPRESSED) ++ ++/* The object type is encoded in the f_flags. */ ++#define F_SW_64_OBJECT_TYPE_MASK 0x3000 ++#define F_SW_64_NO_SHARED 0x1000 ++#define F_SW_64_SHARABLE 0x2000 ++#define F_SW_64_CALL_SHARED 0x3000 ++ ++#define FILHDR struct external_filehdr ++#define FILHSZ 24 ++ ++/********************** AOUT "OPTIONAL HEADER" **********************/ ++ ++typedef struct external_aouthdr ++{ ++ unsigned char magic[2]; /* type of file */ ++ unsigned char vstamp[2]; /* version stamp */ ++ unsigned char bldrev[2]; /* ?? */ ++ unsigned char padding[2]; /* pad to quadword boundary */ ++ unsigned char tsize[8]; /* text size in bytes */ ++ unsigned char dsize[8]; /* initialized data " " */ ++ unsigned char bsize[8]; /* uninitialized data " " */ ++ unsigned char entry[8]; /* entry pt. */ ++ unsigned char text_start[8]; /* base of text used for this file */ ++ unsigned char data_start[8]; /* base of data used for this file */ ++ unsigned char bss_start[8]; /* base of bss used for this file */ ++ unsigned char gprmask[4]; /* bitmask of general registers used */ ++ unsigned char fprmask[4]; /* bitmask of floating point registers used */ ++ unsigned char gp_value[8]; /* value for gp register */ ++} AOUTHDR; ++ ++/* compute size of a header */ ++ ++#define AOUTSZ 80 ++#define AOUTHDRSZ 80 ++ ++/********************** SECTION HEADER **********************/ ++ ++struct external_scnhdr ++{ ++ unsigned char s_name[8]; /* section name */ ++ unsigned char s_paddr[8]; /* physical address, aliased s_nlib */ ++ unsigned char s_vaddr[8]; /* virtual address */ ++ unsigned char s_size[8]; /* section size */ ++ unsigned char s_scnptr[8]; /* file ptr to raw data for section */ ++ unsigned char s_relptr[8]; /* file ptr to relocation */ ++ unsigned char s_lnnoptr[8]; /* file ptr to line numbers */ ++ unsigned char s_nreloc[2]; /* number of relocation entries */ ++ unsigned char s_nlnno[2]; /* number of line number entries*/ ++ unsigned char s_flags[4]; /* flags */ ++}; ++ ++#define SCNHDR struct external_scnhdr ++#define SCNHSZ 64 ++ ++/********************** RELOCATION DIRECTIVES **********************/ ++ ++struct external_reloc ++{ ++ unsigned char r_vaddr[8]; ++ unsigned char r_symndx[4]; ++ unsigned char r_bits[4]; ++}; ++ ++#define RELOC struct external_reloc ++#define RELSZ 16 ++ ++/* Constants to unpack the r_bits field. The SW_64 seems to always be ++ little endian, so I haven't bothered to define big endian variants ++ of these. */ ++ ++#define RELOC_BITS0_TYPE_LITTLE 0xff ++#define RELOC_BITS0_TYPE_SH_LITTLE 0 ++ ++#define RELOC_BITS1_EXTERN_LITTLE 0x01 ++ ++#define RELOC_BITS1_OFFSET_LITTLE 0x7e ++#define RELOC_BITS1_OFFSET_SH_LITTLE 1 ++ ++#define RELOC_BITS1_RESERVED_LITTLE 0x80 ++#define RELOC_BITS1_RESERVED_SH_LITTLE 7 ++#define RELOC_BITS2_RESERVED_LITTLE 0xff ++#define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE 1 ++#define RELOC_BITS3_RESERVED_LITTLE 0x03 ++#define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE 9 ++ ++#define RELOC_BITS3_SIZE_LITTLE 0xfc ++#define RELOC_BITS3_SIZE_SH_LITTLE 2 ++ ++/* The r_type field in a reloc is one of the following values. */ ++#define SW_64_R_IGNORE 0 ++#define SW_64_R_REFLONG 1 ++#define SW_64_R_REFQUAD 2 ++#define SW_64_R_GPREL32 3 ++#define SW_64_R_LITERAL 4 ++#define SW_64_R_LITUSE 5 ++#define SW_64_R_GPDISP 6 ++#define SW_64_R_BRADDR 7 ++#define SW_64_R_HINT 8 ++#define SW_64_R_SREL16 9 ++#define SW_64_R_SREL32 10 ++#define SW_64_R_SREL64 11 ++#define SW_64_R_OP_PUSH 12 ++#define SW_64_R_OP_STORE 13 ++#define SW_64_R_OP_PSUB 14 ++#define SW_64_R_OP_PRSHIFT 15 ++#define SW_64_R_GPVALUE 16 ++#define SW_64_R_GPRELHIGH 17 ++#define SW_64_R_GPRELLOW 18 ++#define SW_64_R_IMMED 19 ++ ++#ifndef _SW64_ ++#define SW_64_R_BR18ADDR 20 ++#define SW_64_R_BR22ADDR 21 ++#endif ++ ++/* Overloaded reloc value used by Net- and OpenBSD. */ ++#define SW_64_R_LITERALSLEAZY 17 ++ ++/* With SW_64_R_LITUSE, the r_size field is one of the following values. */ ++#define SW_64_R_LU_BASE 1 ++#define SW_64_R_LU_BYTOFF 2 ++#define SW_64_R_LU_JSR 3 ++ ++/* With SW_64_R_IMMED, the r_size field is one of the following values. */ ++#define SW_64_R_IMMED_GP_16 1 ++#define SW_64_R_IMMED_GP_HI32 2 ++#define SW_64_R_IMMED_SCN_HI32 3 ++#define SW_64_R_IMMED_BR_HI32 4 ++#define SW_64_R_IMMED_LO32 5 ++ ++/********************** SYMBOLIC INFORMATION **********************/ ++ ++/* Written by John Gilmore. */ ++ ++/* ECOFF uses COFF-like section structures, but its own symbol format. ++ This file defines the symbol format in fields whose size and alignment ++ will not vary on different host systems. */ ++ ++/* File header as a set of bytes */ ++ ++struct hdr_ext ++{ ++ unsigned char h_magic[2]; ++ unsigned char h_vstamp[2]; ++ unsigned char h_ilineMax[4]; ++ unsigned char h_idnMax[4]; ++ unsigned char h_ipdMax[4]; ++ unsigned char h_isymMax[4]; ++ unsigned char h_ioptMax[4]; ++ unsigned char h_iauxMax[4]; ++ unsigned char h_issMax[4]; ++ unsigned char h_issExtMax[4]; ++ unsigned char h_ifdMax[4]; ++ unsigned char h_crfd[4]; ++ unsigned char h_iextMax[4]; ++ unsigned char h_cbLine[8]; ++ unsigned char h_cbLineOffset[8]; ++ unsigned char h_cbDnOffset[8]; ++ unsigned char h_cbPdOffset[8]; ++ unsigned char h_cbSymOffset[8]; ++ unsigned char h_cbOptOffset[8]; ++ unsigned char h_cbAuxOffset[8]; ++ unsigned char h_cbSsOffset[8]; ++ unsigned char h_cbSsExtOffset[8]; ++ unsigned char h_cbFdOffset[8]; ++ unsigned char h_cbRfdOffset[8]; ++ unsigned char h_cbExtOffset[8]; ++}; ++ ++/* File descriptor external record */ ++ ++struct fdr_ext ++{ ++ unsigned char f_adr[8]; ++ unsigned char f_cbLineOffset[8]; ++ unsigned char f_cbLine[8]; ++ unsigned char f_cbSs[8]; ++ unsigned char f_rss[4]; ++ unsigned char f_issBase[4]; ++ unsigned char f_isymBase[4]; ++ unsigned char f_csym[4]; ++ unsigned char f_ilineBase[4]; ++ unsigned char f_cline[4]; ++ unsigned char f_ioptBase[4]; ++ unsigned char f_copt[4]; ++ unsigned char f_ipdFirst[4]; ++ unsigned char f_cpd[4]; ++ unsigned char f_iauxBase[4]; ++ unsigned char f_caux[4]; ++ unsigned char f_rfdBase[4]; ++ unsigned char f_crfd[4]; ++ unsigned char f_bits1[1]; ++ unsigned char f_bits2[3]; ++ unsigned char f_padding[4]; ++}; ++ ++#define FDR_BITS1_LANG_BIG 0xF8 ++#define FDR_BITS1_LANG_SH_BIG 3 ++#define FDR_BITS1_LANG_LITTLE 0x1F ++#define FDR_BITS1_LANG_SH_LITTLE 0 ++ ++#define FDR_BITS1_FMERGE_BIG 0x04 ++#define FDR_BITS1_FMERGE_LITTLE 0x20 ++ ++#define FDR_BITS1_FREADIN_BIG 0x02 ++#define FDR_BITS1_FREADIN_LITTLE 0x40 ++ ++#define FDR_BITS1_FBIGENDIAN_BIG 0x01 ++#define FDR_BITS1_FBIGENDIAN_LITTLE 0x80 ++ ++#define FDR_BITS2_GLEVEL_BIG 0xC0 ++#define FDR_BITS2_GLEVEL_SH_BIG 6 ++#define FDR_BITS2_GLEVEL_LITTLE 0x03 ++#define FDR_BITS2_GLEVEL_SH_LITTLE 0 ++ ++/* We ignore the `reserved' field in bits2. */ ++ ++/* Procedure descriptor external record */ ++ ++struct pdr_ext { ++ unsigned char p_adr[8]; ++ unsigned char p_cbLineOffset[8]; ++ unsigned char p_isym[4]; ++ unsigned char p_iline[4]; ++ unsigned char p_regmask[4]; ++ unsigned char p_regoffset[4]; ++ unsigned char p_iopt[4]; ++ unsigned char p_fregmask[4]; ++ unsigned char p_fregoffset[4]; ++ unsigned char p_frameoffset[4]; ++ unsigned char p_lnLow[4]; ++ unsigned char p_lnHigh[4]; ++ unsigned char p_gp_prologue[1]; ++ unsigned char p_bits1[1]; ++ unsigned char p_bits2[1]; ++ unsigned char p_localoff[1]; ++ unsigned char p_framereg[2]; ++ unsigned char p_pcreg[2]; ++}; ++ ++#define PDR_BITS1_GP_USED_BIG 0x80 ++#define PDR_BITS1_REG_FRAME_BIG 0x40 ++#define PDR_BITS1_PROF_BIG 0x20 ++#define PDR_BITS1_RESERVED_BIG 0x1f ++#define PDR_BITS1_RESERVED_SH_LEFT_BIG 8 ++#define PDR_BITS2_RESERVED_BIG 0xff ++#define PDR_BITS2_RESERVED_SH_BIG 0 ++ ++#define PDR_BITS1_GP_USED_LITTLE 0x01 ++#define PDR_BITS1_REG_FRAME_LITTLE 0x02 ++#define PDR_BITS1_PROF_LITTLE 0x04 ++#define PDR_BITS1_RESERVED_LITTLE 0xf8 ++#define PDR_BITS1_RESERVED_SH_LITTLE 3 ++#define PDR_BITS2_RESERVED_LITTLE 0xff ++#define PDR_BITS2_RESERVED_SH_LEFT_LITTLE 5 ++ ++/* Line numbers */ ++ ++struct line_ext { ++ unsigned char l_line[4]; ++}; ++ ++/* Symbol external record */ ++ ++struct sym_ext { ++ unsigned char s_value[8]; ++ unsigned char s_iss[4]; ++ unsigned char s_bits1[1]; ++ unsigned char s_bits2[1]; ++ unsigned char s_bits3[1]; ++ unsigned char s_bits4[1]; ++}; ++ ++#define SYM_BITS1_ST_BIG 0xFC ++#define SYM_BITS1_ST_SH_BIG 2 ++#define SYM_BITS1_ST_LITTLE 0x3F ++#define SYM_BITS1_ST_SH_LITTLE 0 ++ ++#define SYM_BITS1_SC_BIG 0x03 ++#define SYM_BITS1_SC_SH_LEFT_BIG 3 ++#define SYM_BITS1_SC_LITTLE 0xC0 ++#define SYM_BITS1_SC_SH_LITTLE 6 ++ ++#define SYM_BITS2_SC_BIG 0xE0 ++#define SYM_BITS2_SC_SH_BIG 5 ++#define SYM_BITS2_SC_LITTLE 0x07 ++#define SYM_BITS2_SC_SH_LEFT_LITTLE 2 ++ ++#define SYM_BITS2_RESERVED_BIG 0x10 ++#define SYM_BITS2_RESERVED_LITTLE 0x08 ++ ++#define SYM_BITS2_INDEX_BIG 0x0F ++#define SYM_BITS2_INDEX_SH_LEFT_BIG 16 ++#define SYM_BITS2_INDEX_LITTLE 0xF0 ++#define SYM_BITS2_INDEX_SH_LITTLE 4 ++ ++#define SYM_BITS3_INDEX_SH_LEFT_BIG 8 ++#define SYM_BITS3_INDEX_SH_LEFT_LITTLE 4 ++ ++#define SYM_BITS4_INDEX_SH_LEFT_BIG 0 ++#define SYM_BITS4_INDEX_SH_LEFT_LITTLE 12 ++ ++/* External symbol external record */ ++ ++struct ext_ext { ++ struct sym_ext es_asym; ++ unsigned char es_bits1[1]; ++ unsigned char es_bits2[3]; ++ unsigned char es_ifd[4]; ++}; ++ ++#define EXT_BITS1_JMPTBL_BIG 0x80 ++#define EXT_BITS1_JMPTBL_LITTLE 0x01 ++ ++#define EXT_BITS1_COBOL_MAIN_BIG 0x40 ++#define EXT_BITS1_COBOL_MAIN_LITTLE 0x02 ++ ++#define EXT_BITS1_WEAKEXT_BIG 0x20 ++#define EXT_BITS1_WEAKEXT_LITTLE 0x04 ++ ++/* Dense numbers external record */ ++ ++struct dnr_ext { ++ unsigned char d_rfd[4]; ++ unsigned char d_index[4]; ++}; ++ ++/* Relative file descriptor */ ++ ++struct rfd_ext { ++ unsigned char rfd[4]; ++}; ++ ++/* Optimizer symbol external record */ ++ ++struct opt_ext { ++ unsigned char o_bits1[1]; ++ unsigned char o_bits2[1]; ++ unsigned char o_bits3[1]; ++ unsigned char o_bits4[1]; ++ struct rndx_ext o_rndx; ++ unsigned char o_offset[4]; ++}; ++ ++#define OPT_BITS2_VALUE_SH_LEFT_BIG 16 ++#define OPT_BITS2_VALUE_SH_LEFT_LITTLE 0 ++ ++#define OPT_BITS3_VALUE_SH_LEFT_BIG 8 ++#define OPT_BITS3_VALUE_SH_LEFT_LITTLE 8 ++ ++#define OPT_BITS4_VALUE_SH_LEFT_BIG 0 ++#define OPT_BITS4_VALUE_SH_LEFT_LITTLE 16 +diff -Nuar gdb-10.2/include/elf/common.h gdb-10.2/include/elf/common.h +--- gdb-10.2/include/elf/common.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/include/elf/common.h 2025-04-16 17:06:52.002086800 +0800 +@@ -396,7 +396,8 @@ + /* Alpha backend magic number. Written in the absence of an ABI. */ + #define EM_ALPHA 0x9026 +- ++/* SW_64 backend magic number. Written in the absence of an ABI. */ ++#define EM_SW_64 0x9916 + /* Cygnus M32R ELF backend. Written in the absence of an ABI. */ + #define EM_CYGNUS_M32R 0x9041 - /* -+ * Follow the type linkage for full member and value type resolution, with callback -+ */ -+static void drillDownType(struct gnu_request *req, struct type *type) +diff -Nuar gdb-10.2/include/elf/sw_64.h gdb-10.2/include/elf/sw_64.h +--- gdb-10.2/include/elf/sw_64.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/include/elf/sw_64.h 2025-04-16 17:06:52.022086800 +0800 +@@ -0,0 +1,135 @@ ++/* SW_64 ELF support for BFD. ++ Copyright (C) 1996-2019 Free Software Foundation, Inc. ++ ++ By Eric Youngdale, . No processor supplement available ++ for this platform. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/* This file holds definitions specific to the SW_64 ELF ABI. Note ++ that most of this is not actually implemented by BFD. */ ++ ++#ifndef _ELF_SW_64_H ++#define _ELF_SW_64_H ++ ++/* Processor specific flags for the ELF header e_flags field. */ ++ ++/* All addresses must be below 2GB. */ ++#define EF_SW_64_32BIT 0x00000001 ++ ++/* All relocations needed for relaxation with code movement are present. */ ++#define EF_SW_64_CANRELAX 0x00000002 ++ ++/* Processor specific section flags. */ ++ ++/* This section must be in the global data area. */ ++#define SHF_SW_64_GPREL 0x10000000 ++ ++/* Section contains some sort of debugging information. The exact ++ format is unspecified. It's probably ECOFF symbols. */ ++#define SHT_SW_64_DEBUG 0x70000001 ++ ++/* Section contains register usage information. */ ++#define SHT_SW_64_REGINFO 0x70000002 ++ ++/* A section of type SHT_MIPS_REGINFO contains the following ++ structure. */ ++typedef struct +{ -+ while (type) -+ { -+ /* check out for stub types and pull in the definition instead */ -+ if (TYPE_STUB(type) && TYPE_TAG_NAME(type)) { -+ struct symbol *sym; -+ sym = lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0).symbol; -+ if (sym) -+ type = sym->type; -+ } -+ switch (TYPE_CODE(type)) { -+ drill_ops_t op; -+ long l1, l2; -+ int typecode; ++ /* Mask of general purpose registers used. */ ++ unsigned long ri_gprmask; ++ /* Mask of co-processor registers used. */ ++ unsigned long ri_cprmask[4]; ++ /* GP register value for this object file. */ ++ long ri_gp_value; ++} Elf64_RegInfo; + -+ case TYPE_CODE_PTR: -+ req->tcb(EOP_POINTER, req, 0, 0, 0, 0); -+ break; ++/* Special values for the st_other field in the symbol table. */ + -+ case TYPE_CODE_TYPEDEF: -+ req->is_typedef = 1; -+ req->typecode = TYPE_CODE(type); -+ if (!req->tcb(EOP_TYPEDEF, req, TYPE_NAME(type), 0, 0, 0)) -+ return; -+ break; ++#define STO_SW_64_NOPV 0x80 ++#define STO_SW_64_STD_GPLOAD 0x88 + -+ case TYPE_CODE_FUNC: -+ req->tcb(EOP_FUNCTION, req, 0, 0, 0, 0); -+ break; ++/* Special values for Elf64_Dyn tag. */ ++#define DT_SW_64_PLTRO DT_LOPROC + -+ case TYPE_CODE_ARRAY: -+ l1 = TYPE_LENGTH (type); -+ l2 = TYPE_LENGTH (check_typedef(TYPE_TARGET_TYPE (type))); -+ req->tcb(EOP_ARRAY, req, &l1, &l2, 0, 0); -+ break; ++#include "elf/reloc-macros.h" + -+ case TYPE_CODE_VOID: -+ case TYPE_CODE_INT: -+ case TYPE_CODE_BOOL: -+ l1 = TYPE_LENGTH(type); -+ req->tcb(EOP_INT, req, &l1, 0, 0, 0); -+ break; ++/* sw_64 relocs. */ ++START_RELOC_NUMBERS (elf_sw_64_reloc_type) ++ RELOC_NUMBER (R_SW_64_NONE, 0) /* No reloc */ ++ RELOC_NUMBER (R_SW_64_REFLONG, 1) /* Direct 32 bit */ ++ RELOC_NUMBER (R_SW_64_REFQUAD, 2) /* Direct 64 bit */ ++ RELOC_NUMBER (R_SW_64_GPREL32, 3) /* GP relative 32 bit */ ++ RELOC_NUMBER (R_SW_64_LITERAL, 4) /* GP relative 16 bit w/optimization */ ++ RELOC_NUMBER (R_SW_64_LITUSE, 5) /* Optimization hint for LITERAL */ ++ RELOC_NUMBER (R_SW_64_GPDISP, 6) /* Add displacement to GP */ ++ RELOC_NUMBER (R_SW_64_BRADDR, 7) /* PC+4 relative 23 bit shifted */ ++ RELOC_NUMBER (R_SW_64_HINT, 8) /* PC+4 relative 16 bit shifted */ ++ RELOC_NUMBER (R_SW_64_SREL16, 9) /* PC relative 16 bit */ ++ RELOC_NUMBER (R_SW_64_SREL32, 10) /* PC relative 32 bit */ ++ RELOC_NUMBER (R_SW_64_SREL64, 11) /* PC relative 64 bit */ ++ ++ /* Skip 12 - 16; deprecated ECOFF relocs. */ ++#ifndef _SW64_ ++ RELOC_NUMBER (R_SW_64_BR18ADDR, 12) /* PC+4 relative 20 bit shifted */ ++ RELOC_NUMBER (R_SW_64_BR22ADDR, 13) /* PC+4 relative 24 bit shifted */ ++#endif ++ ++ RELOC_NUMBER (R_SW_64_GPRELHIGH, 17) /* GP relative 32 bit, high 16 bits */ ++ RELOC_NUMBER (R_SW_64_GPRELLOW, 18) /* GP relative 32 bit, low 16 bits */ ++ RELOC_NUMBER (R_SW_64_GPREL16, 19) /* GP relative 16 bit */ ++ ++ /* Skip 20 - 23; deprecated ECOFF relocs. */ ++ ++ /* These relocations are specific to shared libraries. */ ++ RELOC_NUMBER (R_SW_64_COPY, 24) /* Copy symbol at runtime */ ++ RELOC_NUMBER (R_SW_64_GLOB_DAT, 25) /* Create GOT entry */ ++ RELOC_NUMBER (R_SW_64_JMP_SLOT, 26) /* Create PLT entry */ ++ RELOC_NUMBER (R_SW_64_RELATIVE, 27) /* Adjust by program base */ ++ ++ /* Like BRADDR, but assert that the source and target object file ++ share the same GP value, and adjust the target address for ++ STO_SW_64_STD_GPLOAD. */ ++ RELOC_NUMBER (R_SW_64_BRSGP, 28) ++ ++ /* Thread-Local Storage. */ ++ RELOC_NUMBER (R_SW_64_TLSGD, 29) ++ RELOC_NUMBER (R_SW_64_TLSLDM, 30) ++ RELOC_NUMBER (R_SW_64_DTPMOD64, 31) ++ RELOC_NUMBER (R_SW_64_GOTDTPREL, 32) ++ RELOC_NUMBER (R_SW_64_DTPREL64, 33) ++ RELOC_NUMBER (R_SW_64_DTPRELHI, 34) ++ RELOC_NUMBER (R_SW_64_DTPRELLO, 35) ++ RELOC_NUMBER (R_SW_64_DTPREL16, 36) ++ RELOC_NUMBER (R_SW_64_GOTTPREL, 37) ++ RELOC_NUMBER (R_SW_64_TPREL64, 38) ++ RELOC_NUMBER (R_SW_64_TPRELHI, 39) ++ RELOC_NUMBER (R_SW_64_TPRELLO, 40) ++ RELOC_NUMBER (R_SW_64_TPREL16, 41) ++ ++END_RELOC_NUMBERS (R_SW_64_max) ++ ++#define LITUSE_SW_64_ADDR 0 ++#define LITUSE_SW_64_BASE 1 ++#define LITUSE_SW_64_BYTOFF 2 ++#define LITUSE_SW_64_JSR 3 ++#define LITUSE_SW_64_TLSGD 4 ++#define LITUSE_SW_64_TLSLDM 5 ++#define LITUSE_SW_64_JSRDIRECT 6 ++ ++#endif /* _ELF_SW_64_H */ +diff -Nuar gdb-10.2/include/opcode/sw_64.h gdb-10.2/include/opcode/sw_64.h +--- gdb-10.2/include/opcode/sw_64.h 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/include/opcode/sw_64.h 2025-04-16 17:06:52.002086800 +0800 +@@ -0,0 +1,247 @@ ++/* sw_64.h -- Header file for Sw_64 opcode table ++ Copyright (C) 1996-2018 Free Software Foundation, Inc. ++ Contributed by Richard Henderson , ++ patterned after the PPC opcode table written by Ian Lance Taylor. ++ ++ This file is part of GDB, GAS, and the GNU binutils. ++ ++ GDB, GAS, and the GNU binutils are free software; you can redistribute ++ them and/or modify them under the terms of the GNU General Public ++ License as published by the Free Software Foundation; either version 3, ++ or (at your option) any later version. ++ ++ GDB, GAS, and the GNU binutils are distributed in the hope that they ++ 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 file; see the file COPYING3. If not, write to the Free ++ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifndef OPCODE_SW_64_H ++#define OPCODE_SW_64_H ++ ++/* The opcode table is an array of struct sw_64_opcode. */ ++ ++struct sw_64_opcode ++{ ++ /* The opcode name. */ ++ const char *name; ++ ++ /* The opcode itself. Those bits which will be filled in with ++ operands are zeroes. */ ++ unsigned opcode; ++ ++ /* The opcode mask. This is used by the disassembler. This is a ++ mask containing ones indicating those bits which must match the ++ opcode field, and zeroes indicating those bits which need not ++ match (and are presumably filled in by operands). */ ++ unsigned mask; ++ ++ /* One bit flags for the opcode. These are primarily used to ++ indicate specific processors and environments support the ++ instructions. The defined values are listed below. */ ++ unsigned flags; ++ ++ /* An array of operand codes. Each code is an index into the ++ operand table. They appear in the order which the operands must ++ appear in assembly code, and are terminated by a zero. */ ++ unsigned char operands[5]; ++}; ++ ++/* The table itself is sorted by major opcode number, and is otherwise ++ in the order in which the disassembler should consider ++ instructions. */ ++extern const struct sw_64_opcode sw_64_opcodes[]; ++extern const unsigned sw_64_num_opcodes; ++ ++/* Values defined for the flags field of a struct sw_64_opcode. */ ++ ++/* CPU Availability */ ++#define AXP_OPCODE_BASE 0x0001 /* Base architecture -- all cpus. */ ++#define AXP_OPCODE_SW6 0x0800 /* SW6 insns. */ ++#define AXP_OPCODE_SW6A 0x1000 /* SW6A insns. */ ++#define AXP_OPCODE_SW6B 0x2000 /* SW6B insns. */ ++ ++#define AXP_LITOP(i) (((i) >> 26) & 0x3D) ++ ++#define AXP_OPCODE_NOPAL (~(AXP_OPCODE_SW6|AXP_OPCODE_SW6A|AXP_OPCODE_SW6B)) ++ ++/* A macro to extract the major opcode from an instruction. */ ++#define AXP_OP(i) (((i) >> 26) & 0x3F) ++ ++/* The total number of major opcodes. */ ++#define AXP_NOPS 0x40 ++ ++ ++/* The operands table is an array of struct sw_64_operand. */ ++ ++struct sw_64_operand ++{ ++ /* The number of bits in the operand. */ ++ unsigned int bits : 5; ++ ++ /* How far the operand is left shifted in the instruction. */ ++ unsigned int shift : 5; ++ ++ /* The default relocation type for this operand. */ ++ signed int default_reloc : 16; ++ ++ /* One bit syntax flags. */ ++ unsigned int flags : 16; ++ ++ /* Insertion function. This is used by the assembler. To insert an ++ operand value into an instruction, check this field. ++ ++ If it is NULL, execute ++ i |= (op & ((1 << o->bits) - 1)) << o->shift; ++ (i is the instruction which we are filling in, o is a pointer to ++ this structure, and op is the opcode value; this assumes twos ++ complement arithmetic). ++ ++ If this field is not NULL, then simply call it with the ++ instruction and the operand value. It will return the new value ++ of the instruction. If the ERRMSG argument is not NULL, then if ++ the operand value is illegal, *ERRMSG will be set to a warning ++ string (the operand will be inserted in any case). If the ++ operand value is legal, *ERRMSG will be unchanged (most operands ++ can accept any value). */ ++ unsigned (*insert) (unsigned instruction, int op, const char **errmsg); ++ ++ /* Extraction function. This is used by the disassembler. To ++ extract this operand type from an instruction, check this field. ++ ++ If it is NULL, compute ++ op = ((i) >> o->shift) & ((1 << o->bits) - 1); ++ if ((o->flags & AXP_OPERAND_SIGNED) != 0 ++ && (op & (1 << (o->bits - 1))) != 0) ++ op -= 1 << o->bits; ++ (i is the instruction, o is a pointer to this structure, and op ++ is the result; this assumes twos complement arithmetic). ++ ++ If this field is not NULL, then simply call it with the ++ instruction value. It will return the value of the operand. If ++ the INVALID argument is not NULL, *INVALID will be set to ++ non-zero if this operand type can not actually be extracted from ++ this operand (i.e., the instruction does not match). If the ++ operand is valid, *INVALID will not be changed. */ ++ int (*extract) (unsigned instruction, int *invalid); ++}; ++ ++/* Elements in the table are retrieved by indexing with values from ++ the operands field of the sw_64_opcodes table. */ ++ ++extern const struct sw_64_operand sw_64_operands[]; ++extern const unsigned sw_64_num_operands; ++ ++/* Values defined for the flags field of a struct sw_64_operand. */ ++ ++/* Mask for selecting the type for typecheck purposes */ ++#define AXP_OPERAND_TYPECHECK_MASK \ ++ (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA | AXP_OPERAND_IR | \ ++ AXP_OPERAND_FPR | AXP_OPERAND_RELATIVE | AXP_OPERAND_SIGNED | \ ++ AXP_OPERAND_UNSIGNED) ++ ++/* This operand does not actually exist in the assembler input. This ++ is used to support extended mnemonics, for which two operands fields ++ are identical. The assembler should call the insert function with ++ any op value. The disassembler should call the extract function, ++ ignore the return value, and check the value placed in the invalid ++ argument. */ ++#define AXP_OPERAND_FAKE 01 ++ ++/* The operand should be wrapped in parentheses rather than separated ++ from the previous by a comma. This is used for the load and store ++ instructions which want their operands to look like "Ra,disp(Rb)". */ ++#define AXP_OPERAND_PARENS 02 ++ ++/* Used in combination with PARENS, this supresses the supression of ++ the comma. This is used for "jmp Ra,(Rb),hint". */ ++#define AXP_OPERAND_COMMA 04 ++ ++/* This operand names an integer register. */ ++#define AXP_OPERAND_IR 010 ++ ++/* This operand names a floating point register. */ ++#define AXP_OPERAND_FPR 020 ++ ++/* This operand is a relative branch displacement. The disassembler ++ prints these symbolically if possible. */ ++#define AXP_OPERAND_RELATIVE 040 ++ ++/* This operand takes signed values. */ ++#define AXP_OPERAND_SIGNED 0100 ++ ++/* This operand takes unsigned values. This exists primarily so that ++ a flags value of 0 can be treated as end-of-arguments. */ ++#define AXP_OPERAND_UNSIGNED 0200 ++ ++/* Supress overflow detection on this field. This is used for hints. */ ++#define AXP_OPERAND_NOOVERFLOW 0400 ++ ++/* Mask for optional argument default value. */ ++#define AXP_OPERAND_OPTIONAL_MASK 07000 + -+ case TYPE_CODE_UNION: -+ op = EOP_UNION; -+ goto label; ++/* This operand defaults to zero. This is used for jump hints. */ ++#define AXP_OPERAND_DEFAULT_ZERO 01000 + -+ case TYPE_CODE_ENUM: -+ op = EOP_ENUM; -+ goto label; ++/* This operand should default to the first (real) operand and is used ++ in conjunction with AXP_OPERAND_OPTIONAL. This allows ++ "and $0,3,$0" to be written as "and $0,3", etc. I don't like ++ it, but it's what DEC does. */ ++#define AXP_OPERAND_DEFAULT_FIRST 02000 + -+ case TYPE_CODE_STRUCT: -+ op = EOP_STRUCT; -+ goto label; ++/* Similarly, this operand should default to the second (real) operand. ++ This allows "negl $0" instead of "negl $0,$0". */ ++#define AXP_OPERAND_DEFAULT_SECOND 04000 + -+ default: -+ typecode = TYPE_CODE(type); -+ req->tcb(EOP_OOPS, req, &typecode, "Unknown typecode", 0, 0); -+ return; /* not reached */ ++#ifndef XWB20200308 ++/* Similarly, this operand should default to the third (real) operand. ++ This allows "selne $0,$1,$2,$2" to be written as "selne $0,$1,$2" */ ++#define AXP_OPERAND_DEFAULT_THIRD 0xa00 + -+ label: -+ l1 = TYPE_LENGTH(type); -+ req->tcb(op, req, &l1, type, TYPE_TAG_NAME(type), 0); -+ } -+ type = TYPE_TARGET_TYPE(type); -+ } -+ req->tcb(EOP_DONE, req, 0, 0, 0, 0); -+} ++/* This operand names a vect register. */ ++#define AXP_OPERAND_VPR 0100000 + -+/* - * General purpose routine for determining datatypes. - */ ++#endif ++ ++ ++/* Register common names */ ++ ++#define AXP_REG_V0 0 ++#define AXP_REG_T0 1 ++#define AXP_REG_T1 2 ++#define AXP_REG_T2 3 ++#define AXP_REG_T3 4 ++#define AXP_REG_T4 5 ++#define AXP_REG_T5 6 ++#define AXP_REG_T6 7 ++#define AXP_REG_T7 8 ++#define AXP_REG_S0 9 ++#define AXP_REG_S1 10 ++#define AXP_REG_S2 11 ++#define AXP_REG_S3 12 ++#define AXP_REG_S4 13 ++#define AXP_REG_S5 14 ++#define AXP_REG_FP 15 ++#define AXP_REG_A0 16 ++#define AXP_REG_A1 17 ++#define AXP_REG_A2 18 ++#define AXP_REG_A3 19 ++#define AXP_REG_A4 20 ++#define AXP_REG_A5 21 ++#define AXP_REG_T8 22 ++#define AXP_REG_T9 23 ++#define AXP_REG_T10 24 ++#define AXP_REG_T11 25 ++#define AXP_REG_RA 26 ++#define AXP_REG_PV 27 ++#define AXP_REG_T12 27 ++#define AXP_REG_AT 28 ++#define AXP_REG_GP 29 ++#define AXP_REG_SP 30 ++#define AXP_REG_ZERO 31 ++ ++#endif /* OPCODE_SW_64_H */ +diff -Nuar gdb-10.2/intl/configure gdb-10.2/intl/configure +--- gdb-10.2/intl/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/intl/configure 2025-04-16 17:06:52.002086800 +0800 +@@ -4721,7 +4721,7 @@ -@@ -7149,10 +7222,8 @@ - if (req->member) - get_member_data(req, sym->type, 0, 1); + # Guess based on the CPU. + case "$host_cpu" in +- alpha* | i3456786 | m68k | s390*) ++ alpha* | sw_64* | i3456786 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; +diff -Nuar gdb-10.2/intl/dcigettext.c gdb-10.2/intl/dcigettext.c +--- gdb-10.2/intl/dcigettext.c 2020-09-13 10:33:41.000000000 +0800 ++++ gdb-10.2/intl/dcigettext.c 2025-04-16 17:06:52.002086800 +0800 +@@ -72,7 +72,7 @@ + #ifdef _LIBC + /* Guess whether integer division by zero raises signal SIGFPE. + Set to 1 only if you know for sure. In case of doubt, set to 0. */ +-# if defined __alpha__ || defined __arm__ || defined __i386__ \ ++# if defined __alpha__ || defined __sw_64__ || defined __arm__ || defined __i386__ \ + || defined __m68k__ || defined __s390__ + # define INTDIV0_RAISES_SIGFPE 1 + # else +diff -Nuar gdb-10.2/libiberty/aclocal.m4 gdb-10.2/libiberty/aclocal.m4 +--- gdb-10.2/libiberty/aclocal.m4 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/libiberty/aclocal.m4 2025-04-16 17:06:41.932086800 +0800 +@@ -16,6 +16,8 @@ + [AC_TRY_RUN([ + /* Test by Jim Wilson and Kaveh Ghazi. + Check whether strncmp reads past the end of its string parameters. */ ++#include ++#include + #include -- if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) { -- if (req->flags & GNU_PRINT_ENUMERATORS) -- dump_enum(sym->type, req); -- } -+ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) -+ walk_enum(sym->type, req); + #ifdef HAVE_FCNTL_H +@@ -43,7 +45,8 @@ - return; - } -@@ -7172,17 +7243,25 @@ - if (gdb_CRASHDEBUG(2)) - console("expr->elts[0].opcode: OP_VAR_VALUE\n"); - type = expr.get()->elts[2].symbol->type; -- if (req->flags & GNU_VAR_LENGTH_TYPECODE) { -+ if (req->tcb) { -+ long value = SYMBOL_VALUE(expr->elts[2].symbol); -+ /* callback with symbol value */ - req->typecode = TYPE_CODE(type); -- req->length = TYPE_LENGTH(type); -- } -- if (TYPE_CODE(type) == TYPE_CODE_ENUM) { -- req->typecode = TYPE_CODE(type); -- req->value = SYMBOL_VALUE(expr.get()->elts[2].symbol); -- req->tagname = (char *)TYPE_TAG_NAME(type); -- if (!req->tagname) { -- val = evaluate_type(expr.get()); -- eval_enum(value_type(val), req); -+ req->tcb(EOP_VALUE, req, &value, 0, 0, 0); -+ drillDownType(req, type); -+ } else { -+ if (req->flags & GNU_VAR_LENGTH_TYPECODE) { -+ req->typecode = TYPE_CODE(type); -+ req->length = TYPE_LENGTH(type); -+ } -+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) { -+ req->typecode = TYPE_CODE(type); -+ req->value = SYMBOL_VALUE(expr->elts[2].symbol); -+ req->tagname = (char *)TYPE_TAG_NAME(type); -+ if (!req->tagname) { -+ val = evaluate_type(expr.get()); -+ eval_enum(value_type(val), req); -+ } - } - } - break; -@@ -7192,26 +7271,21 @@ - console("expr->elts[0].opcode: OP_TYPE\n"); - type = expr.get()->elts[1].type; - -- req->typecode = TYPE_CODE(type); -- req->length = TYPE_LENGTH(type); -- -- if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) { -- req->is_typedef = TYPE_CODE_TYPEDEF; -- if ((typedef_type = check_typedef(type))) { -- req->typecode = TYPE_CODE(typedef_type); -- req->length = TYPE_LENGTH(typedef_type); -- type = typedef_type; -- } -- } -- -- if (TYPE_CODE(type) == TYPE_CODE_ENUM) { -- if (req->is_typedef) -- if (req->flags & GNU_PRINT_ENUMERATORS) { -- if (req->is_typedef) -- fprintf_filtered(gdb_stdout, -- "typedef "); -- dump_enum(type, req); -+ if (req->tcb) { -+ drillDownType(req, type); -+ } else { -+ req->typecode = TYPE_CODE(type); -+ req->length = TYPE_LENGTH(type); -+ if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) { -+ req->is_typedef = TYPE_CODE_TYPEDEF; -+ if ((typedef_type = check_typedef(type))) { -+ req->typecode = TYPE_CODE(typedef_type); -+ req->length = TYPE_LENGTH(typedef_type); -+ type = typedef_type; -+ } - } -+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) -+ walk_enum(type, req); - } + #define MAP_LEN 0x10000 - if (req->member) -@@ -7233,36 +7307,38 @@ - * identifier, each on its own line. - */ - static void --dump_enum(struct type *type, struct gnu_request *req) -+walk_enum(struct type *type, struct gnu_request *req) +-main () ++int ++main (void) { - int i; -- int len; -+ int len, print = (req->flags & GNU_PRINT_ENUMERATORS); - long long lastval; - -- len = TYPE_NFIELDS (type); -- lastval = 0; -- if (TYPE_TAG_NAME(type)) -- fprintf_filtered(gdb_stdout, -- "enum %s {\n", TYPE_TAG_NAME (type)); -- else -- fprintf_filtered(gdb_stdout, "enum {\n"); -+ if (print) { -+ if (req->is_typedef) -+ fprintf_filtered(gdb_stdout, "typedef "); -+ if (TYPE_TAG_NAME(type)) -+ fprintf_filtered(gdb_stdout, "enum %s {\n", TYPE_TAG_NAME (type)); -+ else -+ fprintf_filtered(gdb_stdout, "enum {\n"); -+ } + #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) + char *p; +@@ -149,7 +152,10 @@ + fi -+ len = TYPE_NFIELDS (type); - for (i = 0; i < len; i++) { -- fprintf_filtered(gdb_stdout, " %s", -- TYPE_FIELD_NAME (type, i)); -- if (lastval != TYPE_FIELD_ENUMVAL (type, i)) { -- fprintf_filtered (gdb_stdout, " = %s", -- plongest(TYPE_FIELD_ENUMVAL (type, i))); -- lastval = TYPE_FIELD_ENUMVAL (type, i); -- } else -+ if (print) -+ fprintf_filtered(gdb_stdout, " %s", TYPE_FIELD_NAME (type, i)); -+ lastval = TYPE_FIELD_ENUMVAL (type, i); -+ if (print) { - fprintf_filtered(gdb_stdout, " = %s", plongest(lastval)); -- fprintf_filtered(gdb_stdout, "\n"); -- lastval++; -+ fprintf_filtered(gdb_stdout, "\n"); -+ } else if (req->tcb) -+ req->tcb(EOP_ENUMVAL, req, TYPE_FIELD_NAME (type, i), &lastval, 0, 0); -+ } -+ if (print) { -+ if (TYPE_TAG_NAME(type)) -+ fprintf_filtered(gdb_stdout, "};\n"); -+ else -+ fprintf_filtered(gdb_stdout, "} %s;\n", req->name); - } -- if (TYPE_TAG_NAME(type)) -- fprintf_filtered(gdb_stdout, "};\n"); -- else -- fprintf_filtered(gdb_stdout, "} %s;\n", req->name); + AC_CACHE_CHECK(stack direction for C alloca, ac_cv_c_stack_direction, +-[AC_TRY_RUN([find_stack_direction () ++[AC_TRY_RUN([#include ++ ++int ++find_stack_direction (void) + { + static char *addr = 0; + auto char dummy; +@@ -161,7 +167,9 @@ + else + return (&dummy > addr) ? 1 : -1; } - - /* -@@ -7320,26 +7396,43 @@ - } - - for (i = 0; i < nfields; i++) { -- if (STREQ(req->member, nextfield->name)) { -- req->member_offset = offset + nextfield->loc.bitpos; -- req->member_length = TYPE_LENGTH(nextfield->type()); -- req->member_typecode = TYPE_CODE(nextfield->type()); -- req->member_main_type_name = (char *)TYPE_NAME(nextfield->type()); -- req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type()); -- target_type = TYPE_TARGET_TYPE(nextfield->type()); -- if (target_type) { -- req->member_target_type_name = (char *)TYPE_NAME(target_type); -- req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type); -- } -- if ((req->member_typecode == TYPE_CODE_TYPEDEF) && -- (typedef_type = check_typedef(nextfield->type()))) -- req->member_length = TYPE_LENGTH(typedef_type); -- return; -- } else if (*nextfield->name == 0) { /* Anonymous struct/union */ -+ if (*nextfield->name == 0) { /* Anonymous struct/union */ - get_member_data(req, nextfield->type(), - offset + nextfield->loc.bitpos, 0); - if (req->member_offset != -1) - return; -+ } else { -+ /* callback may be just looking for a specific member name */ -+ if (req->tcb) { -+ if (req->tcb(EOP_MEMBER_NAME, req, nextfield->name, 0, 0, 0)) { -+ long bitpos = FIELD_BITPOS(*nextfield); -+ long bitsize = FIELD_BITSIZE(*nextfield); -+ long len = TYPE_LENGTH(nextfield->type()); -+ long byteOffset; -+ offset += nextfield->loc.bitpos; -+ byteOffset = offset/8; -+ console("EOP_MEMBER_SIZES\n"); -+ req->tcb(EOP_MEMBER_SIZES, req, &byteOffset, &len, &bitpos, &bitsize); -+ /* callback with full type info */ -+ drillDownType(req, nextfield->type()); -+ } -+ } else if (STREQ(req->member, nextfield->name)) { -+ req->member_offset = offset + nextfield->loc.bitpos; -+ req->member_length = TYPE_LENGTH(nextfield->type()); -+ req->member_typecode = TYPE_CODE(nextfield->type()); -+ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type()); -+ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type()); -+ target_type = TYPE_TARGET_TYPE(nextfield->type()); -+ if (target_type) { -+ req->member_target_type_name = (char *)TYPE_NAME(target_type); -+ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type); -+ } -+ if ((req->member_typecode == TYPE_CODE_TYPEDEF) && -+ (typedef_type = check_typedef(nextfield->type()))) { -+ req->member_length = TYPE_LENGTH(typedef_type); -+ } -+ return; -+ } - } - nextfield++; - } ---- gdb-10.2/gdb/gdbtypes.c.orig -+++ gdb-10.2/gdb/gdbtypes.c -@@ -5492,27 +5492,25 @@ copy_type_recursive (struct objfile *objfile, +-main () ++ ++int ++main (void) + { + exit (find_stack_direction() < 0); + }], +diff -Nuar gdb-10.2/libiberty/configure gdb-10.2/libiberty/configure +--- gdb-10.2/libiberty/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/libiberty/configure 2025-04-16 17:06:41.942086800 +0800 +@@ -6724,7 +6724,10 @@ + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ +-find_stack_direction () ++#include ++ ++int ++find_stack_direction (void) + { + static char *addr = 0; + auto char dummy; +@@ -6736,7 +6739,9 @@ + else + return (&dummy > addr) ? 1 : -1; } - - /* Make a copy of the given TYPE, except that the pointer & reference -- types are not preserved. -- -- This function assumes that the given type has an associated objfile. -- This objfile is used to allocate the new type. */ -+ types are not preserved. */ - - struct type * - copy_type (const struct type *type) +-main () ++ ++int ++main (void) { -- struct type *new_type; -- -- gdb_assert (TYPE_OBJFILE_OWNED (type)); -+ struct type *new_type = alloc_type_copy (type); - -- new_type = alloc_type_copy (type); - TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); - TYPE_LENGTH (new_type) = TYPE_LENGTH (type); - memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type), - sizeof (struct main_type)); - if (type->main_type->dyn_prop_list != NULL) -- new_type->main_type->dyn_prop_list -- = copy_dynamic_prop_list (&TYPE_OBJFILE (type) -> objfile_obstack, -- type->main_type->dyn_prop_list); -+ { -+ struct obstack *storage = (TYPE_OBJFILE_OWNED (type) -+ ? &TYPE_OBJFILE (type)->objfile_obstack -+ : gdbarch_obstack (TYPE_OWNER (type).gdbarch)); -+ new_type->main_type->dyn_prop_list -+ = copy_dynamic_prop_list (storage, type->main_type->dyn_prop_list); -+ } - - return new_type; + exit (find_stack_direction() < 0); } ---- gdb-10.2/bfd/elf-bfd.h.orig -+++ gdb-10.2/bfd/elf-bfd.h -@@ -27,6 +27,8 @@ - #include "elf/internal.h" - #include "bfdlink.h" +@@ -7557,6 +7562,8 @@ + /* Test by Jim Wilson and Kaveh Ghazi. + Check whether strncmp reads past the end of its string parameters. */ ++#include +#include -+ - #ifdef __cplusplus - extern "C" { - #endif ---- gdb-10.2/gnulib/import/cdefs.h.orig -+++ gdb-10.2/gnulib/import/cdefs.h -@@ -1,17 +1,18 @@ --/* Copyright (C) 1992-2020 Free Software Foundation, Inc. -+/* Copyright (C) 1992-2023 Free Software Foundation, Inc. -+ Copyright The GNU Toolchain Authors. - This file is part of the GNU C Library. + #include - The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public -+ modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either -- version 3 of the License, or (at your option) any later version. -+ version 2.1 of the License, or (at your option) any later version. + #ifdef HAVE_FCNTL_H +@@ -7584,7 +7591,8 @@ - The GNU C Library 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. -+ Lesser General Public License for more details. + #define MAP_LEN 0x10000 -- You should have received a copy of the GNU General Public -+ You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ +-main () ++int ++main (void) + { + #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) + char *p; +diff -Nuar gdb-10.2/libiberty/Makefile.in gdb-10.2/libiberty/Makefile.in +--- gdb-10.2/libiberty/Makefile.in 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/libiberty/Makefile.in 2025-04-16 17:06:41.912086800 +0800 +@@ -180,6 +180,7 @@ + ./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \ + ./lbasename.$(objext) ./lrealpath.$(objext) \ + ./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \ ++ ./mkstemps.$(objext) \ + ./objalloc.$(objext) \ + ./obstack.$(objext) \ + ./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \ +@@ -213,7 +214,7 @@ + ./index.$(objext) ./insque.$(objext) \ + ./memchr.$(objext) ./memcmp.$(objext) ./memcpy.$(objext) \ + ./memmem.$(objext) ./memmove.$(objext) \ +- ./mempcpy.$(objext) ./memset.$(objext) ./mkstemps.$(objext) \ ++ ./mempcpy.$(objext) ./memset.$(objext) \ + ./pex-djgpp.$(objext) ./pex-msdos.$(objext) \ + ./pex-unix.$(objext) ./pex-win32.$(objext) \ + ./putenv.$(objext) \ +diff -Nuar gdb-10.2/libiberty/pex-common.h gdb-10.2/libiberty/pex-common.h +--- gdb-10.2/libiberty/pex-common.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/libiberty/pex-common.h 2025-04-16 17:06:52.002086800 +0800 +@@ -99,10 +99,10 @@ + { + /* Open file NAME for reading. If BINARY is non-zero, open in + binary mode. Return >= 0 on success, -1 on error. */ +- int (*open_read) (struct pex_obj *, const char */* name */, int /* binary */); ++ int (*open_read) (struct pex_obj *, const char * /* name */, int /* binary */); + /* Open file NAME for writing. If BINARY is non-zero, open in + binary mode. Return >= 0 on success, -1 on error. */ +- int (*open_write) (struct pex_obj *, const char */* name */, ++ int (*open_write) (struct pex_obj *, const char * /* name */, + int /* binary */, int /* append */); + /* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from + pex_run. IN, OUT, ERRDES, TOCLOSE are all descriptors, from +@@ -114,11 +114,11 @@ + PEX_STDERR_TO_STDOUT flag. Return >= 0 on success, or -1 on + error and set *ERRMSG and *ERR. */ + pid_t (*exec_child) (struct pex_obj *, int /* flags */, +- const char */* executable */, char * const * /* argv */, ++ const char * /* executable */, char * const * /* argv */, + char * const * /* env */, + int /* in */, int /* out */, int /* errdes */, +- int /* toclose */, const char **/* errmsg */, +- int */* err */); ++ int /* toclose */, const char ** /* errmsg */, ++ int * /* err */); + /* Close a descriptor. Return 0 on success, -1 on error. */ + int (*close) (struct pex_obj *, int); + /* Wait for a child to complete, returning exit status in *STATUS +diff -Nuar gdb-10.2/Makefile.in gdb-10.2/Makefile.in +--- gdb-10.2/Makefile.in 2021-04-25 12:07:50.000000000 +0800 ++++ gdb-10.2/Makefile.in 2025-04-16 17:06:41.892086800 +0800 +@@ -340,6 +340,9 @@ + AS_FOR_BUILD = @AS_FOR_BUILD@ + CC_FOR_BUILD = @CC_FOR_BUILD@ + CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ ++ifeq (${CRASH_TARGET}, PPC64) ++CFLAGS_FOR_BUILD += -m64 -fPIC ++endif + CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@ + CXX_FOR_BUILD = @CXX_FOR_BUILD@ + DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@ +@@ -406,6 +409,9 @@ + GNATMAKE = @GNATMAKE@ -@@ -25,16 +26,38 @@ + CFLAGS = @CFLAGS@ ++ifeq (${CRASH_TARGET}, PPC64) ++CFLAGS += -m64 -fPIC ++endif + LDFLAGS = @LDFLAGS@ + LIBCFLAGS = $(CFLAGS) + CXXFLAGS = @CXXFLAGS@ +diff -Nuar gdb-10.2/opcodes/configure gdb-10.2/opcodes/configure +--- gdb-10.2/opcodes/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/configure 2025-04-16 17:06:52.012086800 +0800 +@@ -12866,6 +12866,7 @@ + case "$arch" in + bfd_aarch64_arch) ta="$ta aarch64-asm.lo aarch64-dis.lo aarch64-opc.lo aarch64-asm-2.lo aarch64-dis-2.lo aarch64-opc-2.lo" ;; + bfd_alpha_arch) ta="$ta alpha-dis.lo alpha-opc.lo" ;; ++ bfd_sw_64_arch) ta="$ta sw_64-dis.lo sw_64-opc.lo" ;; + bfd_arc_arch) ta="$ta arc-dis.lo arc-opc.lo arc-ext.lo" ;; + bfd_arm_arch) ta="$ta arm-dis.lo" ;; + bfd_avr_arch) ta="$ta avr-dis.lo" ;; +diff -Nuar gdb-10.2/opcodes/configure.ac gdb-10.2/opcodes/configure.ac +--- gdb-10.2/opcodes/configure.ac 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/configure.ac 2025-04-16 17:06:52.012086800 +0800 +@@ -341,6 +341,7 @@ + bfd_z8k_arch) ta="$ta z8k-dis.lo" ;; + bfd_bpf_arch) ta="$ta bpf-asm.lo bpf-desc.lo bpf-dis.lo bpf-ibld.lo bpf-opc.lo" using_cgen=yes ;; - /* The GNU libc does not support any K&R compilers or the traditional mode - of ISO C compilers anymore. Check for some of the combinations not -- anymore supported. */ --#if defined __GNUC__ && !defined __STDC__ --# error "You need a ISO C conforming compiler to use the glibc headers" -+ supported anymore. */ -+#if defined __GNUC__ && !defined __STDC__ && !defined __cplusplus -+# error "You need a ISO C or C++ conforming compiler to use the glibc headers" ++ bfd_sw_64_arch) ta="$ta sw_64-dis.lo sw_64-opc.lo" ;; + "") ;; + *) AC_MSG_ERROR(*** unknown target architecture $arch) ;; + esac +diff -Nuar gdb-10.2/opcodes/configure.com gdb-10.2/opcodes/configure.com +--- gdb-10.2/opcodes/configure.com 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/configure.com 2025-04-16 17:06:52.012086800 +0800 +@@ -44,6 +44,14 @@ + $ DEFS="""ARCH_alpha""" + $EOD + $ endif ++$ if arch.eqs."sw_64" ++$ then ++$ create build.com ++$DECK ++$ FILES="sw_64-dis,sw_64-opc" ++$ DEFS="""ARCH_sw_64""" ++$EOD ++$ endif + $! + $ append sys$input build.com + $DECK +diff -Nuar gdb-10.2/opcodes/disassemble.c gdb-10.2/opcodes/disassemble.c +--- gdb-10.2/opcodes/disassemble.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/disassemble.c 2025-04-16 17:06:52.012086800 +0800 +@@ -100,6 +100,7 @@ + #define ARCH_xtensa + #define ARCH_z80 + #define ARCH_z8k ++#define ARCH_sw_64 #endif - /* Some user header file might have defined this before. */ - #undef __P - #undef __PMT + #ifdef ARCH_m32c +@@ -135,6 +136,11 @@ + { + /* If you add a case to this table, also add it to the + ARCH_all definition right above this function. */ ++#ifdef ARCH_sw_64 ++ case bfd_arch_sw_64: ++ disassemble = print_insn_sw_64; ++ break; ++#endif + #ifdef ARCH_aarch64 + case bfd_arch_aarch64: + disassemble = print_insn_aarch64; +diff -Nuar gdb-10.2/opcodes/disassemble.h gdb-10.2/opcodes/disassemble.h +--- gdb-10.2/opcodes/disassemble.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/disassemble.h 2025-04-16 17:06:52.012086800 +0800 +@@ -100,6 +100,7 @@ + extern int print_insn_z80 (bfd_vma, disassemble_info *); + extern int print_insn_z8001 (bfd_vma, disassemble_info *); + extern int print_insn_z8002 (bfd_vma, disassemble_info *); ++extern int print_insn_sw_64 (bfd_vma, disassemble_info *); --#ifdef __GNUC__ -+/* Compilers that lack __has_attribute may object to -+ #if defined __has_attribute && __has_attribute (...) -+ even though they do not need to evaluate the right-hand side of the &&. -+ Similarly for __has_builtin, etc. */ -+#if (defined __has_attribute \ -+ && (!defined __clang_minor__ \ -+ || 3 < __clang_major__ + (5 <= __clang_minor__))) -+# define __glibc_has_attribute(attr) __has_attribute (attr) + extern disassembler_ftype csky_get_disassembler (bfd *); + extern disassembler_ftype rl78_get_disassembler (bfd *); +diff -Nuar gdb-10.2/opcodes/i386-dis.c gdb-10.2/opcodes/i386-dis.c +--- gdb-10.2/opcodes/i386-dis.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/i386-dis.c 2025-04-16 17:06:41.912086800 +0800 +@@ -9778,6 +9778,10 @@ + threebyte = *codep; + dp = &dis386_twobyte[threebyte]; + need_modrm = twobyte_has_modrm[*codep]; ++ if (dp->name && ((strcmp(dp->name, "ud2a") == 0) || (strcmp(dp->name, "ud2") == 0))) { ++ extern int kernel_BUG_encoding_bytes(void); ++ codep += kernel_BUG_encoding_bytes(); ++ } + codep++; + } + else +diff -Nuar gdb-10.2/opcodes/Makefile.am gdb-10.2/opcodes/Makefile.am +--- gdb-10.2/opcodes/Makefile.am 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/Makefile.am 2025-04-16 17:06:52.002086800 +0800 +@@ -96,6 +96,8 @@ + aarch64-opc-2.c \ + alpha-dis.c \ + alpha-opc.c \ ++ sw_64-dis.c \ ++ sw_64-opc.c \ + arc-dis.c \ + arc-ext.c \ + arc-opc.c \ +diff -Nuar gdb-10.2/opcodes/Makefile.in gdb-10.2/opcodes/Makefile.in +--- gdb-10.2/opcodes/Makefile.in 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/opcodes/Makefile.in 2025-04-16 17:06:52.002086800 +0800 +@@ -486,6 +486,8 @@ + aarch64-opc-2.c \ + alpha-dis.c \ + alpha-opc.c \ ++ sw_64-dis.c \ ++ sw_64-opc.c \ + arc-dis.c \ + arc-ext.c \ + arc-opc.c \ +@@ -897,6 +899,8 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64-opc.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha-dis.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha-opc.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sw_64-dis.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sw_64-opc.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc-dis.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc-ext.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc-opc.Plo@am__quote@ +diff -Nuar gdb-10.2/opcodes/sw_64-dis.c gdb-10.2/opcodes/sw_64-dis.c +--- gdb-10.2/opcodes/sw_64-dis.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/opcodes/sw_64-dis.c 2025-04-16 17:06:52.012086800 +0800 +@@ -0,0 +1,221 @@ ++/* sw_64-dis.c -- Disassemble Sw_64 AXP instructions ++ Copyright (C) 1996-2016 Free Software Foundation, Inc. ++ Contributed by Richard Henderson , ++ patterned after the PPC opcode handling written by Ian Lance Taylor. ++ ++ This file is part of libopcodes. ++ ++ This library 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, or (at your option) ++ any later version. ++ ++ It 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 file; see the file COPYING. If not, write to the Free ++ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA ++ 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include ++#include "disassemble.h" ++#include "opcode/sw_64.h" ++ ++/* OSF register names. */ ++ ++static const char * const osf_regnames[96] = { ++#ifndef XWB20181112 ++ "$r0", "$r1", "$r2", "$r3" , "$r4", "$r5", "$r6", "$r7", ++ "$r8", "$r9", "$r10", "$r11" , "$r12", "$r13", "$r14", "fp", ++ "$r16", "$r17", "$r18", "$r19" , "$r20", "$r21", "$r22", "$r23", ++ "$r24", "$r25", "ra", "$r27" , "$r28", "$r29", "sp", "$r31", +#else -+# define __glibc_has_attribute(attr) 0 ++ "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", +#endif -+#ifdef __has_builtin -+# define __glibc_has_builtin(name) __has_builtin (name) -+#else -+# define __glibc_has_builtin(name) 0 ++ "$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", "$f31" ++#ifndef XWB20180523 ++ , ++ "$V0", "$V1", "$V2", "$V3", "$V4", "$V5", "$V6", "$V7", ++ "$V8", "$V9", "$V10", "$V11", "$V12", "$V13", "$V14", "$V15", ++ "$V16", "$V17", "$V18", "$V19", "$V20", "$V21", "$V22", "$V23", ++ "$V24", "$V25", "$V26", "$V27", "$V28", "$V29", "$V30", "$V31" +#endif -+#ifdef __has_extension -+# define __glibc_has_extension(ext) __has_extension (ext) -+#else -+# define __glibc_has_extension(ext) 0 ++}; ++ ++/* VMS register names. */ ++ ++static const char * const vms_regnames[64] = { ++ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", ++ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", ++ "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23", ++ "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ", ++ "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", "FZ" ++}; ++ ++int ++print_insn_sw_64(bfd_vma memaddr, struct disassemble_info *info) ++{ ++ static const struct sw_64_opcode *opcode_index[AXP_NOPS+1]; ++ const char * const * regnames; ++ const struct sw_64_opcode *opcode, *opcode_end; ++ const unsigned char *opindex; ++ unsigned insn, op, isa_mask; ++ int need_comma; ++ ++ /* Initialize the majorop table the first time through */ ++ if (!opcode_index[0]) ++ { ++ opcode = sw_64_opcodes; ++ opcode_end = opcode + sw_64_num_opcodes; ++ ++ for (op = 0; op < AXP_NOPS; ++op) ++ { ++ opcode_index[op] = opcode; ++ while (opcode < opcode_end && op == AXP_OP (opcode->opcode)) ++ ++opcode; ++ } ++ opcode_index[op] = opcode; ++ } ++ ++ if (info->flavour == bfd_target_evax_flavour) ++ regnames = vms_regnames; ++ else ++ regnames = osf_regnames; ++ isa_mask = AXP_OPCODE_NOPAL; ++ ++ switch (info->mach) ++ { ++ case bfd_mach_sw_64_sw6a: ++ isa_mask |= AXP_OPCODE_SW6; ++ break; ++ } ++ ++ /* Read the insn into a host word */ ++ { ++ bfd_byte buffer[4]; ++ int status = (*info->read_memory_func) (memaddr, buffer, 4, info); ++ if (status != 0) ++ { ++ (*info->memory_error_func) (status, memaddr, info); ++ return -1; ++ } ++ insn = bfd_getl32 (buffer); ++ } ++ /* Get the major opcode of the instruction. */ ++ op = AXP_OP (insn); ++ ++ /* Find the first match in the opcode table. */ ++ opcode_end = opcode_index[op + 1]; ++ for (opcode = opcode_index[op]; opcode < opcode_end; ++opcode) ++ { ++ if ((insn ^ opcode->opcode) & opcode->mask) ++ continue; ++ ++ if (!(opcode->flags & isa_mask)) ++ continue; ++ ++ /* Make two passes over the operands. First see if any of them ++ have extraction functions, and, if they do, make sure the ++ instruction is valid. */ ++ { ++ int invalid = 0; ++ for (opindex = opcode->operands; *opindex != 0; opindex++) ++ { ++ const struct sw_64_operand *operand = sw_64_operands + *opindex; ++ if (operand->extract) ++ (*operand->extract) (insn, &invalid); ++ } ++ if (invalid) ++ continue; ++ } ++ ++ /* The instruction is valid. */ ++ goto found; ++ } ++ ++ /* No instruction found */ ++ (*info->fprintf_func) (info->stream, ".long %#08x", insn); ++ ++ return 4; ++ ++found: ++ (*info->fprintf_func) (info->stream, "%s", opcode->name); ++#ifndef XWB20200308 ++ /* for recomposing intr... */ ++ if (op > 0x13 && op < 0x18 ) ++ (*info->fprintf_func) (info->stream, "%x", (((insn>>26)&0x3))<<6|((insn>>10)&0x3f)); +#endif ++ if (opcode->operands[0] != 0) ++ (*info->fprintf_func) (info->stream, "\t"); + -+#if defined __GNUC__ || defined __clang__ - - /* All functions, except those with callbacks or those that - synchronize memory, are leaf functions. */ -@@ -47,21 +70,26 @@ - # endif - - /* GCC can always grok prototypes. For C++ programs we add throw() -- to help it optimize the function calls. But this works only with -- gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions -+ to help it optimize the function calls. But this only works with -+ gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions - as non-throwing using a function attribute since programs can use - the -fexceptions options for C code as well. */ --# if !defined __cplusplus && __GNUC_PREREQ (3, 3) -+# if !defined __cplusplus \ -+ && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__)) - # define __THROW __attribute__ ((__nothrow__ __LEAF)) - # define __THROWNL __attribute__ ((__nothrow__)) - # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct - # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct - # else --# if defined __cplusplus && __GNUC_PREREQ (2,8) --# define __THROW throw () --# define __THROWNL throw () --# define __NTH(fct) __LEAF_ATTR fct throw () --# define __NTHNL(fct) fct throw () -+# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) -+# if __cplusplus >= 201103L -+# define __THROW noexcept (true) -+# else -+# define __THROW throw () -+# endif -+# define __THROWNL __THROW -+# define __NTH(fct) __LEAF_ATTR fct __THROW -+# define __NTHNL(fct) fct __THROW - # else - # define __THROW - # define __THROWNL -@@ -70,7 +98,7 @@ - # endif - # endif - --#else /* Not GCC. */ -+#else /* Not GCC or clang. */ - - # if (defined __cplusplus \ - || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) -@@ -83,16 +111,7 @@ - # define __THROWNL - # define __NTH(fct) fct - --#endif /* GCC. */ -- --/* Compilers that are not clang may object to -- #if defined __clang__ && __has_extension(...) -- even though they do not need to evaluate the right-hand side of the &&. */ --#if defined __clang__ && defined __has_extension --# define __glibc_clang_has_extension(ext) __has_extension (ext) --#else --# define __glibc_clang_has_extension(ext) 0 --#endif -+#endif /* GCC || clang. */ - - /* These two macros are not used in glibc anymore. They are kept here - only because some other projects expect the macros to be defined. */ -@@ -123,14 +142,70 @@ - #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) - #define __bos0(ptr) __builtin_object_size (ptr, 0) - -+/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ -+#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ -+ || __GNUC_PREREQ (12, 0)) -+# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) -+# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) ++ /* Now extract and print the operands. */ ++ need_comma = 0; ++ for (opindex = opcode->operands; *opindex != 0; opindex++) ++ { ++ const struct sw_64_operand *operand = sw_64_operands + *opindex; ++ int value; ++ ++ /* Operands that are marked FAKE are simply ignored. We ++ already made sure that the extract function considered ++ the instruction to be valid. */ ++ if ((operand->flags & AXP_OPERAND_FAKE) != 0) ++ continue; ++ ++ /* Extract the value from the instruction. */ ++ if (operand->extract) ++ value = (*operand->extract) (insn, (int *) NULL); ++ else ++ { ++ value = (insn >> operand->shift) & ((1 << operand->bits) - 1); ++ if (operand->flags & AXP_OPERAND_SIGNED) ++ { ++ int signbit = 1 << (operand->bits - 1); ++ value = (value ^ signbit) - signbit; ++ } ++ } ++ ++ if (need_comma && ++ ((operand->flags & (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA)) ++ != AXP_OPERAND_PARENS)) ++ { ++ (*info->fprintf_func) (info->stream, ","); ++ } ++ if (operand->flags & AXP_OPERAND_PARENS) ++ (*info->fprintf_func) (info->stream, "("); ++ ++ /* Print the operand as directed by the flags. */ ++ if (operand->flags & AXP_OPERAND_IR) ++ (*info->fprintf_func) (info->stream, "%s", regnames[value]); ++ else if (operand->flags & AXP_OPERAND_FPR) ++ (*info->fprintf_func) (info->stream, "%s", regnames[value + 32]); ++#ifndef XWB20200308 ++ else if (operand->flags & AXP_OPERAND_VPR) ++ (*info->fprintf_func) (info->stream, "%s", regnames[value + 64]); ++#endif ++ else if (operand->flags & AXP_OPERAND_RELATIVE) ++ (*info->print_address_func) (memaddr + 4 + value, info); ++ else if (operand->flags & AXP_OPERAND_SIGNED) ++ (*info->fprintf_func) (info->stream, "%d", value); ++ else ++ (*info->fprintf_func) (info->stream, "%#x", value); ++ ++ if (operand->flags & AXP_OPERAND_PARENS) ++ (*info->fprintf_func) (info->stream, ")"); ++ need_comma = 1; ++ } ++ ++ return 4; ++} +diff -Nuar gdb-10.2/opcodes/sw_64-opc.c gdb-10.2/opcodes/sw_64-opc.c +--- gdb-10.2/opcodes/sw_64-opc.c 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/opcodes/sw_64-opc.c 2025-04-16 17:06:52.012086800 +0800 +@@ -0,0 +1,1042 @@ ++/* sw_64-opc.c -- Sw_64 AXP opcode list ++ Copyright (C) 1996-2015 Free Software Foundation, Inc. ++ Contributed by Richard Henderson , ++ patterned after the PPC opcode handling written by Ian Lance Taylor. ++ ++ This file is part of libopcodes. ++ ++ This library 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, or (at your option) ++ any later version. ++ ++ It 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 file; see the file COPYING. If not, write to the ++ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA ++ 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include ++#include "opcode/sw_64.h" ++#include "bfd.h" ++#include "opintl.h" ++ ++/* This file holds the Sw_64 AXP opcode table. The opcode table includes ++ almost all of the extended instruction mnemonics. This permits the ++ disassembler to use them, and simplifies the assembler logic, at the ++ cost of increasing the table size. The table is strictly constant ++ data, so the compiler should be able to put it in the text segment. ++ ++ This file also holds the operand table. All knowledge about inserting ++ and extracting operands from instructions is kept in this file. ++ ++ The information for the base instruction set was compiled from the ++ _Sw_64 Architecture Handbook_, Digital Order Number EC-QD2KB-TE, ++ version 2. ++ ++ The information for the post-ev5 architecture extensions BWX, CIX and ++ MAX came from version 3 of this same document, which is also available ++ on-line at http://ftp.digital.com/pub/Digital/info/semiconductor ++ /literature/sw_64hb2.pdf ++ ++ ++/* The RB field when it is the same as the RA field in the same insn. ++ This operand is marked fake. The insertion function just copies ++ the RA field into the RB field, and the extraction function just ++ checks that the fields are the same. */ ++ ++static unsigned ++insert_rba (unsigned insn, ++ int value ATTRIBUTE_UNUSED, ++ const char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return insn | (((insn >> 21) & 0x1f) << 16); ++} ++ ++static int ++extract_rba (unsigned insn, int *invalid) ++{ ++ if (invalid != (int *) NULL ++ && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f)) ++ *invalid = 1; ++ return 0; ++} ++ ++/* The same for the RC field. */ ++ ++static unsigned ++insert_rca (unsigned insn, ++ int value ATTRIBUTE_UNUSED, ++ const char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return insn | ((insn >> 21) & 0x1f); ++} ++ ++static int ++extract_rca (unsigned insn, int *invalid) ++{ ++ if (invalid != (int *) NULL ++ && ((insn >> 21) & 0x1f) != (insn & 0x1f)) ++ *invalid = 1; ++ return 0; ++} ++ ++/* Fake arguments in which the registers must be set to ZERO. */ ++ ++static unsigned ++insert_za (unsigned insn, ++ int value ATTRIBUTE_UNUSED, ++ const char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return insn | (31 << 21); ++} ++ ++static int ++extract_za (unsigned insn, int *invalid) ++{ ++ if (invalid != (int *) NULL && ((insn >> 21) & 0x1f) != 31) ++ *invalid = 1; ++ return 0; ++} ++ ++static unsigned ++insert_zb (unsigned insn, ++ int value ATTRIBUTE_UNUSED, ++ const char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return insn | (31 << 16); ++} ++ ++static int ++extract_zb (unsigned insn, int *invalid) ++{ ++ if (invalid != (int *) NULL && ((insn >> 16) & 0x1f) != 31) ++ *invalid = 1; ++ return 0; ++} ++ ++static unsigned ++insert_zc (unsigned insn, ++ int value ATTRIBUTE_UNUSED, ++ const char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return insn | 31; ++} ++ ++static int ++extract_zc (unsigned insn, int *invalid) ++{ ++ if (invalid != (int *) NULL && (insn & 0x1f) != 31) ++ *invalid = 1; ++ return 0; ++} ++ ++ ++/* The displacement field of a Branch format insn. */ ++ ++static unsigned ++insert_bdisp (unsigned insn, int value, const char **errmsg) ++{ ++ if (errmsg != (const char **)NULL && (value & 3)) ++ *errmsg = _("branch operand unaligned"); ++ return insn | ((value / 4) & 0x1FFFFF); ++} ++ ++static int ++extract_bdisp (unsigned insn, int *invalid ATTRIBUTE_UNUSED) ++{ ++ return 4 * (((insn & 0x1FFFFF) ^ 0x100000) - 0x100000); ++} ++ ++/* The hint field of a JMP/JSR insn. */ ++ ++static unsigned ++insert_jhint (unsigned insn, int value, const char **errmsg) ++{ ++ if (errmsg != (const char **)NULL && (value & 3)) ++ *errmsg = _("jump hint unaligned"); ++ return insn | ((value / 4) & 0x3FFF); ++} ++ ++static int ++extract_jhint (unsigned insn, int *invalid ATTRIBUTE_UNUSED) ++{ ++ return 4 * (((insn & 0x3FFF) ^ 0x2000) - 0x2000); ++} ++ ++/* The hint field of an SW6 HW_JMP/JSR insn. */ ++ ++static unsigned ++insert_sw6hwjhint (unsigned insn, int value, const char **errmsg) ++{ ++ if (errmsg != (const char **)NULL && (value & 3)) ++ *errmsg = _("jump hint unaligned"); ++ return insn | ((value / 4) & 0x1FFF); ++} ++ ++static int ++extract_sw6hwjhint (unsigned insn, int *invalid ATTRIBUTE_UNUSED) ++{ ++ return 4 * (((insn & 0x1FFF) ^ 0x1000) - 0x1000); ++} ++ ++/* The operands table. */ ++ ++const struct sw_64_operand sw_64_operands[] = ++{ ++ /* The fields are bits, shift, insert, extract, flags */ ++ /* The zero index is used to indicate end-of-list */ ++#define UNUSED 0 ++ { 0, 0, 0, 0, 0, 0 }, ++ ++ /* The plain integer register fields. */ ++#define RA (UNUSED + 1) ++ { 5, 21, 0, AXP_OPERAND_IR, 0, 0 }, ++#define RB (RA + 1) ++ { 5, 16, 0, AXP_OPERAND_IR, 0, 0 }, ++#define RC (RB + 1) ++ { 5, 0, 0, AXP_OPERAND_IR, 0, 0 }, ++ ++ /* The plain fp register fields. */ ++#define FA (RC + 1) ++ { 5, 21, 0, AXP_OPERAND_FPR, 0, 0 }, ++#define FB (FA + 1) ++ { 5, 16, 0, AXP_OPERAND_FPR, 0, 0 }, ++#define FC (FB + 1) ++ { 5, 0, 0, AXP_OPERAND_FPR, 0, 0 }, ++ ++ /* The integer registers when they are ZERO. */ ++#define ZA (FC + 1) ++ { 5, 21, 0, AXP_OPERAND_FAKE, insert_za, extract_za }, ++#define ZB (ZA + 1) ++ { 5, 16, 0, AXP_OPERAND_FAKE, insert_zb, extract_zb }, ++#define ZC (ZB + 1) ++ { 5, 0, 0, AXP_OPERAND_FAKE, insert_zc, extract_zc }, ++ ++ /* The RB field when it needs parentheses. */ ++#define PRB (ZC + 1) ++ { 5, 16, 0, AXP_OPERAND_IR|AXP_OPERAND_PARENS, 0, 0 }, ++ ++ /* The RB field when it needs parentheses _and_ a preceding comma. */ ++#define CPRB (PRB + 1) ++ { 5, 16, 0, ++ AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA, 0, 0 }, ++ ++ /* The RB field when it must be the same as the RA field. */ ++#define RBA (CPRB + 1) ++ { 5, 16, 0, AXP_OPERAND_FAKE, insert_rba, extract_rba }, ++ ++ /* The RC field when it must be the same as the RB field. */ ++#define RCA (RBA + 1) ++ { 5, 0, 0, AXP_OPERAND_FAKE, insert_rca, extract_rca }, ++ ++ /* The RC field when it can *default* to RA. */ ++#define DRC1 (RCA + 1) ++ { 5, 0, 0, ++ AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_FIRST, 0, 0 }, ++ ++ /* The RC field when it can *default* to RB. */ ++#define DRC2 (DRC1 + 1) ++ { 5, 0, 0, ++ AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_SECOND, 0, 0 }, ++ ++ /* The FC field when it can *default* to RA. */ ++#define DFC1 (DRC2 + 1) ++ { 5, 0, 0, ++ AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_FIRST, 0, 0 }, ++ ++ /* The FC field when it can *default* to RB. */ ++#define DFC2 (DFC1 + 1) ++ { 5, 0, 0, ++ AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_SECOND, 0, 0 }, ++ ++ /* The unsigned 8-bit literal of Operate format insns. */ ++#define LIT (DFC2 + 1) ++ { 8, 13, -LIT, AXP_OPERAND_UNSIGNED, 0, 0 }, ++ ++ /* The signed 16-bit displacement of Memory format insns. From here ++ we can't tell what relocation should be used, so don't use a default. */ ++#define MDISP (LIT + 1) ++ { 16, 0, -MDISP, AXP_OPERAND_SIGNED, 0, 0 }, ++ ++ /* The signed "23-bit" aligned displacement of Branch format insns. */ ++#define BDISP (MDISP + 1) ++ { 21, 0, BFD_RELOC_23_PCREL_S2, ++ AXP_OPERAND_RELATIVE, insert_bdisp, extract_bdisp }, ++ /* The 26-bit PALcode function */ ++#ifdef XWB20180315 ++#define PALFN (BDISP + 1) ++ { 26, 0, -PALFN, AXP_OPERAND_UNSIGNED, 0, 0 }, +#else -+# define __glibc_objsize0(__o) __bos0 (__o) -+# define __glibc_objsize(__o) __bos (__o) ++#define PALFN (BDISP + 1) ++ { 25, 0, -PALFN, AXP_OPERAND_UNSIGNED, 0, 0 }, +#endif ++ /* The optional signed "16-bit" aligned displacement of the JMP/JSR hint. */ ++#define JMPHINT (PALFN + 1) ++ { 14, 0, BFD_RELOC_SW_64_HINT, ++ AXP_OPERAND_RELATIVE|AXP_OPERAND_DEFAULT_ZERO|AXP_OPERAND_NOOVERFLOW, ++ insert_jhint, extract_jhint }, + -+#if __USE_FORTIFY_LEVEL > 0 -+/* Compile time conditions to choose between the regular, _chk and _chk_warn -+ variants. These conditions should get evaluated to constant and optimized -+ away. */ ++ /* The optional hint to RET/JSR_COROUTINE. */ ++#define RETHINT (JMPHINT + 1) ++ { 14, 0, -RETHINT, ++ AXP_OPERAND_UNSIGNED|AXP_OPERAND_DEFAULT_ZERO, 0, 0 }, + -+#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) -+#define __glibc_unsigned_or_positive(__l) \ -+ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ -+ || (__builtin_constant_p (__l) && (__l) > 0)) ++ /* The 12-bit displacement for the ev[46] hw_{ld,st} (pal1b/pal1f) insns. */ ++#define SW6HWDISP (RETHINT + 1) ++ { 12, 0, -SW6HWDISP, AXP_OPERAND_SIGNED, 0, 0 }, + -+/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ -+ condition can be folded to a constant and if it is true, or unknown (-1) */ -+#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ -+ ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) \ -+ || (__glibc_unsigned_or_positive (__l) \ -+ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ -+ (__s), (__osz))) \ -+ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz)))) ++ /* The 8-bit index for the oddly unqualified hw_m[tf]pr insns ++ that occur in DEC PALcode. */ ++#define EV4EXTHWINDEX (SW6HWDISP + 1) ++ { 8, 0, -EV4EXTHWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 }, + -+/* Conversely, we know at compile time that the length is unsafe if the -+ __L * __S <= __OBJSZ condition can be folded to a constant and if it is -+ false. */ -+#define __glibc_unsafe_len(__l, __s, __osz) \ -+ (__glibc_unsigned_or_positive (__l) \ -+ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ -+ __s, __osz)) \ -+ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ /* The 16-bit combined index/scoreboard mask for the ev6 ++ hw_m[ft]pr (pal19/pal1d) insns. */ ++#define SW6HWINDEX (EV4EXTHWINDEX + 1) ++ { 16, 0, -SW6HWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 }, + -+/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be -+ declared. */ ++ /* The 13-bit branch hint for the ev6 hw_jmp/jsr (pal1e) insn. */ ++#define SW6HWJMPHINT (SW6HWINDEX+ 1) ++ { 8, 0, -SW6HWJMPHINT, ++ AXP_OPERAND_RELATIVE|AXP_OPERAND_DEFAULT_ZERO|AXP_OPERAND_NOOVERFLOW, ++ insert_sw6hwjhint, extract_sw6hwjhint } ++#ifndef SPS20160530 ++, ++#define PRIDISP (SW6HWJMPHINT+ 1) ++ { 8, 0, -PRIDISP, AXP_OPERAND_SIGNED, 0, 0 }, + -+#define __glibc_fortify(f, __l, __s, __osz, ...) \ -+ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ -+ ? __ ## f ## _alias (__VA_ARGS__) \ -+ : (__glibc_unsafe_len (__l, __s, __osz) \ -+ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ -+ : __ ## f ## _chk (__VA_ARGS__, __osz))) ++/* The RC for sw6 interger composite insns */ ++#define SRC (PRIDISP + 1) ++ { 5, 5, 0, AXP_OPERAND_IR, 0, 0 }, + -+/* Fortify function f, where object size argument passed to f is the number of -+ elements and not total size. */ ++/* The RD for sw6 interger composite insns */ ++#define SRD RC ++ ++/* The RC for sw6 interger composite insns */ ++#define SFC (SRC + 1) ++ { 5, 5, 0, AXP_OPERAND_FPR, 0, 0 }, ++ ++/* The RD for sw6 interger composite insns */ ++#define SFD FC ++ ++ /* The plain f31 register fields. */ ++#define ZFA (SFC + 1) ++ { 5, 21, 0, AXP_OPERAND_FPR|AXP_OPERAND_FAKE, insert_za, extract_za }, ++ ++#define ZFB (ZFA + 1) ++ { 5, 16, 0, AXP_OPERAND_FPR|AXP_OPERAND_FAKE, insert_zb, extract_zb }, ++ ++#define ZFC (ZFB + 1) ++ { 5, 0, 0, AXP_OPERAND_FPR|AXP_OPERAND_FAKE, insert_zc, extract_zc }, ++ ++ /* The unsigned 5-bit literal of Operate format insns. */ ++#define CIB (ZFC + 1) ++ { 5, 5, -CIB, AXP_OPERAND_UNSIGNED, 0, 0 }, ++ ++ /* The plain vector register fields. */ ++#define VA (CIB + 1) ++ { 5, 21, 0, AXP_OPERAND_VPR, 0, 0 }, ++#define VB (VA + 1) ++ { 5, 16, 0, AXP_OPERAND_VPR, 0, 0 }, ++#define VC (VB + 1) ++ { 5, 0, 0, AXP_OPERAND_VPR, 0, 0 }, ++#define VD (VC + 1) ++ { 5, 5, 0, AXP_OPERAND_VPR, 0, 0 }, ++ ++#define SPE_RC (VD + 1) ++ { 5, 5, 0, AXP_OPERAND_IR, 0, 0 }, ++ ++ /* The unsigned 8-bit literal of Operate format insns. */ ++#define HX_LIT (SPE_RC + 1) ++ { 8, 5, -HX_LIT, AXP_OPERAND_UNSIGNED, 0, 0 }, + -+#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ -+ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ -+ ? __ ## f ## _alias (__VA_ARGS__) \ -+ : (__glibc_unsafe_len (__l, __s, __osz) \ -+ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ -+ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +#endif ++#ifndef XWB20161017 ++/* for the third operand of ternary operands integer insn. */ ++#define R3 (SW6HWJMPHINT + 1) ++ { 5, 5, 0, AXP_OPERAND_IR, 0, 0 }, ++ /* The plain fp register fields */ ++#define F3 (R3 + 1) ++ { 5, 5, 0, AXP_OPERAND_FPR, 0, 0 }, ++/* sw6 simd settle instruction lit */ ++#define FMALIT (F3 + 1) ++ { 5,5, -FMALIT, AXP_OPERAND_UNSIGNED, 0, 0 },//V1.1 ++/*for pal to check disp which must be plus sign and less than 0x8000,WCH20080901*/ ++#define LMDISP (FMALIT + 1) ++ { 15, 0, -LMDISP, AXP_OPERAND_UNSIGNED, 0, 0 }, ++#define RPIINDEX (LMDISP + 1) ++ { 8, 0, -RPIINDEX, AXP_OPERAND_UNSIGNED, 0, 0 }, + - #if __GNUC_PREREQ (4,3) --# define __warndecl(name, msg) \ -- extern void name (void) __attribute__((__warning__ (msg))) - # define __warnattr(msg) __attribute__((__warning__ (msg))) - # define __errordecl(name, msg) \ - extern void name (void) __attribute__((__error__ (msg))) ++#define ATMDISP (RPIINDEX + 1) ++ { 12, 0, -ATMDISP, AXP_OPERAND_SIGNED, 0, 0 } ++#endif ++ ++}; ++ ++const unsigned sw_64_num_operands = sizeof(sw_64_operands)/sizeof(*sw_64_operands); ++ ++ ++/* Macros used to form opcodes. */ ++ ++/* The main opcode. */ ++#define OP(x) (((x) & 0x3F) << 26) ++#define OP_MASK 0xFC000000 ++ ++/* Branch format instructions. */ ++#define BRA_(oo) OP(oo) ++#define BRA_MASK OP_MASK ++#define BRA(oo) BRA_(oo), BRA_MASK ++ ++#ifndef SPS20160530 ++/* Simple computing format instructions. */ ++#define SIMP_(oo,fff) (OP(oo) | (((fff) & 0xFF) << 5)) ++#define SIMP_MASK (OP_MASK | 0x1FE0) ++#define SIMP(oo,fff) SIMP_(oo,fff), SIMP_MASK ++#else ++/* Floating point format instructions. */ ++#define FP_(oo,fff) (OP(oo) | (((fff) & 0x7FF) << 5)) ++#define FP_MASK (OP_MASK | 0xFFE0) ++#define FP(oo,fff) FP_(oo,fff), FP_MASK ++#endif ++ ++/* Memory format instructions. */ ++#define MEM_(oo) OP(oo) ++#define MEM_MASK OP_MASK ++#define MEM(oo) MEM_(oo), MEM_MASK ++ ++/* Memory/Func Code format instructions. */ ++#ifndef SPS20160530 ++#define MFC_(oo,ffff) (OP(oo) | (((ffff) & 0xF)<<12)) ++//#define MFC_MASK (OP_MASK | 0xFFFF) ++#define MFC_MASK (OP_MASK | 0xF000) ++#define MFC(oo,ffff) MFC_(oo,ffff), MFC_MASK ++#else ++#define MFC_(oo,ffff) (OP(oo) | ((ffff) & 0xFFFF)) ++#define MFC_MASK (OP_MASK | 0xFFFF) ++#define MFC(oo,ffff) MFC_(oo,ffff), MFC_MASK ++#endif ++ ++/* Memory/Branch format instructions. */ ++#define MBR_(oo,h) (OP(oo) | (((h) & 3) << 14)) ++#define MBR_MASK (OP_MASK | 0xC000) ++#define MBR(oo,h) MBR_(oo,h), MBR_MASK ++ ++#ifndef SPS20160530 ++/* Memory/miscellaneous atom format instructions. */ ++#define MAT_(oo,h) (OP(oo) | ((h) & 0xffff) ) ++#define MAT_MASK (OP_MASK | 0xFFFF) ++#define MAT(oo,h) MAT_(oo,h), MAT_MASK ++ ++/* priority format instructions. */ ++#define PRI_(oo,ty,len) (OP(oo) | (((ty) & 0x7)<<13) | (((len) & 0x1)<<12)) ++#define PRI_MASK (OP_MASK | 0xF000) ++#define PRI(oo,ty,len) PRI_(oo,ty,len), PRI_MASK ++#define PRI_SR_(oo,h) (OP(oo) | (((h) & 0xff)<<8) ) ++#define PRI_SR_MASK (OP_MASK | 0xFF00) ++#define PRI_SR(oo,h) PRI_SR_(oo,h), PRI_SR_MASK ++#define PRI_RET_(oo,h) (OP(oo) | (((h) & 0x1)<<20) ) ++#define PRI_RET_MASK (OP_MASK | (0x1<<20)) ++#define PRI_RET(oo,h) PRI_RET_(oo,h), PRI_RET_MASK ++ ++/* interger composite intr... */ ++#define INT_COM_(oo,h) (OP(oo) | (((h) & 7) << 10)) ++#define INT_COM_MASK (OP_MASK | 0x1C00) ++#define INT_COM(oo,h) INT_COM_(oo,h), INT_COM_MASK ++ ++/* float composite intr... */ ++#define FP_COM_(oo,h) (OP(oo) | (((h) & 0x3f) << 10)) ++#define FP_COM_MASK (OP_MASK | 0xFC00) ++#define FP_COM(oo,h) FP_COM_(oo,h), FP_COM_MASK ++#else ++ ++/* Operate format instructions. The OPRL variant specifies a ++ literal second argument. */ ++#define OPR_(oo,ff) (OP(oo) | (((ff) & 0x7F) << 5)) ++#define OPRL_(oo,ff) (OPR_((oo),(ff)) | 0x1000) ++#define OPR_MASK (OP_MASK | 0x1FE0) ++#define OPR(oo,ff) OPR_(oo,ff), OPR_MASK ++#define OPRL(oo,ff) OPRL_(oo,ff), OPR_MASK ++#endif ++ ++/* Generic PALcode format instructions. */ ++#define PCD_(oo) OP(oo) ++#define PCD_MASK OP_MASK ++#define PCD(oo) PCD_(oo), PCD_MASK ++#ifndef XWB20170510 ++#define PCDL_(oo,ff) (OP(oo) | (ff << 25)) ++#define PCDL_MASK OP_MASK ++#define PCDL(oo,ff) PCDL_(oo,ff), PCDL_MASK ++#endif ++ ++/* Specific PALcode instructions. */ ++#define SPCD_(oo,ffff) (OP(oo) | ((ffff) & 0x3FFFFFF)) ++#define SPCD_MASK 0xFFFFFFFF ++#define SPCD(oo,ffff) SPCD_(oo,ffff), SPCD_MASK ++ ++/* Hardware memory (hw_{ld,st}) instructions. */ ++#define SW6HWMEM_(oo,f) (OP(oo) | (((f) & 0xF) << 12)) ++#define SW6HWMEM_MASK (OP_MASK | 0xF000) ++#define SW6HWMEM(oo,f) SW6HWMEM_(oo,f), SW6HWMEM_MASK ++ ++#define SW6HWMBR_(oo,h) (OP(oo) | (((h) & 7) << 13)) ++#define SW6HWMBR_MASK (OP_MASK | 0xE000) ++#define SW6HWMBR(oo,h) SW6HWMBR_(oo,h), SW6HWMBR_MASK ++ ++/* Abbreviations for instruction subsets. */ ++#define BASE AXP_OPCODE_BASE ++#define SW6 AXP_OPCODE_SW6 ++#define BWX AXP_OPCODE_BWX ++#define CIX AXP_OPCODE_CIX ++#define MAX AXP_OPCODE_MAX ++ ++/* Common combinations of arguments. */ ++#define ARG_NONE { 0 } ++#define ARG_BRA { RA, BDISP } ++#define ARG_FBRA { FA, BDISP } ++#ifdef SPS20160530 ++#define ARG_FP { FA, FB, DFC1 } ++#define ARG_FPZ1 { ZA, FB, DFC1 } ++#endif ++#define ARG_MEM { RA, MDISP, PRB } ++#define ARG_FMEM { FA, MDISP, PRB } ++ ++#ifndef SPS20160530 ++#define ARG_FMEM_12DISP { FA, SW6HWDISP, PRB } ++#define ARG_VMEM_12DISP { VA, SW6HWDISP, PRB } ++#define ARG_FP { FA, FB, FC } ++#define ARG_FPZ1 { FB, FC } ++#define ARG_FPZB { FA, FC } ++#define ARG_OPR { RA, RB, RC } ++#define ARG_OPRL { RA, LIT, RC } ++#define ARG_OPRZ1 { RB, RC } ++#define ARG_OPRLZ1 { LIT, RC } ++#define ARG_VMEM { VA, MDISP, PRB } ++#define ARG_VOPR { VA, VB, VC } ++#define ARG_VOPRL { RA, LIT, RC } ++#define ARG_VOPR4 { VA, VB, VD, VC } ++#define ARG_VOPRL4 { VA, VB, CIB, VC } ++#else ++#define ARG_OPR { RA, RB, DRC1 } ++#define ARG_OPRL { RA, LIT, DRC1 } ++#define ARG_OPRZ1 { ZA, RB, DRC1 } ++#define ARG_OPRLZ1 { ZA, LIT, RC } ++#endif ++ ++#define ARG_PCD { PALFN } ++#define ARG_SW6HWMEM { RA, SW6HWDISP, PRB } ++ ++#ifndef SPS20160530 ++#define ARG_INT_COM { RA, RB, SRC, SRD } ++#define ARG_INT_COML { RA, LIT, SRC, SRD } ++#define ARG_FP_COM { FA, FB, SFC, SFD } ++#define ARG_FP_COML { FA, FB, CIB, SFD } ++#define ARG_FP_COMZL { FA, LIT, FC } ++#define ARG_FP_COMLC { FA, CIB, FC } ++#define ARG_FP_VCOMZL { VA, LIT, VC } ++#define ARG_FP_ITOF { RA, FC } ++#define ARG_FP_FTOI { FA, RC } ++#define ARG_ATOM {RA , PRIDISP, PRB } ++#endif ++#define ARG_VUAMEM { FA, ATMDISP, PRB } //WCH20090805 New V1.1 add ++ ++ ++ ++/* The opcode table. ++ ++ The format of the opcode table is: ++ ++ NAME OPCODE MASK { OPERANDS } ++ ++ NAME is the name of the instruction. ++ ++ OPCODE is the instruction opcode. ++ ++ MASK is the opcode mask; this is used to tell the disassembler ++ which bits in the actual opcode must match OPCODE. ++ ++ OPERANDS is the list of operands. ++ ++ The preceding macros merge the text of the OPCODE and MASK fields. ++ ++ The disassembler reads the table in order and prints the first ++ instruction which matches, so this table is sorted to put more ++ specific instructions before more general instructions. ++ ++ Otherwise, it is sorted by major opcode and minor function code. ++ ++ There are three classes of not-really-instructions in this table: ++ ++ ALIAS is another name for another instruction. Some of ++ these come from the Architecture Handbook, some ++ come from the original gas opcode tables. In all ++ cases, the functionality of the opcode is unchanged. ++ ++ PSEUDO a stylized code form endorsed by Chapter A.4 of the ++ Architecture Handbook. ++ ++ EXTRA a stylized code form found in the original gas tables. ++ ++ And two annotations: */ ++ ++ ++const struct sw_64_opcode sw_64_opcodes[] = ++{ ++ { "halt", SPCD(0x00,0x0000), BASE, ARG_NONE }, ++ { "draina", SPCD(0x00,0x0002), BASE, ARG_NONE }, ++ { "bpt", SPCD(0x00,0x0080), BASE, ARG_NONE }, ++ { "bugchk", SPCD(0x00,0x0081), BASE, ARG_NONE }, ++ { "callsys", SPCD(0x00,0x0083), BASE, ARG_NONE }, ++ { "chmk", SPCD(0x00,0x0083), BASE, ARG_NONE }, ++ { "imb", SPCD(0x00,0x0086), BASE, ARG_NONE }, ++ { "rduniq", SPCD(0x00,0x009e), BASE, ARG_NONE }, ++ { "wruniq", SPCD(0x00,0x009f), BASE, ARG_NONE }, ++ { "gentrap", SPCD(0x00,0x00aa), BASE, ARG_NONE }, ++ { "sys_call", PCDL(0x00,0x01), BASE, ARG_PCD }, ++ { "sys_call/b", PCDL(0x00,0x00), BASE, ARG_PCD }, ++ ++ { "call", MEM(0x1), BASE, { RA, CPRB, JMPHINT } }, ++ { "ret", MEM(0x2), BASE, { RA, CPRB, JMPHINT } }, ++ { "jmp", MEM(0x3), BASE, { RA, CPRB, JMPHINT } }, ++ { "br", BRA(0x4), BASE, ARG_BRA }, ++ { "bsr", BRA(0x5), BASE, ARG_BRA }, ++ { "memb", MAT(0x06,0x0), BASE, ARG_NONE }, ++ { "imemb", MAT(0x06,0x1), BASE, ARG_NONE }, ++ { "rtc", MAT(0x06,0x0020), BASE, {RA, RB } }, ++ { "rcid", MAT(0x06,0x0040), BASE, {RA, RB } }, ++ { "halt", MAT(0x06,0x0080), BASE, {RA, RB } }, ++ { "rd_f", MAT(0x06,0x1000), BASE, {RA, RB } }, ++ { "wr_f", MAT(0x06,0x1020), BASE, {RA, RB } }, ++ { "rtid", MAT(0x06,0x1040), BASE, { RA } }, ++ { "pri_rcsr", PRI_SR(0x06,0xfe), BASE, {RA, ZB, EV4EXTHWINDEX } }, ++ { "pri_wcsr", PRI_SR(0x06,0xff), BASE, {RA, ZB, EV4EXTHWINDEX } }, ++ { "pri_ret", PRI_RET(0x07,0x0), BASE, {RA } }, ++ { "pri_ret_barrier",PRI_RET(0x07,0x1), BASE, {RA } }, ++ ++ { "lldw", MFC(0x08,0x0), BASE, ARG_SW6HWMEM }, ++ { "lldl", MFC(0x08,0x1), BASE, ARG_SW6HWMEM }, ++ { "ldw_inc", MFC(0x08,0x2), BASE, ARG_SW6HWMEM }, ++ { "ldl_inc", MFC(0x08,0x3), BASE, ARG_SW6HWMEM }, ++ { "ldw_dec", MFC(0x08,0x4), BASE, ARG_SW6HWMEM }, ++ { "ldl_dec", MFC(0x08,0x5), BASE, ARG_SW6HWMEM }, ++ { "ldw_set", MFC(0x08,0x6), BASE, ARG_SW6HWMEM }, ++ { "ldl_set", MFC(0x08,0x7), BASE, ARG_SW6HWMEM }, ++ { "lstw", MFC(0x08,0x8), BASE, ARG_SW6HWMEM }, ++ { "lstl", MFC(0x08,0x9), BASE, ARG_SW6HWMEM }, ++ { "ldw_nc", MFC(0x08,0xa), BASE, ARG_SW6HWMEM }, ++ { "ldl_nc", MFC(0x08,0xb), BASE, ARG_SW6HWMEM }, ++ { "ldd_nc", MFC(0x08,0xc), BASE, ARG_SW6HWMEM }, ++ { "stw_nc", MFC(0x08,0xd), BASE, ARG_SW6HWMEM }, ++ { "stl_nc", MFC(0x08,0xe), BASE, ARG_SW6HWMEM }, ++ { "std_nc", MFC(0x08,0xf), BASE, ARG_SW6HWMEM }, ++ ++ { "ldwe", MEM(0x09), BASE, ARG_FMEM }, ++ { "ldse", MEM(0x0A), BASE, ARG_FMEM }, ++ { "ldde", MEM(0x0B), BASE, ARG_FMEM }, ++ { "vlds", MEM(0x0C), BASE, ARG_VMEM }, ++ { "vldd", MEM(0x0D), BASE, ARG_VMEM }, ++ { "vsts", MEM(0x0E), BASE, ARG_VMEM }, ++ { "vstd", MEM(0x0F), BASE, ARG_VMEM }, ++ ++ { "addw", SIMP(0x10,0x00), BASE, ARG_OPR }, ++ { "subw", SIMP(0x10,0x01), BASE, ARG_OPR }, ++ { "s4addw", SIMP(0x10,0x02), BASE, ARG_OPR }, ++ { "s4subw", SIMP(0x10,0x03), BASE, ARG_OPR }, ++ { "s8addw", SIMP(0x10,0x04), BASE, ARG_OPR }, ++ { "s8subw", SIMP(0x10,0x05), BASE, ARG_OPR }, ++ { "addl", SIMP(0x10,0x08), BASE, ARG_OPR }, ++ { "subl", SIMP(0x10,0x09), BASE, ARG_OPR }, ++ { "s4addl", SIMP(0x10,0x0A), BASE, ARG_OPR }, ++ { "s4subl", SIMP(0x10,0x0B), BASE, ARG_OPR }, ++ { "s8addl", SIMP(0x10,0x0C), BASE, ARG_OPR }, ++ { "s8subl", SIMP(0x10,0x0D), BASE, ARG_OPR }, ++ { "mulw", SIMP(0x10,0x10), BASE, ARG_OPR }, ++ { "mull", SIMP(0x10,0x18), BASE, ARG_OPR }, ++ { "umulh", SIMP(0x10,0x19), BASE, ARG_OPR }, ++ { "cmpeq", SIMP(0x10,0x28), BASE, ARG_OPR }, ++ { "cmplt", SIMP(0x10,0x29), BASE, ARG_OPR }, ++ { "cmple", SIMP(0x10,0x2A), BASE, ARG_OPR }, ++ { "cmpult", SIMP(0x10,0x2B), BASE, ARG_OPR }, ++ { "cmpule", SIMP(0x10,0x2C), BASE, ARG_OPR }, ++ ++ { "and", SIMP(0x10,0x38), BASE, ARG_OPR }, ++ { "bic", SIMP(0x10,0x39), BASE, ARG_OPR }, ++ { "bis", SIMP(0x10,0x3A), BASE, ARG_OPR }, ++ { "ornot", SIMP(0x10,0x3B), BASE, ARG_OPR }, ++ { "xor", SIMP(0x10,0x3c), BASE, ARG_OPR }, ++ { "eqv", SIMP(0x10,0x3D), BASE, ARG_OPR }, ++ ++ { "ins0b", SIMP(0x10,0x40), BASE, ARG_OPR }, ++ { "ins1b", SIMP(0x10,0x41), BASE, ARG_OPR }, ++ { "ins2b", SIMP(0x10,0x42), BASE, ARG_OPR }, ++ { "ins3b", SIMP(0x10,0x43), BASE, ARG_OPR }, ++ { "ins4b", SIMP(0x10,0x44), BASE, ARG_OPR }, ++ { "ins5b", SIMP(0x10,0x45), BASE, ARG_OPR }, ++ { "ins6b", SIMP(0x10,0x46), BASE, ARG_OPR }, ++ { "ins7b", SIMP(0x10,0x47), BASE, ARG_OPR }, ++ ++ { "sll", SIMP(0x10,0x48), BASE, ARG_OPR }, ++ { "srl", SIMP(0x10,0x49), BASE, ARG_OPR }, ++ { "sra", SIMP(0x10,0x4A), BASE, ARG_OPR }, ++ ++ { "ext0b", SIMP(0x10,0x50), BASE, ARG_OPR }, ++ { "ext1b", SIMP(0x10,0x51), BASE, ARG_OPR }, ++ { "ext2b", SIMP(0x10,0x52), BASE, ARG_OPR }, ++ { "ext3b", SIMP(0x10,0x53), BASE, ARG_OPR }, ++ { "ext4b", SIMP(0x10,0x54), BASE, ARG_OPR }, ++ { "ext5b", SIMP(0x10,0x55), BASE, ARG_OPR }, ++ { "ext6b", SIMP(0x10,0x56), BASE, ARG_OPR }, ++ { "ext7b", SIMP(0x10,0x57), BASE, ARG_OPR }, ++ ++ { "ctpop", SIMP(0x10,0x58), BASE, ARG_OPRZ1 }, ++ { "ctlz", SIMP(0x10,0x59), BASE, ARG_OPRZ1 }, ++ { "cttz", SIMP(0x10,0x5A), BASE, ARG_OPRZ1 }, ++ ++ { "mask0b", SIMP(0x10,0x60), BASE, ARG_OPR }, ++ { "mask1b", SIMP(0x10,0x61), BASE, ARG_OPR }, ++ { "mask2b", SIMP(0x10,0x62), BASE, ARG_OPR }, ++ { "mask3b", SIMP(0x10,0x63), BASE, ARG_OPR }, ++ { "mask4b", SIMP(0x10,0x64), BASE, ARG_OPR }, ++ { "mask5b", SIMP(0x10,0x65), BASE, ARG_OPR }, ++ { "mask6b", SIMP(0x10,0x66), BASE, ARG_OPR }, ++ { "mask7b", SIMP(0x10,0x67), BASE, ARG_OPR }, ++ { "zap", SIMP(0x10,0x68), BASE, ARG_OPR }, ++ { "zapnot", SIMP(0x10,0x69), BASE, ARG_OPR }, ++ { "sextb", SIMP(0x10,0x6A), BASE, ARG_OPRZ1 }, ++ { "sexth", SIMP(0x10,0x6B), BASE, ARG_OPRZ1 }, ++ { "cmpgeb", SIMP(0x10,0x6c), BASE, ARG_OPR }, ++ { "ftois", SIMP(0x10,0x70), BASE, ARG_FP_FTOI }, ++ { "ftoid", SIMP(0x10,0x78), BASE, ARG_FP_FTOI }, ++ { "SelEq", INT_COM(0x11,0x0), BASE, ARG_INT_COM }, ++ { "SelGe", INT_COM(0x11,0x1), BASE, ARG_INT_COM }, ++ { "SelGt", INT_COM(0x11,0x2), BASE, ARG_INT_COM }, ++ { "SelLe", INT_COM(0x11,0x3), BASE, ARG_INT_COM }, ++ { "SelLt", INT_COM(0x11,0x4), BASE, ARG_INT_COM }, ++ { "SelNe", INT_COM(0x11,0x5), BASE, ARG_INT_COM }, ++ { "SelLbC", INT_COM(0x11,0x6), BASE, ARG_INT_COM }, ++ { "selLbS", INT_COM(0x11,0x7), BASE, ARG_INT_COM }, ++ ++ { "addw", SIMP(0x12,0x00), BASE, ARG_OPRL }, ++ { "subw", SIMP(0x12,0x01), BASE, ARG_OPRL }, ++ { "s4addw", SIMP(0x12,0x02), BASE, ARG_OPRL }, ++ { "s4subw", SIMP(0x12,0x03), BASE, ARG_OPRL }, ++ { "s8addw", SIMP(0x12,0x04), BASE, ARG_OPRL }, ++ { "s8subw", SIMP(0x12,0x05), BASE, ARG_OPRL }, ++ { "addl", SIMP(0x12,0x08), BASE, ARG_OPRL }, ++ { "subl", SIMP(0x12,0x09), BASE, ARG_OPRL }, ++ { "s4addl", SIMP(0x12,0x0A), BASE, ARG_OPRL }, ++ { "s4subl", SIMP(0x12,0x0B), BASE, ARG_OPRL }, ++ { "s8addl", SIMP(0x12,0x0C), BASE, ARG_OPRL }, ++ { "s8subl", SIMP(0x12,0x0D), BASE, ARG_OPRL }, ++ { "mulw", SIMP(0x12,0x10), BASE, ARG_OPRL }, ++ { "mull", SIMP(0x12,0x18), BASE, ARG_OPRL }, ++ { "umulh", SIMP(0x12,0x19), BASE, ARG_OPRL }, ++ { "cmpeq", SIMP(0x12,0x28), BASE, ARG_OPRL }, ++ { "cmplt", SIMP(0x12,0x29), BASE, ARG_OPRL }, ++ { "cmple", SIMP(0x12,0x2A), BASE, ARG_OPRL }, ++ { "cmpult", SIMP(0x12,0x2B), BASE, ARG_OPRL }, ++ { "cmpule", SIMP(0x12,0x2C), BASE, ARG_OPRL }, ++ ++ { "and", SIMP(0x12,0x38), BASE, ARG_OPRL }, ++ { "bic", SIMP(0x12,0x39), BASE, ARG_OPRL }, ++ { "bis", SIMP(0x12,0x3A), BASE, ARG_OPRL }, ++ { "ornot", SIMP(0x12,0x3B), BASE, ARG_OPRL }, ++ { "xor", SIMP(0x12,0x3c), BASE, ARG_OPRL }, ++ { "eqv", SIMP(0x12,0x3D), BASE, ARG_OPRL }, ++ { "ins0b", SIMP(0x12,0x40), BASE, ARG_OPRL }, ++ { "ins1b", SIMP(0x12,0x41), BASE, ARG_OPRL }, ++ { "ins2b", SIMP(0x12,0x42), BASE, ARG_OPRL }, ++ { "ins3b", SIMP(0x12,0x43), BASE, ARG_OPRL }, ++ { "ins4b", SIMP(0x12,0x44), BASE, ARG_OPRL }, ++ { "ins5b", SIMP(0x12,0x45), BASE, ARG_OPRL }, ++ { "ins6b", SIMP(0x12,0x46), BASE, ARG_OPRL }, ++ { "ins7b", SIMP(0x12,0x47), BASE, ARG_OPRL }, ++ ++ { "sll", SIMP(0x12,0x48), BASE, ARG_OPRL }, ++ { "srl", SIMP(0x12,0x49), BASE, ARG_OPRL }, ++ { "sra", SIMP(0x12,0x4A), BASE, ARG_OPRL }, ++ { "ext0b", SIMP(0x12,0x50), BASE, ARG_OPRL }, ++ { "ext1b", SIMP(0x12,0x51), BASE, ARG_OPRL }, ++ { "ext2b", SIMP(0x12,0x52), BASE, ARG_OPRL }, ++ { "ext3b", SIMP(0x12,0x53), BASE, ARG_OPRL }, ++ { "ext4b", SIMP(0x12,0x54), BASE, ARG_OPRL }, ++ { "ext5b", SIMP(0x12,0x55), BASE, ARG_OPRL }, ++ { "ext6b", SIMP(0x12,0x56), BASE, ARG_OPRL }, ++ { "ext7b", SIMP(0x12,0x57), BASE, ARG_OPRL }, ++ ++ { "mask0b", SIMP(0x12,0x60), BASE, ARG_OPRL }, ++ { "mask1b", SIMP(0x12,0x61), BASE, ARG_OPRL }, ++ { "mask2b", SIMP(0x12,0x62), BASE, ARG_OPRL }, ++ { "mask3b", SIMP(0x12,0x63), BASE, ARG_OPRL }, ++ { "mask4b", SIMP(0x12,0x64), BASE, ARG_OPRL }, ++ { "mask5b", SIMP(0x12,0x65), BASE, ARG_OPRL }, ++ { "mask6b", SIMP(0x12,0x66), BASE, ARG_OPRL }, ++ { "mask7b", SIMP(0x12,0x67), BASE, ARG_OPRL }, ++ { "zap", SIMP(0x12,0x68), BASE, ARG_OPRLZ1 }, ++ { "zapnot", SIMP(0x12,0x69), BASE, ARG_OPRL }, ++ { "sextb", SIMP(0x12,0x6A), BASE, ARG_OPRLZ1 }, ++ { "sexth", SIMP(0x12,0x6B), BASE, ARG_OPRLZ1 }, ++ { "cmpgeb", SIMP(0x12,0x6c), BASE, ARG_OPRL }, ++ ++ { "SelEqI", INT_COM(0x13,0x0), BASE, ARG_INT_COML }, ++ { "SelGeI", INT_COM(0x13,0x1), BASE, ARG_INT_COML }, ++ { "SelGtI", INT_COM(0x13,0x2), BASE, ARG_INT_COML }, ++ { "SelLeI", INT_COM(0x13,0x3), BASE, ARG_INT_COML }, ++ { "SelLtI", INT_COM(0x13,0x4), BASE, ARG_INT_COML }, ++ { "SelNeI", INT_COM(0x13,0x5), BASE, ARG_INT_COML }, ++ { "SelLbCI", INT_COM(0x13,0x6), BASE, ARG_INT_COML }, ++ { "selLbSI", INT_COM(0x13,0x7), BASE, ARG_INT_COML }, ++ ++ { "vlog", MEM(0x14), BASE, ARG_VOPR4 }, ++ { "vlog", MEM(0x15), BASE, ARG_VOPR4 }, ++ { "vlog", MEM(0x16), BASE, ARG_VOPR4 }, ++ { "vlog", MEM(0x17), BASE, ARG_VOPR4 }, ++ { "fadds", SIMP(0x18,0x00), BASE, ARG_FP }, ++ { "faddd", SIMP(0x18,0x01), BASE, ARG_FP }, ++ { "fsubs", SIMP(0x18,0x02), BASE, ARG_FP }, ++ { "fsubd", SIMP(0x18,0x03), BASE, ARG_FP }, ++ { "fmuls", SIMP(0x18,0x04), BASE, ARG_FP }, ++ { "fmuld", SIMP(0x18,0x05), BASE, ARG_FP }, ++ { "fdivs", SIMP(0x18,0x06), BASE, ARG_FP }, ++ { "fdivd", SIMP(0x18,0x07), BASE, ARG_FP }, ++ { "fsqrts", SIMP(0x18,0x08), BASE, ARG_FPZ1 }, ++ { "fsqrtd", SIMP(0x18,0x09), BASE, ARG_FPZ1 }, ++ { "fcmpEq", SIMP(0x18,0x10), BASE, ARG_FP }, ++ { "fcmpLe", SIMP(0x18,0x11), BASE, ARG_FP }, ++ { "fcmpLt", SIMP(0x18,0x12), BASE, ARG_FP }, ++ { "fcmpUn", SIMP(0x18,0x13), BASE, ARG_FP }, ++ { "fcvtSD", SIMP(0x18,0x20), BASE, ARG_FPZ1 }, ++ { "fcvtDS", SIMP(0x18,0x21), BASE, ARG_FPZ1 }, ++ ++ { "fcvtdl_g", SIMP(0x18,0x22), BASE, ARG_FPZ1 }, ++ { "fcvtdl_p", SIMP(0x18,0x23), BASE, ARG_FPZ1 }, ++ { "fcvtdl_z", SIMP(0x18,0x24), BASE, ARG_FPZ1 }, ++ { "fcvtdl_n", SIMP(0x18,0x25), BASE, ARG_FPZ1 }, ++ { "fcvtDL", SIMP(0x18,0x27), BASE, ARG_FPZ1 }, ++ { "fcvtWL", SIMP(0x18,0x28), BASE, ARG_FPZ1 }, ++ { "fcvtLW", SIMP(0x18,0x29), BASE, ARG_FPZ1 }, ++ { "fcvtLS", SIMP(0x18,0x2D), BASE, ARG_FPZ1 }, ++ { "fcvtLD", SIMP(0x18,0x2F), BASE, ARG_FPZ1 }, ++ { "fcpys", SIMP(0x18,0x30), BASE, ARG_FP }, ++ { "fcpyse", SIMP(0x18,0x31), BASE, ARG_FP }, ++ { "fcpysn", SIMP(0x18,0x32), BASE, ARG_FP }, ++ { "ItoFS", SIMP(0x18,0x40), BASE, ARG_FP_ITOF }, ++ { "ItoFD", SIMP(0x18,0x41), BASE, ARG_FP_ITOF }, ++ { "rfpcr", SIMP(0x18,0x50), BASE, { FA } }, ++ { "wfpcr", SIMP(0x18,0x51), BASE, { FA } }, ++ { "setfpec0", SIMP(0x18,0x54), BASE, ARG_NONE }, ++ { "setfpec1", SIMP(0x18,0x55), BASE, ARG_NONE }, ++ { "setfpec2", SIMP(0x18,0x56), BASE, ARG_NONE }, ++ { "setfpec3", SIMP(0x18,0x57), BASE, ARG_NONE }, ++ ++ { "fmas", FP_COM(0x19,0x00), BASE, ARG_FP_COM }, ++ { "fmad", FP_COM(0x19,0x01), BASE, ARG_FP_COM }, ++ { "fmss", FP_COM(0x19,0x02), BASE, ARG_FP_COM }, ++ { "fmsd", FP_COM(0x19,0x03), BASE, ARG_FP_COM }, ++ { "fnmas", FP_COM(0x19,0x04), BASE, ARG_FP_COM }, ++ { "fnmad", FP_COM(0x19,0x05), BASE, ARG_FP_COM }, ++ { "fnmss", FP_COM(0x19,0x06), BASE, ARG_FP_COM }, ++ { "fnmsd", FP_COM(0x19,0x07), BASE, ARG_FP_COM }, ++ { "fselEq", FP_COM(0x19,0x10), BASE, ARG_FP_COM }, ++ { "fselNe", FP_COM(0x19,0x11), BASE, ARG_FP_COM }, ++ { "fselLt", FP_COM(0x19,0x12), BASE, ARG_FP_COM }, ++ { "fselLe", FP_COM(0x19,0x13), BASE, ARG_FP_COM }, ++ { "fselGt", FP_COM(0x19,0x14), BASE, ARG_FP_COM }, ++ { "fselGe", FP_COM(0x19,0x15), BASE, ARG_FP_COM }, ++ { "vaddw", SIMP(0x1A,0x00), BASE, ARG_VOPR }, ++ { "vsubw", SIMP(0x1A,0x01), BASE, ARG_VOPR }, ++ { "vcmpgew", SIMP(0x1A,0x02), BASE, {VA, VB, FC} }, ++ { "vcmpeqw", SIMP(0x1A,0x03), BASE, ARG_VOPR }, ++ { "vcmplew", SIMP(0x1A,0x04), BASE, ARG_VOPR }, ++ { "vcmpltw", SIMP(0x1A,0x05), BASE, ARG_VOPR }, ++ { "vcmpulew", SIMP(0x1A,0x06), BASE, ARG_VOPR }, ++ { "vcmpultw", SIMP(0x1A,0x07), BASE, ARG_VOPR }, ++ { "vsllw", SIMP(0x1A,0x08), BASE, {VA, FB, VC} }, ++ { "vsrlw", SIMP(0x1A,0x09), BASE, {VA, FB, VC} }, ++ { "vsraw", SIMP(0x1A,0x0A), BASE, {VA, FB, VC} }, ++ { "vrolw", SIMP(0x1A,0x0B), BASE, {VA, FB, VC} }, ++ { "sllow", SIMP(0x1A,0x0C), BASE, {VA, FB, VC} }, ++ { "srlow", SIMP(0x1A,0x0D), BASE, {VA, FB, VC} }, ++ { "vaddl", SIMP(0x1A,0x0E), BASE, ARG_VOPR }, ++ { "vsubl", SIMP(0x1A,0x0F), BASE, ARG_VOPR }, ++ { "ctpopow", SIMP(0x1A,0x18), BASE, {VA, FC} }, ++ { "ctlzow", SIMP(0x1A,0x19), BASE, {VA, FC} }, ++ { "vaddw", SIMP(0x1A,0x20), BASE, ARG_FP_VCOMZL }, ++ { "vsubw", SIMP(0x1A,0x21), BASE, ARG_FP_VCOMZL }, ++ { "vcmpgew", SIMP(0x1A,0x22), BASE, ARG_FP_VCOMZL }, ++ { "vcmpeqw", SIMP(0x1A,0x23), BASE, ARG_FP_VCOMZL }, ++ { "vcmplew", SIMP(0x1A,0x24), BASE, ARG_FP_VCOMZL }, ++ { "vcmpltw", SIMP(0x1A,0x25), BASE, ARG_FP_VCOMZL }, ++ { "vcmpulew", SIMP(0x1A,0x26), BASE, ARG_FP_VCOMZL }, ++ { "vcmpultw", SIMP(0x1A,0x27), BASE, ARG_FP_VCOMZL }, ++ ++ { "vsllw", SIMP(0x1A,0x28), BASE, ARG_FP_VCOMZL }, ++ { "vsrlw", SIMP(0x1A,0x29), BASE, ARG_FP_VCOMZL }, ++ { "vsraw", SIMP(0x1A,0x2A), BASE, ARG_FP_VCOMZL }, ++ { "vrolw", SIMP(0x1A,0x0B), BASE, ARG_FP_VCOMZL }, ++ { "sllow", SIMP(0x1A,0x2C), BASE, ARG_FP_VCOMZL }, ++ { "srlow", SIMP(0x1A,0x2D), BASE, ARG_FP_VCOMZL }, ++ { "vaddl", SIMP(0x1A,0x2E), BASE, ARG_FP_VCOMZL }, ++ { "vsubl", SIMP(0x1A,0x2F), BASE, ARG_FP_VCOMZL }, ++#ifdef SPS20160315 ++ { "vbicw", PSE_LOGX(0x14,0x30), SW6, { FA , FB , DFC1 } }, ++ { "vxorw", PSE_LOGX(0x14,0x3c), SW6, { FA , FB , DFC1 } }, ++ { "vandw", PSE_LOGX(0x14,0xc0), SW6, { FA , FB , DFC1 } }, ++ { "veqvw", PSE_LOGX(0x14,0xc3), SW6, { FA , FB , DFC1 } }, ++ { "vornotw", PSE_LOGX(0x14,0xf3), SW6, { FA , FB , DFC1 } }, ++ { "vbisw", PSE_LOGX(0x14,0xfc), SW6, { FA , FB , DFC1 } }, ++#endif ++ ++ { "vucaddw", SIMP(0x1A,0x40), BASE, ARG_VOPR }, ++ { "vucsubw", SIMP(0x1A,0x41), BASE, ARG_VOPR }, ++ { "vucaddh", SIMP(0x1A,0x42), BASE, ARG_VOPR }, ++ { "vucsubh", SIMP(0x1A,0x43), BASE, ARG_VOPR }, ++ { "vucaddb", SIMP(0x1A,0x44), BASE, ARG_VOPR }, ++ { "vucsubb", SIMP(0x1A,0x45), BASE, ARG_VOPR }, ++ ++ { "vucaddw", SIMP(0x1A,0x60), BASE, ARG_FP_VCOMZL }, ++ { "vucsubw", SIMP(0x1A,0x61), BASE, ARG_FP_VCOMZL }, ++ { "vucaddh", SIMP(0x1A,0x62), BASE, ARG_FP_VCOMZL }, ++ { "vucsubh", SIMP(0x1A,0x63), BASE, ARG_FP_VCOMZL }, ++ { "vucaddb", SIMP(0x1A,0x64), BASE, ARG_FP_VCOMZL }, ++ { "vucsubb", SIMP(0x1A,0x65), BASE, ARG_FP_VCOMZL }, ++ ++ { "vadds", SIMP(0x1A,0x80), BASE, ARG_VOPR }, ++ { "vaddd", SIMP(0x1A,0x81), BASE, ARG_VOPR }, ++ { "vsubs", SIMP(0x1A,0x82), BASE, ARG_VOPR }, ++ { "vsubd", SIMP(0x1A,0x83), BASE, ARG_VOPR }, ++ { "vmuls", SIMP(0x1A,0x84), BASE, ARG_VOPR }, ++ { "vmuld", SIMP(0x1A,0x85), BASE, ARG_VOPR }, ++ { "vdivs", SIMP(0x1A,0x86), BASE, ARG_VOPR }, ++ { "vdivd", SIMP(0x1A,0x87), BASE, ARG_VOPR }, ++ { "vsqrts", SIMP(0x1A,0x88), BASE, { VB, VC } }, ++ { "vsqrtd", SIMP(0x1A,0x89), BASE, { VB, VC } }, ++ { "vfcmpeq", SIMP(0x1A,0x8c), BASE, ARG_VOPR }, ++ { "vfcmple", SIMP(0x1A,0x8d), BASE, ARG_VOPR }, ++ { "vfcmplt", SIMP(0x1A,0x8e), BASE, ARG_VOPR }, ++ { "vfcmpun", SIMP(0x1A,0x8f), BASE, ARG_VOPR }, ++ ++ { "vcpys", SIMP(0x1A,0x90), BASE, ARG_VOPR }, ++ { "vcpyse", SIMP(0x1A,0x91), BASE, ARG_VOPR }, ++ { "vcpysn", SIMP(0x1A,0x92), BASE, ARG_VOPR }, ++ ++ { "vmas", FP_COM(0x1B,0x00), BASE, ARG_VOPR4 }, ++ { "vmad", FP_COM(0x1B,0x01), BASE, ARG_VOPR4 }, ++ { "vmss", FP_COM(0x1B,0x02), BASE, ARG_VOPR4 }, ++ { "vmsd", FP_COM(0x1B,0x03), BASE, ARG_VOPR4 }, ++ { "vnmas", FP_COM(0x1B,0x04), BASE, ARG_VOPR4 }, ++ { "vnmad", FP_COM(0x1B,0x05), BASE, ARG_VOPR4 }, ++ { "vnmss", FP_COM(0x1B,0x06), BASE, ARG_VOPR4 }, ++ { "vnmsd", FP_COM(0x1B,0x07), BASE, ARG_VOPR4 }, ++ { "vfseleq", FP_COM(0x1B,0x10), BASE, ARG_VOPR4 }, ++ { "vfsellt", FP_COM(0x1B,0x12), BASE, ARG_VOPR4 }, ++ { "vfselle", FP_COM(0x1B,0x13), BASE, ARG_VOPR4 }, ++ ++ { "vseleqw", FP_COM(0x1B,0x18), BASE, ARG_VOPR4 }, ++ { "vsellbcw", FP_COM(0x1B,0x19), BASE, ARG_VOPR4 }, ++ { "vselltw", FP_COM(0x1B,0x1A), BASE, ARG_VOPR4 }, ++ { "vsellew", FP_COM(0x1B,0x1B), BASE, ARG_VOPR4 }, ++ ++ { "vseleqw", FP_COM(0x1B,0x38), BASE, ARG_VOPRL4 }, ++ { "vsellbcw", FP_COM(0x1B,0x39), BASE, ARG_VOPRL4 }, ++ { "vselltw", FP_COM(0x1B,0x3A), BASE, ARG_VOPRL4 }, ++ { "vsellew", FP_COM(0x1B,0x3B), BASE, ARG_VOPRL4 }, ++ ++ { "vinsw", FP_COM(0x1B,0x20), BASE, { FA, VB, CIB, VC } }, ++ { "vinsf", FP_COM(0x1B,0x21), BASE, { FA, VB, CIB, VC } }, ++ { "vextw", FP_COM(0x1B,0x22), BASE, { FA, CIB, SFD } }, ++ { "vextf", FP_COM(0x1B,0x23), BASE, { FA, CIB, SFD } }, ++ { "vcpyw", FP_COM(0x1B,0x24), BASE, { FA, VC } }, ++ { "vcpyf", FP_COM(0x1B,0x25), BASE, { FA, VC } }, ++ { "vconw", FP_COM(0x1B,0x26), BASE, ARG_VOPR4 }, ++ { "vshfw", FP_COM(0x1B,0x27), BASE, ARG_VOPR4 }, ++ { "vcons", FP_COM(0x1B,0x28), BASE, ARG_VOPR4 }, ++ { "vcond", FP_COM(0x1B,0x29), BASE, ARG_VOPR4 }, ++ ++#ifdef XWB20170510 ++ { "vldw_ul", MFC(0x1C,0), BASE, ARG_VMEM_12DISP }, ++ { "vldw_uh", MFC(0x1C,1), BASE, ARG_VMEM_12DISP }, ++ { "vlds_ul", MFC(0x1C,2), BASE, ARG_VMEM_12DISP }, ++ { "vlds_uh", MFC(0x1C,3), BASE, ARG_VMEM_12DISP }, ++ { "vldd_ul", MFC(0x1C,4), BASE, ARG_VMEM_12DISP }, ++ { "vldd_uh", MFC(0x1C,5), BASE, ARG_VMEM_12DISP }, ++ { "vldd_nc", MFC(0x1C,6), BASE, ARG_VMEM_12DISP }, ++#else ++ { "vldw_u", MFC(0x1C,0), BASE, ARG_SW6HWMEM }, ++ { "vstw_u", MFC(0x1C,1), BASE, ARG_SW6HWMEM }, ++ { "vlds_u", MFC(0x1C,2), BASE, ARG_SW6HWMEM }, ++ { "vsts_u", MFC(0x1C,3), BASE, ARG_SW6HWMEM }, ++ { "vldd_u", MFC(0x1C,4), BASE, ARG_SW6HWMEM }, ++ { "vstd_u", MFC(0x1C,5), BASE, ARG_SW6HWMEM }, ++#endif ++ { "vstw_ul", MFC(0x1C,8), BASE, ARG_SW6HWMEM }, ++ { "vstw_uh", MFC(0x1C,9), BASE, ARG_SW6HWMEM }, ++ { "vsts_ul", MFC(0x1C,0xA), BASE, ARG_SW6HWMEM }, ++ { "vsts_uh", MFC(0x1C,0xB), BASE, ARG_SW6HWMEM }, ++ { "vstd_ul", MFC(0x1C,0xC), BASE, ARG_SW6HWMEM }, ++ { "vstd_uh", MFC(0x1C,0xD), BASE, ARG_SW6HWMEM }, ++#ifdef XWB20170510 ++ { "vstd_nc", MFC(0x1C,0xE), BASE, ARG_VMEM_12DISP }, ++#else ++ { "vldd_nc", MFC(0x1C,0xE), BASE, ARG_VMEM_12DISP }, ++ { "vstd_nc", MFC(0x1C,0xF), BASE, ARG_VMEM_12DISP }, ++#endif ++ { "ldbu", MEM(0x20), BASE, ARG_MEM }, ++ { "ldhu", MEM(0x21), BASE, ARG_MEM }, ++ { "ldw", MEM(0x22), BASE, ARG_MEM }, ++ { "ldl", MEM(0x23), BASE, ARG_MEM }, ++ { "ldl_u", MEM(0x24), BASE, ARG_MEM }, ++ ++ { "pri_ldw/p", PRI(0x25,0x0,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldw_inc/p", PRI(0x25,0x2,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldw/v", PRI(0x25,0x4,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldw/vpte", PRI(0x25,0x6,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldl/p", PRI(0x25,0x0,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldl_inc/p", PRI(0x25,0x2,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldl/v", PRI(0x25,0x4,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_ldl/vpte", PRI(0x25,0x6,0x1), BASE, {RA, PRIDISP, PRB } }, ++ ++ { "flds", MEM(0x26), BASE, ARG_FMEM }, ++ { "fldd", MEM(0x27), BASE, ARG_FMEM }, ++ { "stb", MEM(0x28), BASE, ARG_MEM }, ++ { "sth", MEM(0x29), BASE, ARG_MEM }, ++ { "stw", MEM(0x2A), BASE, ARG_MEM }, ++ { "stl", MEM(0x2B), BASE, ARG_MEM }, ++ { "stl_u", MEM(0x2C), BASE, ARG_MEM }, ++ ++ { "pri_stw/p", PRI(0x2d,0x0,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stw_inc/p", PRI(0x2d,0x2,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stw/v", PRI(0x2d,0x4,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stw/vpte", PRI(0x2d,0x6,0x0), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stl/p", PRI(0x2d,0x0,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stl_inc/p", PRI(0x2d,0x2,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stl/v", PRI(0x2d,0x4,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "pri_stl/vpte", PRI(0x2d,0x6,0x1), BASE, {RA, PRIDISP, PRB } }, ++ { "fsts", MEM(0x2E), BASE, ARG_FMEM }, ++ { "fstd", MEM(0x2F), BASE, ARG_FMEM }, ++ ++ { "beq", BRA(0x30), BASE, ARG_BRA }, ++ { "bne", BRA(0x31), BASE, ARG_BRA }, ++ { "blt", BRA(0x32), BASE, ARG_BRA }, ++ { "ble", BRA(0x33), BASE, ARG_BRA }, ++ { "bgt", BRA(0x34), BASE, ARG_BRA }, ++ { "bge", BRA(0x35), BASE, ARG_BRA }, ++ { "blbc", BRA(0x36), BASE, ARG_BRA }, ++ { "blbs", BRA(0x37), BASE, ARG_BRA }, ++ { "fbeq", BRA(0x38), BASE, ARG_FBRA }, ++ { "fbne", BRA(0x39), BASE, ARG_FBRA }, ++ { "fblt", BRA(0x3A), BASE, ARG_FBRA }, ++ { "fble", BRA(0x3B), BASE, ARG_FBRA }, ++ { "fbgt", BRA(0x3C), BASE, ARG_FBRA }, ++ { "fbge", BRA(0x3D), BASE, ARG_FBRA }, ++ ++ { "ldi", MEM(0x3E), BASE, ARG_MEM }, ++ { "ldih", MEM(0x3F), BASE, ARG_MEM }, ++}; ++ ++const unsigned sw_64_num_opcodes = sizeof(sw_64_opcodes)/sizeof(*sw_64_opcodes); +diff -Nuar gdb-10.2/readline/readline/aclocal.m4 gdb-10.2/readline/readline/aclocal.m4 +--- gdb-10.2/readline/readline/aclocal.m4 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/aclocal.m4 2025-04-16 17:06:52.012086800 +0800 +@@ -10,6 +10,7 @@ + ac_cv_c_long_long=yes + else + AC_TRY_RUN([ ++#include + int + main() + { +@@ -33,6 +34,7 @@ + ac_cv_c_long_double=yes + else + AC_TRY_RUN([ ++#include + int + main() + { +@@ -134,6 +136,8 @@ #else --# define __warndecl(name, msg) extern void name (void) - # define __warnattr(msg) - # define __errordecl(name, msg) extern void name (void) + typedef int (*_bashfunc)(); #endif -@@ -142,8 +217,8 @@ - #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc - # define __flexarr [] - # define __glibc_c99_flexarr_available 1 --#elif __GNUC_PREREQ (2,97) --/* GCC 2.97 supports C99 flexible array members as an extension, -+#elif __GNUC_PREREQ (2,97) || defined __clang__ -+/* GCC 2.97 and clang support C99 flexible array members as an extension, - even when in C89 mode or compiling C++ (any version). */ - # define __flexarr [] - # define __glibc_c99_flexarr_available 1 -@@ -169,7 +244,7 @@ - Example: - int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ - --#if defined __GNUC__ && __GNUC__ >= 2 -+#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4) - - # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) - # ifdef __cplusplus -@@ -194,17 +269,17 @@ - */ ++#include ++int + main() + { + _bashfunc pf; +@@ -191,9 +195,11 @@ + #ifdef HAVE_UNISTD_H + #include #endif - --/* GCC has various useful declarations that can be made with the -- `__attribute__' syntax. All of the ways we use this do fine if -- they are omitted for compilers that don't understand it. */ --#if !defined __GNUC__ || __GNUC__ < 2 -+/* GCC and clang have various useful declarations that can be made with -+ the '__attribute__' syntax. All of the ways we use this do fine if -+ they are omitted for compilers that don't understand it. */ -+#if !(defined __GNUC__ || defined __clang__) - # define __attribute__(xyz) /* Ignore */ ++#include + #ifndef UNDER_SYS_SIGLIST_DECLARED + extern char *_sys_siglist[]; + #endif ++int + main() + { + char *msg = (char *)_sys_siglist[2]; +@@ -218,9 +224,11 @@ + #ifdef HAVE_UNISTD_H + #include + #endif ++#include + #if !HAVE_DECL_SYS_SIGLIST + extern char *sys_siglist[]; + #endif ++int + main() + { + char *msg = sys_siglist[2]; +@@ -273,6 +281,8 @@ + [AC_TRY_RUN([ + #include + #include ++#include ++int + main() + { + int fd1, fd2, fl; +@@ -335,6 +345,8 @@ + # include + # endif + #endif /* HAVE_DIRENT_H */ ++#include ++int + main() + { + DIR *dir; +@@ -514,6 +526,8 @@ + #include + #include + #include ++#include ++int + main() + { + #ifdef HAVE_QUAD_T +@@ -583,6 +597,7 @@ + #ifdef HAVE_UNISTD_H + # include #endif ++#include + #ifndef __STDC__ + # ifndef const + # define const +@@ -598,6 +613,7 @@ + { + return "42"; + } ++int + main() + { + char *s; +@@ -786,7 +802,9 @@ + #include + #include + #include ++#include - /* At some point during the gcc 2.96 development the `malloc' attribute - for functions was introduced. We don't want to use it unconditionally - (although this would be possible) since it generates warnings. */ --#if __GNUC_PREREQ (2,96) -+#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__) - # define __attribute_malloc__ __attribute__ ((__malloc__)) - #else - # define __attribute_malloc__ /* Ignore */ -@@ -219,26 +294,41 @@ - # define __attribute_alloc_size__(params) /* Ignore. */ ++int + main() + { + #if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) +@@ -835,7 +853,10 @@ + #if defined (HAVE_LOCALE_H) + #include #endif ++#include ++#include -+/* Tell the compiler which argument to an allocation function -+ indicates the alignment of the allocation. */ -+#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__) -+# define __attribute_alloc_align__(param) \ -+ __attribute__ ((__alloc_align__ param)) -+#else -+# define __attribute_alloc_align__(param) /* Ignore. */ -+#endif -+ - /* At some point during the gcc 2.96 development the `pure' attribute - for functions was introduced. We don't want to use it unconditionally - (although this would be possible) since it generates warnings. */ --#if __GNUC_PREREQ (2,96) -+#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__) - # define __attribute_pure__ __attribute__ ((__pure__)) - #else - # define __attribute_pure__ /* Ignore */ - #endif ++int + main(c, v) + int c; + char *v[]; +@@ -881,6 +902,7 @@ + [AC_TRY_RUN([ + #include + #include ++#include - /* This declaration tells the compiler that the value is constant. */ --#if __GNUC_PREREQ (2,5) -+#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__) - # define __attribute_const__ __attribute__ ((__const__)) - #else - # define __attribute_const__ /* Ignore */ + int + main() +@@ -1241,6 +1263,8 @@ + #ifdef HAVE_UNISTD_H + # include #endif - -+#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__) -+# define __attribute_maybe_unused__ __attribute__ ((__unused__)) -+#else -+# define __attribute_maybe_unused__ /* Ignore */ -+#endif -+ - /* At some point during the gcc 3.1 development the `used' attribute - for functions was introduced. We don't want to use it unconditionally - (although this would be possible) since it generates warnings. */ --#if __GNUC_PREREQ (3,1) -+#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__) - # define __attribute_used__ __attribute__ ((__used__)) - # define __attribute_noinline__ __attribute__ ((__noinline__)) - #else -@@ -247,7 +337,7 @@ ++#include ++int + main() + { + # ifdef GETPGRP_VOID +@@ -1305,6 +1329,7 @@ + #ifdef HAVE_UNISTD_H + #include #endif ++#include - /* Since version 3.2, gcc allows marking deprecated functions. */ --#if __GNUC_PREREQ (3,2) -+#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__) - # define __attribute_deprecated__ __attribute__ ((__deprecated__)) - #else - # define __attribute_deprecated__ /* Ignore */ -@@ -256,8 +346,8 @@ - /* Since version 4.5, gcc also allows one to specify the message printed - when a deprecated function is used. clang claims to be gcc 4.2, but - may also support this feature. */ --#if __GNUC_PREREQ (4,5) || \ -- __glibc_clang_has_extension (__attribute_deprecated_with_message__) -+#if __GNUC_PREREQ (4,5) \ -+ || __glibc_has_extension (__attribute_deprecated_with_message__) - # define __attribute_deprecated_msg__(msg) \ - __attribute__ ((__deprecated__ (msg))) - #else -@@ -270,7 +360,7 @@ - If several `format_arg' attributes are given for the same function, in - gcc-3.0 and older, all but the last one are ignored. In newer gccs, - all designated arguments are considered. */ --#if __GNUC_PREREQ (2,8) -+#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__) - # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) - #else - # define __attribute_format_arg__(x) /* Ignore */ -@@ -280,7 +370,7 @@ - attribute for functions was introduced. We don't want to use it - unconditionally (although this would be possible) since it - generates warnings. */ --#if __GNUC_PREREQ (2,97) -+#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__) - # define __attribute_format_strfmon__(a,b) \ - __attribute__ ((__format__ (__strfmon__, a, b))) - #else -@@ -288,19 +378,33 @@ - #endif + typedef RETSIGTYPE sigfunc(); - /* The nonnull function attribute marks pointer parameters that -- must not be NULL. Do not define __nonnull if it is already defined, -- for portability when this file is used in Gnulib. */ -+ must not be NULL. This has the name __nonnull in glibc, -+ and __attribute_nonnull__ in files shared with Gnulib to avoid -+ collision with a different __nonnull in DragonFlyBSD 5.9. */ -+#ifndef __attribute_nonnull__ -+# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) -+# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) -+# else -+# define __attribute_nonnull__(params) -+# endif -+#endif - #ifndef __nonnull --# if __GNUC_PREREQ (3,3) --# define __nonnull(params) __attribute__ ((__nonnull__ params)) -+# define __nonnull(params) __attribute_nonnull__ (params) -+#endif -+ -+/* The returns_nonnull function attribute marks the return type of the function -+ as always being non-null. */ -+#ifndef __returns_nonnull -+# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__) -+# define __returns_nonnull __attribute__ ((__returns_nonnull__)) - # else --# define __nonnull(params) -+# define __returns_nonnull - # endif - #endif +@@ -1335,6 +1360,7 @@ + nsigint++; + } - /* If fortification mode, we warn about unused results of certain - function calls which can lead to problems. */ --#if __GNUC_PREREQ (3,4) -+#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__) - # define __attribute_warn_unused_result__ \ - __attribute__ ((__warn_unused_result__)) - # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 -@@ -314,7 +418,7 @@ ++int + main() + { + nsigint = 0; +@@ -1418,8 +1444,11 @@ + #ifdef HAVE_UNISTD_H + #include #endif ++#include ++#include - /* Forces a function to be always inlined. */ --#if __GNUC_PREREQ (3,2) -+#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__) - /* The Linux kernel defines __always_inline in stddef.h (283d7573), and - it conflicts with this definition. Therefore undefine it first to - allow either header to be included first. */ -@@ -327,7 +431,7 @@ + /* Add more tests in here as appropriate. */ ++int + main() + { + int fd, err; +@@ -1651,11 +1680,13 @@ + [AC_TRY_RUN([ + #include + #include ++#include - /* Associate error messages with the source location of the call site rather - than with the source location inside the function. */ --#if __GNUC_PREREQ (4,3) -+#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__) - # define __attribute_artificial__ __attribute__ ((__artificial__)) - #else - # define __attribute_artificial__ /* Ignore */ -@@ -370,12 +474,14 @@ - run in pedantic mode if the uses are carefully marked using the - `__extension__' keyword. But this is not generally available before - version 2.8. */ --#if !__GNUC_PREREQ (2,8) -+#if !(__GNUC_PREREQ (2,8) || defined __clang__) - # define __extension__ /* Ignore */ + #ifndef NSIG + # define NSIG 64 #endif --/* __restrict is known in EGCS 1.2 and above. */ --#if !__GNUC_PREREQ (2,92) -+/* __restrict is known in EGCS 1.2 and above, and in clang. -+ It works also in C++ mode (outside of arrays), but only when spelled -+ as '__restrict', not 'restrict'. */ -+#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3) - # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L - # define __restrict restrict - # else -@@ -385,8 +491,9 @@ ++int + main () + { + int n_sigs = 2 * NSIG; +@@ -1770,6 +1801,7 @@ + #include + #include - /* ISO C99 also allows to declare arrays as non-overlapping. The syntax is - array_name[restrict] -- GCC 3.1 supports this. */ --#if __GNUC_PREREQ (3,1) && !defined __GNUG__ -+ GCC 3.1 and clang support this. -+ This syntax is not usable in C++ mode. */ -+#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus - # define __restrict_arr __restrict - #else - # ifdef __GNUC__ -@@ -401,7 +508,7 @@ - # endif - #endif ++int + main(c, v) + int c; + char **v; +@@ -1834,9 +1866,11 @@ + [AC_TRY_RUN([ + #include + #include ++#include --#if __GNUC__ >= 3 -+#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect) - # define __glibc_unlikely(cond) __builtin_expect ((cond), 0) - # define __glibc_likely(cond) __builtin_expect ((cond), 1) - #else -@@ -409,15 +516,10 @@ - # define __glibc_likely(cond) (cond) - #endif + extern int rl_gnu_readline_p; --#ifdef __has_attribute --# define __glibc_has_attribute(attr) __has_attribute (attr) --#else --# define __glibc_has_attribute(attr) 0 --#endif -- - #if (!defined _Noreturn \ - && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ -- && !__GNUC_PREREQ (4,7)) -+ && !(__GNUC_PREREQ (4,7) \ -+ || (3 < __clang_major__ + (5 <= __clang_minor__)))) - # if __GNUC_PREREQ (2,8) - # define _Noreturn __attribute__ ((__noreturn__)) - # else -@@ -434,22 +536,63 @@ - # define __attribute_nonstring__ ++int + main() + { + FILE *fp; +@@ -1926,7 +1960,9 @@ #endif + #include + #include ++#include -+/* Undefine (also defined in libc-symbols.h). */ -+#undef __attribute_copy__ -+#if __GNUC_PREREQ (9, 0) -+/* Copies attributes from the declaration or type referenced by -+ the argument. */ -+# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg))) -+#else -+# define __attribute_copy__(arg) -+#endif -+ - #if (!defined _Static_assert && !defined __cplusplus \ - && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ -- && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__)) -+ && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \ -+ || defined __STRICT_ANSI__)) - # define _Static_assert(expr, diagnostic) \ - extern int (*__Static_assert_function (void)) \ - [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] - #endif ++int + main(c, v) + int c; + char *v[]; +@@ -2657,7 +2693,7 @@ + [ + # Guess based on the CPU. + case "$host_cpu" in +- alpha* | i[34567]86 | m68k | s390*) ++ w_64* | alpha* | i[34567]86 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; +@@ -4068,7 +4104,9 @@ + AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf], + [AC_TRY_RUN([ + #include ++#include --/* The #ifndef lets Gnulib avoid including these on non-glibc -- platforms, where the includes typically do not exist. */ --#ifndef __WORDSIZE -+/* Gnulib avoids including these, as they don't work on non-glibc or -+ older glibc platforms. */ -+#ifndef __GNULIB_CDEFS - # include - # include - #endif ++int + main() + { + int n; +@@ -4154,6 +4192,7 @@ --#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH -+#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 -+# ifdef __REDIRECT -+ -+/* Alias name defined automatically. */ -+# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir -+# define __LDBL_REDIR_DECL(name) \ -+ extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128")); -+ -+/* Alias name defined automatically, with leading underscores. */ -+# define __LDBL_REDIR2_DECL(name) \ -+ extern __typeof (__##name) __##name \ -+ __asm (__ASMNAME ("__" #name "ieee128")); + #include + ++int + main(c, v) + int c; + char **v; +diff -Nuar gdb-10.2/readline/readline/aclocal.m4.orig gdb-10.2/readline/readline/aclocal.m4.orig +--- gdb-10.2/readline/readline/aclocal.m4.orig 1970-01-01 08:00:00.000000000 +0800 ++++ gdb-10.2/readline/readline/aclocal.m4.orig 2025-04-16 17:06:41.942086800 +0800 +@@ -0,0 +1,4301 @@ ++nl ++dnl Bash specific tests ++dnl ++dnl Some derived from PDKSH 5.1.3 autoconf tests ++dnl + -+/* Alias name defined manually. */ -+# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1 -+# define __LDBL_REDIR1_DECL(name, alias) \ -+ extern __typeof (name) name __asm (__ASMNAME (#alias)); ++AC_DEFUN(BASH_C_LONG_LONG, ++[AC_CACHE_CHECK(for long long, ac_cv_c_long_long, ++[if test "$GCC" = yes; then ++ ac_cv_c_long_long=yes ++else ++AC_TRY_RUN([ ++#include ++int ++main() ++{ ++long long foo = 0; ++exit(sizeof(long long) < sizeof(long)); ++} ++], ac_cv_c_long_long=yes, ac_cv_c_long_long=no) ++fi]) ++if test $ac_cv_c_long_long = yes; then ++ AC_DEFINE(HAVE_LONG_LONG, 1, [Define if the `long long' type works.]) ++fi ++]) + -+# define __LDBL_REDIR1_NTH(name, proto, alias) \ -+ __REDIRECT_NTH (name, proto, alias) -+# define __REDIRECT_NTH_LDBL(name, proto, alias) \ -+ __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128) ++dnl ++dnl This is very similar to AC_C_LONG_DOUBLE, with the fix for IRIX ++dnl (< changed to <=) added. ++dnl ++AC_DEFUN(BASH_C_LONG_DOUBLE, ++[AC_CACHE_CHECK(for long double, ac_cv_c_long_double, ++[if test "$GCC" = yes; then ++ ac_cv_c_long_double=yes ++else ++AC_TRY_RUN([ ++#include ++int ++main() ++{ ++ /* The Stardent Vistra knows sizeof(long double), but does not ++ support it. */ ++ long double foo = 0.0; ++ /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ ++ /* On IRIX 5.3, the compiler converts long double to double with a warning, ++ but compiles this successfully. */ ++ exit(sizeof(long double) <= sizeof(double)); ++} ++], ac_cv_c_long_double=yes, ac_cv_c_long_double=no) ++fi]) ++if test $ac_cv_c_long_double = yes; then ++ AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if the `long double' type works.]) ++fi ++]) + -+/* Unused. */ -+# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl -+# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth ++dnl ++dnl Check for . This is separated out so that it can be ++dnl AC_REQUIREd. ++dnl ++dnl BASH_HEADER_INTTYPES ++AC_DEFUN(BASH_HEADER_INTTYPES, ++[ ++ AC_CHECK_HEADERS(inttypes.h) ++]) + -+# else -+_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform"); -+# endif -+#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH - # define __LDBL_COMPAT 1 - # ifdef __REDIRECT - # define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias) -@@ -458,6 +601,8 @@ - # define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias) - # define __LDBL_REDIR_NTH(name, proto) \ - __LDBL_REDIR1_NTH (name, proto, __nldbl_##name) -+# define __LDBL_REDIR2_DECL(name) \ -+ extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name)); - # define __LDBL_REDIR1_DECL(name, alias) \ - extern __typeof (name) name __asm (__ASMNAME (#alias)); - # define __LDBL_REDIR_DECL(name) \ -@@ -468,11 +613,13 @@ - __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) - # endif - #endif --#if !defined __LDBL_COMPAT || !defined __REDIRECT -+#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \ -+ || !defined __REDIRECT - # define __LDBL_REDIR1(name, proto, alias) name proto - # define __LDBL_REDIR(name, proto) name proto - # define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW - # define __LDBL_REDIR_NTH(name, proto) name proto __THROW -+# define __LDBL_REDIR2_DECL(name) - # define __LDBL_REDIR_DECL(name) - # ifdef __REDIRECT - # define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias) -@@ -503,7 +650,7 @@ - check is required to enable the use of generic selection. */ - #if !defined __cplusplus \ - && (__GNUC_PREREQ (4, 9) \ -- || __glibc_clang_has_extension (c_generic_selections) \ -+ || __glibc_has_extension (c_generic_selections) \ - || (!defined __GNUC__ && defined __STDC_VERSION__ \ - && __STDC_VERSION__ >= 201112L)) - # define __HAVE_GENERIC_SELECTION 1 -@@ -511,4 +658,50 @@ - # define __HAVE_GENERIC_SELECTION 0 - #endif - -+#if __GNUC_PREREQ (10, 0) -+/* Designates a 1-based positional argument ref-index of pointer type -+ that can be used to access size-index elements of the pointed-to -+ array according to access mode, or at least one element when -+ size-index is not provided: -+ access (access-mode, [, ]) */ -+# define __attr_access(x) __attribute__ ((__access__ x)) -+/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may -+ use the access attribute to get object sizes from function definition -+ arguments, so we can't use them on functions we fortify. Drop the object -+ size hints for such functions. */ -+# if __USE_FORTIFY_LEVEL == 3 -+# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) -+# else -+# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) -+# endif -+# if __GNUC_PREREQ (11, 0) -+# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno))) -+# else -+# define __attr_access_none(argno) -+# endif -+#else -+# define __fortified_attr_access(a, o, s) -+# define __attr_access(x) -+# define __attr_access_none(argno) ++dnl ++dnl check for typedef'd symbols in header files, but allow the caller to ++dnl specify the include files to be checked in addition to the default ++dnl ++dnl BASH_CHECK_TYPE(TYPE, HEADERS, DEFAULT[, VALUE-IF-FOUND]) ++AC_DEFUN(BASH_CHECK_TYPE, ++[ ++AC_REQUIRE([AC_HEADER_STDC])dnl ++AC_REQUIRE([BASH_HEADER_INTTYPES]) ++AC_MSG_CHECKING(for $1) ++AC_CACHE_VAL(bash_cv_type_$1, ++[AC_EGREP_CPP($1, [#include ++#if STDC_HEADERS ++#include ++#include ++#endif ++#if HAVE_INTTYPES_H ++#include +#endif ++#if HAVE_STDINT_H ++#include ++#endif ++$2 ++], bash_cv_type_$1=yes, bash_cv_type_$1=no)]) ++AC_MSG_RESULT($bash_cv_type_$1) ++ifelse($#, 4, [if test $bash_cv_type_$1 = yes; then ++ AC_DEFINE($4) ++ fi]) ++if test $bash_cv_type_$1 = no; then ++ AC_DEFINE_UNQUOTED($1, $3) ++fi ++]) + -+#if __GNUC_PREREQ (11, 0) -+/* Designates dealloc as a function to call to deallocate objects -+ allocated by the declared function. */ -+# define __attr_dealloc(dealloc, argno) \ -+ __attribute__ ((__malloc__ (dealloc, argno))) -+# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1) -+#else -+# define __attr_dealloc(dealloc, argno) -+# define __attr_dealloc_free ++dnl ++dnl BASH_CHECK_DECL(FUNC) ++dnl ++dnl Check for a declaration of FUNC in stdlib.h and inttypes.h like ++dnl AC_CHECK_DECL ++dnl ++AC_DEFUN(BASH_CHECK_DECL, ++[ ++AC_REQUIRE([AC_HEADER_STDC]) ++AC_REQUIRE([BASH_HEADER_INTTYPES]) ++AC_CACHE_CHECK([for declaration of $1], bash_cv_decl_$1, ++[AC_TRY_LINK( ++[ ++#if STDC_HEADERS ++# include +#endif ++#if HAVE_INTTYPES_H ++# include ++#endif ++], ++[return !$1;], ++bash_cv_decl_$1=yes, bash_cv_decl_$1=no)]) ++bash_tr_func=HAVE_DECL_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` ++if test $bash_cv_decl_$1 = yes; then ++ AC_DEFINE_UNQUOTED($bash_tr_func, 1) ++else ++ AC_DEFINE_UNQUOTED($bash_tr_func, 0) ++fi ++]) + -+/* Specify that a function such as setjmp or vfork may return -+ twice. */ -+#if __GNUC_PREREQ (4, 1) -+# define __attribute_returns_twice__ __attribute__ ((__returns_twice__)) ++AC_DEFUN(BASH_DECL_PRINTF, ++[AC_MSG_CHECKING(for declaration of printf in ) ++AC_CACHE_VAL(bash_cv_printf_declared, ++[AC_TRY_RUN([ ++#include ++#ifdef __STDC__ ++typedef int (*_bashfunc)(const char *, ...); +#else -+# define __attribute_returns_twice__ /* Ignore. */ ++typedef int (*_bashfunc)(); +#endif -+ - #endif /* sys/cdefs.h */ ---- gdb-10.2/gnulib/import/libc-config.h.orig -+++ gdb-10.2/gnulib/import/libc-config.h -@@ -79,13 +79,9 @@ - #ifndef _FEATURES_H - # define _FEATURES_H 1 - #endif --/* Define __WORDSIZE so that does not attempt to include -- nonexistent files. Make it a syntax error, since Gnulib does not -- use __WORDSIZE now, and if Gnulib uses it later the syntax error -- will let us know that __WORDSIZE needs configuring. */ --#ifndef __WORDSIZE --# define __WORDSIZE %%% --#endif -+/* Define __GNULIB_CDEFS so that does not attempt to include -+ nonexistent files. */ -+# define __GNULIB_CDEFS - /* Undef the macros unconditionally defined by our copy of glibc - , so that they do not clash with any system-defined - versions. */ ---- gdb-10.2/libiberty/aclocal.m4.orig -+++ gdb-10.2/libiberty/aclocal.m4 -@@ -16,6 +16,8 @@ AC_CACHE_CHECK([for working strncmp], ac - [AC_TRY_RUN([ - /* Test by Jim Wilson and Kaveh Ghazi. - Check whether strncmp reads past the end of its string parameters. */ +#include -+#include - #include - - #ifdef HAVE_FCNTL_H -@@ -43,7 +45,8 @@ AC_CACHE_CHECK([for working strncmp], ac - - #define MAP_LEN 0x10000 - --main () +int -+main (void) - { - #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) - char *p; -@@ -149,7 +152,10 @@ if test $ac_cv_os_cray = yes; then - fi - - AC_CACHE_CHECK(stack direction for C alloca, ac_cv_c_stack_direction, --[AC_TRY_RUN([find_stack_direction () -+[AC_TRY_RUN([#include ++main() ++{ ++_bashfunc pf; ++pf = (_bashfunc) printf; ++exit(pf == 0); ++} ++], bash_cv_printf_declared=yes, bash_cv_printf_declared=no, ++ [AC_MSG_WARN(cannot check printf declaration if cross compiling -- defaulting to yes) ++ bash_cv_printf_declared=yes] ++)]) ++AC_MSG_RESULT($bash_cv_printf_declared) ++if test $bash_cv_printf_declared = yes; then ++AC_DEFINE(PRINTF_DECLARED) ++fi ++]) ++ ++AC_DEFUN(BASH_DECL_SBRK, ++[AC_MSG_CHECKING(for declaration of sbrk in ) ++AC_CACHE_VAL(bash_cv_sbrk_declared, ++[AC_EGREP_HEADER(sbrk, unistd.h, ++ bash_cv_sbrk_declared=yes, bash_cv_sbrk_declared=no)]) ++AC_MSG_RESULT($bash_cv_sbrk_declared) ++if test $bash_cv_sbrk_declared = yes; then ++AC_DEFINE(SBRK_DECLARED) ++fi ++]) ++ ++dnl ++dnl Check for sys_siglist[] or _sys_siglist[] ++dnl ++AC_DEFUN(BASH_DECL_UNDER_SYS_SIGLIST, ++[AC_MSG_CHECKING([for _sys_siglist in signal.h or unistd.h]) ++AC_CACHE_VAL(bash_cv_decl_under_sys_siglist, ++[AC_TRY_COMPILE([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif], [ char *msg = _sys_siglist[2]; ], ++ bash_cv_decl_under_sys_siglist=yes, bash_cv_decl_under_sys_siglist=no, ++ [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no)])])dnl ++AC_MSG_RESULT($bash_cv_decl_under_sys_siglist) ++if test $bash_cv_decl_under_sys_siglist = yes; then ++AC_DEFINE(UNDER_SYS_SIGLIST_DECLARED) ++fi ++]) + ++AC_DEFUN(BASH_UNDER_SYS_SIGLIST, ++[AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST]) ++AC_MSG_CHECKING([for _sys_siglist in system C library]) ++AC_CACHE_VAL(bash_cv_under_sys_siglist, ++[AC_TRY_RUN([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++#ifndef UNDER_SYS_SIGLIST_DECLARED ++extern char *_sys_siglist[]; ++#endif +int -+find_stack_direction (void) - { - static char *addr = 0; - auto char dummy; -@@ -161,7 +167,9 @@ AC_CACHE_CHECK(stack direction for C all - else - return (&dummy > addr) ? 1 : -1; - } --main () ++main() ++{ ++char *msg = (char *)_sys_siglist[2]; ++exit(msg == 0); ++}], ++ bash_cv_under_sys_siglist=yes, bash_cv_under_sys_siglist=no, ++ [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no) ++ bash_cv_under_sys_siglist=no])]) ++AC_MSG_RESULT($bash_cv_under_sys_siglist) ++if test $bash_cv_under_sys_siglist = yes; then ++AC_DEFINE(HAVE_UNDER_SYS_SIGLIST) ++fi ++]) + ++AC_DEFUN(BASH_SYS_SIGLIST, ++[AC_REQUIRE([AC_DECL_SYS_SIGLIST]) ++AC_MSG_CHECKING([for sys_siglist in system C library]) ++AC_CACHE_VAL(bash_cv_sys_siglist, ++[AC_TRY_RUN([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++#if !HAVE_DECL_SYS_SIGLIST ++extern char *sys_siglist[]; ++#endif +int -+main (void) - { - exit (find_stack_direction() < 0); - }], ---- gdb-10.2/libiberty/configure.orig -+++ gdb-10.2/libiberty/configure -@@ -6724,7 +6724,10 @@ else - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ --find_stack_direction () ++main() ++{ ++char *msg = sys_siglist[2]; ++exit(msg == 0); ++}], ++ bash_cv_sys_siglist=yes, bash_cv_sys_siglist=no, ++ [AC_MSG_WARN(cannot check for sys_siglist if cross compiling -- defaulting to no) ++ bash_cv_sys_siglist=no])]) ++AC_MSG_RESULT($bash_cv_sys_siglist) ++if test $bash_cv_sys_siglist = yes; then ++AC_DEFINE(HAVE_SYS_SIGLIST) ++fi ++]) ++ ++dnl Check for the various permutations of sys_siglist and make sure we ++dnl compile in siglist.o if they're not defined ++AC_DEFUN(BASH_CHECK_SYS_SIGLIST, [ ++AC_REQUIRE([BASH_SYS_SIGLIST]) ++AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST]) ++AC_REQUIRE([BASH_FUNC_STRSIGNAL]) ++if test "$bash_cv_sys_siglist" = no && test "$bash_cv_under_sys_siglist" = no && test "$bash_cv_have_strsignal" = no; then ++ SIGLIST_O=siglist.o ++else ++ SIGLIST_O= ++fi ++AC_SUBST([SIGLIST_O]) ++]) ++ ++dnl Check for sys_errlist[] and sys_nerr, check for declaration ++AC_DEFUN(BASH_SYS_ERRLIST, ++[AC_MSG_CHECKING([for sys_errlist and sys_nerr]) ++AC_CACHE_VAL(bash_cv_sys_errlist, ++[AC_TRY_LINK([#include ], ++[extern char *sys_errlist[]; ++ extern int sys_nerr; ++ char *msg = sys_errlist[sys_nerr - 1];], ++ bash_cv_sys_errlist=yes, bash_cv_sys_errlist=no)])dnl ++AC_MSG_RESULT($bash_cv_sys_errlist) ++if test $bash_cv_sys_errlist = yes; then ++AC_DEFINE(HAVE_SYS_ERRLIST) ++fi ++]) ++ ++dnl ++dnl Check if dup2() does not clear the close on exec flag ++dnl ++AC_DEFUN(BASH_FUNC_DUP2_CLOEXEC_CHECK, ++[AC_MSG_CHECKING(if dup2 fails to clear the close-on-exec flag) ++AC_CACHE_VAL(bash_cv_dup2_broken, ++[AC_TRY_RUN([ ++#include ++#include +#include ++int ++main() ++{ ++ int fd1, fd2, fl; ++ fd1 = open("/dev/null", 2); ++ if (fcntl(fd1, 2, 1) < 0) ++ exit(1); ++ fd2 = dup2(fd1, 1); ++ if (fd2 < 0) ++ exit(2); ++ fl = fcntl(fd2, 1, 0); ++ /* fl will be 1 if dup2 did not reset the close-on-exec flag. */ ++ exit(fl != 1); ++} ++], bash_cv_dup2_broken=yes, bash_cv_dup2_broken=no, ++ [AC_MSG_WARN(cannot check dup2 if cross compiling -- defaulting to no) ++ bash_cv_dup2_broken=no]) ++]) ++AC_MSG_RESULT($bash_cv_dup2_broken) ++if test $bash_cv_dup2_broken = yes; then ++AC_DEFINE(DUP2_BROKEN) ++fi ++]) + ++AC_DEFUN(BASH_FUNC_STRSIGNAL, ++[AC_MSG_CHECKING([for the existence of strsignal]) ++AC_CACHE_VAL(bash_cv_have_strsignal, ++[AC_TRY_LINK([#include ++#include ], ++[char *s = (char *)strsignal(2);], ++ bash_cv_have_strsignal=yes, bash_cv_have_strsignal=no)]) ++AC_MSG_RESULT($bash_cv_have_strsignal) ++if test $bash_cv_have_strsignal = yes; then ++AC_DEFINE(HAVE_STRSIGNAL) ++fi ++]) ++ ++dnl Check to see if opendir will open non-directories (not a nice thing) ++AC_DEFUN(BASH_FUNC_OPENDIR_CHECK, ++[AC_REQUIRE([AC_HEADER_DIRENT])dnl ++AC_MSG_CHECKING(if opendir() opens non-directories) ++AC_CACHE_VAL(bash_cv_opendir_not_robust, ++[AC_TRY_RUN([ ++#include ++#include ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++#if defined(HAVE_DIRENT_H) ++# include ++#else ++# define dirent direct ++# ifdef HAVE_SYS_NDIR_H ++# include ++# endif /* SYSNDIR */ ++# ifdef HAVE_SYS_DIR_H ++# include ++# endif /* SYSDIR */ ++# ifdef HAVE_NDIR_H ++# include ++# endif ++#endif /* HAVE_DIRENT_H */ ++#include +int -+find_stack_direction (void) - { - static char *addr = 0; - auto char dummy; -@@ -6736,7 +6739,9 @@ find_stack_direction () - else - return (&dummy > addr) ? 1 : -1; - } --main () ++main() ++{ ++DIR *dir; ++int fd, err; ++err = mkdir("bash-aclocal", 0700); ++if (err < 0) { ++ perror("mkdir"); ++ exit(1); ++} ++unlink("bash-aclocal/not_a_directory"); ++fd = open("bash-aclocal/not_a_directory", O_WRONLY|O_CREAT|O_EXCL, 0666); ++write(fd, "\n", 1); ++close(fd); ++dir = opendir("bash-aclocal/not_a_directory"); ++unlink("bash-aclocal/not_a_directory"); ++rmdir("bash-aclocal"); ++exit (dir == 0); ++}], bash_cv_opendir_not_robust=yes,bash_cv_opendir_not_robust=no, ++ [AC_MSG_WARN(cannot check opendir if cross compiling -- defaulting to no) ++ bash_cv_opendir_not_robust=no] ++)]) ++AC_MSG_RESULT($bash_cv_opendir_not_robust) ++if test $bash_cv_opendir_not_robust = yes; then ++AC_DEFINE(OPENDIR_NOT_ROBUST) ++fi ++]) ++ ++dnl ++AC_DEFUN(BASH_TYPE_SIGHANDLER, ++[AC_MSG_CHECKING([whether signal handlers are of type void]) ++AC_CACHE_VAL(bash_cv_void_sighandler, ++[AC_TRY_COMPILE([#include ++#include ++#ifdef signal ++#undef signal ++#endif ++#ifdef __cplusplus ++extern "C" ++#endif ++void (*signal ()) ();], ++[int i;], bash_cv_void_sighandler=yes, bash_cv_void_sighandler=no)])dnl ++AC_MSG_RESULT($bash_cv_void_sighandler) ++if test $bash_cv_void_sighandler = yes; then ++AC_DEFINE(VOID_SIGHANDLER) ++fi ++]) ++ ++dnl ++dnl A signed 16-bit integer quantity ++dnl ++AC_DEFUN(BASH_TYPE_BITS16_T, ++[ ++if test "$ac_cv_sizeof_short" = 2; then ++ AC_CHECK_TYPE(bits16_t, short) ++elif test "$ac_cv_sizeof_char" = 2; then ++ AC_CHECK_TYPE(bits16_t, char) ++else ++ AC_CHECK_TYPE(bits16_t, short) ++fi ++]) ++ ++dnl ++dnl An unsigned 16-bit integer quantity ++dnl ++AC_DEFUN(BASH_TYPE_U_BITS16_T, ++[ ++if test "$ac_cv_sizeof_short" = 2; then ++ AC_CHECK_TYPE(u_bits16_t, unsigned short) ++elif test "$ac_cv_sizeof_char" = 2; then ++ AC_CHECK_TYPE(u_bits16_t, unsigned char) ++else ++ AC_CHECK_TYPE(u_bits16_t, unsigned short) ++fi ++]) ++ ++dnl ++dnl A signed 32-bit integer quantity ++dnl ++AC_DEFUN(BASH_TYPE_BITS32_T, ++[ ++if test "$ac_cv_sizeof_int" = 4; then ++ AC_CHECK_TYPE(bits32_t, int) ++elif test "$ac_cv_sizeof_long" = 4; then ++ AC_CHECK_TYPE(bits32_t, long) ++else ++ AC_CHECK_TYPE(bits32_t, int) ++fi ++]) ++ ++dnl ++dnl An unsigned 32-bit integer quantity ++dnl ++AC_DEFUN(BASH_TYPE_U_BITS32_T, ++[ ++if test "$ac_cv_sizeof_int" = 4; then ++ AC_CHECK_TYPE(u_bits32_t, unsigned int) ++elif test "$ac_cv_sizeof_long" = 4; then ++ AC_CHECK_TYPE(u_bits32_t, unsigned long) ++else ++ AC_CHECK_TYPE(u_bits32_t, unsigned int) ++fi ++]) + ++AC_DEFUN(BASH_TYPE_PTRDIFF_T, ++[ ++if test "$ac_cv_sizeof_int" = "$ac_cv_sizeof_char_p"; then ++ AC_CHECK_TYPE(ptrdiff_t, int) ++elif test "$ac_cv_sizeof_long" = "$ac_cv_sizeof_char_p"; then ++ AC_CHECK_TYPE(ptrdiff_t, long) ++elif test "$ac_cv_type_long_long" = yes && test "$ac_cv_sizeof_long_long" = "$ac_cv_sizeof_char_p"; then ++ AC_CHECK_TYPE(ptrdiff_t, [long long]) ++else ++ AC_CHECK_TYPE(ptrdiff_t, int) ++fi ++]) ++ ++dnl ++dnl A signed 64-bit quantity ++dnl ++AC_DEFUN(BASH_TYPE_BITS64_T, ++[ ++if test "$ac_cv_sizeof_char_p" = 8; then ++ AC_CHECK_TYPE(bits64_t, char *) ++elif test "$ac_cv_sizeof_double" = 8; then ++ AC_CHECK_TYPE(bits64_t, double) ++elif test -n "$ac_cv_type_long_long" && test "$ac_cv_sizeof_long_long" = 8; then ++ AC_CHECK_TYPE(bits64_t, [long long]) ++elif test "$ac_cv_sizeof_long" = 8; then ++ AC_CHECK_TYPE(bits64_t, long) ++else ++ AC_CHECK_TYPE(bits64_t, double) ++fi ++]) ++ ++AC_DEFUN(BASH_TYPE_LONG_LONG, ++[ ++AC_CACHE_CHECK([for long long], bash_cv_type_long_long, ++[AC_TRY_LINK([ ++long long ll = 1; int i = 63;], ++[ ++long long llm = (long long) -1; ++return ll << i | ll >> i | llm / ll | llm % ll; ++], bash_cv_type_long_long='long long', bash_cv_type_long_long='long')]) ++if test "$bash_cv_type_long_long" = 'long long'; then ++ AC_DEFINE(HAVE_LONG_LONG, 1) ++fi ++]) ++ ++AC_DEFUN(BASH_TYPE_UNSIGNED_LONG_LONG, ++[ ++AC_CACHE_CHECK([for unsigned long long], bash_cv_type_unsigned_long_long, ++[AC_TRY_LINK([ ++unsigned long long ull = 1; int i = 63;], ++[ ++unsigned long long ullmax = (unsigned long long) -1; ++return ull << i | ull >> i | ullmax / ull | ullmax % ull; ++], bash_cv_type_unsigned_long_long='unsigned long long', ++ bash_cv_type_unsigned_long_long='unsigned long')]) ++if test "$bash_cv_type_unsigned_long_long" = 'unsigned long long'; then ++ AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1) ++fi ++]) ++ ++dnl ++dnl Type of struct rlimit fields: some systems (OSF/1, NetBSD, RISC/os 5.0) ++dnl have a rlim_t, others (4.4BSD based systems) use quad_t, others use ++dnl long and still others use int (HP-UX 9.01, SunOS 4.1.3). To simplify ++dnl matters, this just checks for rlim_t, quad_t, or long. ++dnl ++AC_DEFUN(BASH_TYPE_RLIMIT, ++[AC_MSG_CHECKING(for size and type of struct rlimit fields) ++AC_CACHE_VAL(bash_cv_type_rlimit, ++[AC_TRY_COMPILE([#include ++#include ], ++[rlim_t xxx;], bash_cv_type_rlimit=rlim_t,[ ++AC_TRY_RUN([ ++#include ++#include ++#include ++#include +int -+main (void) - { - exit (find_stack_direction() < 0); - } -@@ -7557,6 +7562,8 @@ else - - /* Test by Jim Wilson and Kaveh Ghazi. - Check whether strncmp reads past the end of its string parameters. */ ++main() ++{ ++#ifdef HAVE_QUAD_T ++ struct rlimit rl; ++ if (sizeof(rl.rlim_cur) == sizeof(quad_t)) ++ exit(0); ++#endif ++ exit(1); ++}], bash_cv_type_rlimit=quad_t, bash_cv_type_rlimit=long, ++ [AC_MSG_WARN(cannot check quad_t if cross compiling -- defaulting to long) ++ bash_cv_type_rlimit=long])]) ++]) ++AC_MSG_RESULT($bash_cv_type_rlimit) ++if test $bash_cv_type_rlimit = quad_t; then ++AC_DEFINE(RLIMTYPE, quad_t) ++elif test $bash_cv_type_rlimit = rlim_t; then ++AC_DEFINE(RLIMTYPE, rlim_t) ++fi ++]) ++ ++AC_DEFUN(BASH_TYPE_SIG_ATOMIC_T, ++[AC_CACHE_CHECK([for sig_atomic_t in signal.h], ac_cv_have_sig_atomic_t, ++[AC_TRY_LINK([ ++#include ++],[ sig_atomic_t x; ], ++ac_cv_have_sig_atomic_t=yes, ac_cv_have_sig_atomic_t=no)]) ++if test "$ac_cv_have_sig_atomic_t" = "no" ++then ++ AC_CHECK_TYPE(sig_atomic_t,int) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_LSTAT, ++[dnl Cannot use AC_CHECK_FUNCS(lstat) because Linux defines lstat() as an ++dnl inline function in . ++AC_CACHE_CHECK([for lstat], bash_cv_func_lstat, ++[AC_TRY_LINK([ ++#include ++#include ++],[ lstat(".",(struct stat *)0); ], ++bash_cv_func_lstat=yes, bash_cv_func_lstat=no)]) ++if test $bash_cv_func_lstat = yes; then ++ AC_DEFINE(HAVE_LSTAT) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_INET_ATON, ++[ ++AC_CACHE_CHECK([for inet_aton], bash_cv_func_inet_aton, ++[AC_TRY_LINK([ ++#include ++#include ++#include ++struct in_addr ap;], [ inet_aton("127.0.0.1", &ap); ], ++bash_cv_func_inet_aton=yes, bash_cv_func_inet_aton=no)]) ++if test $bash_cv_func_inet_aton = yes; then ++ AC_DEFINE(HAVE_INET_ATON) ++else ++ AC_LIBOBJ(inet_aton) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_GETENV, ++[AC_MSG_CHECKING(to see if getenv can be redefined) ++AC_CACHE_VAL(bash_cv_getenv_redef, ++[AC_TRY_RUN([ ++#ifdef HAVE_UNISTD_H ++# include ++#endif +#include -+#include - #include - - #ifdef HAVE_FCNTL_H -@@ -7584,7 +7591,8 @@ else - - #define MAP_LEN 0x10000 - --main () ++#ifndef __STDC__ ++# ifndef const ++# define const ++# endif ++#endif ++char * ++getenv (name) ++#if defined (__linux__) || defined (__bsdi__) || defined (convex) ++ const char *name; ++#else ++ char const *name; ++#endif /* !__linux__ && !__bsdi__ && !convex */ ++{ ++return "42"; ++} +int -+main (void) - { - #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) - char *p; ---- gdb-10.2/readline/readline/aclocal.m4.orig -+++ gdb-10.2/readline/readline/aclocal.m4 -@@ -10,6 +10,7 @@ AC_DEFUN(BASH_C_LONG_LONG, - ac_cv_c_long_long=yes - else - AC_TRY_RUN([ ++main() ++{ ++char *s; ++/* The next allows this program to run, but does not allow bash to link ++ when it redefines getenv. I'm not really interested in figuring out ++ why not. */ ++#if defined (NeXT) ++exit(1); ++#endif ++s = getenv("ABCDE"); ++exit(s == 0); /* force optimizer to leave getenv in */ ++} ++], bash_cv_getenv_redef=yes, bash_cv_getenv_redef=no, ++ [AC_MSG_WARN(cannot check getenv redefinition if cross compiling -- defaulting to yes) ++ bash_cv_getenv_redef=yes] ++)]) ++AC_MSG_RESULT($bash_cv_getenv_redef) ++if test $bash_cv_getenv_redef = yes; then ++AC_DEFINE(CAN_REDEFINE_GETENV) ++fi ++]) ++ ++# We should check for putenv before calling this ++AC_DEFUN(BASH_FUNC_STD_PUTENV, ++[ ++AC_REQUIRE([AC_HEADER_STDC]) ++AC_REQUIRE([AC_C_PROTOTYPES]) ++AC_CACHE_CHECK([for standard-conformant putenv declaration], bash_cv_std_putenv, ++[AC_TRY_LINK([ ++#if STDC_HEADERS +#include - int - main() - { -@@ -33,6 +34,7 @@ AC_DEFUN(BASH_C_LONG_DOUBLE, - ac_cv_c_long_double=yes - else - AC_TRY_RUN([ ++#include ++#endif ++#ifndef __STDC__ ++# ifndef const ++# define const ++# endif ++#endif ++#ifdef PROTOTYPES ++extern int putenv (char *); ++#else ++extern int putenv (); ++#endif ++], ++[return (putenv == 0);], ++bash_cv_std_putenv=yes, bash_cv_std_putenv=no ++)]) ++if test $bash_cv_std_putenv = yes; then ++AC_DEFINE(HAVE_STD_PUTENV) ++fi ++]) ++ ++# We should check for unsetenv before calling this ++AC_DEFUN(BASH_FUNC_STD_UNSETENV, ++[ ++AC_REQUIRE([AC_HEADER_STDC]) ++AC_REQUIRE([AC_C_PROTOTYPES]) ++AC_CACHE_CHECK([for standard-conformant unsetenv declaration], bash_cv_std_unsetenv, ++[AC_TRY_LINK([ ++#if STDC_HEADERS +#include - int - main() - { -@@ -134,6 +136,8 @@ typedef int (*_bashfunc)(const char *, . - #else - typedef int (*_bashfunc)(); - #endif ++#include ++#endif ++#ifndef __STDC__ ++# ifndef const ++# define const ++# endif ++#endif ++#ifdef PROTOTYPES ++extern int unsetenv (const char *); ++#else ++extern int unsetenv (); ++#endif ++], ++[return (unsetenv == 0);], ++bash_cv_std_unsetenv=yes, bash_cv_std_unsetenv=no ++)]) ++if test $bash_cv_std_unsetenv = yes; then ++AC_DEFINE(HAVE_STD_UNSETENV) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_ULIMIT_MAXFDS, ++[AC_MSG_CHECKING(whether ulimit can substitute for getdtablesize) ++AC_CACHE_VAL(bash_cv_ulimit_maxfds, ++[AC_TRY_RUN([ ++main() ++{ ++long maxfds = ulimit(4, 0L); ++exit (maxfds == -1L); ++} ++], bash_cv_ulimit_maxfds=yes, bash_cv_ulimit_maxfds=no, ++ [AC_MSG_WARN(cannot check ulimit if cross compiling -- defaulting to no) ++ bash_cv_ulimit_maxfds=no] ++)]) ++AC_MSG_RESULT($bash_cv_ulimit_maxfds) ++if test $bash_cv_ulimit_maxfds = yes; then ++AC_DEFINE(ULIMIT_MAXFDS) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_GETCWD, ++[AC_MSG_CHECKING([if getcwd() will dynamically allocate memory with 0 size]) ++AC_CACHE_VAL(bash_cv_getcwd_malloc, ++[AC_TRY_RUN([ ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++ ++main() ++{ ++ char *xpwd; ++ xpwd = getcwd(0, 0); ++ exit (xpwd == 0); ++} ++], bash_cv_getcwd_malloc=yes, bash_cv_getcwd_malloc=no, ++ [AC_MSG_WARN(cannot check whether getcwd allocates memory when cross-compiling -- defaulting to no) ++ bash_cv_getcwd_malloc=no] ++)]) ++AC_MSG_RESULT($bash_cv_getcwd_malloc) ++if test $bash_cv_getcwd_malloc = no; then ++AC_DEFINE(GETCWD_BROKEN) ++AC_LIBOBJ(getcwd) ++fi ++]) ++ ++dnl ++dnl This needs BASH_CHECK_SOCKLIB, but since that's not called on every ++dnl system, we can't use AC_PREREQ ++dnl ++AC_DEFUN(BASH_FUNC_GETHOSTBYNAME, ++[if test "X$bash_cv_have_gethostbyname" = "X"; then ++_bash_needmsg=yes ++else ++AC_MSG_CHECKING(for gethostbyname in socket library) ++_bash_needmsg= ++fi ++AC_CACHE_VAL(bash_cv_have_gethostbyname, ++[AC_TRY_LINK([#include ], ++[ struct hostent *hp; ++ hp = gethostbyname("localhost"); ++], bash_cv_have_gethostbyname=yes, bash_cv_have_gethostbyname=no)] ++) ++if test "X$_bash_needmsg" = Xyes; then ++ AC_MSG_CHECKING(for gethostbyname in socket library) ++fi ++AC_MSG_RESULT($bash_cv_have_gethostbyname) ++if test "$bash_cv_have_gethostbyname" = yes; then ++AC_DEFINE(HAVE_GETHOSTBYNAME) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_FNMATCH_EXTMATCH, ++[AC_MSG_CHECKING(if fnmatch does extended pattern matching with FNM_EXTMATCH) ++AC_CACHE_VAL(bash_cv_fnm_extmatch, ++[AC_TRY_RUN([ ++#include ++ ++main() ++{ ++#ifdef FNM_EXTMATCH ++ exit (0); ++#else ++ exit (1); ++#endif ++} ++], bash_cv_fnm_extmatch=yes, bash_cv_fnm_extmatch=no, ++ [AC_MSG_WARN(cannot check FNM_EXTMATCH if cross compiling -- defaulting to no) ++ bash_cv_fnm_extmatch=no]) ++]) ++AC_MSG_RESULT($bash_cv_fnm_extmatch) ++if test $bash_cv_fnm_extmatch = yes; then ++AC_DEFINE(HAVE_LIBC_FNM_EXTMATCH) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_POSIX_SETJMP, ++[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) ++AC_MSG_CHECKING(for presence of POSIX-style sigsetjmp/siglongjmp) ++AC_CACHE_VAL(bash_cv_func_sigsetjmp, ++[AC_TRY_RUN([ ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++#include ++#include +#include ++ +int - main() - { - _bashfunc pf; -@@ -191,9 +195,11 @@ AC_CACHE_VAL(bash_cv_under_sys_siglist, - #ifdef HAVE_UNISTD_H - #include - #endif ++main() ++{ ++#if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) ++exit (1); ++#else ++ ++int code; ++sigset_t set, oset; ++sigjmp_buf xx; ++ ++/* get the mask */ ++sigemptyset(&set); ++sigemptyset(&oset); ++sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set); ++sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); ++ ++/* save it */ ++code = sigsetjmp(xx, 1); ++if (code) ++ exit(0); /* could get sigmask and compare to oset here. */ ++ ++/* change it */ ++sigaddset(&set, SIGINT); ++sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); ++ ++/* and siglongjmp */ ++siglongjmp(xx, 10); ++exit(1); ++#endif ++}], bash_cv_func_sigsetjmp=present, bash_cv_func_sigsetjmp=missing, ++ [AC_MSG_WARN(cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing) ++ bash_cv_func_sigsetjmp=missing] ++)]) ++AC_MSG_RESULT($bash_cv_func_sigsetjmp) ++if test $bash_cv_func_sigsetjmp = present; then ++AC_DEFINE(HAVE_POSIX_SIGSETJMP) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_STRCOLL, ++[ ++AC_MSG_CHECKING(whether or not strcoll and strcmp differ) ++AC_CACHE_VAL(bash_cv_func_strcoll_broken, ++[AC_TRY_RUN([ ++#include ++#if defined (HAVE_LOCALE_H) ++#include ++#endif ++#include +#include - #ifndef UNDER_SYS_SIGLIST_DECLARED - extern char *_sys_siglist[]; - #endif ++ +int - main() - { - char *msg = (char *)_sys_siglist[2]; -@@ -218,9 +224,11 @@ AC_CACHE_VAL(bash_cv_sys_siglist, - #ifdef HAVE_UNISTD_H - #include - #endif ++main(c, v) ++int c; ++char *v[]; ++{ ++ int r1, r2; ++ char *deflocale, *defcoll; ++ ++#ifdef HAVE_SETLOCALE ++ deflocale = setlocale(LC_ALL, ""); ++ defcoll = setlocale(LC_COLLATE, ""); ++#endif ++ ++#ifdef HAVE_STRCOLL ++ /* These two values are taken from tests/glob-test. */ ++ r1 = strcoll("abd", "aXd"); ++#else ++ r1 = 0; ++#endif ++ r2 = strcmp("abd", "aXd"); ++ ++ /* These two should both be greater than 0. It is permissible for ++ a system to return different values, as long as the sign is the ++ same. */ ++ ++ /* Exit with 1 (failure) if these two values are both > 0, since ++ this tests whether strcoll(3) is broken with respect to strcmp(3) ++ in the default locale. */ ++ exit (r1 > 0 && r2 > 0); ++} ++], bash_cv_func_strcoll_broken=yes, bash_cv_func_strcoll_broken=no, ++ [AC_MSG_WARN(cannot check strcoll if cross compiling -- defaulting to no) ++ bash_cv_func_strcoll_broken=no] ++)]) ++AC_MSG_RESULT($bash_cv_func_strcoll_broken) ++if test $bash_cv_func_strcoll_broken = yes; then ++AC_DEFINE(STRCOLL_BROKEN) ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_PRINTF_A_FORMAT, ++[AC_MSG_CHECKING([for printf floating point output in hex notation]) ++AC_CACHE_VAL(bash_cv_printf_a_format, ++[AC_TRY_RUN([ ++#include ++#include +#include - #if !HAVE_DECL_SYS_SIGLIST - extern char *sys_siglist[]; - #endif ++ +int - main() - { - char *msg = sys_siglist[2]; -@@ -273,6 +281,8 @@ AC_CACHE_VAL(bash_cv_dup2_broken, - [AC_TRY_RUN([ - #include - #include ++main() ++{ ++ double y = 0.0; ++ char abuf[1024]; ++ ++ sprintf(abuf, "%A", y); ++ exit(strchr(abuf, 'P') == (char *)0); ++} ++], bash_cv_printf_a_format=yes, bash_cv_printf_a_format=no, ++ [AC_MSG_WARN(cannot check printf if cross compiling -- defaulting to no) ++ bash_cv_printf_a_format=no] ++)]) ++AC_MSG_RESULT($bash_cv_printf_a_format) ++if test $bash_cv_printf_a_format = yes; then ++AC_DEFINE(HAVE_PRINTF_A_FORMAT) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_TERMIOS_LDISC, ++[ ++AC_CHECK_MEMBER(struct termios.c_line, AC_DEFINE(TERMIOS_LDISC), ,[ ++#include ++#include ++]) ++]) ++ ++AC_DEFUN(BASH_STRUCT_TERMIO_LDISC, ++[ ++AC_CHECK_MEMBER(struct termio.c_line, AC_DEFINE(TERMIO_LDISC), ,[ ++#include ++#include ++]) ++]) ++ ++dnl ++dnl Like AC_STRUCT_ST_BLOCKS, but doesn't muck with LIBOBJS ++dnl ++dnl sets bash_cv_struct_stat_st_blocks ++dnl ++dnl unused for now; we'll see how AC_CHECK_MEMBERS works ++dnl ++AC_DEFUN(BASH_STRUCT_ST_BLOCKS, ++[ ++AC_MSG_CHECKING([for struct stat.st_blocks]) ++AC_CACHE_VAL(bash_cv_struct_stat_st_blocks, ++[AC_TRY_COMPILE( ++[ ++#include ++#include ++], ++[ ++main() ++{ ++static struct stat a; ++if (a.st_blocks) return 0; ++return 0; ++} ++], bash_cv_struct_stat_st_blocks=yes, bash_cv_struct_stat_st_blocks=no) ++]) ++AC_MSG_RESULT($bash_cv_struct_stat_st_blocks) ++if test "$bash_cv_struct_stat_st_blocks" = "yes"; then ++AC_DEFINE(HAVE_STRUCT_STAT_ST_BLOCKS) ++fi ++]) ++ ++AC_DEFUN([BASH_CHECK_LIB_TERMCAP], ++[ ++if test "X$bash_cv_termcap_lib" = "X"; then ++_bash_needmsg=yes ++else ++AC_MSG_CHECKING(which library has the termcap functions) ++_bash_needmsg= ++fi ++AC_CACHE_VAL(bash_cv_termcap_lib, ++[AC_CHECK_FUNC(tgetent, bash_cv_termcap_lib=libc, ++ [AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap, ++ [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, ++ [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, ++ [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, ++ [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, ++ bash_cv_termcap_lib=gnutermcap)])])])])])]) ++if test "X$_bash_needmsg" = "Xyes"; then ++AC_MSG_CHECKING(which library has the termcap functions) ++fi ++AC_MSG_RESULT(using $bash_cv_termcap_lib) ++if test $bash_cv_termcap_lib = gnutermcap && test -z "$prefer_curses"; then ++LDFLAGS="$LDFLAGS -L./lib/termcap" ++TERMCAP_LIB="./lib/termcap/libtermcap.a" ++TERMCAP_DEP="./lib/termcap/libtermcap.a" ++elif test $bash_cv_termcap_lib = libtermcap && test -z "$prefer_curses"; then ++TERMCAP_LIB=-ltermcap ++TERMCAP_DEP= ++elif test $bash_cv_termcap_lib = libtinfo; then ++TERMCAP_LIB=-ltinfo ++TERMCAP_DEP= ++elif test $bash_cv_termcap_lib = libncurses; then ++TERMCAP_LIB=-lncurses ++TERMCAP_DEP= ++elif test $bash_cv_termcap_lib = libc; then ++TERMCAP_LIB= ++TERMCAP_DEP= ++else ++TERMCAP_LIB=-lcurses ++TERMCAP_DEP= ++fi ++]) ++ ++dnl ++dnl Check for the presence of getpeername in libsocket. ++dnl If libsocket is present, check for libnsl and add it to LIBS if ++dnl it's there, since most systems with libsocket require linking ++dnl with libnsl as well. This should only be called if getpeername ++dnl was not found in libc. ++dnl ++dnl NOTE: IF WE FIND GETPEERNAME, WE ASSUME THAT WE HAVE BIND/CONNECT ++dnl AS WELL ++dnl ++AC_DEFUN(BASH_CHECK_LIB_SOCKET, ++[ ++if test "X$bash_cv_have_socklib" = "X"; then ++_bash_needmsg= ++else ++AC_MSG_CHECKING(for socket library) ++_bash_needmsg=yes ++fi ++AC_CACHE_VAL(bash_cv_have_socklib, ++[AC_CHECK_LIB(socket, getpeername, ++ bash_cv_have_socklib=yes, bash_cv_have_socklib=no, -lnsl)]) ++if test "X$_bash_needmsg" = Xyes; then ++ AC_MSG_RESULT($bash_cv_have_socklib) ++ _bash_needmsg= ++fi ++if test $bash_cv_have_socklib = yes; then ++ # check for libnsl, add it to LIBS if present ++ if test "X$bash_cv_have_libnsl" = "X"; then ++ _bash_needmsg= ++ else ++ AC_MSG_CHECKING(for libnsl) ++ _bash_needmsg=yes ++ fi ++ AC_CACHE_VAL(bash_cv_have_libnsl, ++ [AC_CHECK_LIB(nsl, t_open, ++ bash_cv_have_libnsl=yes, bash_cv_have_libnsl=no)]) ++ if test "X$_bash_needmsg" = Xyes; then ++ AC_MSG_RESULT($bash_cv_have_libnsl) ++ _bash_needmsg= ++ fi ++ if test $bash_cv_have_libnsl = yes; then ++ LIBS="-lsocket -lnsl $LIBS" ++ else ++ LIBS="-lsocket $LIBS" ++ fi ++ AC_DEFINE(HAVE_LIBSOCKET) ++ AC_DEFINE(HAVE_GETPEERNAME) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_DIRENT_D_INO, ++[AC_REQUIRE([AC_HEADER_DIRENT]) ++AC_MSG_CHECKING(for struct dirent.d_ino) ++AC_CACHE_VAL(bash_cv_dirent_has_dino, ++[AC_TRY_COMPILE([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++#if defined(HAVE_DIRENT_H) ++# include ++#else ++# define dirent direct ++# ifdef HAVE_SYS_NDIR_H ++# include ++# endif /* SYSNDIR */ ++# ifdef HAVE_SYS_DIR_H ++# include ++# endif /* SYSDIR */ ++# ifdef HAVE_NDIR_H ++# include ++# endif ++#endif /* HAVE_DIRENT_H */ ++],[ ++struct dirent d; int z; z = d.d_ino; ++], bash_cv_dirent_has_dino=yes, bash_cv_dirent_has_dino=no)]) ++AC_MSG_RESULT($bash_cv_dirent_has_dino) ++if test $bash_cv_dirent_has_dino = yes; then ++AC_DEFINE(HAVE_STRUCT_DIRENT_D_INO) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_DIRENT_D_FILENO, ++[AC_REQUIRE([AC_HEADER_DIRENT]) ++AC_MSG_CHECKING(for struct dirent.d_fileno) ++AC_CACHE_VAL(bash_cv_dirent_has_d_fileno, ++[AC_TRY_COMPILE([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++#if defined(HAVE_DIRENT_H) ++# include ++#else ++# define dirent direct ++# ifdef HAVE_SYS_NDIR_H ++# include ++# endif /* SYSNDIR */ ++# ifdef HAVE_SYS_DIR_H ++# include ++# endif /* SYSDIR */ ++# ifdef HAVE_NDIR_H ++# include ++# endif ++#endif /* HAVE_DIRENT_H */ ++],[ ++struct dirent d; int z; z = d.d_fileno; ++], bash_cv_dirent_has_d_fileno=yes, bash_cv_dirent_has_d_fileno=no)]) ++AC_MSG_RESULT($bash_cv_dirent_has_d_fileno) ++if test $bash_cv_dirent_has_d_fileno = yes; then ++AC_DEFINE(HAVE_STRUCT_DIRENT_D_FILENO) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_DIRENT_D_NAMLEN, ++[AC_REQUIRE([AC_HEADER_DIRENT]) ++AC_MSG_CHECKING(for struct dirent.d_namlen) ++AC_CACHE_VAL(bash_cv_dirent_has_d_namlen, ++[AC_TRY_COMPILE([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif /* HAVE_UNISTD_H */ ++#if defined(HAVE_DIRENT_H) ++# include ++#else ++# define dirent direct ++# ifdef HAVE_SYS_NDIR_H ++# include ++# endif /* SYSNDIR */ ++# ifdef HAVE_SYS_DIR_H ++# include ++# endif /* SYSDIR */ ++# ifdef HAVE_NDIR_H ++# include ++# endif ++#endif /* HAVE_DIRENT_H */ ++],[ ++struct dirent d; int z; z = d.d_namlen; ++], bash_cv_dirent_has_d_namlen=yes, bash_cv_dirent_has_d_namlen=no)]) ++AC_MSG_RESULT($bash_cv_dirent_has_d_namlen) ++if test $bash_cv_dirent_has_d_namlen = yes; then ++AC_DEFINE(HAVE_STRUCT_DIRENT_D_NAMLEN) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_TIMEVAL, ++[AC_MSG_CHECKING(for struct timeval in sys/time.h and time.h) ++AC_CACHE_VAL(bash_cv_struct_timeval, ++[ ++AC_EGREP_HEADER(struct timeval, sys/time.h, ++ bash_cv_struct_timeval=yes, ++ AC_EGREP_HEADER(struct timeval, time.h, ++ bash_cv_struct_timeval=yes, ++ bash_cv_struct_timeval=no)) ++]) ++AC_MSG_RESULT($bash_cv_struct_timeval) ++if test $bash_cv_struct_timeval = yes; then ++ AC_DEFINE(HAVE_TIMEVAL) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_TIMEZONE, ++[AC_MSG_CHECKING(for struct timezone in sys/time.h and time.h) ++AC_CACHE_VAL(bash_cv_struct_timezone, ++[ ++AC_EGREP_HEADER(struct timezone, sys/time.h, ++ bash_cv_struct_timezone=yes, ++ AC_EGREP_HEADER(struct timezone, time.h, ++ bash_cv_struct_timezone=yes, ++ bash_cv_struct_timezone=no)) ++]) ++AC_MSG_RESULT($bash_cv_struct_timezone) ++if test $bash_cv_struct_timezone = yes; then ++ AC_DEFINE(HAVE_STRUCT_TIMEZONE) ++fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_WINSIZE, ++[AC_MSG_CHECKING(for struct winsize in sys/ioctl.h and termios.h) ++AC_CACHE_VAL(bash_cv_struct_winsize_header, ++[AC_TRY_COMPILE([#include ++#include ], [struct winsize x;], ++ bash_cv_struct_winsize_header=ioctl_h, ++ [AC_TRY_COMPILE([#include ++#include ], [struct winsize x;], ++ bash_cv_struct_winsize_header=termios_h, bash_cv_struct_winsize_header=other) ++])]) ++if test $bash_cv_struct_winsize_header = ioctl_h; then ++ AC_MSG_RESULT(sys/ioctl.h) ++ AC_DEFINE(STRUCT_WINSIZE_IN_SYS_IOCTL) ++elif test $bash_cv_struct_winsize_header = termios_h; then ++ AC_MSG_RESULT(termios.h) ++ AC_DEFINE(STRUCT_WINSIZE_IN_TERMIOS) ++else ++ AC_MSG_RESULT(not found) ++fi ++]) ++ ++dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7) ++AC_DEFUN(BASH_SYS_SIGNAL_VINTAGE, ++[AC_REQUIRE([AC_TYPE_SIGNAL]) ++AC_MSG_CHECKING(for type of signal functions) ++AC_CACHE_VAL(bash_cv_signal_vintage, ++[ ++ AC_TRY_LINK([#include ],[ ++ sigset_t ss; ++ struct sigaction sa; ++ sigemptyset(&ss); sigsuspend(&ss); ++ sigaction(SIGINT, &sa, (struct sigaction *) 0); ++ sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); ++ ], bash_cv_signal_vintage=posix, ++ [ ++ AC_TRY_LINK([#include ], [ ++ int mask = sigmask(SIGINT); ++ sigsetmask(mask); sigblock(mask); sigpause(mask); ++ ], bash_cv_signal_vintage=4.2bsd, ++ [ ++ AC_TRY_LINK([ ++ #include ++ RETSIGTYPE foo() { }], [ ++ int mask = sigmask(SIGINT); ++ sigset(SIGINT, foo); sigrelse(SIGINT); ++ sighold(SIGINT); sigpause(SIGINT); ++ ], bash_cv_signal_vintage=svr3, bash_cv_signal_vintage=v7 ++ )] ++ )] ++) ++]) ++AC_MSG_RESULT($bash_cv_signal_vintage) ++if test "$bash_cv_signal_vintage" = posix; then ++AC_DEFINE(HAVE_POSIX_SIGNALS) ++elif test "$bash_cv_signal_vintage" = "4.2bsd"; then ++AC_DEFINE(HAVE_BSD_SIGNALS) ++elif test "$bash_cv_signal_vintage" = svr3; then ++AC_DEFINE(HAVE_USG_SIGHOLD) ++fi ++]) ++ ++dnl Check if the pgrp of setpgrp() can't be the pid of a zombie process. ++AC_DEFUN(BASH_SYS_PGRP_SYNC, ++[AC_REQUIRE([AC_FUNC_GETPGRP]) ++AC_MSG_CHECKING(whether pgrps need synchronization) ++AC_CACHE_VAL(bash_cv_pgrp_pipe, ++[AC_TRY_RUN([ ++#ifdef HAVE_UNISTD_H ++# include ++#endif +#include +int - main() - { - int fd1, fd2, fl; -@@ -335,6 +345,8 @@ AC_CACHE_VAL(bash_cv_opendir_not_robust, - # include - # endif - #endif /* HAVE_DIRENT_H */ ++main() ++{ ++# ifdef GETPGRP_VOID ++# define getpgID() getpgrp() ++# else ++# define getpgID() getpgrp(0) ++# define setpgid(x,y) setpgrp(x,y) ++# endif ++ int pid1, pid2, fds[2]; ++ int status; ++ char ok; ++ ++ switch (pid1 = fork()) { ++ case -1: ++ exit(1); ++ case 0: ++ setpgid(0, getpid()); ++ exit(0); ++ } ++ setpgid(pid1, pid1); ++ ++ sleep(2); /* let first child die */ ++ ++ if (pipe(fds) < 0) ++ exit(2); ++ ++ switch (pid2 = fork()) { ++ case -1: ++ exit(3); ++ case 0: ++ setpgid(0, pid1); ++ ok = getpgID() == pid1; ++ write(fds[1], &ok, 1); ++ exit(0); ++ } ++ setpgid(pid2, pid1); ++ ++ close(fds[1]); ++ if (read(fds[0], &ok, 1) != 1) ++ exit(4); ++ wait(&status); ++ wait(&status); ++ exit(ok ? 0 : 5); ++} ++], bash_cv_pgrp_pipe=no,bash_cv_pgrp_pipe=yes, ++ [AC_MSG_WARN(cannot check pgrp synchronization if cross compiling -- defaulting to no) ++ bash_cv_pgrp_pipe=no]) ++]) ++AC_MSG_RESULT($bash_cv_pgrp_pipe) ++if test $bash_cv_pgrp_pipe = yes; then ++AC_DEFINE(PGRP_PIPE) ++fi ++]) ++ ++AC_DEFUN(BASH_SYS_REINSTALL_SIGHANDLERS, ++[AC_REQUIRE([AC_TYPE_SIGNAL]) ++AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) ++AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked]) ++AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers, ++[AC_TRY_RUN([ ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif +#include ++ ++typedef RETSIGTYPE sigfunc(); ++ ++volatile int nsigint; ++ ++#ifdef HAVE_POSIX_SIGNALS ++sigfunc * ++set_signal_handler(sig, handler) ++ int sig; ++ sigfunc *handler; ++{ ++ struct sigaction act, oact; ++ act.sa_handler = handler; ++ act.sa_flags = 0; ++ sigemptyset (&act.sa_mask); ++ sigemptyset (&oact.sa_mask); ++ sigaction (sig, &act, &oact); ++ return (oact.sa_handler); ++} ++#else ++#define set_signal_handler(s, h) signal(s, h) ++#endif ++ ++RETSIGTYPE ++sigint(s) ++int s; ++{ ++ nsigint++; ++} ++ +int - main() - { - DIR *dir; -@@ -514,6 +526,8 @@ AC_TRY_RUN([ - #include - #include - #include ++main() ++{ ++ nsigint = 0; ++ set_signal_handler(SIGINT, sigint); ++ kill((int)getpid(), SIGINT); ++ kill((int)getpid(), SIGINT); ++ exit(nsigint != 2); ++} ++], bash_cv_must_reinstall_sighandlers=no, bash_cv_must_reinstall_sighandlers=yes, ++ [AC_MSG_WARN(cannot check signal handling if cross compiling -- defaulting to no) ++ bash_cv_must_reinstall_sighandlers=no] ++)]) ++AC_MSG_RESULT($bash_cv_must_reinstall_sighandlers) ++if test $bash_cv_must_reinstall_sighandlers = yes; then ++AC_DEFINE(MUST_REINSTALL_SIGHANDLERS) ++fi ++]) ++ ++dnl check that some necessary job control definitions are present ++AC_DEFUN(BASH_SYS_JOB_CONTROL_MISSING, ++[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) ++AC_MSG_CHECKING(for presence of necessary job control definitions) ++AC_CACHE_VAL(bash_cv_job_control_missing, ++[AC_TRY_COMPILE([ ++#include ++#ifdef HAVE_SYS_WAIT_H ++#include ++#endif ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++ ++/* add more tests in here as appropriate */ ++ ++/* signal type */ ++#if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS) ++#error ++#endif ++ ++/* signals and tty control. */ ++#if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT) ++#error ++#endif ++ ++/* process control */ ++#if !defined (WNOHANG) || !defined (WUNTRACED) ++#error ++#endif ++ ++/* Posix systems have tcgetpgrp and waitpid. */ ++#if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP) ++#error ++#endif ++ ++#if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID) ++#error ++#endif ++ ++/* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */ ++#if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3) ++#error ++#endif ++ ++], , bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing ++)]) ++AC_MSG_RESULT($bash_cv_job_control_missing) ++if test $bash_cv_job_control_missing = missing; then ++AC_DEFINE(JOB_CONTROL_MISSING) ++fi ++]) ++ ++dnl check whether named pipes are present ++dnl this requires a previous check for mkfifo, but that is awkward to specify ++AC_DEFUN(BASH_SYS_NAMED_PIPES, ++[AC_MSG_CHECKING(for presence of named pipes) ++AC_CACHE_VAL(bash_cv_sys_named_pipes, ++[AC_TRY_RUN([ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include +#include ++ ++/* Add more tests in here as appropriate. */ +int - main() - { - #ifdef HAVE_QUAD_T -@@ -583,6 +597,7 @@ AC_CACHE_VAL(bash_cv_getenv_redef, - #ifdef HAVE_UNISTD_H - # include - #endif ++main() ++{ ++int fd, err; ++ ++#if defined (HAVE_MKFIFO) ++exit (0); ++#endif ++ ++#if !defined (S_IFIFO) && (defined (_POSIX_VERSION) && !defined (S_ISFIFO)) ++exit (1); ++#endif ++ ++#if defined (NeXT) ++exit (1); ++#endif ++err = mkdir("bash-aclocal", 0700); ++if (err < 0) { ++ perror ("mkdir"); ++ exit(1); ++} ++fd = mknod ("bash-aclocal/sh-np-autoconf", 0666 | S_IFIFO, 0); ++if (fd == -1) { ++ rmdir ("bash-aclocal"); ++ exit (1); ++} ++close(fd); ++unlink ("bash-aclocal/sh-np-autoconf"); ++rmdir ("bash-aclocal"); ++exit(0); ++}], bash_cv_sys_named_pipes=present, bash_cv_sys_named_pipes=missing, ++ [AC_MSG_WARN(cannot check for named pipes if cross-compiling -- defaulting to missing) ++ bash_cv_sys_named_pipes=missing] ++)]) ++AC_MSG_RESULT($bash_cv_sys_named_pipes) ++if test $bash_cv_sys_named_pipes = missing; then ++AC_DEFINE(NAMED_PIPES_MISSING) ++fi ++]) ++ ++AC_DEFUN(BASH_SYS_DEFAULT_MAIL_DIR, ++[AC_MSG_CHECKING(for default mail directory) ++AC_CACHE_VAL(bash_cv_mail_dir, ++[if test -d /var/mail; then ++ bash_cv_mail_dir=/var/mail ++ elif test -d /var/spool/mail; then ++ bash_cv_mail_dir=/var/spool/mail ++ elif test -d /usr/mail; then ++ bash_cv_mail_dir=/usr/mail ++ elif test -d /usr/spool/mail; then ++ bash_cv_mail_dir=/usr/spool/mail ++ else ++ bash_cv_mail_dir=unknown ++ fi ++]) ++AC_MSG_RESULT($bash_cv_mail_dir) ++AC_DEFINE_UNQUOTED(DEFAULT_MAIL_DIRECTORY, "$bash_cv_mail_dir") ++]) ++ ++AC_DEFUN(BASH_HAVE_TIOCGWINSZ, ++[AC_MSG_CHECKING(for TIOCGWINSZ in sys/ioctl.h) ++AC_CACHE_VAL(bash_cv_tiocgwinsz_in_ioctl, ++[AC_TRY_COMPILE([#include ++#include ], [int x = TIOCGWINSZ;], ++ bash_cv_tiocgwinsz_in_ioctl=yes,bash_cv_tiocgwinsz_in_ioctl=no)]) ++AC_MSG_RESULT($bash_cv_tiocgwinsz_in_ioctl) ++if test $bash_cv_tiocgwinsz_in_ioctl = yes; then ++AC_DEFINE(GWINSZ_IN_SYS_IOCTL) ++fi ++]) ++ ++AC_DEFUN(BASH_HAVE_TIOCSTAT, ++[AC_MSG_CHECKING(for TIOCSTAT in sys/ioctl.h) ++AC_CACHE_VAL(bash_cv_tiocstat_in_ioctl, ++[AC_TRY_COMPILE([#include ++#include ], [int x = TIOCSTAT;], ++ bash_cv_tiocstat_in_ioctl=yes,bash_cv_tiocstat_in_ioctl=no)]) ++AC_MSG_RESULT($bash_cv_tiocstat_in_ioctl) ++if test $bash_cv_tiocstat_in_ioctl = yes; then ++AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL) ++fi ++]) ++ ++AC_DEFUN(BASH_HAVE_FIONREAD, ++[AC_MSG_CHECKING(for FIONREAD in sys/ioctl.h) ++AC_CACHE_VAL(bash_cv_fionread_in_ioctl, ++[AC_TRY_COMPILE([#include ++#include ], [int x = FIONREAD;], ++ bash_cv_fionread_in_ioctl=yes,bash_cv_fionread_in_ioctl=no)]) ++AC_MSG_RESULT($bash_cv_fionread_in_ioctl) ++if test $bash_cv_fionread_in_ioctl = yes; then ++AC_DEFINE(FIONREAD_IN_SYS_IOCTL) ++fi ++]) ++ ++dnl ++dnl See if speed_t is declared in . Some versions of linux ++dnl require a definition of speed_t each time is included, ++dnl but you can only get speed_t if you include (on some ++dnl versions) or (on others). ++dnl ++AC_DEFUN(BASH_CHECK_SPEED_T, ++[AC_MSG_CHECKING(for speed_t in sys/types.h) ++AC_CACHE_VAL(bash_cv_speed_t_in_sys_types, ++[AC_TRY_COMPILE([#include ], [speed_t x;], ++ bash_cv_speed_t_in_sys_types=yes,bash_cv_speed_t_in_sys_types=no)]) ++AC_MSG_RESULT($bash_cv_speed_t_in_sys_types) ++if test $bash_cv_speed_t_in_sys_types = yes; then ++AC_DEFINE(SPEED_T_IN_SYS_TYPES) ++fi ++]) ++ ++AC_DEFUN(BASH_CHECK_GETPW_FUNCS, ++[AC_MSG_CHECKING(whether getpw functions are declared in pwd.h) ++AC_CACHE_VAL(bash_cv_getpw_declared, ++[AC_EGREP_CPP(getpwuid, ++[ ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif ++#include ++], ++bash_cv_getpw_declared=yes,bash_cv_getpw_declared=no)]) ++AC_MSG_RESULT($bash_cv_getpw_declared) ++if test $bash_cv_getpw_declared = yes; then ++AC_DEFINE(HAVE_GETPW_DECLS) ++fi ++]) ++ ++AC_DEFUN(BASH_CHECK_DEV_FD, ++[AC_MSG_CHECKING(whether /dev/fd is available) ++AC_CACHE_VAL(bash_cv_dev_fd, ++[bash_cv_dev_fd="" ++if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then ++# check for systems like FreeBSD 5 that only provide /dev/fd/[012] ++ if (exec test -r /dev/fd/3 3 ++#include ++], ++[ ++ int f; ++ f = RLIMIT_DATA; ++], bash_cv_kernel_rlimit=no, ++[AC_TRY_COMPILE([ ++#include ++#define _KERNEL ++#include ++#undef _KERNEL ++], ++[ ++ int f; ++ f = RLIMIT_DATA; ++], bash_cv_kernel_rlimit=yes, bash_cv_kernel_rlimit=no)] ++)]) ++AC_MSG_RESULT($bash_cv_kernel_rlimit) ++if test $bash_cv_kernel_rlimit = yes; then ++AC_DEFINE(RLIMIT_NEEDS_KERNEL) ++fi ++]) ++ ++dnl ++dnl Check for 64-bit off_t -- used for malloc alignment ++dnl ++dnl C does not allow duplicate case labels, so the compile will fail if ++dnl sizeof(off_t) is > 4. ++dnl ++AC_DEFUN(BASH_CHECK_OFF_T_64, ++[AC_CACHE_CHECK(for 64-bit off_t, bash_cv_off_t_64, ++AC_TRY_COMPILE([ ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++],[ ++switch (0) case 0: case (sizeof (off_t) <= 4):; ++], bash_cv_off_t_64=no, bash_cv_off_t_64=yes)) ++if test $bash_cv_off_t_64 = yes; then ++ AC_DEFINE(HAVE_OFF_T_64) ++fi]) ++ ++AC_DEFUN(BASH_CHECK_RTSIGS, ++[AC_MSG_CHECKING(for unusable real-time signals due to large values) ++AC_CACHE_VAL(bash_cv_unusable_rtsigs, ++[AC_TRY_RUN([ ++#include ++#include +#include - #ifndef __STDC__ - # ifndef const - # define const -@@ -598,6 +613,7 @@ getenv (name) - { - return "42"; - } ++ ++#ifndef NSIG ++# define NSIG 64 ++#endif ++ +int - main() - { - char *s; -@@ -786,7 +802,9 @@ AC_CACHE_VAL(bash_cv_func_sigsetjmp, - #include - #include - #include ++main () ++{ ++ int n_sigs = 2 * NSIG; ++#ifdef SIGRTMIN ++ int rtmin = SIGRTMIN; ++#else ++ int rtmin = 0; ++#endif ++ ++ exit(rtmin < n_sigs); ++}], bash_cv_unusable_rtsigs=yes, bash_cv_unusable_rtsigs=no, ++ [AC_MSG_WARN(cannot check real-time signals if cross compiling -- defaulting to yes) ++ bash_cv_unusable_rtsigs=yes] ++)]) ++AC_MSG_RESULT($bash_cv_unusable_rtsigs) ++if test $bash_cv_unusable_rtsigs = yes; then ++AC_DEFINE(UNUSABLE_RT_SIGNALS) ++fi ++]) ++ ++dnl ++dnl check for availability of multibyte characters and functions ++dnl ++dnl geez, I wish I didn't have to check for all of this stuff separately ++dnl ++AC_DEFUN(BASH_CHECK_MULTIBYTE, ++[ ++AC_CHECK_HEADERS(wctype.h) ++AC_CHECK_HEADERS(wchar.h) ++AC_CHECK_HEADERS(langinfo.h) ++ ++AC_CHECK_HEADERS(mbstr.h) ++ ++AC_CHECK_FUNC(mbrlen, AC_DEFINE(HAVE_MBRLEN)) ++AC_CHECK_FUNC(mbscasecmp, AC_DEFINE(HAVE_MBSCMP)) ++AC_CHECK_FUNC(mbscmp, AC_DEFINE(HAVE_MBSCMP)) ++AC_CHECK_FUNC(mbsnrtowcs, AC_DEFINE(HAVE_MBSNRTOWCS)) ++AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS)) ++ ++AC_REPLACE_FUNCS(mbschr) ++ ++AC_CHECK_FUNC(wcrtomb, AC_DEFINE(HAVE_WCRTOMB)) ++AC_CHECK_FUNC(wcscoll, AC_DEFINE(HAVE_WCSCOLL)) ++AC_CHECK_FUNC(wcsdup, AC_DEFINE(HAVE_WCSDUP)) ++AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH)) ++AC_CHECK_FUNC(wctype, AC_DEFINE(HAVE_WCTYPE)) ++ ++AC_REPLACE_FUNCS(wcswidth) ++ ++dnl checks for both mbrtowc and mbstate_t ++AC_FUNC_MBRTOWC ++if test $ac_cv_func_mbrtowc = yes; then ++ AC_DEFINE(HAVE_MBSTATE_T) ++fi ++ ++AC_CHECK_FUNCS(iswlower iswupper towlower towupper iswctype) ++ ++AC_CACHE_CHECK([for nl_langinfo and CODESET], bash_cv_langinfo_codeset, ++[AC_TRY_LINK( ++[#include ], ++[char* cs = nl_langinfo(CODESET);], ++bash_cv_langinfo_codeset=yes, bash_cv_langinfo_codeset=no)]) ++if test $bash_cv_langinfo_codeset = yes; then ++ AC_DEFINE(HAVE_LANGINFO_CODESET) ++fi ++ ++dnl check for wchar_t in ++AC_CACHE_CHECK([for wchar_t in wchar.h], bash_cv_type_wchar_t, ++[AC_TRY_COMPILE( ++[#include ++], ++[ ++ wchar_t foo; ++ foo = 0; ++], bash_cv_type_wchar_t=yes, bash_cv_type_wchar_t=no)]) ++if test $bash_cv_type_wchar_t = yes; then ++ AC_DEFINE(HAVE_WCHAR_T, 1, [systems should define this type here]) ++fi ++ ++dnl check for wctype_t in ++AC_CACHE_CHECK([for wctype_t in wctype.h], bash_cv_type_wctype_t, ++[AC_TRY_COMPILE( ++[#include ], ++[ ++ wctype_t foo; ++ foo = 0; ++], bash_cv_type_wctype_t=yes, bash_cv_type_wctype_t=no)]) ++if test $bash_cv_type_wctype_t = yes; then ++ AC_DEFINE(HAVE_WCTYPE_T, 1, [systems should define this type here]) ++fi ++ ++dnl check for wint_t in ++AC_CACHE_CHECK([for wint_t in wctype.h], bash_cv_type_wint_t, ++[AC_TRY_COMPILE( ++[#include ], ++[ ++ wint_t foo; ++ foo = 0; ++], bash_cv_type_wint_t=yes, bash_cv_type_wint_t=no)]) ++if test $bash_cv_type_wint_t = yes; then ++ AC_DEFINE(HAVE_WINT_T, 1, [systems should define this type here]) ++fi ++ ++dnl check for broken wcwidth ++AC_CACHE_CHECK([for wcwidth broken with unicode combining characters], ++bash_cv_wcwidth_broken, ++[AC_TRY_RUN([ ++#include +#include - ++#include ++ ++#include ++#include ++ +int - main() - { - #if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) -@@ -835,7 +853,10 @@ AC_CACHE_VAL(bash_cv_func_strcoll_broken - #if defined (HAVE_LOCALE_H) - #include - #endif -+#include ++main(c, v) ++int c; ++char **v; ++{ ++ int w; ++ ++ setlocale(LC_ALL, "en_US.UTF-8"); ++ w = wcwidth (0x0301); ++ exit (w == 0); /* exit 0 if wcwidth broken */ ++} ++], ++bash_cv_wcwidth_broken=yes, bash_cv_wcwidth_broken=no, bash_cv_wcwidth_broken=no)]) ++if test "$bash_cv_wcwidth_broken" = yes; then ++ AC_DEFINE(WCWIDTH_BROKEN, 1, [wcwidth is usually not broken]) ++fi ++ ++if test "$am_cv_func_iconv" = yes; then ++ OLDLIBS="$LIBS" ++ LIBS="$LIBS $LIBINTL $LIBICONV" ++ AC_CHECK_FUNCS(locale_charset) ++ LIBS="$OLDLIBS" ++fi ++ ++AC_CHECK_SIZEOF(wchar_t, 4) ++ ++]) ++ ++dnl need: prefix exec_prefix libdir includedir CC TERMCAP_LIB ++dnl require: ++dnl AC_PROG_CC ++dnl BASH_CHECK_LIB_TERMCAP ++ ++AC_DEFUN([RL_LIB_READLINE_VERSION], ++[ ++AC_REQUIRE([BASH_CHECK_LIB_TERMCAP]) ++ ++AC_MSG_CHECKING([version of installed readline library]) ++ ++# What a pain in the ass this is. ++ ++# save cpp and ld options ++_save_CFLAGS="$CFLAGS" ++_save_LDFLAGS="$LDFLAGS" ++_save_LIBS="$LIBS" ++ ++# Don't set ac_cv_rl_prefix if the caller has already assigned a value. This ++# allows the caller to do something like $_rl_prefix=$withval if the user ++# specifies --with-installed-readline=PREFIX as an argument to configure ++ ++if test -z "$ac_cv_rl_prefix"; then ++test "x$prefix" = xNONE && ac_cv_rl_prefix=$ac_default_prefix || ac_cv_rl_prefix=${prefix} ++fi ++ ++eval ac_cv_rl_includedir=${ac_cv_rl_prefix}/include ++eval ac_cv_rl_libdir=${ac_cv_rl_prefix}/lib ++ ++LIBS="$LIBS -lreadline ${TERMCAP_LIB}" ++CFLAGS="$CFLAGS -I${ac_cv_rl_includedir}" ++LDFLAGS="$LDFLAGS -L${ac_cv_rl_libdir}" ++ ++AC_CACHE_VAL(ac_cv_rl_version, ++[AC_TRY_RUN([ ++#include ++#include +#include - ++ ++extern int rl_gnu_readline_p; ++ +int - main(c, v) - int c; - char *v[]; -@@ -881,6 +902,7 @@ AC_CACHE_VAL(bash_cv_printf_a_format, - [AC_TRY_RUN([ - #include - #include -+#include - - int - main() -@@ -1241,6 +1263,8 @@ AC_CACHE_VAL(bash_cv_pgrp_pipe, - #ifdef HAVE_UNISTD_H - # include - #endif ++main() ++{ ++ FILE *fp; ++ fp = fopen("conftest.rlv", "w"); ++ if (fp == 0) ++ exit(1); ++ if (rl_gnu_readline_p != 1) ++ fprintf(fp, "0.0\n"); ++ else ++ fprintf(fp, "%s\n", rl_library_version ? rl_library_version : "0.0"); ++ fclose(fp); ++ exit(0); ++} ++], ++ac_cv_rl_version=`cat conftest.rlv`, ++ac_cv_rl_version='0.0', ++ac_cv_rl_version='8.0')]) ++ ++CFLAGS="$_save_CFLAGS" ++LDFLAGS="$_save_LDFLAGS" ++LIBS="$_save_LIBS" ++ ++RL_MAJOR=0 ++RL_MINOR=0 ++ ++# ( ++case "$ac_cv_rl_version" in ++2*|3*|4*|5*|6*|7*|8*|9*) ++ RL_MAJOR=`echo $ac_cv_rl_version | sed 's:\..*$::'` ++ RL_MINOR=`echo $ac_cv_rl_version | sed -e 's:^.*\.::' -e 's:[[a-zA-Z]]*$::'` ++ ;; ++esac ++ ++# ((( ++case $RL_MAJOR in ++[[0-9][0-9]]) _RL_MAJOR=$RL_MAJOR ;; ++[[0-9]]) _RL_MAJOR=0$RL_MAJOR ;; ++*) _RL_MAJOR=00 ;; ++esac ++ ++# ((( ++case $RL_MINOR in ++[[0-9][0-9]]) _RL_MINOR=$RL_MINOR ;; ++[[0-9]]) _RL_MINOR=0$RL_MINOR ;; ++*) _RL_MINOR=00 ;; ++esac ++ ++RL_VERSION="0x${_RL_MAJOR}${_RL_MINOR}" ++ ++# Readline versions greater than 4.2 have these defines in readline.h ++ ++if test $ac_cv_rl_version = '0.0' ; then ++ AC_MSG_WARN([Could not test version of installed readline library.]) ++elif test $RL_MAJOR -gt 4 || { test $RL_MAJOR = 4 && test $RL_MINOR -gt 2 ; } ; then ++ # set these for use by the caller ++ RL_PREFIX=$ac_cv_rl_prefix ++ RL_LIBDIR=$ac_cv_rl_libdir ++ RL_INCLUDEDIR=$ac_cv_rl_includedir ++ AC_MSG_RESULT($ac_cv_rl_version) ++else ++ ++AC_DEFINE_UNQUOTED(RL_READLINE_VERSION, $RL_VERSION, [encoded version of the installed readline library]) ++AC_DEFINE_UNQUOTED(RL_VERSION_MAJOR, $RL_MAJOR, [major version of installed readline library]) ++AC_DEFINE_UNQUOTED(RL_VERSION_MINOR, $RL_MINOR, [minor version of installed readline library]) ++ ++AC_SUBST(RL_VERSION) ++AC_SUBST(RL_MAJOR) ++AC_SUBST(RL_MINOR) ++ ++# set these for use by the caller ++RL_PREFIX=$ac_cv_rl_prefix ++RL_LIBDIR=$ac_cv_rl_libdir ++RL_INCLUDEDIR=$ac_cv_rl_includedir ++ ++AC_MSG_RESULT($ac_cv_rl_version) ++ ++fi ++]) ++ ++AC_DEFUN(BASH_FUNC_CTYPE_NONASCII, ++[ ++AC_MSG_CHECKING(whether the ctype macros accept non-ascii characters) ++AC_CACHE_VAL(bash_cv_func_ctype_nonascii, ++[AC_TRY_RUN([ ++#ifdef HAVE_LOCALE_H ++#include ++#endif ++#include ++#include +#include ++ +int - main() - { - # ifdef GETPGRP_VOID -@@ -1305,6 +1329,7 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sigh - #ifdef HAVE_UNISTD_H - #include - #endif ++main(c, v) ++int c; ++char *v[]; ++{ ++ char *deflocale; ++ unsigned char x; ++ int r1, r2; ++ ++#ifdef HAVE_SETLOCALE ++ /* We take a shot here. If that locale is not known, try the ++ system default. We try this one because '\342' (226) is ++ known to be a printable character in that locale. */ ++ deflocale = setlocale(LC_ALL, "en_US.ISO8859-1"); ++ if (deflocale == 0) ++ deflocale = setlocale(LC_ALL, ""); ++#endif ++ ++ x = '\342'; ++ r1 = isprint(x); ++ x -= 128; ++ r2 = isprint(x); ++ exit (r1 == 0 || r2 == 0); ++} ++], bash_cv_func_ctype_nonascii=yes, bash_cv_func_ctype_nonascii=no, ++ [AC_MSG_WARN(cannot check ctype macros if cross compiling -- defaulting to no) ++ bash_cv_func_ctype_nonascii=no] ++)]) ++AC_MSG_RESULT($bash_cv_func_ctype_nonascii) ++if test $bash_cv_func_ctype_nonascii = yes; then ++AC_DEFINE(CTYPE_NON_ASCII) ++fi ++]) ++ ++AC_DEFUN(BASH_CHECK_WCONTINUED, ++[ ++AC_MSG_CHECKING(whether WCONTINUED flag to waitpid is unavailable or available but broken) ++AC_CACHE_VAL(bash_cv_wcontinued_broken, ++[AC_TRY_RUN([ ++#include ++#include ++#include ++#include ++ ++#ifndef errno ++extern int errno; ++#endif ++main() ++{ ++ int x; ++ ++ x = waitpid(-1, (int *)0, WNOHANG|WCONTINUED); ++ if (x == -1 && errno == EINVAL) ++ exit (1); ++ else ++ exit (0); ++} ++], bash_cv_wcontinued_broken=no,bash_cv_wcontinued_broken=yes, ++ [AC_MSG_WARN(cannot check WCONTINUED if cross compiling -- defaulting to no) ++ bash_cv_wcontinued_broken=no] ++)]) ++AC_MSG_RESULT($bash_cv_wcontinued_broken) ++if test $bash_cv_wcontinued_broken = yes; then ++AC_DEFINE(WCONTINUED_BROKEN) ++fi ++]) ++ ++dnl ++dnl tests added for bashdb ++dnl ++ ++ ++AC_DEFUN([AM_PATH_LISPDIR], ++ [AC_ARG_WITH(lispdir, AC_HELP_STRING([--with-lispdir], [override the default lisp directory]), ++ [ lispdir="$withval" ++ AC_MSG_CHECKING([where .elc files should go]) ++ AC_MSG_RESULT([$lispdir])], ++ [ ++ # If set to t, that means we are running in a shell under Emacs. ++ # If you have an Emacs named "t", then use the full path. ++ test x"$EMACS" = xt && EMACS= ++ AC_CHECK_PROGS(EMACS, emacs xemacs, no) ++ if test $EMACS != "no"; then ++ if test x${lispdir+set} != xset; then ++ AC_CACHE_CHECK([where .elc files should go], [am_cv_lispdir], [dnl ++ am_cv_lispdir=`$EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) "\n")) (setq load-path (cdr load-path)))' | sed -n -e 's,/$,,' -e '/.*\/lib\/\(x\?emacs\/site-lisp\)$/{s,,${libdir}/\1,;p;q;}' -e '/.*\/share\/\(x\?emacs\/site-lisp\)$/{s,,${datadir}/\1,;p;q;}'` ++ if test -z "$am_cv_lispdir"; then ++ am_cv_lispdir='${datadir}/emacs/site-lisp' ++ fi ++ ]) ++ lispdir="$am_cv_lispdir" ++ fi ++ fi ++ ]) ++ AC_SUBST(lispdir) ++]) ++ ++dnl ++dnl tests added for gettext ++dnl ++# codeset.m4 serial AM1 (gettext-0.10.40) ++dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++AC_DEFUN([AM_LANGINFO_CODESET], ++[ ++ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, ++ [AC_TRY_LINK([#include ], ++ [char* cs = nl_langinfo(CODESET);], ++ am_cv_langinfo_codeset=yes, ++ am_cv_langinfo_codeset=no) ++ ]) ++ if test $am_cv_langinfo_codeset = yes; then ++ AC_DEFINE(HAVE_LANGINFO_CODESET, 1, ++ [Define if you have and nl_langinfo(CODESET).]) ++ fi ++]) ++# gettext.m4 serial 20 (gettext-0.12) ++dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++dnl ++dnl This file can can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Library General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Library General Public License, and the rest of the GNU ++dnl gettext package package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995-2000. ++dnl Bruno Haible , 2000-2003. ++ ++dnl Macro to add for using GNU gettext. ++ ++dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). ++dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The ++dnl default (if it is not specified or empty) is 'no-libtool'. ++dnl INTLSYMBOL should be 'external' for packages with no intl directory, ++dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. ++dnl If INTLSYMBOL is 'use-libtool', then a libtool library ++dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, ++dnl depending on --{enable,disable}-{shared,static} and on the presence of ++dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library ++dnl $(top_builddir)/intl/libintl.a will be created. ++dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext ++dnl implementations (in libc or libintl) without the ngettext() function ++dnl will be ignored. If NEEDSYMBOL is specified and is ++dnl 'need-formatstring-macros', then GNU gettext implementations that don't ++dnl support the ISO C 99 formatstring macros will be ignored. ++dnl INTLDIR is used to find the intl libraries. If empty, ++dnl the value `$(top_builddir)/intl/' is used. ++dnl ++dnl The result of the configuration is one of three cases: ++dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled ++dnl and used. ++dnl Catalog format: GNU --> install in $(datadir) ++dnl Catalog extension: .mo after installation, .gmo in source tree ++dnl 2) GNU gettext has been found in the system's C library. ++dnl Catalog format: GNU --> install in $(datadir) ++dnl Catalog extension: .mo after installation, .gmo in source tree ++dnl 3) No internationalization, always use English msgid. ++dnl Catalog format: none ++dnl Catalog extension: none ++dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. ++dnl The use of .gmo is historical (it was needed to avoid overwriting the ++dnl GNU format catalogs when building on a platform with an X/Open gettext), ++dnl but we keep it in order not to force irrelevant filename changes on the ++dnl maintainers. ++dnl ++AC_DEFUN([AM_GNU_GETTEXT], ++[ ++ dnl Argument checking. ++ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , ++ [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ++])])])])]) ++ ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , ++ [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ++])])])]) ++ define(gt_included_intl, ifelse([$1], [external], [no], [yes])) ++ define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) ++ ++ AC_REQUIRE([AM_PO_SUBDIRS])dnl ++ ifelse(gt_included_intl, yes, [ ++ AC_REQUIRE([AM_INTL_SUBDIR])dnl ++ ]) ++ ++ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. ++ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) ++ AC_REQUIRE([AC_LIB_RPATH]) ++ ++ dnl Sometimes libintl requires libiconv, so first search for libiconv. ++ dnl Ideally we would do this search only after the ++ dnl if test "$USE_NLS" = "yes"; then ++ dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then ++ dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT ++ dnl the configure script would need to contain the same shell code ++ dnl again, outside any 'if'. There are two solutions: ++ dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. ++ dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. ++ dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not ++ dnl documented, we avoid it. ++ ifelse(gt_included_intl, yes, , [ ++ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ++ ]) ++ ++ dnl Set USE_NLS. ++ AM_NLS ++ ++ ifelse(gt_included_intl, yes, [ ++ BUILD_INCLUDED_LIBINTL=no ++ USE_INCLUDED_LIBINTL=no ++ ]) ++ LIBINTL= ++ LTLIBINTL= ++ POSUB= ++ ++ dnl If we use NLS figure out what method ++ if test "$USE_NLS" = "yes"; then ++ gt_use_preinstalled_gnugettext=no ++ ifelse(gt_included_intl, yes, [ ++ AC_MSG_CHECKING([whether included gettext is requested]) ++ AC_ARG_WITH(included-gettext, ++ [ --with-included-gettext use the GNU gettext library included here], ++ nls_cv_force_use_gnu_gettext=$withval, ++ nls_cv_force_use_gnu_gettext=no) ++ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) ++ ++ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" ++ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ++ ]) ++ dnl User does not insist on using GNU NLS library. Figure out what ++ dnl to use. If GNU gettext is available we use this. Else we have ++ dnl to fall back to GNU NLS library. ++ ++ dnl Add a version number to the cache macros. ++ define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) ++ define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) ++ define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) ++ ++ AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, ++ [AC_TRY_LINK([#include ++]ifelse([$2], [need-formatstring-macros], ++[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION ++#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) ++#endif ++changequote(,)dnl ++typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; ++changequote([,])dnl ++], [])[extern int _nl_msg_cat_cntr; ++extern int *_nl_domain_bindings;], ++ [bindtextdomain ("", ""); ++return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], ++ gt_cv_func_gnugettext_libc=yes, ++ gt_cv_func_gnugettext_libc=no)]) ++ ++ if test "$gt_cv_func_gnugettext_libc" != "yes"; then ++ dnl Sometimes libintl requires libiconv, so first search for libiconv. ++ ifelse(gt_included_intl, yes, , [ ++ AM_ICONV_LINK ++ ]) ++ dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL ++ dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) ++ dnl because that would add "-liconv" to LIBINTL and LTLIBINTL ++ dnl even if libiconv doesn't exist. ++ AC_LIB_LINKFLAGS_BODY([intl]) ++ AC_CACHE_CHECK([for GNU gettext in libintl], ++ gt_cv_func_gnugettext_libintl, ++ [gt_save_CPPFLAGS="$CPPFLAGS" ++ CPPFLAGS="$CPPFLAGS $INCINTL" ++ gt_save_LIBS="$LIBS" ++ LIBS="$LIBS $LIBINTL" ++ dnl Now see whether libintl exists and does not depend on libiconv. ++ AC_TRY_LINK([#include ++]ifelse([$2], [need-formatstring-macros], ++[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION ++#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) ++#endif ++changequote(,)dnl ++typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; ++changequote([,])dnl ++], [])[extern int _nl_msg_cat_cntr; ++extern ++#ifdef __cplusplus ++"C" ++#endif ++const char *_nl_expand_alias ();], ++ [bindtextdomain ("", ""); ++return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], ++ gt_cv_func_gnugettext_libintl=yes, ++ gt_cv_func_gnugettext_libintl=no) ++ dnl Now see whether libintl exists and depends on libiconv. ++ if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then ++ LIBS="$LIBS $LIBICONV" ++ AC_TRY_LINK([#include ++]ifelse([$2], [need-formatstring-macros], ++[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION ++#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) ++#endif ++changequote(,)dnl ++typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; ++changequote([,])dnl ++], [])[extern int _nl_msg_cat_cntr; ++extern ++#ifdef __cplusplus ++"C" ++#endif ++const char *_nl_expand_alias ();], ++ [bindtextdomain ("", ""); ++return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], ++ [LIBINTL="$LIBINTL $LIBICONV" ++ LTLIBINTL="$LTLIBINTL $LTLIBICONV" ++ gt_cv_func_gnugettext_libintl=yes ++ ]) ++ fi ++ CPPFLAGS="$gt_save_CPPFLAGS" ++ LIBS="$gt_save_LIBS"]) ++ fi ++ ++ dnl If an already present or preinstalled GNU gettext() is found, ++ dnl use it. But if this macro is used in GNU gettext, and GNU ++ dnl gettext is already preinstalled in libintl, we update this ++ dnl libintl. (Cf. the install rule in intl/Makefile.in.) ++ if test "$gt_cv_func_gnugettext_libc" = "yes" \ ++ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ ++ && test "$PACKAGE" != gettext-runtime \ ++ && test "$PACKAGE" != gettext-tools; }; then ++ gt_use_preinstalled_gnugettext=yes ++ else ++ dnl Reset the values set by searching for libintl. ++ LIBINTL= ++ LTLIBINTL= ++ INCINTL= ++ fi ++ ++ ifelse(gt_included_intl, yes, [ ++ if test "$gt_use_preinstalled_gnugettext" != "yes"; then ++ dnl GNU gettext is not found in the C library. ++ dnl Fall back on included GNU gettext library. ++ nls_cv_use_gnu_gettext=yes ++ fi ++ fi ++ ++ if test "$nls_cv_use_gnu_gettext" = "yes"; then ++ dnl Mark actions used to generate GNU NLS library. ++ BUILD_INCLUDED_LIBINTL=yes ++ USE_INCLUDED_LIBINTL=yes ++ LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" ++ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" ++ LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` ++ fi ++ ++ if test "$gt_use_preinstalled_gnugettext" = "yes" \ ++ || test "$nls_cv_use_gnu_gettext" = "yes"; then ++ dnl Mark actions to use GNU gettext tools. ++ CATOBJEXT=.gmo ++ fi ++ ]) ++ ++ if test "$gt_use_preinstalled_gnugettext" = "yes" \ ++ || test "$nls_cv_use_gnu_gettext" = "yes"; then ++ AC_DEFINE(ENABLE_NLS, 1, ++ [Define to 1 if translation of program messages to the user's native language ++ is requested.]) ++ else ++ USE_NLS=no ++ fi ++ fi ++ ++ AC_MSG_CHECKING([whether to use NLS]) ++ AC_MSG_RESULT([$USE_NLS]) ++ if test "$USE_NLS" = "yes"; then ++ AC_MSG_CHECKING([where the gettext function comes from]) ++ if test "$gt_use_preinstalled_gnugettext" = "yes"; then ++ if test "$gt_cv_func_gnugettext_libintl" = "yes"; then ++ gt_source="external libintl" ++ else ++ gt_source="libc" ++ fi ++ else ++ gt_source="included intl directory" ++ fi ++ AC_MSG_RESULT([$gt_source]) ++ fi ++ ++ if test "$USE_NLS" = "yes"; then ++ ++ if test "$gt_use_preinstalled_gnugettext" = "yes"; then ++ if test "$gt_cv_func_gnugettext_libintl" = "yes"; then ++ AC_MSG_CHECKING([how to link with libintl]) ++ AC_MSG_RESULT([$LIBINTL]) ++ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) ++ fi ++ ++ dnl For backward compatibility. Some packages may be using this. ++ AC_DEFINE(HAVE_GETTEXT, 1, ++ [Define if the GNU gettext() function is already present or preinstalled.]) ++ AC_DEFINE(HAVE_DCGETTEXT, 1, ++ [Define if the GNU dcgettext() function is already present or preinstalled.]) ++ fi ++ ++ dnl We need to process the po/ directory. ++ POSUB=po ++ fi ++ ++ ifelse(gt_included_intl, yes, [ ++ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL ++ dnl to 'yes' because some of the testsuite requires it. ++ if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then ++ BUILD_INCLUDED_LIBINTL=yes ++ fi ++ ++ dnl Make all variables we use known to autoconf. ++ AC_SUBST(BUILD_INCLUDED_LIBINTL) ++ AC_SUBST(USE_INCLUDED_LIBINTL) ++ AC_SUBST(CATOBJEXT) ++ ++ dnl For backward compatibility. Some configure.ins may be using this. ++ nls_cv_header_intl= ++ nls_cv_header_libgt= ++ ++ dnl For backward compatibility. Some Makefiles may be using this. ++ DATADIRNAME=share ++ AC_SUBST(DATADIRNAME) ++ ++ dnl For backward compatibility. Some Makefiles may be using this. ++ INSTOBJEXT=.mo ++ AC_SUBST(INSTOBJEXT) ++ ++ dnl For backward compatibility. Some Makefiles may be using this. ++ GENCAT=gencat ++ AC_SUBST(GENCAT) ++ ++ dnl For backward compatibility. Some Makefiles may be using this. ++ if test "$USE_INCLUDED_LIBINTL" = yes; then ++ INTLOBJS="\$(GETTOBJS)" ++ fi ++ AC_SUBST(INTLOBJS) ++ ++ dnl Enable libtool support if the surrounding package wishes it. ++ INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix ++ AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) ++ ]) ++ ++ dnl For backward compatibility. Some Makefiles may be using this. ++ INTLLIBS="$LIBINTL" ++ AC_SUBST(INTLLIBS) ++ ++ dnl Make all documented variables known to autoconf. ++ AC_SUBST(LIBINTL) ++ AC_SUBST(LTLIBINTL) ++ AC_SUBST(POSUB) ++]) ++ ++ ++dnl Checks for all prerequisites of the intl subdirectory, ++dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, ++dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. ++AC_DEFUN([AM_INTL_SUBDIR], ++[ ++ AC_REQUIRE([AC_PROG_INSTALL])dnl ++ AC_REQUIRE([AM_MKINSTALLDIRS])dnl ++ AC_REQUIRE([AC_PROG_CC])dnl ++ AC_REQUIRE([AC_CANONICAL_HOST])dnl ++ AC_REQUIRE([AC_PROG_RANLIB])dnl ++ AC_REQUIRE([AC_ISC_POSIX])dnl ++ AC_REQUIRE([AC_HEADER_STDC])dnl ++ AC_REQUIRE([AC_C_CONST])dnl ++ AC_REQUIRE([AC_C_INLINE])dnl ++ AC_REQUIRE([AC_TYPE_OFF_T])dnl ++ AC_REQUIRE([AC_TYPE_SIZE_T])dnl ++ AC_REQUIRE([AC_FUNC_ALLOCA])dnl ++ AC_REQUIRE([AC_FUNC_MMAP])dnl ++ AC_REQUIRE([jm_GLIBC21])dnl ++ AC_REQUIRE([gt_INTDIV0])dnl ++ AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl ++ AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl ++ AC_REQUIRE([gt_INTTYPES_PRI])dnl ++ ++ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ ++stdlib.h string.h unistd.h sys/param.h]) ++ AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ ++geteuid getgid getuid mempcpy munmap putenv setenv setlocale localeconv stpcpy \ ++strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \ ++__fsetlocking]) ++ ++ AM_ICONV ++ AM_LANGINFO_CODESET ++ if test $ac_cv_header_locale_h = yes; then ++ AM_LC_MESSAGES ++ fi ++ ++ dnl intl/plural.c is generated from intl/plural.y. It requires bison, ++ dnl because plural.y uses bison specific features. It requires at least ++ dnl bison-1.26 because earlier versions generate a plural.c that doesn't ++ dnl compile. ++ dnl bison is only needed for the maintainer (who touches plural.y). But in ++ dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put ++ dnl the rule in general Makefile. Now, some people carelessly touch the ++ dnl files or have a broken "make" program, hence the plural.c rule will ++ dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not ++ dnl present or too old. ++ AC_CHECK_PROGS([INTLBISON], [bison]) ++ if test -z "$INTLBISON"; then ++ ac_verc_fail=yes ++ else ++ dnl Found it, now check the version. ++ AC_MSG_CHECKING([version of bison]) ++changequote(<<,>>)dnl ++ ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` ++ case $ac_prog_version in ++ '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; ++ 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) ++changequote([,])dnl ++ ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; ++ *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; ++ esac ++ AC_MSG_RESULT([$ac_prog_version]) ++ fi ++ if test $ac_verc_fail = yes; then ++ INTLBISON=: ++ fi ++]) ++ ++ ++dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) ++AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) ++# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) ++dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++# Test for the GNU C Library, version 2.1 or newer. ++# From Bruno Haible. ++ ++AC_DEFUN([jm_GLIBC21], ++ [ ++ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, ++ ac_cv_gnu_library_2_1, ++ [AC_EGREP_CPP([Lucky GNU user], ++ [ ++#include ++#ifdef __GNU_LIBRARY__ ++ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) ++ Lucky GNU user ++ #endif ++#endif ++ ], ++ ac_cv_gnu_library_2_1=yes, ++ ac_cv_gnu_library_2_1=no) ++ ] ++ ) ++ AC_SUBST(GLIBC21) ++ GLIBC21="$ac_cv_gnu_library_2_1" ++ ] ++) ++# iconv.m4 serial AM4 (gettext-0.11.3) ++dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], ++[ ++ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. ++ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) ++ AC_REQUIRE([AC_LIB_RPATH]) ++ ++ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV ++ dnl accordingly. ++ AC_LIB_LINKFLAGS_BODY([iconv]) ++]) ++ ++AC_DEFUN([AM_ICONV_LINK], ++[ ++ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and ++ dnl those with the standalone portable GNU libiconv installed). ++ ++ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV ++ dnl accordingly. ++ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ++ ++ dnl Add $INCICONV to CPPFLAGS before performing the following checks, ++ dnl because if the user has installed libiconv and not disabled its use ++ dnl via --without-libiconv-prefix, he wants to use it. The first ++ dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. ++ am_save_CPPFLAGS="$CPPFLAGS" ++ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) ++ ++ AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ ++ am_cv_func_iconv="no, consider installing GNU libiconv" ++ am_cv_lib_iconv=no ++ AC_TRY_LINK([#include ++#include ], ++ [iconv_t cd = iconv_open("",""); ++ iconv(cd,NULL,NULL,NULL,NULL); ++ iconv_close(cd);], ++ am_cv_func_iconv=yes) ++ if test "$am_cv_func_iconv" != yes; then ++ am_save_LIBS="$LIBS" ++ LIBS="$LIBS $LIBICONV" ++ AC_TRY_LINK([#include ++#include ], ++ [iconv_t cd = iconv_open("",""); ++ iconv(cd,NULL,NULL,NULL,NULL); ++ iconv_close(cd);], ++ am_cv_lib_iconv=yes ++ am_cv_func_iconv=yes) ++ LIBS="$am_save_LIBS" ++ fi ++ ]) ++ if test "$am_cv_func_iconv" = yes; then ++ AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) ++ fi ++ if test "$am_cv_lib_iconv" = yes; then ++ AC_MSG_CHECKING([how to link with libiconv]) ++ AC_MSG_RESULT([$LIBICONV]) ++ else ++ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV ++ dnl either. ++ CPPFLAGS="$am_save_CPPFLAGS" ++ LIBICONV= ++ LTLIBICONV= ++ fi ++ AC_SUBST(LIBICONV) ++ AC_SUBST(LTLIBICONV) ++]) ++ ++AC_DEFUN([AM_ICONV], ++[ ++ AM_ICONV_LINK ++ if test "$am_cv_func_iconv" = yes; then ++ AC_MSG_CHECKING([for iconv declaration]) ++ AC_CACHE_VAL(am_cv_proto_iconv, [ ++ AC_TRY_COMPILE([ +#include - - typedef RETSIGTYPE sigfunc(); - -@@ -1335,6 +1360,7 @@ int s; - nsigint++; - } - -+int - main() - { - nsigint = 0; -@@ -1418,8 +1444,11 @@ AC_CACHE_VAL(bash_cv_sys_named_pipes, - #ifdef HAVE_UNISTD_H - #include - #endif ++#include ++extern ++#ifdef __cplusplus ++"C" ++#endif ++#if defined(__STDC__) || defined(__cplusplus) ++size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); ++#else ++size_t iconv(); ++#endif ++], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") ++ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) ++ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` ++ AC_MSG_RESULT([$]{ac_t:- ++ }[$]am_cv_proto_iconv) ++ AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, ++ [Define as const if the declaration of iconv() needs const.]) ++ fi ++]) ++# intdiv0.m4 serial 1 (gettext-0.11.3) ++dnl Copyright (C) 2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++AC_DEFUN([gt_INTDIV0], ++[ ++ AC_REQUIRE([AC_PROG_CC])dnl ++ AC_REQUIRE([AC_CANONICAL_HOST])dnl ++ ++ AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], ++ gt_cv_int_divbyzero_sigfpe, ++ [ ++ AC_TRY_RUN([ ++#include ++#include ++ ++static void ++#ifdef __cplusplus ++sigfpe_handler (int sig) ++#else ++sigfpe_handler (sig) int sig; ++#endif ++{ ++ /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ ++ exit (sig != SIGFPE); ++} ++ ++int x = 1; ++int y = 0; ++int z; ++int nan; ++ ++int main () ++{ ++ signal (SIGFPE, sigfpe_handler); ++/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ ++#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) ++ signal (SIGTRAP, sigfpe_handler); ++#endif ++/* Linux/SPARC yields signal SIGILL. */ ++#if defined (__sparc__) && defined (__linux__) ++ signal (SIGILL, sigfpe_handler); ++#endif ++ ++ z = x / y; ++ nan = y / y; ++ exit (1); ++} ++], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, ++ [ ++ # Guess based on the CPU. ++ case "$host_cpu" in ++ alpha* | i[34567]86 | m68k | s390*) ++ gt_cv_int_divbyzero_sigfpe="guessing yes";; ++ *) ++ gt_cv_int_divbyzero_sigfpe="guessing no";; ++ esac ++ ]) ++ ]) ++ case "$gt_cv_int_divbyzero_sigfpe" in ++ *yes) value=1;; ++ *) value=0;; ++ esac ++ AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, ++ [Define if integer division by zero raises signal SIGFPE.]) ++]) ++# inttypes.m4 serial 1 (gettext-0.11.4) ++dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Paul Eggert. ++ ++# Define HAVE_INTTYPES_H if exists and doesn't clash with ++# . ++ ++AC_DEFUN([gt_HEADER_INTTYPES_H], ++[ ++ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, ++ [ ++ AC_TRY_COMPILE( ++ [#include ++#include ], ++ [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) ++ ]) ++ if test $gt_cv_header_inttypes_h = yes; then ++ AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, ++ [Define if exists and doesn't clash with .]) ++ fi ++]) ++# inttypes_h.m4 serial 5 (gettext-0.12) ++dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Paul Eggert. ++ ++# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, ++# doesn't clash with , and declares uintmax_t. ++ ++AC_DEFUN([jm_AC_HEADER_INTTYPES_H], ++[ ++ AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, ++ [AC_TRY_COMPILE( ++ [#include ++#include ], ++ [uintmax_t i = (uintmax_t) -1;], ++ jm_ac_cv_header_inttypes_h=yes, ++ jm_ac_cv_header_inttypes_h=no)]) ++ if test $jm_ac_cv_header_inttypes_h = yes; then ++ AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, ++ [Define if exists, doesn't clash with , ++ and declares uintmax_t. ]) ++ fi ++]) ++# inttypes-pri.m4 serial 1 (gettext-0.11.4) ++dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++# Define PRI_MACROS_BROKEN if exists and defines the PRI* ++# macros to non-string values. This is the case on AIX 4.3.3. ++ ++AC_DEFUN([gt_INTTYPES_PRI], ++[ ++ AC_REQUIRE([gt_HEADER_INTTYPES_H]) ++ if test $gt_cv_header_inttypes_h = yes; then ++ AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], ++ gt_cv_inttypes_pri_broken, ++ [ ++ AC_TRY_COMPILE([#include ++#ifdef PRId32 ++char *p = PRId32; ++#endif ++], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) ++ ]) ++ fi ++ if test "$gt_cv_inttypes_pri_broken" = yes; then ++ AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, ++ [Define if exists and defines unusable PRI* macros.]) ++ fi ++]) ++# isc-posix.m4 serial 2 (gettext-0.11.2) ++dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. ++ ++# This test replaces the one in autoconf. ++# Currently this macro should have the same name as the autoconf macro ++# because gettext's gettext.m4 (distributed in the automake package) ++# still uses it. Otherwise, the use in gettext.m4 makes autoheader ++# give these diagnostics: ++# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX ++# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX ++ ++undefine([AC_ISC_POSIX]) ++ ++AC_DEFUN([AC_ISC_POSIX], ++ [ ++ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. ++ AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ++ ] ++) ++# lcmessage.m4 serial 3 (gettext-0.11.3) ++dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++dnl ++dnl This file can can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Library General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Library General Public License, and the rest of the GNU ++dnl gettext package package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995. ++ ++# Check whether LC_MESSAGES is available in . ++ ++AC_DEFUN([AM_LC_MESSAGES], ++[ ++ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, ++ [AC_TRY_LINK([#include ], [return LC_MESSAGES], ++ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) ++ if test $am_cv_val_LC_MESSAGES = yes; then ++ AC_DEFINE(HAVE_LC_MESSAGES, 1, ++ [Define if your file defines LC_MESSAGES.]) ++ fi ++]) ++# lib-ld.m4 serial 2 (gettext-0.12) ++dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl Subroutines of libtool.m4, ++dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision ++dnl with libtool.m4. ++ ++dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. ++AC_DEFUN([AC_LIB_PROG_LD_GNU], ++[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, ++[# I'd rather use --version here, but apparently some GNU ld's only accept -v. ++if $LD -v 2>&1 &5; then ++ acl_cv_prog_gnu_ld=yes ++else ++ acl_cv_prog_gnu_ld=no ++fi]) ++with_gnu_ld=$acl_cv_prog_gnu_ld ++]) ++ ++dnl From libtool-1.4. Sets the variable LD. ++AC_DEFUN([AC_LIB_PROG_LD], ++[AC_ARG_WITH(gnu-ld, ++[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], ++test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ AC_MSG_CHECKING([for ld used by GCC]) ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [[\\/]* | [A-Za-z]:[\\/]*)] ++ [re_direlt='/[^/][^/]*/\.\./'] ++ # Canonicalize the path of ld ++ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ AC_MSG_CHECKING([for GNU ld]) ++else ++ AC_MSG_CHECKING([for non-GNU ld]) ++fi ++AC_CACHE_VAL(acl_cv_path_LD, ++[if test -z "$LD"; then ++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" ++ for ac_dir in $PATH; do ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ acl_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some GNU ld's only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then ++ test "$with_gnu_ld" != no && break ++ else ++ test "$with_gnu_ld" != yes && break ++ fi ++ fi ++ done ++ IFS="$ac_save_ifs" ++else ++ acl_cv_path_LD="$LD" # Let the user override the test with a path. ++fi]) ++LD="$acl_cv_path_LD" ++if test -n "$LD"; then ++ AC_MSG_RESULT($LD) ++else ++ AC_MSG_RESULT(no) ++fi ++test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) ++AC_LIB_PROG_LD_GNU ++]) ++# lib-link.m4 serial 4 (gettext-0.12) ++dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and ++dnl the libraries corresponding to explicit and implicit dependencies. ++dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and ++dnl augments the CPPFLAGS variable. ++AC_DEFUN([AC_LIB_LINKFLAGS], ++[ ++ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) ++ AC_REQUIRE([AC_LIB_RPATH]) ++ define([Name],[translit([$1],[./-], [___])]) ++ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], ++ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) ++ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ ++ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ++ ac_cv_lib[]Name[]_libs="$LIB[]NAME" ++ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ++ ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ++ ]) ++ LIB[]NAME="$ac_cv_lib[]Name[]_libs" ++ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" ++ INC[]NAME="$ac_cv_lib[]Name[]_cppflags" ++ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) ++ AC_SUBST([LIB]NAME) ++ AC_SUBST([LTLIB]NAME) ++ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the ++ dnl results of this search when this library appears as a dependency. ++ HAVE_LIB[]NAME=yes ++ undefine([Name]) ++ undefine([NAME]) ++]) ++ ++dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) ++dnl searches for libname and the libraries corresponding to explicit and ++dnl implicit dependencies, together with the specified include files and ++dnl the ability to compile and link the specified testcode. If found, it ++dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and ++dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and ++dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs ++dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. ++AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], ++[ ++ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) ++ AC_REQUIRE([AC_LIB_RPATH]) ++ define([Name],[translit([$1],[./-], [___])]) ++ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], ++ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) ++ ++ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME ++ dnl accordingly. ++ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ++ ++ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, ++ dnl because if the user has installed lib[]Name and not disabled its use ++ dnl via --without-lib[]Name-prefix, he wants to use it. ++ ac_save_CPPFLAGS="$CPPFLAGS" ++ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) ++ ++ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ++ ac_save_LIBS="$LIBS" ++ LIBS="$LIBS $LIB[]NAME" ++ AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) ++ LIBS="$ac_save_LIBS" ++ ]) ++ if test "$ac_cv_lib[]Name" = yes; then ++ HAVE_LIB[]NAME=yes ++ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) ++ AC_MSG_CHECKING([how to link with lib[]$1]) ++ AC_MSG_RESULT([$LIB[]NAME]) ++ else ++ HAVE_LIB[]NAME=no ++ dnl If $LIB[]NAME didn't lead to a usable library, we don't need ++ dnl $INC[]NAME either. ++ CPPFLAGS="$ac_save_CPPFLAGS" ++ LIB[]NAME= ++ LTLIB[]NAME= ++ fi ++ AC_SUBST([HAVE_LIB]NAME) ++ AC_SUBST([LIB]NAME) ++ AC_SUBST([LTLIB]NAME) ++ undefine([Name]) ++ undefine([NAME]) ++]) ++ ++dnl Determine the platform dependent parameters needed to use rpath: ++dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, ++dnl hardcode_direct, hardcode_minus_L. ++AC_DEFUN([AC_LIB_RPATH], ++[ ++ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS ++ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host ++ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir ++ AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ ++ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ++ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh ++ . ./conftest.sh ++ rm -f ./conftest.sh ++ acl_cv_rpath=done ++ ]) ++ wl="$acl_cv_wl" ++ libext="$acl_cv_libext" ++ shlibext="$acl_cv_shlibext" ++ hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" ++ hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" ++ hardcode_direct="$acl_cv_hardcode_direct" ++ hardcode_minus_L="$acl_cv_hardcode_minus_L" ++ dnl Determine whether the user wants rpath handling at all. ++ AC_ARG_ENABLE(rpath, ++ [ --disable-rpath do not hardcode runtime library paths], ++ :, enable_rpath=yes) ++]) ++ ++dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and ++dnl the libraries corresponding to explicit and implicit dependencies. ++dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. ++AC_DEFUN([AC_LIB_LINKFLAGS_BODY], ++[ ++ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], ++ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) ++ dnl By default, look in $includedir and $libdir. ++ use_additional=yes ++ AC_LIB_WITH_FINAL_PREFIX([ ++ eval additional_includedir=\"$includedir\" ++ eval additional_libdir=\"$libdir\" ++ ]) ++ AC_LIB_ARG_WITH([lib$1-prefix], ++[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib ++ --without-lib$1-prefix don't search for lib$1 in includedir and libdir], ++[ ++ if test "X$withval" = "Xno"; then ++ use_additional=no ++ else ++ if test "X$withval" = "X"; then ++ AC_LIB_WITH_FINAL_PREFIX([ ++ eval additional_includedir=\"$includedir\" ++ eval additional_libdir=\"$libdir\" ++ ]) ++ else ++ additional_includedir="$withval/include" ++ additional_libdir="$withval/lib" ++ fi ++ fi ++]) ++ dnl Search the library and its dependencies in $additional_libdir and ++ dnl $LDFLAGS. Using breadth-first-seach. ++ LIB[]NAME= ++ LTLIB[]NAME= ++ INC[]NAME= ++ rpathdirs= ++ ltrpathdirs= ++ names_already_handled= ++ names_next_round='$1 $2' ++ while test -n "$names_next_round"; do ++ names_this_round="$names_next_round" ++ names_next_round= ++ for name in $names_this_round; do ++ already_handled= ++ for n in $names_already_handled; do ++ if test "$n" = "$name"; then ++ already_handled=yes ++ break ++ fi ++ done ++ if test -z "$already_handled"; then ++ names_already_handled="$names_already_handled $name" ++ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS ++ dnl or AC_LIB_HAVE_LINKFLAGS call. ++ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` ++ eval value=\"\$HAVE_LIB$uppername\" ++ if test -n "$value"; then ++ if test "$value" = yes; then ++ eval value=\"\$LIB$uppername\" ++ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" ++ eval value=\"\$LTLIB$uppername\" ++ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" ++ else ++ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined ++ dnl that this library doesn't exist. So just drop it. ++ : ++ fi ++ else ++ dnl Search the library lib$name in $additional_libdir and $LDFLAGS ++ dnl and the already constructed $LIBNAME/$LTLIBNAME. ++ found_dir= ++ found_la= ++ found_so= ++ found_a= ++ if test $use_additional = yes; then ++ if test "X$prefer_shared" = "Xyes" && test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then ++ found_dir="$additional_libdir" ++ found_so="$additional_libdir/lib$name.$shlibext" ++ if test -f "$additional_libdir/lib$name.la"; then ++ found_la="$additional_libdir/lib$name.la" ++ fi ++ else ++ if test -f "$additional_libdir/lib$name.$libext"; then ++ found_dir="$additional_libdir" ++ found_a="$additional_libdir/lib$name.$libext" ++ if test -f "$additional_libdir/lib$name.la"; then ++ found_la="$additional_libdir/lib$name.la" ++ fi ++ fi ++ fi ++ fi ++ if test "X$found_dir" = "X"; then ++ for x in $LDFLAGS $LTLIB[]NAME; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ case "$x" in ++ -L*) ++ dir=`echo "X$x" | sed -e 's/^X-L//'` ++ if test "X$prefer_shared" = "Xyes" && test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then ++ found_dir="$dir" ++ found_so="$dir/lib$name.$shlibext" ++ if test -f "$dir/lib$name.la"; then ++ found_la="$dir/lib$name.la" ++ fi ++ else ++ if test -f "$dir/lib$name.$libext"; then ++ found_dir="$dir" ++ found_a="$dir/lib$name.$libext" ++ if test -f "$dir/lib$name.la"; then ++ found_la="$dir/lib$name.la" ++ fi ++ fi ++ fi ++ ;; ++ esac ++ if test "X$found_dir" != "X"; then ++ break ++ fi ++ done ++ fi ++ if test "X$found_dir" != "X"; then ++ dnl Found the library. ++ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" ++ if test "X$found_so" != "X"; then ++ dnl Linking with a shared library. We attempt to hardcode its ++ dnl directory into the executable's runpath, unless it's the ++ dnl standard /usr/lib. ++ if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then ++ dnl No hardcoding is needed. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" ++ else ++ dnl Use an explicit option to hardcode DIR into the resulting ++ dnl binary. ++ dnl Potentially add DIR to ltrpathdirs. ++ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. ++ haveit= ++ for x in $ltrpathdirs; do ++ if test "X$x" = "X$found_dir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ ltrpathdirs="$ltrpathdirs $found_dir" ++ fi ++ dnl The hardcoding into $LIBNAME is system dependent. ++ if test "$hardcode_direct" = yes; then ++ dnl Using DIR/libNAME.so during linking hardcodes DIR into the ++ dnl resulting binary. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" ++ else ++ if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then ++ dnl Use an explicit option to hardcode DIR into the resulting ++ dnl binary. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" ++ dnl Potentially add DIR to rpathdirs. ++ dnl The rpathdirs will be appended to $LIBNAME at the end. ++ haveit= ++ for x in $rpathdirs; do ++ if test "X$x" = "X$found_dir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ rpathdirs="$rpathdirs $found_dir" ++ fi ++ else ++ dnl Rely on "-L$found_dir". ++ dnl But don't add it if it's already contained in the LDFLAGS ++ dnl or the already constructed $LIBNAME ++ haveit= ++ for x in $LDFLAGS $LIB[]NAME; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-L$found_dir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" ++ fi ++ if test "$hardcode_minus_L" != no; then ++ dnl FIXME: Not sure whether we should use ++ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" ++ dnl here. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" ++ else ++ dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH ++ dnl here, because this doesn't fit in flags passed to the ++ dnl compiler. So give up. No hardcoding. This affects only ++ dnl very old systems. ++ dnl FIXME: Not sure whether we should use ++ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" ++ dnl here. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" ++ fi ++ fi ++ fi ++ fi ++ else ++ if test "X$found_a" != "X"; then ++ dnl Linking with a static library. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" ++ else ++ dnl We shouldn't come here, but anyway it's good to have a ++ dnl fallback. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" ++ fi ++ fi ++ dnl Assume the include files are nearby. ++ additional_includedir= ++ case "$found_dir" in ++ */lib | */lib/) ++ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` ++ additional_includedir="$basedir/include" ++ ;; ++ esac ++ if test "X$additional_includedir" != "X"; then ++ dnl Potentially add $additional_includedir to $INCNAME. ++ dnl But don't add it ++ dnl 1. if it's the standard /usr/include, ++ dnl 2. if it's /usr/local/include and we are using GCC on Linux, ++ dnl 3. if it's already present in $CPPFLAGS or the already ++ dnl constructed $INCNAME, ++ dnl 4. if it doesn't exist as a directory. ++ if test "X$additional_includedir" != "X/usr/include"; then ++ haveit= ++ if test "X$additional_includedir" = "X/usr/local/include"; then ++ if test -n "$GCC"; then ++ case $host_os in ++ linux*) haveit=yes;; ++ esac ++ fi ++ fi ++ if test -z "$haveit"; then ++ for x in $CPPFLAGS $INC[]NAME; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-I$additional_includedir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ if test -d "$additional_includedir"; then ++ dnl Really add $additional_includedir to $INCNAME. ++ INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" ++ fi ++ fi ++ fi ++ fi ++ fi ++ dnl Look for dependencies. ++ if test -n "$found_la"; then ++ dnl Read the .la file. It defines the variables ++ dnl dlname, library_names, old_library, dependency_libs, current, ++ dnl age, revision, installed, dlopen, dlpreopen, libdir. ++ save_libdir="$libdir" ++ case "$found_la" in ++ */* | *\\*) . "$found_la" ;; ++ *) . "./$found_la" ;; ++ esac ++ libdir="$save_libdir" ++ dnl We use only dependency_libs. ++ for dep in $dependency_libs; do ++ case "$dep" in ++ -L*) ++ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` ++ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. ++ dnl But don't add it ++ dnl 1. if it's the standard /usr/lib, ++ dnl 2. if it's /usr/local/lib and we are using GCC on Linux, ++ dnl 3. if it's already present in $LDFLAGS or the already ++ dnl constructed $LIBNAME, ++ dnl 4. if it doesn't exist as a directory. ++ if test "X$additional_libdir" != "X/usr/lib"; then ++ haveit= ++ if test "X$additional_libdir" = "X/usr/local/lib"; then ++ if test -n "$GCC"; then ++ case $host_os in ++ linux*) haveit=yes;; ++ esac ++ fi ++ fi ++ if test -z "$haveit"; then ++ haveit= ++ for x in $LDFLAGS $LIB[]NAME; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-L$additional_libdir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ if test -d "$additional_libdir"; then ++ dnl Really add $additional_libdir to $LIBNAME. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" ++ fi ++ fi ++ haveit= ++ for x in $LDFLAGS $LTLIB[]NAME; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-L$additional_libdir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ if test -d "$additional_libdir"; then ++ dnl Really add $additional_libdir to $LTLIBNAME. ++ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" ++ fi ++ fi ++ fi ++ fi ++ ;; ++ -R*) ++ dir=`echo "X$dep" | sed -e 's/^X-R//'` ++ if test "$enable_rpath" != no; then ++ dnl Potentially add DIR to rpathdirs. ++ dnl The rpathdirs will be appended to $LIBNAME at the end. ++ haveit= ++ for x in $rpathdirs; do ++ if test "X$x" = "X$dir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ rpathdirs="$rpathdirs $dir" ++ fi ++ dnl Potentially add DIR to ltrpathdirs. ++ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. ++ haveit= ++ for x in $ltrpathdirs; do ++ if test "X$x" = "X$dir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ ltrpathdirs="$ltrpathdirs $dir" ++ fi ++ fi ++ ;; ++ -l*) ++ dnl Handle this in the next round. ++ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ++ ;; ++ *.la) ++ dnl Handle this in the next round. Throw away the .la's ++ dnl directory; it is already contained in a preceding -L ++ dnl option. ++ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ++ ;; ++ *) ++ dnl Most likely an immediate library name. ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" ++ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ++ ;; ++ esac ++ done ++ fi ++ else ++ dnl Didn't find the library; assume it is in the system directories ++ dnl known to the linker and runtime loader. (All the system ++ dnl directories known to the linker should also be known to the ++ dnl runtime loader, otherwise the system is severely misconfigured.) ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" ++ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" ++ fi ++ fi ++ fi ++ done ++ done ++ if test "X$rpathdirs" != "X"; then ++ if test -n "$hardcode_libdir_separator"; then ++ dnl Weird platform: only the last -rpath option counts, the user must ++ dnl pass all path elements in one option. We can arrange that for a ++ dnl single library, but not when more than one $LIBNAMEs are used. ++ alldirs= ++ for found_dir in $rpathdirs; do ++ alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" ++ done ++ dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. ++ acl_save_libdir="$libdir" ++ libdir="$alldirs" ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ libdir="$acl_save_libdir" ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" ++ else ++ dnl The -rpath options are cumulative. ++ for found_dir in $rpathdirs; do ++ acl_save_libdir="$libdir" ++ libdir="$found_dir" ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ libdir="$acl_save_libdir" ++ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" ++ done ++ fi ++ fi ++ if test "X$ltrpathdirs" != "X"; then ++ dnl When using libtool, the option that works for both libraries and ++ dnl executables is -R. The -R options are cumulative. ++ for found_dir in $ltrpathdirs; do ++ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" ++ done ++ fi ++]) ++ ++dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, ++dnl unless already present in VAR. ++dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes ++dnl contains two or three consecutive elements that belong together. ++AC_DEFUN([AC_LIB_APPENDTOVAR], ++[ ++ for element in [$2]; do ++ haveit= ++ for x in $[$1]; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X$element"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ [$1]="${[$1]}${[$1]:+ }$element" ++ fi ++ done ++]) ++# lib-prefix.m4 serial 2 (gettext-0.12) ++dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Bruno Haible. ++ ++dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and ++dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't ++dnl require excessive bracketing. ++ifdef([AC_HELP_STRING], ++[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], ++[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) ++ ++dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed ++dnl to access previously installed libraries. The basic assumption is that ++dnl a user will want packages to use other packages he previously installed ++dnl with the same --prefix option. ++dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate ++dnl libraries, but is otherwise very convenient. ++AC_DEFUN([AC_LIB_PREFIX], ++[ ++ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) ++ AC_REQUIRE([AC_PROG_CC]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) ++ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) ++ dnl By default, look in $includedir and $libdir. ++ use_additional=yes ++ AC_LIB_WITH_FINAL_PREFIX([ ++ eval additional_includedir=\"$includedir\" ++ eval additional_libdir=\"$libdir\" ++ ]) ++ AC_LIB_ARG_WITH([lib-prefix], ++[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib ++ --without-lib-prefix don't search for libraries in includedir and libdir], ++[ ++ if test "X$withval" = "Xno"; then ++ use_additional=no ++ else ++ if test "X$withval" = "X"; then ++ AC_LIB_WITH_FINAL_PREFIX([ ++ eval additional_includedir=\"$includedir\" ++ eval additional_libdir=\"$libdir\" ++ ]) ++ else ++ additional_includedir="$withval/include" ++ additional_libdir="$withval/lib" ++ fi ++ fi ++]) ++ if test $use_additional = yes; then ++ dnl Potentially add $additional_includedir to $CPPFLAGS. ++ dnl But don't add it ++ dnl 1. if it's the standard /usr/include, ++ dnl 2. if it's already present in $CPPFLAGS, ++ dnl 3. if it's /usr/local/include and we are using GCC on Linux, ++ dnl 4. if it doesn't exist as a directory. ++ if test "X$additional_includedir" != "X/usr/include"; then ++ haveit= ++ for x in $CPPFLAGS; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-I$additional_includedir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ if test "X$additional_includedir" = "X/usr/local/include"; then ++ if test -n "$GCC"; then ++ case $host_os in ++ linux*) haveit=yes;; ++ esac ++ fi ++ fi ++ if test -z "$haveit"; then ++ if test -d "$additional_includedir"; then ++ dnl Really add $additional_includedir to $CPPFLAGS. ++ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" ++ fi ++ fi ++ fi ++ fi ++ dnl Potentially add $additional_libdir to $LDFLAGS. ++ dnl But don't add it ++ dnl 1. if it's the standard /usr/lib, ++ dnl 2. if it's already present in $LDFLAGS, ++ dnl 3. if it's /usr/local/lib and we are using GCC on Linux, ++ dnl 4. if it doesn't exist as a directory. ++ if test "X$additional_libdir" != "X/usr/lib"; then ++ haveit= ++ for x in $LDFLAGS; do ++ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) ++ if test "X$x" = "X-L$additional_libdir"; then ++ haveit=yes ++ break ++ fi ++ done ++ if test -z "$haveit"; then ++ if test "X$additional_libdir" = "X/usr/local/lib"; then ++ if test -n "$GCC"; then ++ case $host_os in ++ linux*) haveit=yes;; ++ esac ++ fi ++ fi ++ if test -z "$haveit"; then ++ if test -d "$additional_libdir"; then ++ dnl Really add $additional_libdir to $LDFLAGS. ++ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" ++ fi ++ fi ++ fi ++ fi ++ fi ++]) ++ ++dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, ++dnl acl_final_exec_prefix, containing the values to which $prefix and ++dnl $exec_prefix will expand at the end of the configure script. ++AC_DEFUN([AC_LIB_PREPARE_PREFIX], ++[ ++ dnl Unfortunately, prefix and exec_prefix get only finally determined ++ dnl at the end of configure. ++ if test "X$prefix" = "XNONE"; then ++ acl_final_prefix="$ac_default_prefix" ++ else ++ acl_final_prefix="$prefix" ++ fi ++ if test "X$exec_prefix" = "XNONE"; then ++ acl_final_exec_prefix='${prefix}' ++ else ++ acl_final_exec_prefix="$exec_prefix" ++ fi ++ acl_save_prefix="$prefix" ++ prefix="$acl_final_prefix" ++ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" ++ prefix="$acl_save_prefix" ++]) ++ ++dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the ++dnl variables prefix and exec_prefix bound to the values they will have ++dnl at the end of the configure script. ++AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], ++[ ++ acl_save_prefix="$prefix" ++ prefix="$acl_final_prefix" ++ acl_save_exec_prefix="$exec_prefix" ++ exec_prefix="$acl_final_exec_prefix" ++ $1 ++ exec_prefix="$acl_save_exec_prefix" ++ prefix="$acl_save_prefix" ++]) ++# nls.m4 serial 1 (gettext-0.12) ++dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++dnl ++dnl This file can can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Library General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Library General Public License, and the rest of the GNU ++dnl gettext package package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995-2000. ++dnl Bruno Haible , 2000-2003. ++ ++AC_DEFUN([AM_NLS], ++[ ++ AC_MSG_CHECKING([whether NLS is requested]) ++ dnl Default is enabled NLS ++ AC_ARG_ENABLE(nls, ++ [ --disable-nls do not use Native Language Support], ++ USE_NLS=$enableval, USE_NLS=yes) ++ AC_MSG_RESULT($USE_NLS) ++ AC_SUBST(USE_NLS) ++]) ++ ++AC_DEFUN([AM_MKINSTALLDIRS], ++[ ++ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly ++ dnl find the mkinstalldirs script in another subdir but $(top_srcdir). ++ dnl Try to locate it. ++ MKINSTALLDIRS= ++ if test -n "$ac_aux_dir"; then ++ case "$ac_aux_dir" in ++ /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; ++ *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; ++ esac ++ fi ++ if test -z "$MKINSTALLDIRS"; then ++ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" ++ fi ++ AC_SUBST(MKINSTALLDIRS) ++]) ++# po.m4 serial 1 (gettext-0.12) ++dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++dnl ++dnl This file can can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Library General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Library General Public License, and the rest of the GNU ++dnl gettext package package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995-2000. ++dnl Bruno Haible , 2000-2003. ++ ++dnl Checks for all prerequisites of the po subdirectory. ++AC_DEFUN([AM_PO_SUBDIRS], ++[ ++ AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++ AC_REQUIRE([AC_PROG_INSTALL])dnl ++ AC_REQUIRE([AM_MKINSTALLDIRS])dnl ++ AC_REQUIRE([AM_NLS])dnl ++ ++ dnl Perform the following tests also if --disable-nls has been given, ++ dnl because they are needed for "make dist" to work. ++ ++ dnl Search for GNU msgfmt in the PATH. ++ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. ++ dnl The second test excludes FreeBSD msgfmt. ++ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, ++ [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && ++ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) ++ ++ dnl Search for GNU xgettext 0.12 or newer in the PATH. ++ dnl The first test excludes Solaris xgettext and early GNU xgettext versions. ++ dnl The second test excludes FreeBSD xgettext. ++ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, ++ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && ++ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ dnl Remove leftover from FreeBSD xgettext call. ++ rm -f messages.po ++ ++ dnl Search for GNU msgmerge 0.11 or newer in the PATH. ++ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, ++ [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) ++ ++ dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. ++ dnl Test whether we really found GNU msgfmt. ++ if test "$GMSGFMT" != ":"; then ++ dnl If it is no GNU msgfmt we define it as : so that the ++ dnl Makefiles still can work. ++ if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && ++ (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ : ; ++ else ++ GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` ++ AC_MSG_RESULT( ++ [found $GMSGFMT program is not GNU msgfmt; ignore it]) ++ GMSGFMT=":" ++ fi ++ fi ++ ++ dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. ++ dnl Test whether we really found GNU xgettext. ++ if test "$XGETTEXT" != ":"; then ++ dnl If it is no GNU xgettext we define it as : so that the ++ dnl Makefiles still can work. ++ if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && ++ (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ : ; ++ else ++ AC_MSG_RESULT( ++ [found xgettext program is not GNU xgettext; ignore it]) ++ XGETTEXT=":" ++ fi ++ dnl Remove leftover from FreeBSD xgettext call. ++ rm -f messages.po ++ fi ++ ++ AC_OUTPUT_COMMANDS([ ++ for ac_file in $CONFIG_FILES; do ++ # Support "outfile[:infile[:infile...]]" ++ case "$ac_file" in ++ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; ++ esac ++ # PO directories have a Makefile.in generated from Makefile.in.in. ++ case "$ac_file" in */Makefile.in) ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then ++ rm -f "$ac_dir/POTFILES" ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" ++ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" ++ POMAKEFILEDEPS="POTFILES.in" ++ # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend ++ # on $ac_dir but don't depend on user-specified configuration ++ # parameters. ++ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then ++ # The LINGUAS file contains the set of available languages. ++ if test -n "$OBSOLETE_ALL_LINGUAS"; then ++ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" ++ fi ++ ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` ++ # Hide the ALL_LINGUAS assigment from automake. ++ eval 'ALL_LINGUAS''=$ALL_LINGUAS_' ++ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" ++ else ++ # The set of available languages was given in configure.in. ++ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' ++ fi ++ case "$ac_given_srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++ esac ++ POFILES= ++ GMOFILES= ++ UPDATEPOFILES= ++ DUMMYPOFILES= ++ for lang in $ALL_LINGUAS; do ++ POFILES="$POFILES $srcdirpre$lang.po" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" ++ DUMMYPOFILES="$DUMMYPOFILES $lang.nop" ++ done ++ # CATALOGS depends on both $ac_dir and the user's LINGUAS ++ # environment variable. ++ INST_LINGUAS= ++ if test -n "$ALL_LINGUAS"; then ++ for presentlang in $ALL_LINGUAS; do ++ useit=no ++ if test "%UNSET%" != "$LINGUAS"; then ++ desiredlanguages="$LINGUAS" ++ else ++ desiredlanguages="$ALL_LINGUAS" ++ fi ++ for desiredlang in $desiredlanguages; do ++ # Use the presentlang catalog if desiredlang is ++ # a. equal to presentlang, or ++ # b. a variant of presentlang (because in this case, ++ # presentlang can be used as a fallback for messages ++ # which are not translated in the desiredlang catalog). ++ case "$desiredlang" in ++ "$presentlang"*) useit=yes;; ++ esac ++ done ++ if test $useit = yes; then ++ INST_LINGUAS="$INST_LINGUAS $presentlang" ++ fi ++ done ++ fi ++ CATALOGS= ++ if test -n "$INST_LINGUAS"; then ++ for lang in $INST_LINGUAS; do ++ CATALOGS="$CATALOGS $lang.gmo" ++ done ++ fi ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" ++ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" ++ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do ++ if test -f "$f"; then ++ case "$f" in ++ *.orig | *.bak | *~) ;; ++ *) cat "$f" >> "$ac_dir/Makefile" ;; ++ esac ++ fi ++ done ++ fi ++ ;; ++ esac ++ done], ++ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute ++ # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it ++ # from automake. ++ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' ++ # Capture the value of LINGUAS because we need it to compute CATALOGS. ++ LINGUAS="${LINGUAS-%UNSET%}" ++ ]) ++]) ++# progtest.m4 serial 3 (gettext-0.12) ++dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++dnl ++dnl This file can can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Library General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Library General Public License, and the rest of the GNU ++dnl gettext package package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1996. ++ ++# Search path for a program which passes the given test. ++ ++dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, ++dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) ++AC_DEFUN([AM_PATH_PROG_WITH_TEST], ++[ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "$2", so it can be a program name with args. ++set dummy $2; ac_word=[$]2 ++AC_MSG_CHECKING([for $ac_word]) ++AC_CACHE_VAL(ac_cv_path_$1, ++[case "[$]$1" in ++ [[\\/]]* | ?:[[\\/]]*) ++ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in ifelse([$5], , $PATH, [$5]); do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ if [$3]; then ++ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++dnl If no 4th arg is given, leave the cache variable unset, ++dnl so AC_PATH_PROGS will keep looking. ++ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ++])dnl ++ ;; ++esac])dnl ++$1="$ac_cv_path_$1" ++if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then ++ AC_MSG_RESULT([$]$1) ++else ++ AC_MSG_RESULT(no) ++fi ++AC_SUBST($1)dnl ++]) ++# stdint_h.m4 serial 3 (gettext-0.12) ++dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Paul Eggert. ++ ++# Define HAVE_STDINT_H_WITH_UINTMAX if exists, ++# doesn't clash with , and declares uintmax_t. ++ ++AC_DEFUN([jm_AC_HEADER_STDINT_H], ++[ ++ AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, ++ [AC_TRY_COMPILE( ++ [#include ++#include ], ++ [uintmax_t i = (uintmax_t) -1;], ++ jm_ac_cv_header_stdint_h=yes, ++ jm_ac_cv_header_stdint_h=no)]) ++ if test $jm_ac_cv_header_stdint_h = yes; then ++ AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, ++ [Define if exists, doesn't clash with , ++ and declares uintmax_t. ]) ++ fi ++]) ++# uintmax_t.m4 serial 7 (gettext-0.12) ++dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Paul Eggert. ++ ++AC_PREREQ(2.13) ++ ++# Define uintmax_t to 'unsigned long' or 'unsigned long long' ++# if it is not already defined in or . ++ ++AC_DEFUN([jm_AC_TYPE_UINTMAX_T], ++[ ++ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) ++ AC_REQUIRE([jm_AC_HEADER_STDINT_H]) ++ if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then ++ AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) ++ test $ac_cv_type_unsigned_long_long = yes \ ++ && ac_type='unsigned long long' \ ++ || ac_type='unsigned long' ++ AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, ++ [Define to unsigned long or unsigned long long ++ if and don't define.]) ++ else ++ AC_DEFINE(HAVE_UINTMAX_T, 1, ++ [Define if you have the 'uintmax_t' type in or .]) ++ fi ++]) ++# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) ++dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++dnl From Paul Eggert. ++ ++AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], ++[ ++ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, ++ [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], ++ [unsigned long long ullmax = (unsigned long long) -1; ++ return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ++ ac_cv_type_unsigned_long_long=yes, ++ ac_cv_type_unsigned_long_long=no)]) ++ if test $ac_cv_type_unsigned_long_long = yes; then ++ AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, ++ [Define if you have the unsigned long long type.]) ++ fi ++]) ++ ++dnl From gnulib ++AC_DEFUN([BASH_FUNC_FPURGE], ++[ ++ AC_CHECK_FUNCS_ONCE([fpurge]) ++ AC_CHECK_FUNCS_ONCE([__fpurge]) ++ AC_CHECK_DECLS([fpurge], , , [#include ]) ++]) ++ ++AC_DEFUN([BASH_FUNC_SNPRINTF], ++[ ++ AC_CHECK_FUNCS_ONCE([snprintf]) ++ if test X$ac_cv_func_snprintf = Xyes; then ++ AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf], ++ [AC_TRY_RUN([ +#include +#include - - /* Add more tests in here as appropriate. */ ++ +int - main() - { - int fd, err; -@@ -1651,11 +1680,13 @@ AC_CACHE_VAL(bash_cv_unusable_rtsigs, - [AC_TRY_RUN([ - #include - #include ++main() ++{ ++ int n; ++ n = snprintf (0, 0, "%s", "0123456"); ++ exit(n != 7); ++} ++], bash_cv_func_snprintf=yes, bash_cv_func_snprintf=no, ++ [AC_MSG_WARN([cannot check standard snprintf if cross-compiling]) ++ bash_cv_func_snprintf=yes] ++)]) ++ if test $bash_cv_func_snprintf = no; then ++ ac_cv_func_snprintf=no ++ fi ++ fi ++ if test $ac_cv_func_snprintf = no; then ++ AC_DEFINE(HAVE_SNPRINTF, 0, ++ [Define if you have a standard-conformant snprintf function.]) ++ fi ++]) ++ ++AC_DEFUN([BASH_FUNC_VSNPRINTF], ++[ ++ AC_CHECK_FUNCS_ONCE([vsnprintf]) ++ if test X$ac_cv_func_vsnprintf = Xyes; then ++ AC_CACHE_CHECK([for standard-conformant vsnprintf], [bash_cv_func_vsnprintf], ++ [AC_TRY_RUN([ ++#if HAVE_STDARG_H ++#include ++#else ++#include ++#endif ++#include +#include - - #ifndef NSIG - # define NSIG 64 - #endif - -+int - main () - { - int n_sigs = 2 * NSIG; -@@ -1770,6 +1801,7 @@ bash_cv_wcwidth_broken, - #include - #include - -+int - main(c, v) - int c; - char **v; -@@ -1834,9 +1866,11 @@ AC_CACHE_VAL(ac_cv_rl_version, - [AC_TRY_RUN([ - #include - #include ++ ++static int ++#if HAVE_STDARG_H ++foo(const char *fmt, ...) ++#else ++foo(format, va_alist) ++ const char *format; ++ va_dcl ++#endif ++{ ++ va_list args; ++ int n; ++ ++#if HAVE_STDARG_H ++ va_start(args, fmt); ++#else ++ va_start(args); ++#endif ++ n = vsnprintf(0, 0, fmt, args); ++ va_end (args); ++ return n; ++} ++ ++main() ++{ ++ int n; ++ n = foo("%s", "0123456"); ++ exit(n != 7); ++} ++], bash_cv_func_vsnprintf=yes, bash_cv_func_vsnprintf=no, ++ [AC_MSG_WARN([cannot check standard vsnprintf if cross-compiling]) ++ bash_cv_func_vsnprintf=yes] ++)]) ++ if test $bash_cv_func_vsnprintf = no; then ++ ac_cv_func_vsnprintf=no ++ fi ++ fi ++ if test $ac_cv_func_vsnprintf = no; then ++ AC_DEFINE(HAVE_VSNPRINTF, 0, ++ [Define if you have a standard-conformant vsnprintf function.]) ++ fi ++]) ++ ++AC_DEFUN(BASH_STRUCT_WEXITSTATUS_OFFSET, ++[AC_MSG_CHECKING(for offset of exit status in return status from wait) ++AC_CACHE_VAL(bash_cv_wexitstatus_offset, ++[AC_TRY_RUN([ +#include - - extern int rl_gnu_readline_p; - ++#include ++ ++#include ++ +int - main() - { - FILE *fp; -@@ -1926,7 +1960,9 @@ AC_CACHE_VAL(bash_cv_func_ctype_nonascii - #endif - #include - #include ++main(c, v) ++ int c; ++ char **v; ++{ ++ pid_t pid, p; ++ int s, i, n; ++ ++ s = 0; ++ pid = fork(); ++ if (pid == 0) ++ exit (42); ++ ++ /* wait for the process */ ++ p = wait(&s); ++ if (p != pid) ++ exit (255); ++ ++ /* crack s */ ++ for (i = 0; i < (sizeof(s) - 8); i++) ++ { ++ n = (s >> i) & 0xff; ++ if (n == 42) ++ exit (i); ++ } ++ ++ exit (254); ++} ++], bash_cv_wexitstatus_offset=0, bash_cv_wexitstatus_offset=$?, ++ [AC_MSG_WARN(cannot check WEXITSTATUS offset if cross compiling -- defaulting to 0) ++ bash_cv_wexitstatus_offset=0] ++)]) ++if test "$bash_cv_wexitstatus_offset" -gt 32 ; then ++ AC_MSG_WARN(bad exit status from test program -- defaulting to 0) ++ bash_cv_wexitstatus_offset=0 ++fi ++AC_MSG_RESULT($bash_cv_wexitstatus_offset) ++AC_DEFINE_UNQUOTED([WEXITSTATUS_OFFSET], [$bash_cv_wexitstatus_offset], [Offset of exit status in wait status word]) ++]) ++ ++AC_DEFUN([BASH_FUNC_SBRK], ++[ ++ AC_CHECK_FUNCS_ONCE([sbrk]) ++ if test X$ac_cv_func_sbrk = Xyes; then ++ AC_CACHE_CHECK([for working sbrk], [bash_cv_func_sbrk], ++ [AC_TRY_RUN([ +#include - ++#include ++ +int - main(c, v) - int c; - char *v[]; -@@ -4068,7 +4104,9 @@ AC_DEFUN([BASH_FUNC_SNPRINTF], - AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf], - [AC_TRY_RUN([ - #include ++main(int c, char **v) ++{ ++ void *x; ++ ++ x = sbrk (4096); ++ exit ((x == (void *)-1) ? 1 : 0); ++} ++], bash_cv_func_sbrk=yes, bash_cv_func_snprintf=sbrk, ++ [AC_MSG_WARN([cannot check working sbrk if cross-compiling]) ++ bash_cv_func_sbrk=yes] ++)]) ++ if test $bash_cv_func_sbrk = no; then ++ ac_cv_func_sbrk=no ++ fi ++ fi ++ if test $ac_cv_func_sbrk = no; then ++ AC_DEFINE(HAVE_SBRK, 0, ++ [Define if you have a working sbrk function.]) ++ fi ++]) ++ ++AC_DEFUN(BASH_FUNC_FNMATCH_EQUIV_FALLBACK, ++[AC_MSG_CHECKING(whether fnmatch can be used to check bracket equivalence classes) ++AC_CACHE_VAL(bash_cv_fnmatch_equiv_fallback, ++[AC_TRY_RUN([ +#include - -+int - main() - { - int n; -@@ -4154,6 +4192,7 @@ AC_CACHE_VAL(bash_cv_wexitstatus_offset, - - #include - ++#include ++#include ++#include ++#include ++ ++char *pattern = "[[=a=]]"; ++ ++/* char *string = "ä"; */ ++unsigned char string[4] = { '\xc3', '\xa4', '\0' }; ++ +int - main(c, v) - int c; - char **v; ---- gdb-10.2/readline/readline/configure.orig -+++ gdb-10.2/readline/readline/configure ++main (int c, char **v) ++{ ++ setlocale (LC_ALL, "de_DE.UTF-8"); ++ if (fnmatch (pattern, (const char *)string, 0) != FNM_NOMATCH) ++ exit (0); ++ exit (1); ++} ++ ++], bash_cv_fnmatch_equiv_fallback=yes, bash_cv_fnmatch_equiv_fallback=no, ++ [AC_MSG_WARN(cannot check fnmatch if cross compiling -- defaulting to no) ++ bash_cv_fnmatch_equiv_fallback=no] ++)]) ++AC_MSG_RESULT($bash_cv_fnmatch_equiv_fallback) ++if test "$bash_cv_fnmatch_equiv_fallback" = "yes" ; then ++ bash_cv_fnmatch_equiv_value=1 ++else ++ bash_cv_fnmatch_equiv_value=0 ++fi ++AC_DEFINE_UNQUOTED([FNMATCH_EQUIV_FALLBACK], [$bash_cv_fnmatch_equiv_value], [Whether fnmatch can be used for bracket equivalence classes]) ++]) +diff -Nuar gdb-10.2/readline/readline/configure gdb-10.2/readline/readline/configure +--- gdb-10.2/readline/readline/configure 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/configure 2025-04-16 17:06:41.942086800 +0800 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Readline 8.0, version 2.85. @@ -3028,7 +99462,7 @@ exit 0 # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for readline 8.0. # -@@ -5316,6 +5316,7 @@ else +@@ -5316,6 +5316,7 @@ #ifdef HAVE_UNISTD_H #include #endif @@ -3036,7 +99470,7 @@ exit 0 typedef RETSIGTYPE sigfunc(); -@@ -5346,7 +5347,8 @@ int s; +@@ -5346,7 +5347,8 @@ nsigint++; } @@ -3046,7 +99480,7 @@ exit 0 { nsigint = 0; set_signal_handler(SIGINT, sigint); -@@ -5396,8 +5398,10 @@ else +@@ -5396,8 +5398,10 @@ #include #include #include @@ -3058,7 +99492,7 @@ exit 0 { #if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) exit (1); -@@ -5499,7 +5503,10 @@ else +@@ -5499,7 +5503,10 @@ #if defined (HAVE_LOCALE_H) #include #endif @@ -3069,7 +99503,7 @@ exit 0 main(c, v) int c; char *v[]; -@@ -5569,7 +5576,9 @@ else +@@ -5569,7 +5576,9 @@ #endif #include #include @@ -3079,7 +99513,7 @@ exit 0 main(c, v) int c; char *v[]; -@@ -6713,6 +6722,7 @@ else +@@ -6713,6 +6722,7 @@ #include #include @@ -3087,9 +99521,10 @@ exit 0 main(c, v) int c; char **v; ---- gdb-10.2/readline/readline/configure.ac.orig -+++ gdb-10.2/readline/readline/configure.ac -@@ -5,7 +5,7 @@ dnl report bugs to chet@po.cwru.edu +diff -Nuar gdb-10.2/readline/readline/configure.ac gdb-10.2/readline/readline/configure.ac +--- gdb-10.2/readline/readline/configure.ac 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/configure.ac 2025-04-16 17:06:41.942086800 +0800 +@@ -5,7 +5,7 @@ dnl dnl Process this file with autoconf to produce a configure script. @@ -3098,7 +99533,7 @@ exit 0 # 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 -@@ -20,7 +20,7 @@ dnl Process this file with autoconf to p +@@ -20,7 +20,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . @@ -3107,83 +99542,113 @@ exit 0 m4_include([../../config/override.m4]) ---- gdb-10.2/gdb/dwarf2/read.c.orig -+++ gdb-10.2/gdb/dwarf2/read.c -@@ -4925,7 +4925,10 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile, - result = recursively_find_pc_sect_compunit_symtab - (dw2_instantiate_symtab (data, per_objfile, false), pc); - -- gdb_assert (result != NULL); -+ if (warn_if_readin && result == nullptr) -+ warning (_("(Error: pc %s in address map, but not in symtab.)"), -+ paddress (objfile->arch (), pc)); -+ - return result; - } +diff -Nuar gdb-10.2/readline/readline/misc.c gdb-10.2/readline/readline/misc.c +--- gdb-10.2/readline/readline/misc.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/misc.c 2025-04-16 17:06:41.912086800 +0800 +@@ -403,7 +403,7 @@ ---- gdb-10.2/gdb/symtab.c.orig -+++ gdb-10.2/gdb/symtab.c -@@ -7476,7 +7476,7 @@ gdb_add_symbol_file(struct gnu_request * - int i; - int allsect = 0; - char *secname; -- char buf[80]; -+ char buf[96]; + #if defined (VI_MODE) + if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap) +- rl_point = 0; ++ rl_point = rl_end; + #endif /* VI_MODE */ - gdb_current_load_module = lm = (struct load_module *)req->addr; + if (rl_editing_mode == emacs_mode) +diff -Nuar gdb-10.2/readline/readline/readline.h gdb-10.2/readline/readline/readline.h +--- gdb-10.2/readline/readline/readline.h 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/readline.h 2025-04-16 17:06:41.922086800 +0800 +@@ -395,7 +395,7 @@ + #if defined (USE_VARARGS) && defined (PREFER_STDARG) + extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); + #else +-extern int rl_message (); ++extern int rl_message (void); + #endif -@@ -7515,8 +7515,11 @@ gdb_add_symbol_file(struct gnu_request * - secname = lm->mod_section_data[i].name; - if ((lm->mod_section_data[i].flags & SEC_FOUND) && - !STREQ(secname, ".text")) { -- sprintf(buf, " -s %s 0x%lx", secname, -- lm->mod_section_data[i].offset + lm->mod_base); -+ if (lm->mod_section_data[i].addr) -+ sprintf(buf, " -s %s 0x%lx", secname, lm->mod_section_data[i].addr); -+ else -+ sprintf(buf, " -s %s 0x%lx", secname, -+ lm->mod_section_data[i].offset + lm->mod_base); - strcat(req->buf, buf); - } - } ---- gdb-10.2/gdb/ada-lang.c.orig -+++ gdb-10.2/gdb/ada-lang.c -@@ -1158,7 +1158,7 @@ ada_decode (const char *encoded) - i -= 1; - if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_') - len0 = i - 1; -- else if (encoded[i] == '$') -+ else if (i >= 0 && encoded[i] == '$') - len0 = i; - } + extern int rl_show_char PARAMS((int)); +diff -Nuar gdb-10.2/readline/readline/rltypedefs.h gdb-10.2/readline/readline/rltypedefs.h +--- gdb-10.2/readline/readline/rltypedefs.h 2020-09-13 10:33:41.000000000 +0800 ++++ gdb-10.2/readline/readline/rltypedefs.h 2025-04-16 17:06:41.922086800 +0800 +@@ -32,10 +32,10 @@ + # define _FUNCTION_DEF ---- gdb-10.2/gdb/coffread.c.orig -+++ gdb-10.2/gdb/coffread.c -@@ -159,6 +159,7 @@ static long linetab_offset; - static unsigned long linetab_size; + #if defined(__GNUC__) || defined(__clang__) +-typedef int Function () __attribute__ ((deprecated)); +-typedef void VFunction () __attribute__ ((deprecated)); +-typedef char *CPFunction () __attribute__ ((deprecated)); +-typedef char **CPPFunction () __attribute__ ((deprecated)); ++typedef int Function (void) __attribute__ ((deprecated)); ++typedef void VFunction (void) __attribute__ ((deprecated)); ++typedef char *CPFunction (void) __attribute__ ((deprecated)); ++typedef char **CPPFunction (void) __attribute__ ((deprecated)); + #else + typedef int Function (); + typedef void VFunction (); +diff -Nuar gdb-10.2/readline/readline/support/config.guess gdb-10.2/readline/readline/support/config.guess +--- gdb-10.2/readline/readline/support/config.guess 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/support/config.guess 2025-04-16 17:06:52.012086800 +0800 +@@ -941,6 +941,15 @@ + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ SW6A) UNAME_MACHINE=sw_64sw6a ;; ++ SW6B) UNAME_MACHINE=sw_64sw6b ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" ++ exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; +diff -Nuar gdb-10.2/readline/readline/support/config.sub gdb-10.2/readline/readline/support/config.sub +--- gdb-10.2/readline/readline/support/config.sub 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/support/config.sub 2025-04-16 17:06:52.012086800 +0800 +@@ -1164,6 +1164,7 @@ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ ++ | sw_64 | sw_64sw6a | sw_64sw6b \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ +diff -Nuar gdb-10.2/readline/readline/util.c gdb-10.2/readline/readline/util.c +--- gdb-10.2/readline/readline/util.c 2021-04-25 12:06:26.000000000 +0800 ++++ gdb-10.2/readline/readline/util.c 2025-04-16 17:06:41.922086800 +0800 +@@ -487,10 +487,13 @@ - static char *stringtab = NULL; -+static long stringtab_length = 0; + if (_rl_tracefp == 0) + _rl_tropen (); ++ if (!_rl_tracefp) ++ goto out; + vfprintf (_rl_tracefp, format, args); + fprintf (_rl_tracefp, "\n"); + fflush (_rl_tracefp); - extern void stabsread_clear_cache (void); ++out: + va_end (args); + } -@@ -1297,6 +1298,7 @@ init_stringtab (bfd *abfd, long offset, gdb::unique_xmalloc_ptr *storage) - /* This is in target format (probably not very useful, and not - currently used), not host format. */ - memcpy (stringtab, lengthbuf, sizeof lengthbuf); -+ stringtab_length = length; - if (length == sizeof length) /* Empty table -- just the count. */ - return 0; +@@ -513,16 +516,17 @@ + sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long) getpid ()); + #endif + unlink (fnbuf); +- _rl_tracefp = fopen (fnbuf, "w+"); ++ _rl_tracefp = fopen (fnbuf, "w+xe"); + return _rl_tracefp != 0; + } -@@ -1316,8 +1318,9 @@ getsymname (struct internal_syment *symbol_entry) + int + _rl_trclose (void) + { +- int r; ++ int r = 0; - if (symbol_entry->_n._n_n._n_zeroes == 0) - { -- /* FIXME: Probably should be detecting corrupt symbol files by -- seeing whether offset points to within the stringtab. */ -+ if (symbol_entry->_n._n_n._n_offset > stringtab_length) -+ error (_("COFF Error: string table offset (%ld) outside string table (length %ld)"), -+ symbol_entry->_n._n_n._n_offset, stringtab_length); - result = stringtab + symbol_entry->_n._n_n._n_offset; - } - else +- r = fclose (_rl_tracefp); ++ if (_rl_tracefp) ++ r = fclose (_rl_tracefp); + _rl_tracefp = 0; + return r; + } diff --git a/gdb_interface.c b/gdb_interface.c index b14319c..17ffa40 100644 --- a/gdb_interface.c +++ b/gdb_interface.c @@ -75,7 +75,7 @@ gdb_main_loop(int argc, char **argv) #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) command_loop_hook = main_loop; #else - deprecated_command_loop_hook = main_loop; +// deprecated_command_loop_hook = main_loop; #endif #endif gdb_main_entry(argc, argv); @@ -126,7 +126,7 @@ display_gdb_banner(void) #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) command_loop_hook = exit_after_gdb_info; #else - deprecated_command_loop_hook = exit_after_gdb_info; +// deprecated_command_loop_hook = exit_after_gdb_info; #endif #endif args[0] = "gdb"; diff --git a/lkcd_vmdump_v1.h b/lkcd_vmdump_v1.h index 98ee094..dd57746 100644 --- a/lkcd_vmdump_v1.h +++ b/lkcd_vmdump_v1.h @@ -114,7 +114,7 @@ typedef struct _dump_header_s { struct new_utsname dh_utsname; /* the dump registers */ -#if !defined(IA64) && !defined(S390) && !defined(S390X) && !defined(ARM64) && !defined(RISCV64) +#if !defined(IA64) && !defined(S390) && !defined(S390X) && !defined(ARM64) && !defined(RISCV64) && !defined(SW_64) struct pt_regs dh_regs; #endif diff --git a/lkcd_vmdump_v2_v3.h b/lkcd_vmdump_v2_v3.h index ef3067f..63609bb 100644 --- a/lkcd_vmdump_v2_v3.h +++ b/lkcd_vmdump_v2_v3.h @@ -94,7 +94,7 @@ typedef struct _dump_header_asm_s { #endif /* ARM || X86 || PPC */ -#if defined(ALPHA) || defined(IA64) || defined(X86_64) || defined(PPC64) +#if defined(ALPHA) || defined(SW_64) || defined(IA64) || defined(X86_64) || defined(PPC64) /* * Plug in the real ../arch/alpha/vmdump.h when available. For now the @@ -130,8 +130,10 @@ typedef struct _dump_header_asm_s { /* the dump registers */ #ifndef IA64 +#ifndef SW_64 struct pt_regs dha_regs; #endif +#endif } dump_header_asm_t; diff --git a/sw_64.c b/sw_64.c new file mode 100644 index 0000000..5ce132f --- /dev/null +++ b/sw_64.c @@ -0,0 +1,2716 @@ +/* sw64.c - core analysis suite + * + * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. + * Copyright (C) 2002-2006, 2010-2013 David Anderson + * Copyright (C) 2002-2006, 2010-2013 Red Hat, Inc. All rights reserved. + * + * 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 2 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. + * + */ +#ifdef SW_64 +#include "defs.h" +#include +#include +#include + +static struct machine_specific sw64_machine_specific = { 0 }; + +static int sw64_trace_status(struct gnu_request *, struct bt_info *); +static void sw64_exception_frame(ulong, ulong, + struct gnu_request *, struct bt_info *); +static void sw64_frame_offset(struct gnu_request *, ulong); +static int sw64_backtrace_resync(struct gnu_request *, ulong, + struct bt_info *); +static void sw64_print_stack_entry(struct gnu_request *, ulong, + char *, ulong, struct bt_info *); +static int sw64_resync_speculate(struct gnu_request *, ulong,struct bt_info *); +static int sw64_dis_filter(ulong, char *, unsigned int); +static void dis_address_translation(ulong, char *, unsigned int); +static void sw64_cmd_mach(void); +static int sw64_get_smp_cpus(void); +static void sw64_display_machine_stats(void); +static void sw64_dump_line_number(char *, ulong); +static void display_hwrpb(unsigned int); +static void sw64_post_init(void); +static struct line_number_hook sw64_line_number_hooks[]; + + +#define SW64_CONTINUE_TRACE (1) +#define SW64_END_OF_TRACE (2) +#define SW64_EXCEPTION_FRAME (3) +#define SW64_SYSCALL_FRAME (4) +#define SW64_MM_FAULT (5) +#define SW64_INTERRUPT_PENDING (6) +#define SW64_RESCHEDULE (7) +#define SW64_DOWN_FAILED (8) +#define SW64_RET_FROM_SMP_FORK (9) +#define SW64_SIGNAL_RETURN (10) +#define SW64_STRACE (11) + +static int sw64_eframe_search(struct bt_info *); +static int sw64_uvtop(struct task_context *, ulong, physaddr_t *, int); +static int sw64_is_kvddr(ulong addr); +static int sw3231_kvtop(struct task_context *, ulong, physaddr_t *, int); +static int sw6432_kvtop(struct task_context *, ulong, physaddr_t *, int); +static void sw64_back_trace_cmd(struct bt_info *); +static void sw64_kernel_back_trace(struct gnu_request *req, struct bt_info *bt); +static ulong sw64_get_task_pgd(ulong task); +static ulong sw64_processor_speed(void); +static void sw64_get_stack_frame(struct bt_info *, ulong *, ulong *); +static void get_sw64_frame(struct bt_info *, ulong *, ulong *); +static int verify_user_eframe(struct bt_info *, ulong, ulong); +static int sw64_translate_pte(ulong, void *, ulonglong); +static uint64_t sw64_memory_size(void); +static ulong sw64_vmalloc_start(void); +static int sw64_is_task_addr(ulong); +static int sw64_verify_symbol(const char *, ulong, char); + +struct percpu_data { + ulong halt_PC; + ulong halt_ra; + ulong halt_pv; +}; +#define GET_HALT_PC 0x1 +#define GET_HALT_RA 0x2 +#define GET_HALT_PV 0x3 +static ulong get_percpu_data(int, ulong, struct percpu_data *); + +#define SW64_MAX_PHYSMEM_BITS 48 +#define SW64_SECTION_SIZE_BITS 28 + +/* + * Retrieve task registers for the time of the crash. + */ +static int +sw64_get_crash_notes(void) +{ + struct machine_specific *ms = machdep->machspec; + ulong crash_notes, mini_coco; + Elf64_Nhdr *note; + ulong offset; + char *buf, *p; + struct sw64_pt_regs *pt_regs; + ulong *notes_ptrs; + ulong i; + + if (!symbol_exists("crash_notes")) + return FALSE; + + crash_notes = symbol_value("crash_notes"); + + notes_ptrs = (ulong *)GETBUF(kt->cpus*sizeof(notes_ptrs[0])); + + /* + * Read crash_notes for the first CPU. crash_notes are in standard ELF + * note format. + */ + if (!readmem(crash_notes, KVADDR, ¬es_ptrs[kt->cpus-1], + sizeof(notes_ptrs[kt->cpus-1]), "crash_notes", RETURN_ON_ERROR)) { + error(WARNING, "cannot read crash_notes\n"); + FREEBUF(notes_ptrs); + return FALSE; + } + + if (symbol_exists("__per_cpu_offset")) { + /* + * Add __per_cpu_offset for each cpu to form the notes pointer. + */ + for (i = 0; icpus; i++){ + notes_ptrs[i] = notes_ptrs[kt->cpus-1] + kt->__per_cpu_offset[i]; + } + } + + buf = GETBUF(SIZE(note_buf)); + + if (!(ms->panic_task_regs = calloc((size_t)kt->cpus, sizeof(struct sw64_pt_regs)))) + error(FATAL, "cannot calloc panic_task_regs space. cpus:%d\n", kt->cpus); + + for (i = 0; i < kt->cpus; i++) { + + if (!readmem(notes_ptrs[i], KVADDR, buf, SIZE(note_buf), + "note_buf_t", RETURN_ON_ERROR)) { + error(WARNING, "failed to read note_buf_t\n"); + goto fail; + } + + /* + * Do some sanity checks for this note before reading registers from it. + */ + note = (Elf64_Nhdr *)buf; + p = buf + sizeof(Elf64_Nhdr); + /* + * dumpfiles created with qemu won't have crash_notes, but there will + * be elf notes; dumpfiles created by kdump do not create notes for + * offline cpus. + */ + if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) { + if (DISKDUMP_DUMPFILE()) + note = diskdump_get_prstatus_percpu(i); + else if (KDUMP_DUMPFILE()) + note = netdump_get_prstatus_percpu(i); + if (note) { + /* + * SIZE(note_buf) accounts for a "final note", which is a + * trailing empty elf note header. + */ + long notesz = SIZE(note_buf) - sizeof(Elf64_Nhdr); + + if (sizeof(Elf64_Nhdr) + roundup(note->n_namesz, 4) + + note->n_descsz == notesz) + BCOPY((char *)note, buf, notesz); + } else { + error(WARNING, + "cannot find NT_PRSTATUS note for cpu: %d\n", i); + continue; + } + } + + if (note->n_type != NT_PRSTATUS) { + error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n"); + goto fail; + } + if (p[0] != 'C' || p[1] != 'O' || p[2] != 'R' || p[3] != 'E') { + error(WARNING, "invalid note (name != \"CORE\"\n"); + goto fail; + } + offset = sizeof(Elf64_Nhdr); + offset = roundup(offset + note->n_namesz, 4); + p = buf + offset; + + BCOPY(p + OFFSET(elf_prstatus_pr_reg), &ms->panic_task_regs[i], + sizeof(struct sw64_pt_regs)); + } + FREEBUF(buf); + FREEBUF(notes_ptrs); + return TRUE; +fail: + FREEBUF(buf); + FREEBUF(notes_ptrs); + free(ms->panic_task_regs); + ms->panic_task_regs = NULL; + return FALSE; +} + +#define BUFFER_SIZE 1024 + +static int is_sw3231(void) +{ + FILE *file; + char buffer[BUFFER_SIZE]; + const char *filename = "/proc/cpuinfo"; + const char *keyword = "SW3231"; + int found = 0; + + file = fopen(filename, "r"); + if (file == NULL) { + perror("fopen failed!"); + return -1; + } + + while (fgets(buffer, BUFFER_SIZE, file) != NULL) { + buffer[strcspn(buffer, "\n")] = 0; + + if (strstr(buffer, keyword) != NULL) { + found = 1; + break; + } + } + + fclose(file); + + return found; +} + +/* + * Do all necessary machine-specific setup here. This is called three times, + * before symbol table initialization, and before and after GDB has been + * initialized. + */ +void +sw64_init(int when) +{ + int tmp; + + switch (when) + { + case SETUP_ENV: + machdep->process_elf_notes = process_elf64_notes; + break; + + case PRE_SYMTAB: + machdep->machspec = &sw64_machine_specific; + machdep->verify_symbol = sw64_verify_symbol; + if (pc->flags & KERNEL_DEBUG_QUERY) + return; + machdep->pagesize = memory_page_size(); + machdep->pageshift = ffs(machdep->pagesize) - 1; + machdep->pageoffset = machdep->pagesize - 1; + machdep->pagemask = ~(machdep->pageoffset); + machdep->stacksize = machdep->pagesize; + if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc pgd space."); + if ((machdep->pud = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc pud space."); + if ((machdep->pmd = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc pmd space."); + if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL) + error(FATAL, "cannot malloc ptbl space."); + machdep->last_pgd_read = 0; + machdep->last_pud_read = 0; + machdep->last_pmd_read = 0; + machdep->last_ptbl_read = 0; + machdep->verify_paddr = generic_verify_paddr; + machdep->ptrs_per_pgd = PTRS_PER_PGD; + break; + + case PRE_GDB: + switch (symbol_value("_stext") & KSEG_BASE) + { + case KSEG_BASE: + machdep->kvbase = KSEG_BASE; + break; + + default: + error(FATAL, + "cannot determine KSEG base from _stext: %lx\n", + symbol_value("_stext")); + } + + machdep->identity_map_base = machdep->kvbase; + machdep->is_kvaddr = sw64_is_kvddr; + machdep->is_uvaddr = generic_is_uvaddr; + machdep->eframe_search = sw64_eframe_search; + machdep->back_trace = sw64_back_trace_cmd; + machdep->processor_speed = sw64_processor_speed; + machdep->uvtop = sw64_uvtop; + if (is_sw3231()) + machdep->kvtop = sw3231_kvtop; + else + machdep->kvtop = sw6432_kvtop; + machdep->get_task_pgd = sw64_get_task_pgd; + machdep->dump_irq = generic_dump_irq; + machdep->get_stack_frame = sw64_get_stack_frame; + machdep->get_stackbase = generic_get_stackbase; + machdep->get_stacktop = generic_get_stacktop; + machdep->translate_pte = sw64_translate_pte; + machdep->memory_size = sw64_memory_size; + machdep->vmalloc_start = sw64_vmalloc_start; + machdep->is_task_addr = sw64_is_task_addr; + if (symbol_exists("console_crash")) { + get_symbol_data("console_crash", sizeof(int), &tmp); + if (tmp) + machdep->flags |= HWRESET; + } + machdep->dis_filter = sw64_dis_filter; + machdep->cmd_mach = sw64_cmd_mach; + machdep->get_smp_cpus = sw64_get_smp_cpus; + machdep->line_number_hooks = sw64_line_number_hooks; + machdep->value_to_symbol = generic_machdep_value_to_symbol; + machdep->init_kernel_pgd = NULL; + break; + + case POST_GDB: + MEMBER_OFFSET_INIT(thread_struct_ptbr, + "thread_struct", "ptbr"); + MEMBER_OFFSET_INIT(hwrpb_struct_cycle_freq, + "hwrpb_struct", "cycle_freq"); + MEMBER_OFFSET_INIT(hwrpb_struct_processor_offset, + "hwrpb_struct", "processor_offset"); + MEMBER_OFFSET_INIT(hwrpb_struct_processor_size, + "hwrpb_struct", "processor_size"); + MEMBER_OFFSET_INIT(percpu_struct_halt_PC, + "percpu_struct", "halt_PC"); + MEMBER_OFFSET_INIT(percpu_struct_halt_ra, + "percpu_struct", "halt_ra"); + MEMBER_OFFSET_INIT(percpu_struct_halt_pv, + "percpu_struct", "halt_pv"); + MEMBER_OFFSET_INIT(switch_stack_r26, + "switch_stack", "r26"); + + if (symbol_exists("irq_desc")) + ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc, + "irq_desc", NULL, 0); + else if (kernel_symbol_exists("nr_irqs")) + get_symbol_data("nr_irqs", sizeof(unsigned int), + &machdep->nr_irqs); + else + machdep->nr_irqs = 0; + if (!machdep->hz) + machdep->hz = HZ; + machdep->max_physmem_bits = SW64_MAX_PHYSMEM_BITS; + machdep->section_size_bits = SW64_SECTION_SIZE_BITS; + STRUCT_SIZE_INIT(note_buf, "note_buf_t"); + STRUCT_SIZE_INIT(elf_prstatus, "elf_prstatus"); + MEMBER_OFFSET_INIT(elf_prstatus_pr_pid, "elf_prstatus", "pr_pid"); + MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus", "pr_reg"); + + break; + + case POST_INIT: + sw64_post_init(); + break; + case POST_VM: + /* + * crash_notes contains machine specific information about the + * crash. In particular, it contains CPU registers at the time + * of the crash. We need this information to extract correct + * backtraces from the panic task. + */ + if (!LIVE() && !sw64_get_crash_notes()) + error(WARNING, + "cannot retrieve registers for active task%s\n\n", + kt->cpus > 1 ? "s" : ""); + + break; + } +} + +/* + * Unroll a kernel stack. + */ +static void +sw64_back_trace_cmd(struct bt_info *bt) +{ + char buf[BUFSIZE]; + struct gnu_request *req; + + bt->flags |= BT_EXCEPTION_FRAME; + + if (CRASHDEBUG(1) || bt->debug) + fprintf(fp, " => PC: %lx (%s) FP: %lx \n", + bt->instptr, value_to_symstr(bt->instptr, buf, 0), + bt->stkptr ); + + req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); + req->command = GNU_STACK_TRACE; + req->flags = GNU_RETURN_ON_ERROR; + req->buf = GETBUF(BUFSIZE); + req->debug = bt->debug; + req->task = bt->task; + + req->pc = bt->instptr; + req->sp = bt->stkptr; + + if (bt->flags & BT_USE_GDB) { + strcpy(req->buf, "backtrace"); + gdb_interface(req); + } + else + sw64_kernel_back_trace(req, bt); + + FREEBUF(req->buf); + FREEBUF(req); + + +} + + +/* + * Unroll the kernel stack. + */ + +#define SW64_BACKTRACE_SPECULATE(X) \ +{ \ + speculate_location = X; \ + \ + if (bt->flags & BT_SPECULATE) \ + return; \ + \ + BZERO(btloc, sizeof(struct bt_info)); \ + btloc->task = req->task; \ + btloc->tc = bt->tc; \ + btloc->stackbase = bt->stackbase; \ + btloc->stacktop = bt->stacktop; \ + btloc->flags = BT_TEXT_SYMBOLS_NOPRINT; \ + hook.eip = 0; \ + hook.esp = req->lastsp ? req->lastsp + sizeof(long) : 0; \ + btloc->hp = &hook; \ + \ + back_trace(btloc); \ + \ + if (hook.esp && hook.eip) { \ + req->hookp = &hook; \ + if (sw64_resync_speculate(req, bt->flags, bt)) { \ + req->pc = hook.eip; \ + req->sp = hook.esp; \ + continue; \ + } \ + goto show_remaining_text; \ + } \ + goto show_remaining_text; \ +} + +static void +sw64_kernel_back_trace(struct gnu_request *req, struct bt_info *bt) +{ + struct machine_specific *ms = machdep->machspec; + struct sw64_pt_regs *pt_regs; + struct task_context *tc; + ulong next_sp, next_pc; + int i, idx = 0; + ulong *up; + struct load_module *lm; + char buf1[BUFSIZE]; + char buf2[BUFSIZE]; + + tc = task_to_context(req->task); + pt_regs = &ms->panic_task_regs[tc->processor]; + + for (i = (req->pc - bt->stackbase)/sizeof(ulong); + i < LONGS_PER_STACK; i++) { + up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); + if (is_kernel_text_offset(*up)) { + if (!next_pc) + next_pc = *up; + else if (!next_sp) + next_sp = bt->stackbase + (i * sizeof(long)); + } + if (is_kernel_text(*up)) { + fprintf(fp, "#%d %s[%s] %s at %lx", + idx, + bt->flags & BT_ERROR_MASK ? + " " : "", + mkstring(buf1, VADDR_PRLEN, + RJUST|LONG_HEX, + MKSTR(bt->stackbase + + (i * sizeof(long)))), + bt->flags & BT_SYMBOL_OFFSET ? + value_to_symstr(*up, buf2, bt->radix) : + closest_symbol(*up), *up); + if (module_symbol(*up, NULL, &lm, NULL, 0)) + fprintf(fp, " [%s]", lm->mod_name); + fprintf(fp, "\n"); + idx++; + } + } + fprintf(fp, "PC:%lx [%s]\n", pt_regs->pc, value_to_symstr(pt_regs->pc, buf2, bt->radix)); + fprintf(fp, "RA:%lx [%s]\n", pt_regs->r26, value_to_symstr(pt_regs->r26, buf2, bt->radix)); + fprintf(fp, + "v0:%016lx t0:%016lx t1:%016lx\n" + "t2:%016lx t3:%016lx t4:%016lx\n" + "t5:%016lx t6:%016lx t7:%016lx\n" + "r9:%016lx r10:%016lx r11:%016lx\n" + "r12:%016lx r13:%016lx r14:%016lx\n" + "r15:%016lx r16:%016lx r17:%016lx\n" + "r18:%016lx a3:%016lx a4:%016lx\n" + "a5:%016lx t8:%016lx t9:%016lx\n" + "t10:%016lx t11:%016lx ra:%016lx\n" + "pv:%016lx at:%016lx gp:%016lx\n" + "usp:%016lx pc:%016lx unique:%016lx\n", + pt_regs->r0, + pt_regs->r1, + pt_regs->r2, + pt_regs->r3, + pt_regs->r4, + pt_regs->r5, + pt_regs->r6, + pt_regs->r7, + pt_regs->r8, + pt_regs->r9, + pt_regs->r10, + pt_regs->r11, + pt_regs->r12, + pt_regs->r13, + pt_regs->r14, + pt_regs->r15, + pt_regs->r16, + pt_regs->r17, + pt_regs->r18, + pt_regs->r19, + pt_regs->r20, + pt_regs->r21, + pt_regs->r22, + pt_regs->r23, + pt_regs->r24, + pt_regs->r25, + pt_regs->r26, + pt_regs->r27, + pt_regs->r28, + pt_regs->gp, + pt_regs->usp, + pt_regs->pc, + pt_regs->ps + ); +} +/* + * print one entry of a stack trace + */ +static void +sw64_print_stack_entry(struct gnu_request *req, + ulong callpc, + char *name, + ulong flags, + struct bt_info *bt) +{ + struct load_module *lm; + + if (BT_REFERENCE_CHECK(bt)) { + switch (bt->ref->cmdflags & (BT_REF_SYMBOL|BT_REF_HEXVAL)) + { + case BT_REF_SYMBOL: + if (STREQ(name, bt->ref->str) || + (STREQ(name, "strace") && + STREQ(bt->ref->str, "entSys"))) { + bt->ref->cmdflags |= BT_REF_FOUND; + } + break; + + case BT_REF_HEXVAL: + if (bt->ref->hexval == callpc) + bt->ref->cmdflags |= BT_REF_FOUND; + break; + } + } else { + fprintf(fp, "%s#%d [%lx] %s at %lx", + req->curframe < 10 ? " " : "", req->curframe, req->sp, + STREQ(name, "strace") ? "strace (via entSys)" : name, + callpc); + if (module_symbol(callpc, NULL, &lm, NULL, 0)) + fprintf(fp, " [%s]", lm->mod_name); + fprintf(fp, "\n"); + } + + if (!(flags & BT_SPECULATE)) + req->curframe++; + + if (flags & BT_SAVE_LASTSP) + req->lastsp = req->sp; + + if (BT_REFERENCE_CHECK(bt)) + return; + + if (flags & BT_LINE_NUMBERS) + sw64_dump_line_number(name, callpc); +} + +static const char *hook_files[] = { + "arch/sw_64/kernel/entry.S", + "arch/sw_64/kernel/head.S", + "init/main.c", + "arch/sw_64/kernel/smp.c", +}; + +#define ENTRY_S ((char **)&hook_files[0]) +#define HEAD_S ((char **)&hook_files[1]) +#define MAIN_C ((char **)&hook_files[2]) +#define SMP_C ((char **)&hook_files[3]) + +static struct line_number_hook sw64_line_number_hooks[] = { + {"entInt", ENTRY_S}, + {"entMM", ENTRY_S}, + {"entArith", ENTRY_S}, + {"entIF", ENTRY_S}, + {"entDbg", ENTRY_S}, + {"undo_switch_stack", ENTRY_S}, + {"entUna", ENTRY_S}, + {"entUnaUser", ENTRY_S}, + {"sw_switch_to", ENTRY_S}, + {"entSys", ENTRY_S}, + {"ret_from_sys_call", ENTRY_S}, + {"restore_all", ENTRY_S}, + {"strace", ENTRY_S}, + {"strace_success", ENTRY_S}, + {"strace_error", ENTRY_S}, + {"syscall_error", ENTRY_S}, + {"ret_success", ENTRY_S}, + {"ret_from_fork", ENTRY_S}, + {"sys_sigreturn", ENTRY_S}, + {"sys_rt_sigreturn", ENTRY_S}, + + {"_stext", HEAD_S}, + {"__start", HEAD_S}, + {"__smp_callin", HEAD_S}, + {"halt", HEAD_S}, + + {"start_kernel", MAIN_C}, + + {"smp_callin", SMP_C}, + + {NULL, NULL} /* list must be NULL-terminated */ +}; + +static void +sw64_dump_line_number(char *name, ulong callpc) +{ + char buf[BUFSIZE], *p; + int retries; + + retries = 0; +try_closest: + get_line_number(callpc, buf, FALSE); + if (strlen(buf)) { + if (retries) { + p = strstr(buf, ": "); + if (p) + *p = NULLCHAR; + } + fprintf(fp, " %s\n", buf); + } else { + if (retries) + fprintf(fp, GDB_PATCHED() ? + "" : " (cannot determine file and line number)\n"); + else { + retries++; + callpc = closest_symbol_value(callpc); + goto try_closest; + } + } +} + + +/* + * Look for the frame size storage at the beginning of a function. + * If it's not obvious, try gdb. + * + * For future reference, here's where the numbers come from: + * + * 0xfffffc00003217e8 : subq sp,0x50,sp + * fffffc00003217e8: 43ca153e + * 010000 11110 01010000 1 0101001 11110 + * + * 0xfffffc0000321668 : subq sp,0x60,sp + * fffffc0000321668: 43cc153e + * 010000 11110 01100000 1 0101001 11110 + * + * 0xfffffc000035d028 : subq sp,0x70,sp + * fffffc000035d028: 43ce153e + * 010000 11110 01110000 1 0101001 11110 + * + * 0100 0011 110x xxxx xxx1 0101 0011 1110 + * 1111 1111 111x xxxx xxx1 1111 1111 1111 + * 0000 0000 0001 1111 1110 0000 0000 0000 + * f f e 0 1 f f f instruction mask + * 0 0 1 f e 0 0 0 offset + * + * stq ra,0(sp) + * fffffc000035d034: b75e0000 + */ + +static void +sw64_frame_offset(struct gnu_request *req, ulong alt_pc) +{ + uint *ip, ival; + ulong value; + + req->value = value = 0; + + if (alt_pc && !is_kernel_text(alt_pc)) + error(FATAL, + "trying to get frame offset of non-text address: %lx\n", + alt_pc); + else if (!alt_pc && !is_kernel_text(req->pc)) + error(FATAL, + "trying to get frame offset of non-text address: %lx\n", + req->pc); + + ip = alt_pc ? (int *)closest_symbol_value(alt_pc) : + (int *)closest_symbol_value(req->pc); + if (!ip) + goto use_gdb; + + ival = 0; + + /* + * Don't go any farther than "stq ra,0(sp)" (0xb75e0000) + */ + while (ival != 0xb75e0000) { + if (!text_value_cache((ulong)ip, 0, &ival)) { + readmem((ulong)ip, KVADDR, &ival, + sizeof(uint), "uncached text value", + FAULT_ON_ERROR); + text_value_cache((ulong)ip, ival, NULL); + } + + if ((ival & 0xffe01fff) == 0x43c0153e) { + value = (ival & 0x1fe000) >> 13; + break; + } + ip++; + } + + if (value) { + req->value = value; + return; + } + +use_gdb: +#ifndef GDB_5_3 +{ + static int gdb_frame_offset_warnings = 10; + + if (gdb_frame_offset_warnings-- > 0) + error(WARNING, + "GNU_ALPHA_FRAME_OFFSET functionality not ported to gdb\n"); +} +#endif + req->command = GNU_ALPHA_FRAME_OFFSET; + if (alt_pc) { + ulong pc_save; + pc_save = req->pc; + req->pc = alt_pc; + gdb_interface(req); + req->pc = pc_save; + } else + gdb_interface(req); +} + +/* + * Look for key routines that either mean the trace has ended or has + * bumped into an exception frame. + */ +int +sw64_trace_status(struct gnu_request *req, struct bt_info *bt) +{ + ulong value; + char *func; + ulong frame; + + req->addr = 0; + func = req->name; + frame = req->sp; + + if (STREQ(func, "start_kernel") || + STREQ(func, "smp_callin") || + STREQ(func, "kernel_thread") || + STREQ(func, "__kernel_thread")) + return SW64_END_OF_TRACE; + + if (STREQ(func, "ret_from_smp_fork") || + STREQ(func, "ret_from_smpfork")) + return SW64_RET_FROM_SMP_FORK; + + if (STREQ(func, "entSys")) + return SW64_SYSCALL_FRAME; + + if (STREQ(func, "entMM")) { + req->sp += 56; /* see entMM in entry.S */ + return SW64_MM_FAULT; + } + + if (STREQ(func, "do_entInt")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "do_entArith")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "do_entIF")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "do_entDbg")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "handle_bottom_half")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "handle_softirq")) + return SW64_EXCEPTION_FRAME; + + if (STREQ(func, "reschedule")) + return SW64_RESCHEDULE; + + if (STREQ(func, "ret_from_reschedule")) + return SW64_RESCHEDULE; + + if (STREQ(func, "signal_return")) + return SW64_SIGNAL_RETURN; + + if (STREQ(func, "strace")) + return SW64_STRACE; + + if (STREQ(func, "__down_failed") || + STREQ(func, "__down_failed_interruptible")) { + readmem(req->sp + 144, KVADDR, &req->pc, sizeof(ulong), + "__down_failed r26", FAULT_ON_ERROR); + req->sp += 160; + return SW64_DOWN_FAILED; + } + + value = GET_STACK_ULONG(frame); + + if (STREQ(closest_symbol(value), "do_entInt") || + STREQ(closest_symbol(value), "do_entArith") || + STREQ(closest_symbol(value), "do_entIF") || + STREQ(closest_symbol(value), "do_entDbg")) { + req->addr = value; + req->frame = 0; + + while (INSTACK(frame, bt)) { + frame += sizeof(ulong); + value = GET_STACK_ULONG(frame); + if (STREQ(closest_symbol(value), "ret_from_sys_call")) { + sw64_frame_offset(req, req->addr); + /* req->frame = frame + req->value; XXX */ + break; + } + } + return SW64_INTERRUPT_PENDING; + } + + return SW64_CONTINUE_TRACE; +} + +/* + * Redo the gdb pt_regs structure output. + */ +enum regnames { _r0_, _r1_, _r2_, _r3_, _r4_, _r5_, _r6_, _r7_, _r8_, + _r19_, _r20_, _r21_, _r22_, _r23_, _r24_, _r25_, _r26_, + _r27_, _r28_, _hae_, _trap_a0_, _trap_a1_, _trap_a2_, + _ps_, _pc_, _gp_, _r16_, _r17_, _r18_, NUMREGS}; + +struct sw64_eframe { + char regs[30][30]; + ulong value[29]; +}; + +static void +sw64_exception_frame(ulong addr, + ulong flags, + struct gnu_request *req, + struct bt_info *bt) +{ + int i, j; + char buf[BUFSIZE]; + ulong value; + physaddr_t paddr; + struct sw64_eframe eframe; + + if (CRASHDEBUG(4)) + fprintf(fp, "sw64_exception_frame: %lx\n", addr); + + if (flags & BT_SPECULATE) { + req->pc = 0; + fprintf(fp, "SW64 EXCEPTION FRAME\n"); + return; + } + + BZERO(&eframe, sizeof(struct sw64_eframe)); + + open_tmpfile(); + dump_struct("pt_regs", addr, RADIX(16)); + rewind(pc->tmpfile); + while (fgets(buf, BUFSIZE, pc->tmpfile)) { + strip_comma(clean_line(buf)); + if (!strstr(buf, "0x")) + continue; + + extract_hex(buf, &value, NULLCHAR, TRUE); + if (CRASHDEBUG(4)) + fprintf(pc->saved_fp, "<%s> %lx\n", buf, value); + + if (STRNEQ(buf, "r0 = ")) { + sprintf(eframe.regs[_r0_], " V0/R0: %016lx", value); + eframe.value[_r0_] = value; + } + if (STRNEQ(buf, "r1 = ")) { + sprintf(eframe.regs[_r1_], " T0/R1: %016lx", value); + eframe.value[_r1_] = value; + } + if (STRNEQ(buf, "r2 = ")) { + sprintf(eframe.regs[_r2_], " T1/R2: %016lx", value); + eframe.value[_r2_] = value; + } + if (STRNEQ(buf, "r3 = ")) { + sprintf(eframe.regs[_r3_], " T2/R3: %016lx", value); + eframe.value[_r3_] = value; + } + if (STRNEQ(buf, "r4 = ")) { + sprintf(eframe.regs[_r4_], " T3/R4: %016lx", value); + eframe.value[_r4_] = value; + } + if (STRNEQ(buf, "r5 = ")) { + sprintf(eframe.regs[_r5_], " T4/R5: %016lx", value); + eframe.value[_r5_] = value; + } + if (STRNEQ(buf, "r6 = ")) { + sprintf(eframe.regs[_r6_], " T5/R6: %016lx", value); + eframe.value[_r6_] = value; + } + if (STRNEQ(buf, "r7 = ")) { + sprintf(eframe.regs[_r7_], " T6/R7: %016lx", value); + eframe.value[_r7_] = value; + } + if (STRNEQ(buf, "r8 = ")) { + sprintf(eframe.regs[_r8_], " T7/R8: %016lx", value); + eframe.value[_r8_] = value; + } + if (STRNEQ(buf, "r19 = ")) { + sprintf(eframe.regs[_r19_], " A3/R19: %016lx", value); + eframe.value[_r19_] = value; + } + if (STRNEQ(buf, "r20 = ")) { + sprintf(eframe.regs[_r20_], " A4/R20: %016lx", value); + eframe.value[_r20_] = value; + } + if (STRNEQ(buf, "r21 = ")) { + sprintf(eframe.regs[_r21_], " A5/R21: %016lx", value); + eframe.value[_r21_] = value; + } + if (STRNEQ(buf, "r22 = ")) { + sprintf(eframe.regs[_r22_], " T8/R22: %016lx", value); + eframe.value[_r22_] = value; + } + if (STRNEQ(buf, "r23 = ")) { + sprintf(eframe.regs[_r23_], " T9/R23: %016lx", value); + eframe.value[_r23_] = value; + } + if (STRNEQ(buf, "r24 = ")) { + sprintf(eframe.regs[_r24_], "T10/R24: %016lx", value); + eframe.value[_r24_] = value; + } + if (STRNEQ(buf, "r25 = ")) { + sprintf(eframe.regs[_r25_], "T11/R25: %016lx", value); + eframe.value[_r25_] = value; + } + if (STRNEQ(buf, "r26 = ")) { + sprintf(eframe.regs[_r26_], " RA/R26: %016lx", value); + eframe.value[_r26_] = value; + } + if (STRNEQ(buf, "r27 = ")) { + sprintf(eframe.regs[_r27_], "T12/R27: %016lx", value); + eframe.value[_r27_] = value; + } + if (STRNEQ(buf, "r28 = ")) { + sprintf(eframe.regs[_r28_], " AT/R28: %016lx", value); + eframe.value[_r28_] = value; + } + if (STRNEQ(buf, "hae = ")) { + sprintf(eframe.regs[_hae_], " HAE: %016lx", value); + eframe.value[_hae_] = value; + } + if (STRNEQ(buf, "trap_a0 = ")) { + sprintf(eframe.regs[_trap_a0_], "TRAP_A0: %016lx", + value); + eframe.value[_trap_a0_] = value; + } + if (STRNEQ(buf, "trap_a1 = ")) { + sprintf(eframe.regs[_trap_a1_], "TRAP_A1: %016lx", + value); + eframe.value[_trap_a1_] = value; + } + if (STRNEQ(buf, "trap_a2 = ")) { + sprintf(eframe.regs[_trap_a2_], "TRAP_A2: %016lx", + value); + eframe.value[_trap_a2_] = value; + } + if (STRNEQ(buf, "ps = ")) { + sprintf(eframe.regs[_ps_], " PS: %016lx", value); + eframe.value[_ps_] = value; + } + if (STRNEQ(buf, "pc = ")) { + sprintf(eframe.regs[_pc_], " PC: %016lx", value); + eframe.value[_pc_] = value; + } + if (STRNEQ(buf, "gp = ")) { + sprintf(eframe.regs[_gp_], " GP/R29: %016lx", value); + eframe.value[_gp_] = value; + } + if (STRNEQ(buf, "r16 = ")) { + sprintf(eframe.regs[_r16_], " A0/R16: %016lx", value); + eframe.value[_r16_] = value; + } + if (STRNEQ(buf, "r17 = ")) { + sprintf(eframe.regs[_r17_], " A1/R17: %016lx", value); + eframe.value[_r17_] = value; + } + if (STRNEQ(buf, "r18 =")) { + sprintf(eframe.regs[_r18_], " A2/R18: %016lx", value); + eframe.value[_r18_] = value; + } + } + close_tmpfile(); + + if ((flags & BT_EXCEPTION_FRAME) && !BT_REFERENCE_CHECK(bt)) { +dump_eframe: + fprintf(fp, " EFRAME: %lx ", addr); + fprintf(fp, "%s\n", eframe.regs[_r24_]); + + for (i = 0; i < (((NUMREGS+1)/2)-1); i++) { + fprintf(fp, "%s ", eframe.regs[i]); + pad_line(fp, 21 - strlen(eframe.regs[i]), ' '); + j = i+((NUMREGS+1)/2); + fprintf(fp, "%s", eframe.regs[j]); + if (((j == _pc_) || (j == _r26_)) && + is_kernel_text(eframe.value[j])) + fprintf(fp, " <%s>", + value_to_symstr(eframe.value[j], buf, 0)); + fprintf(fp, "\n"); + } + } + + req->ra = eframe.value[_r26_]; + req->pc = eframe.value[_pc_]; + req->sp = addr + (29 * sizeof(ulong)); + + if (flags & BT_USER_EFRAME) { + flags &= ~BT_USER_EFRAME; + if (!BT_REFERENCE_CHECK(bt) && (eframe.value[_ps_] == 8) && + (((uvtop(task_to_context(req->task), req->pc, &paddr, 0) || + (volatile ulong)paddr) && + (uvtop(task_to_context(req->task), req->ra, &paddr, 0) || + (volatile ulong)paddr)) || + (IS_ZOMBIE(req->task) || IS_EXITING(req->task)))) { + if (!(flags & + (BT_RESCHEDULE|BT_RET_FROM_SMP_FORK|BT_STRACE))) + fprintf(fp, + "NOTE: kernel-entry exception frame:\n"); + goto dump_eframe; + } + } +} + +/* + * Look for likely exception frames in a stack. + */ +struct sw_64_pt_regs { + ulong reg_value[NUMREGS]; +}; + +static int +sw64_eframe_search(struct bt_info *bt) +{ + ulong *first, *last; + ulong eframe; + struct sw_64_pt_regs *pt; + struct gnu_request *req; /* needed for sw64_exception_frame */ + ulong *stack; + int cnt; + + stack = (ulong *)bt->stackbuf; + req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); + req->task = bt->task; + + first = stack + + (roundup(SIZE(task_struct), sizeof(ulong)) / sizeof(ulong)); + last = stack + + (((bt->stacktop - bt->stackbase) - SIZE(pt_regs)) / sizeof(ulong)); + + for (cnt = 0; first <= last; first++) { + pt = (struct sw_64_pt_regs *)first; + + /* check for kernel exception frame */ + + if (!(pt->reg_value[_ps_] & 0xfffffffffffffff8) && + (is_kernel_text(pt->reg_value[_pc_]) || + IS_MODULE_VADDR(pt->reg_value[_pc_])) && + (is_kernel_text(pt->reg_value[_r26_]) || + IS_MODULE_VADDR(pt->reg_value[_r26_])) && + IS_KVADDR(pt->reg_value[_gp_])) { + cnt++; + if (bt->flags & BT_EFRAME_COUNT) + continue; + fprintf(fp, "\nKERNEL-MODE EXCEPTION FRAME:\n"); + eframe = bt->task + ((ulong)first - (ulong)stack); + sw64_exception_frame(eframe, BT_EXCEPTION_FRAME, + req, bt); + continue; + } + + /* check for user exception frame */ + + if ((pt->reg_value[_ps_] == 0x8) && + ((IN_TASK_VMA(bt->task, pt->reg_value[_pc_]) && + IN_TASK_VMA(bt->task, pt->reg_value[_r26_]) && + IS_UVADDR(pt->reg_value[_gp_], bt->tc)) || + ((first == last) && + (IS_ZOMBIE(bt->task) || IS_EXITING(bt->task))))) { + cnt++; + if (bt->flags & BT_EFRAME_COUNT) + continue; + fprintf(fp, "\nUSER-MODE EXCEPTION FRAME:\n"); + eframe = bt->task + ((ulong)first - (ulong)stack); + sw64_exception_frame(eframe, BT_EXCEPTION_FRAME, + req, bt); + } + } + + FREEBUF(req); + + return cnt; +} + +/* + * Before dumping a nonsensical exception frame, give it a quick test. + */ +static int +verify_user_eframe(struct bt_info *bt, ulong task, ulong sp) +{ + struct sw_64_pt_regs ptbuf, *pt; + + readmem(sp, KVADDR, &ptbuf, sizeof(struct sw_64_pt_regs), + "pt_regs", FAULT_ON_ERROR); + + pt = &ptbuf; + + if ((pt->reg_value[_ps_] == 0x8) && + ((IN_TASK_VMA(task, pt->reg_value[_pc_]) && + IN_TASK_VMA(task, pt->reg_value[_r26_]) && + IS_UVADDR(pt->reg_value[_gp_], bt->tc)) || + ((pt == (struct sw_64_pt_regs *)USER_EFRAME_ADDR(task)) && + (IS_ZOMBIE(task) || IS_EXITING(task))))) { + return TRUE; + } + + return FALSE; +} + +/* + * Try to resync the stack location when there is no valid stack frame, + * typically just above an exception frame. Use the req->ra value from the + * exception frame as the new starting req->pc. Then walk up the stack until + * a text routine that calls the newly-assigned pc is found -- that stack + * location then becomes the new req->sp. + * + * If we're not coming from an exception frame, req-ra and req->pc will be + * purposely zeroed out. In that case, use the prevsp value to find the + * first pc that called the last frame's pc. + * + * Add any other repeatable "special-case" frames to the beginning of this + * routine (ex. debug_spin_lock). Last ditch -- at the end of this routine, + * speculate what might have happened (possibly in the background) -- and + * if it looks good, run with it. + */ +static int +sw64_backtrace_resync(struct gnu_request *req, ulong flags, struct bt_info *bt) +{ + char addr[BUFSIZE]; + char buf[BUFSIZE]; + char lookfor1[BUFSIZE]; + char lookfor2[BUFSIZE]; + ulong newpc; + ulong *stkp; + ulong *stkp_newpc, *stkp_next; + ulong value; + int found; + char *name; + int exception; + + if (CRASHDEBUG(1)) + fprintf(fp, + "RESYNC1: [%lx-%d] ra: %lx pc: %lx sp: %lx\n", + flags, req->curframe, req->ra, req->pc, req->sp); + + if (!req->ra && !req->pc) { + req->ra = req->prevpc; + exception = FALSE; + } else + exception = TRUE; + + if (!IS_KVADDR(req->ra)) + return FALSE; + + name = closest_symbol(req->ra); + sprintf(lookfor1, "<%s>", name); + sprintf(lookfor2, "<%s+", name); + + if (CRASHDEBUG(1)) + fprintf(fp, "RESYNC2: exception: %s lookfor: %s or %s\n", + exception ? "TRUE" : "FALSE", + lookfor1, lookfor2); + + /* + * This is common when a non-panicking active CPU is spinning + * in debug_spin_lock(). The next pc is offset by 0x30 from + * the top of the exception frame, and the next sp is equal + * to the frame offset of debug_spin_lock(). I can't explain it... + */ + if ((flags & BT_FROM_EXCEPTION) && STREQ(name, "debug_spin_lock")) { + sw64_print_stack_entry(req, req->ra, + closest_symbol(req->ra), flags, bt); + + if (BT_REFERENCE_FOUND(bt)) + return FALSE; + + sw64_frame_offset(req, req->ra); + stkp = (ulong *)(req->sp + 0x30); + value = GET_STACK_ULONG(stkp); + if (!is_kernel_text(value)) { + req->sp = req->prevsp; + return FALSE; + } + req->pc = value; + req->sp += req->value; + return TRUE; + } + + /* + * If the ra is a system call, then all we should have to do is + * find the next reference to entSys on the stack, and set the + * sp to that value. + */ + if (is_system_call(name, 0)) { + /* stkp = (ulong *)req->sp; */ + stkp = (ulong *)req->prevsp; + + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + + if (IS_KVADDR(value) && is_kernel_text(value)) { + if (STREQ(closest_symbol(value), "entSys")) { + req->pc = value; + req->sp = USER_EFRAME_ADDR(req->task); + return TRUE; + } + } + } + } + + /* + * Just find the next location containing text. (?) + */ + if (STREQ(name, "do_coredump")) { + stkp = (ulong *)(req->sp + sizeof(long)); + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + + if (IS_KVADDR(value) && is_kernel_text(value)) { + req->pc = req->ra; + req->sp = (ulong)stkp; + return TRUE; + } + } + } + + if (flags & BT_SPECULATE) + return FALSE; + + if (CRASHDEBUG(1)) { + fprintf(fp, "RESYNC3: prevsp: %lx ra: %lx name: %s\n", + req->prevsp, req->ra, name); + fprintf(fp, "RESYNC3: prevpc: %lx\n", req->prevpc); + } + + stkp_newpc = stkp_next = 0; + newpc = 0; + found = FALSE; + if (exception) { + newpc = req->ra; + stkp = (ulong *)req->sp; + } else + stkp = (ulong *)req->prevsp; + + if (CRASHDEBUG(1)) + fprintf(fp, "RESYNC4: stkp: %lx newpc: %lx\n", + (ulong)stkp, newpc); + + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + /* + * First find the new pc on the stack. + */ + if (!found) { + if (!exception && is_kernel_text(value)) { + found = TRUE; + } else if (value == newpc) { + found = TRUE; + stkp_newpc = stkp; + continue; + } + } + + if (!IS_KVADDR(value)) + continue; + + if (is_kernel_text(value)) { + if (!stkp_next) + stkp_next = stkp; + if (CRASHDEBUG(2)) { + fprintf(fp, + "RESYNC6: disassemble %lx (%s)\n", + value - sizeof(uint), + value_to_symstr(value - sizeof(uint), + buf, 0)); + } + req->command = GNU_DISASSEMBLE; + req->addr = value - sizeof(uint); + sprintf(addr, "0x%lx", req->addr); + open_tmpfile(); + req->fp = pc->tmpfile; + gdb_interface(req); + rewind(pc->tmpfile); + while (fgets(buf, BUFSIZE, pc->tmpfile)) { + clean_line(buf); + if (STRNEQ(buf, "Dump of") || + STRNEQ(buf, "End of")) + continue; + + if (STRNEQ(buf, addr)) { + if (LASTCHAR(buf) == ':') { + fgets(buf, BUFSIZE, + pc->tmpfile); + clean_line(buf); + } + if (CRASHDEBUG(2) && + (strstr(buf, "jsr") + || strstr(buf, "bsr"))) + fprintf(pc->saved_fp, "%s\n", + buf); + if ((strstr(buf, "jsr") || + strstr(buf, "bsr")) && + (strstr(buf, lookfor1) || + strstr(buf, lookfor2))) { + if (exception) { + req->pc = newpc; + req->sp = (ulong)stkp; + } else + req->pc = req->addr; + close_tmpfile(); + return TRUE; + } + } + } + close_tmpfile(); + } + } + + if (CRASHDEBUG(1)) { + fprintf(fp, "RESYNC9: [%d] name: %s pc: %lx ra: %lx\n", + req->curframe, name, req->pc, req->ra); + fprintf(fp, "RESYNC9: sp: %lx lastsp: %lx\n", + req->sp, req->lastsp); + fprintf(fp, "RESYNC9: prevpc: %lx prevsp: %lx\n", + req->prevpc, req->prevsp); + } + + /* + * At this point, all we can do is speculate based upon + * past experiences... + */ + return (sw64_resync_speculate(req, flags, bt)); +} + +/* + * Try one level of speculation. If it works, fine -- if not, give up. + */ +static int +sw64_resync_speculate(struct gnu_request *req, ulong flags, struct bt_info *bt) +{ + ulong *stkp; + ulong value; + ulong found_sp, found_ra; + struct stack_hook hook; + struct bt_info bt_info, *btloc; + char buf[BUFSIZE]; + int kernel_thread; + int looks_good; + + if (flags & BT_SPECULATE) /* already been here on this trace... */ + return FALSE; + + if (pc->tmpfile) + return FALSE; + + found_ra = found_sp = 0; + kernel_thread = is_kernel_thread(req->task); + + /* + * Add "known" possibilities here. + */ + switch (flags & (BT_FROM_EXCEPTION|BT_FROM_CALLFRAME)) + { + case BT_FROM_EXCEPTION: + if (STREQ(closest_symbol(req->prevpc), "read_lock") || + STREQ(closest_symbol(req->ra), "do_select") || + STREQ(closest_symbol(req->ra), "schedule")) { + stkp = (ulong *)req->sp; + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + + if (found_ra) { + if (is_kernel_text_offset(value)) { + found_sp = (ulong)stkp; + break; + } + continue; + } + + if (value == req->ra) + found_ra = value; + } + } + break; + + case BT_FROM_CALLFRAME: + if (STREQ(closest_symbol(req->ra), "sys_read")) { + value = GET_STACK_ULONG(req->prevsp - 32); + if (STREQ(closest_symbol(value), "entSys")) { + found_ra = value; + found_sp = req->prevsp - 32; + } + } else if (STREQ(closest_symbol(req->ra), "exit_autofs4_fs")) { + stkp = (ulong *)req->sp; + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + + if (found_ra && (value != found_ra)) { + if (is_kernel_text_offset(value)) { + found_sp = (ulong)stkp; + break; + } + continue; + } + + if (is_kernel_text_offset(value)) + found_ra = value; + } + } + + break; + + default: + if (req->hookp && + STREQ(closest_symbol(req->prevpc), "filemap_nopage") && + !STREQ(closest_symbol(req->hookp->eip), "do_no_page")) { + found_ra = found_sp = 0; + stkp = (ulong *)req->prevsp; + for (stkp++; INSTACK(stkp, bt); stkp++) { + value = GET_STACK_ULONG(stkp); + + if (found_ra && (value != found_ra)) { + if (is_kernel_text_offset(value)) { + found_sp = (ulong)stkp; + break; + } + continue; + } + + if (is_kernel_text_offset(value) && + STREQ(closest_symbol(value), "do_no_page")) + found_ra = value; + } + if (found_ra && found_sp) { + req->hookp->eip = found_ra; + req->hookp->esp = found_sp; + return TRUE; + } + } + + if (req->hookp) { + found_ra = req->hookp->eip; + found_sp = req->hookp->esp; + } + + break; + } + + if (found_ra && found_sp) { + looks_good = FALSE; + hook.esp = found_sp; + hook.eip = found_ra; + + if (CRASHDEBUG(1)) + fprintf(pc->saved_fp, + "----- RESYNC SPECULATE START -----\n"); + + open_tmpfile(); + btloc = &bt_info; + BZERO(btloc, sizeof(struct bt_info)); + btloc->task = req->task; + btloc->tc = bt->tc; + btloc->stackbase = bt->stackbase; + btloc->stacktop = bt->stacktop; + btloc->flags = BT_SPECULATE; + btloc->hp = &hook; + back_trace(btloc); + rewind(pc->tmpfile); + while (fgets(buf, BUFSIZE, pc->tmpfile)) { + if (CRASHDEBUG(1)) + fprintf(pc->saved_fp, "%s", buf); + + if (strstr(buf, "NOTE: cannot resolve")) { + looks_good = FALSE; + break; + } + + if (strstr(buf, "SW64 EXCEPTION FRAME")) { + looks_good = TRUE; + break; + } + + if (kernel_thread) { + if (strstr(buf, " kernel_thread ") || + strstr(buf, " __kernel_thread ") || + strstr(buf, " start_kernel ") || + strstr(buf, " smp_callin ")) { + looks_good = TRUE; + break; + } + } + } + close_tmpfile(); + + if (CRASHDEBUG(1)) + fprintf(pc->saved_fp, + "----- RESYNC SPECULATE DONE ------\n"); + + if (looks_good) { + req->pc = found_ra; + req->sp = found_sp; + return TRUE; + } + } + + return FALSE; +} + +/* + * Translates a user virtual address to its physical address. cmd_vtop() + * sets the verbose flag so that the pte translation gets displayed; all + * other callers quietly accept the translation. + * + * This routine can also take mapped kernel virtual addresses if the -u flag + * was passed to cmd_vtop(). If so, it makes the translation using the + * kernel-memory PGD entry instead of swapper_pg_dir. + */ + +static int +sw64_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose) +{ + ulong mm; + ulong *pgd; + ulong *page_dir; + ulong *page_middle; + ulong *page_table; + ulong pgd_pte; + ulong pmd_pte; + ulong pte; + + if (!tc) + error(FATAL, "current context invalid\n"); + + *paddr = 0; + + if (is_kernel_thread(tc->task) && IS_KVADDR(vaddr)) { + pgd = (ulong *)machdep->get_task_pgd(tc->task); + } else { + if (!tc->mm_struct) + pgd = (ulong *)machdep->get_task_pgd(tc->task); + else { + if ((mm = task_mm(tc->task, TRUE))) + pgd = ULONG_PTR(tt->mm_struct + + OFFSET(mm_struct_pgd)); + else + readmem(tc->mm_struct + OFFSET(mm_struct_pgd), + KVADDR, &pgd, sizeof(long), + "mm_struct pgd", FAULT_ON_ERROR); + } + } + + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); + + page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); + pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); + + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); + + if (!(pgd_pte & _PAGE_VALID)) + goto no_upage; + + page_middle = (ulong *) + (PTOV((pgd_pte & _PFN_MASK) >> (32-PAGESHIFT()))) + + ((vaddr >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); + pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); + + if (verbose) + fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); + + if (!(pmd_pte & _PAGE_VALID)) + goto no_upage; + + page_table = (ulong *) + (PTOV((pmd_pte & _PFN_MASK) >> (32-PAGESHIFT()))) + + (BTOP(vaddr) & (PTRS_PER_PAGE - 1)); + + FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); + pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); + + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); + + if (!(pte & (_PAGE_VALID))) { + *paddr = pte; + if (pte && verbose) { + fprintf(fp, "\n"); + sw64_translate_pte(pte, 0, 0); + } + goto no_upage; + } + + *paddr = ((pte & _PFN_MASK) >> (32-PAGESHIFT())) + PAGEOFFSET(vaddr); + + if (verbose) { + fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); + sw64_translate_pte(pte, 0, 0); + } + + return TRUE; + +no_upage: + return FALSE; +} + +/* + * Translates a kernel virtual address to its physical address. cmd_vtop() + * sets the verbose flag so that the pte translation gets displayed; all + * other callers quietly accept the translation. + */ +static int sw64_is_kvddr(ulong addr) +{ + if (addr > 0xffffffff80000000){ + return 1; + } + if (addr > 0xfff0000000000000 && addr < 0xfffff7ffffffffff){ + return 1; + } + return 0; +} + +static int +sw3231_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) +{ + ulong *pgd; + ulong *page_dir; + ulong *page_upper; + ulong *page_middle; + ulong *page_table; + ulong pgd_pte; + ulong pud_pte; + ulong pmd_pte; + ulong pte; + + // if (!IS_KVADDR(kvaddr)) + // return FALSE; + + // if (!vt->vmalloc_start) { /* presume KSEG this early */ + // *paddr = VTOP(kvaddr); + // return TRUE; + // } + + // if (!IS_VMALLOC_ADDR(kvaddr)) { + // *paddr = VTOP(kvaddr); + // return TRUE; + // } + + if (kvaddr > 0xffffffff80000000){ + *paddr = kvaddr - 0xffffffff80000000; + // printf("direct map:%-16lx ----> %-16lx\n", kvaddr, *paddr); + return TRUE; + } + if (kvaddr > 0xfff0000000000000 && kvaddr < 0xfff0ffffffffffff){ + *paddr = kvaddr - 0xfff0000000000000; +// printf("direct map:%-16lx ----> %-16lx\n", kvaddr, *paddr); + return TRUE; + } + + pgd = (ulong *)vt->kernel_pgd[0]; + + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx, kvaddr: %#lx\n", (ulong)pgd, kvaddr); + + page_dir = pgd + ((kvaddr >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); + pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); + + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); + + if (!(pgd_pte & _PAGE_VALID)) + goto no_kpage; + + page_upper = (ulong *) + (PTOV((pgd_pte & _PFN_MASK) >> (PFN_SHIFT - PAGESHIFT()))) + + ((kvaddr >> PUD_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PUD(PAGEBASE(page_upper), KVADDR, PAGESIZE()); + pud_pte = ULONG(machdep->pud + PAGEOFFSET(page_upper)); + + if (verbose) + fprintf(fp, " PUD: %lx => %lx\n", (ulong)page_upper, pud_pte); + + if (!(pud_pte & _PAGE_VALID)) + goto no_kpage; + + page_middle = (ulong *) + (PTOV((pud_pte & _PFN_MASK) >> (PFN_SHIFT - PAGESHIFT()))) + + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); + pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); + + if (verbose) + fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); + + if (!(pmd_pte & _PAGE_VALID)) + goto no_kpage; + + page_table = (ulong *) + (PTOV((pmd_pte & _PFN_MASK) >> (PFN_SHIFT - PAGESHIFT()))) + + (BTOP(kvaddr) & (PTRS_PER_PAGE - 1)); + + FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); + pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); + + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); + + if (!(pte & (_PAGE_VALID))) { + if (pte && verbose) { + fprintf(fp, "\n"); + sw64_translate_pte(pte, 0, 0); + } + goto no_kpage; + } + + *paddr = ((pte & _PFN_MASK) >> (PFN_SHIFT - PAGESHIFT())) + PAGEOFFSET(kvaddr); + + if (verbose) { + fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); + sw64_translate_pte(pte, 0, 0); + } + + return TRUE; + +no_kpage: + return FALSE; +} + +static int +sw6432_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) +{ + ulong *pgd; + ulong *page_dir; + ulong *page_upper; + ulong *page_middle; + ulong *page_table; + ulong pgd_pte; + ulong pud_pte; + ulong pmd_pte; + ulong pte; + + // if (!IS_KVADDR(kvaddr)) + // return FALSE; + + // if (!vt->vmalloc_start) { /* presume KSEG this early */ + // *paddr = VTOP(kvaddr); + // return TRUE; + // } + + // if (!IS_VMALLOC_ADDR(kvaddr)) { + // *paddr = VTOP(kvaddr); + // return TRUE; + // } + + if (kvaddr > 0xffffffff80000000){ + *paddr = kvaddr - 0xffffffff80000000; + // printf("direct map:%-16lx ----> %-16lx\n", kvaddr, *paddr); + return TRUE; + } + if (kvaddr > 0xfff0000000000000 && kvaddr < 0xfff0ffffffffffff){ + *paddr = kvaddr - 0xfff0000000000000; +// printf("direct map:%-16lx ----> %-16lx\n", kvaddr, *paddr); + return TRUE; + } + + pgd = (ulong *)vt->kernel_pgd[0]; + + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %lx, kvaddr: %#lx\n", (ulong)pgd, kvaddr); + + page_dir = pgd + ((kvaddr >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); + pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); + + if (verbose) + fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); + + if (!(pgd_pte & _PAGE_VALID)) + goto no_kpage; + + page_upper = (ulong *) + (PTOV((pgd_pte & (_PFN_MASK / 32)) >> (PFN_SHIFT - 4 - PAGESHIFT()))) + + ((kvaddr >> PUD_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PUD(PAGEBASE(page_upper), KVADDR, PAGESIZE()); + pud_pte = ULONG(machdep->pud + PAGEOFFSET(page_upper)); + + if (verbose) + fprintf(fp, " PUD: %lx => %lx\n", (ulong)page_upper, pud_pte); + + if (!(pud_pte & _PAGE_VALID)) + goto no_kpage; + + page_middle = (ulong *) + (PTOV((pud_pte & (_PFN_MASK / 32)) >> (PFN_SHIFT - 4 - PAGESHIFT()))) + + ((kvaddr >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + + FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); + pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); + + if (verbose) + fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); + + if (!(pmd_pte & _PAGE_VALID)) + goto no_kpage; + + page_table = (ulong *) + (PTOV((pmd_pte & (_PFN_MASK / 32)) >> (PFN_SHIFT - 4 - PAGESHIFT()))) + + (BTOP(kvaddr) & (PTRS_PER_PAGE - 1)); + + FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); + pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); + + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); + + if (!(pte & (_PAGE_VALID))) { + if (pte && verbose) { + fprintf(fp, "\n"); + sw64_translate_pte(pte, 0, 0); + } + goto no_kpage; + } + + *paddr = ((pte & (_PFN_MASK / 32)) >> (PFN_SHIFT - 4 - PAGESHIFT())) + PAGEOFFSET(kvaddr); + + if (verbose) { + fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); + sw64_translate_pte(pte, 0, 0); + } + + return TRUE; + +no_kpage: + return FALSE; +} + + +/* + * Get the relevant page directory pointer from a task structure. + */ +static ulong +sw64_get_task_pgd(ulong task) +{ + long offset; + ulong ptbr; + + offset = OFFSET_OPTION(task_struct_thread, task_struct_tss); + + offset += OFFSET(thread_struct_ptbr); + + readmem(task + offset, KVADDR, &ptbr, + sizeof(ulong), "task thread ptbr", FAULT_ON_ERROR); + + return(PTOV(PTOB(ptbr))); +} + +/* + * Calculate and return the speed of the processor. + */ +static ulong +sw64_processor_speed(void) +{ + ulong mhz; + long cycle_freq = 2400000000; + + mhz = cycle_freq/1000000; + + return (machdep->mhz = mhz); +} + +void +sw64_dump_machdep_table(ulong arg) +{ + int others; + + others = 0; + fprintf(fp, " flags: %lx (", machdep->flags); + if (machdep->flags & HWRESET) + fprintf(fp, "%sHWRESET", others++ ? "|" : ""); + fprintf(fp, ")\n"); + fprintf(fp, " kvbase: %lx\n", machdep->kvbase); + fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base); + fprintf(fp, " pagesize: %d\n", machdep->pagesize); + fprintf(fp, " pageshift: %d\n", machdep->pageshift); + fprintf(fp, " pagemask: %llx\n", machdep->pagemask); + fprintf(fp, " pageoffset: %lx\n", machdep->pageoffset); + fprintf(fp, " stacksize: %ld\n", machdep->stacksize); + fprintf(fp, " hz: %d\n", machdep->hz); + fprintf(fp, " mhz: %ld\n", machdep->mhz); + fprintf(fp, " memsize: %ld (0x%lx)\n", + machdep->memsize, machdep->memsize); + fprintf(fp, " bits: %d\n", machdep->bits); + fprintf(fp, " nr_irqs: %d\n", machdep->nr_irqs); + fprintf(fp, " eframe_search: sw64_eframe_search()\n"); + fprintf(fp, " back_trace: sw64_back_trace_cmd()\n"); + fprintf(fp, " processor_speed: sw64_processor_speed()\n"); + fprintf(fp, " uvtop: sw64_uvtop()\n"); + fprintf(fp, " kvtop: sw64_uvtop()\n"); + fprintf(fp, " get_task_pgd: sw64_get_task_pgd()\n"); + fprintf(fp, " dump_irq: generic_dump_irq()\n"); + fprintf(fp, " get_stack_frame: sw64_get_stack_frame()\n"); + fprintf(fp, " get_stackbase: generic_get_stackbase()\n"); + fprintf(fp, " get_stacktop: generic_get_stacktop()\n"); + fprintf(fp, " translate_pte: sw64_translate_pte()\n"); + fprintf(fp, " memory_size: sw64_get_memory_size()\n"); + fprintf(fp, " vmalloc_start: sw64_get_vmalloc_start()\n"); + fprintf(fp, " is_task_addr: sw64_is_task_addr()\n"); + fprintf(fp, " verify_symbol: sw64_verify_symbol()\n"); + fprintf(fp, " dis_filter: sw64_dis_filter()\n"); + fprintf(fp, " cmd_mach: sw64_cmd_mach()\n"); + fprintf(fp, " get_smp_cpus: sw64_get_smp_cpus()\n"); + fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); + fprintf(fp, " is_uvaddr: generic_is_uvaddr()\n"); + fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); + fprintf(fp, " init_kernel_pgd: NULL\n"); + fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); + fprintf(fp, " line_number_hooks: sw64_line_number_hooks\n"); + fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); + fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read); + fprintf(fp, " last_ptbl_read: %lx\n", machdep->last_ptbl_read); + fprintf(fp, " pgd: %lx\n", (ulong)machdep->pgd); + fprintf(fp, " pud: %lx\n", (ulong)machdep->pud); + fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); + fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); + fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); + fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec); +} + +/* + * Fix up jsr's to show the right target. + * + * If a value is passed with no buf, then cmd_dis is fishing for whether + * the GP can be calculated from the first couple of instructions of the + * target routine: + * + * 0xfffffc0000349fa0 : ldah gp,35(t12) + * 0xfffffc0000349fa4 : lda gp,6216(gp) + * + * If a buf pointer is passed, then check whether the t12 register + * is being set up as an offset from gp, then calculate the target address: + * + * 0xfffffc000042c364 : ldq t12,-29336(gp) + * 0xfffffc000042c368 : + * jsr ra,(t12),0xfffffc0000429dc0 + * + * If the next instruction is a jsr ra,(t12), then correct the bracketed + * target address translation. + * + */ + +#define LDAH_GP_T12 (0x27bb0000) +#define LDA_GP_GP (0x23bd0000) +#define LDQ_T12_GP (0xa77d0000) +#define JSR_RA_T12 (0x6b5b0000) + +#define OPCODE_OPERAND_MASK (0xffff0000) +#define OPCODE_MEM_DISP_MASK (0x0000ffff) + +static struct instruction_data { + uint inst[2]; + short mem_disp[2]; + ulong gp; + ulong target; + char *curfunc; +} instruction_data = { {0} }; + +static int +sw64_dis_filter(ulong vaddr, char *buf, unsigned int output_radix) +{ + struct syment *sp; + struct instruction_data *id; + char buf2[BUFSIZE], *p1; + + id = &instruction_data; + + if (!buf) { + BZERO(id, sizeof(struct instruction_data)); + + if (!(sp = value_search(vaddr, NULL))) + return FALSE; + + readmem(sp->value, KVADDR, &id->inst[0], + sizeof(uint) * 2, "two instructions", FAULT_ON_ERROR); + + if (((id->inst[0] & OPCODE_OPERAND_MASK) == LDAH_GP_T12) && + ((id->inst[1] & OPCODE_OPERAND_MASK) == LDA_GP_GP)) { + id->mem_disp[0] = (short)(id->inst[0] & + OPCODE_MEM_DISP_MASK); + id->mem_disp[1] = (short)(id->inst[1] & + OPCODE_MEM_DISP_MASK); + id->gp = sp->value + (65536*id->mem_disp[0]) + + id->mem_disp[1]; + id->curfunc = sp->name; + + if (CRASHDEBUG(1)) + console("%s: ldah(%d) and lda(%d) gp: %lx\n", + id->curfunc, + id->mem_disp[0], id->mem_disp[1], + id->gp); + + return TRUE; + } + /* send all lines through the generic */ + return TRUE; /* dis_address_translation() filter */ + } + + dis_address_translation(vaddr, buf, output_radix); + + if (!id->gp || !(sp = value_search(vaddr, NULL)) || + !STREQ(id->curfunc, sp->name)) { + BZERO(id, sizeof(struct instruction_data)); + return FALSE; + } + + readmem(vaddr, KVADDR, &id->inst[0], + sizeof(uint), "one instruction", FAULT_ON_ERROR); + + if ((id->inst[0] & OPCODE_OPERAND_MASK) == JSR_RA_T12) { + + if (!id->target || !strstr(buf, "jsr\tra,(t12)") || + !strstr(buf, "<")) + return FALSE; + + p1 = strstr(strstr(buf, "jsr"), "0x"); + sprintf(p1, "0x%lx <%s>%s", + id->target, + value_to_symstr(id->target, buf2, output_radix), + CRASHDEBUG(1) ? " [PATCHED]\n" : "\n"); + return TRUE; + } + + if ((id->inst[0] & OPCODE_OPERAND_MASK) == LDQ_T12_GP) { + id->mem_disp[0] = (short)(id->inst[0] & OPCODE_MEM_DISP_MASK); + readmem(id->gp + id->mem_disp[0], KVADDR, &id->target, + sizeof(ulong), "jsr target", FAULT_ON_ERROR); + } else + id->target = 0; + + return TRUE; +} + +/* + * For some reason gdb can go off into the weeds translating text addresses, + * so this routine both fixes the references as well as imposing the current + * output radix on the translations. + */ +static void +dis_address_translation(ulong vaddr, char *inbuf, unsigned int output_radix) +{ + char buf1[BUFSIZE]; + char buf2[BUFSIZE]; + char *colon, *p1; + int argc; + char *argv[MAXARGS]; + ulong value; + + console("IN: %s", inbuf); + + colon = strstr(inbuf, ":"); + + if (colon) { + sprintf(buf1, "0x%lx <%s>", vaddr, + value_to_symstr(vaddr, buf2, output_radix)); + sprintf(buf2, "%s%s", buf1, colon); + strcpy(inbuf, buf2); + } + + strcpy(buf1, inbuf); + argc = parse_line(buf1, argv); + + if ((FIRSTCHAR(argv[argc-1]) == '<') && + (LASTCHAR(argv[argc-1]) == '>')) { + p1 = rindex(inbuf, '<'); + while ((p1 > inbuf) && (*p1 != ',')) + p1--; + + if (!STRNEQ(p1, ",0x")) + return; + p1++; + + if (!extract_hex(p1, &value, NULLCHAR, TRUE)) + return; + + sprintf(buf1, "0x%lx <%s>\n", value, + value_to_symstr(value, buf2, output_radix)); + + sprintf(p1, "%s", buf1); + } + + console(" %s", inbuf); +} + +static int +sw64_get_dumpfile_stackframe(struct bt_info *bt, ulong *fp, ulong *sp) +{ + struct machine_specific *ms = machdep->machspec; + struct sw64_pt_regs *ptregs; + ulong pc; + + if (!ms->panic_task_regs || + (!ms->panic_task_regs[bt->tc->processor].usp && + !ms->panic_task_regs[bt->tc->processor].pc)) { + bt->flags |= BT_REGS_NOT_FOUND; + return FALSE; + } + + ptregs = &ms->panic_task_regs[bt->tc->processor]; + pc = ptregs->pc; +// if (user_mode(ptregs)) { +// sp = ptregs->usp; +// fp = ptregs->r15; +// if (is_kernel_text(pc) || +// !in_user_stack(bt->tc->task, sp)) { +// error(WARNING, +// "corrupt NT_PRSTATUS? pstate: 0x%lx, but no user frame found\n", +// ptregs->pstate); +// if (is_kernel_text(pc) && +// INSTACK(sp, bt) && INSTACK(fp, bt)) +// goto try_kernel; +// bt->flags |= BT_REGS_NOT_FOUND; +// return FALSE; +// } +// bt->flags |= BT_USER_SPACE; +// } else { +// try_kernel: + *fp = ptregs->r15; + *sp = ptregs->usp; + // } + + return TRUE; +} + +static int +sw64_get_stackframe(struct bt_info *bt, ulong *fp, ulong *sp) +{ + if (!fill_task_struct(bt->task)) + return FALSE; + + *sp = ULONG(tt->task_struct + OFFSET(task_struct_thread_context_sp)); + *fp = ULONG(tt->task_struct + OFFSET(task_struct_thread_context_fp)); + + return TRUE; +} + +static void +sw64_get_stack_frame(struct bt_info *bt, ulong *fp, ulong *sp) +{ + int ret; + if (DUMPFILE()) + ret = sw64_get_dumpfile_stackframe(bt, fp, sp); + else + ret = sw64_get_stackframe(bt, fp, sp); + + if (!ret) + error(WARNING, + "cannot determine starting stack frame for task %lx\n", + bt->task); +} + +/* + * Do the work formerly done by sw64_get_sp() and sw64_get_pc(). + */ +static void +get_sw64_frame(struct bt_info *bt, ulong *getpc, ulong *getsp) +{ + int i; + ulong ip; + ulong r26; + ulong ksp, sp; + ulong *spp; + ulong percpu_ra; + ulong percpu_pv; + struct percpu_data percpu_data; + char buf[BUFSIZE]; + ulong task; + ulong *stack; + + task = bt->task; + stack = (ulong *)bt->stackbuf; + + if (tt->flags & THREAD_INFO) { /* pcb.ksp is 1st word in thread_info */ + readmem(bt->tc->thread_info, KVADDR, &ksp, sizeof(ulong), + "thread_info pcb ksp", FAULT_ON_ERROR); + sp = ksp; + printf("THREAD_INFO ksp:%lx\n", sp); + } else if (VALID_MEMBER(task_struct_tss_ksp)){ + ksp = sp = stack[OFFSET(task_struct_tss_ksp)/sizeof(long)]; + printf("task_struct_tss_ksp ksp:%lx\n", sp); + } + else { + ksp = sp = stack[OFFSET(task_struct_thread_ksp)/sizeof(long)]; + printf("else ksp:%lx\n", sp); + } + + ip = 0; + percpu_ra = percpu_pv = 0; + spp = &stack[(sp - task)/sizeof(long)]; + printf("spp size:%lx\n", (sp - task)/sizeof(long)); + if (DUMPFILE() && getsp) { + if (HWRESET_TASK(task)) { + if (INSTACK(sp, bt)) { + *getsp = sp; + printf("HWRESET_TASK ksp:%lx\n", sp); + return; + } + else { + printf("else\n"); + get_percpu_data(0, 0, &percpu_data); + percpu_ra = percpu_data.halt_ra; + percpu_pv = percpu_data.halt_pv; + spp = &stack[roundup(SIZE(task_struct), + sizeof(ulong)) / sizeof(ulong)]; + } + } + + printf("not HWRESET_TASK\n"); + if (!percpu_ra && (STREQ(closest_symbol(*spp), "panic") || + STREQ(closest_symbol(*spp), "handle_ipi"))) { + *getsp = sp; + return; + } + } + +percpu_retry: + + printf("percpu_retry\n"); + if (CRASHDEBUG(1) && percpu_ra) { + fprintf(fp, "get_sw64_frame: look for %lx (%s)\n", + percpu_ra, value_to_symstr(percpu_ra, buf, 0)); + } + printf("get_sw64_frame: look for %lx (%s)\n", + percpu_ra, value_to_symstr(percpu_ra, buf, 0)); + for (i = 0, spp++; spp < &stack[LONGS_PER_STACK]; spp++,i++) { + + if (CRASHDEBUG(1) && (percpu_ra || percpu_pv) && + is_kernel_text(*spp)) { + fprintf(fp, "%lx: %lx (%s)\n", + ((ulong)spp - (ulong)stack) + task, + *spp, value_to_symstr(*spp, buf, 0)); + } + + if (percpu_ra) { + if (*spp == percpu_ra) { + *getsp = ((ulong)spp - (ulong)stack) + task; + return; + } + continue; + } else if (percpu_pv) { + if (*spp == percpu_pv) { + *getsp = ((ulong)spp - (ulong)stack) + task; + if (getpc) + *getpc = percpu_pv; + return; + } + continue; + } + + if (!INSTACK(*spp, bt)) + continue; + + if (is_kernel_text(*(spp+1))) { + sp = *spp; + ip = *(spp+1); + break; + } + } + + if (percpu_ra) { + percpu_ra = 0; + + error(INFO, + "cannot find return address (percpu_ra) in HARDWARE RESET stack\n"); + error(INFO, + "looking for procedure address (percpu_pv) in HARDWARE RESET stack\n"); + + if (CRASHDEBUG(1)) { + fprintf(fp, "get_sw64_frame: look for %lx (%s)\n", + percpu_pv, value_to_symstr(percpu_pv, buf, 0)); + } + spp = &stack[roundup(SIZE(task_struct), + sizeof(ulong)) / sizeof(ulong)]; + + goto percpu_retry; + } + + if (percpu_pv) { + error(INFO, + "cannot find procedure address (percpu_pv) in HARDWARE RESET stack\n"); + } + + /* + * Check for a forked task that has not yet run in user space. + */ + if (!ip) { + printf("Check for a forked task that has not yet run in user space.\n"); + if (INSTACK(ksp + OFFSET(switch_stack_r26), bt)) { + readmem(ksp + OFFSET(switch_stack_r26), KVADDR, + &r26, sizeof(ulong), + "ret_from_smp_fork check", FAULT_ON_ERROR); + if (STREQ(closest_symbol(r26), "ret_from_smp_fork") || + STREQ(closest_symbol(r26), "ret_from_smpfork")) { + ip = r26; + sp = ksp; + } + } + + } + + if (getsp) + *getsp = sp; + if (getpc) + *getpc = ip; + +} + +/* + * Fill the percpu_data structure with information from the + * hwrpb/percpu_data structures for a given CPU. If requested, + * return one of the specified entries. + */ +static ulong +get_percpu_data(int cpu, ulong flag, struct percpu_data *pd) +{ + ulong hwrpb, halt_ra, halt_PC, halt_pv; + unsigned long processor_offset, processor_size; + + get_symbol_data("hwrpb", sizeof(void *), &hwrpb); + + readmem(hwrpb+OFFSET(hwrpb_struct_processor_offset), KVADDR, + &processor_offset, sizeof(ulong), + "hwrpb processor_offset", FAULT_ON_ERROR); + + readmem(hwrpb+OFFSET(hwrpb_struct_processor_size), KVADDR, + &processor_size, sizeof(ulong), + "hwrpb processor_size", FAULT_ON_ERROR); + + readmem(hwrpb + processor_offset + (cpu * processor_size) + + OFFSET(percpu_struct_halt_PC), + KVADDR, &halt_PC, sizeof(ulong), + "percpu halt_PC", FAULT_ON_ERROR); + + readmem(hwrpb + processor_offset + (cpu * processor_size) + + OFFSET(percpu_struct_halt_ra), + KVADDR, &halt_ra, sizeof(ulong), + "percpu halt_ra", FAULT_ON_ERROR); + + readmem(hwrpb + processor_offset + (cpu * processor_size) + + OFFSET(percpu_struct_halt_pv), + KVADDR, &halt_pv, sizeof(ulong), + "percpu halt_pv", FAULT_ON_ERROR); + + if (pd) { + pd->halt_PC = halt_PC; + pd->halt_ra = halt_ra; + pd->halt_pv = halt_pv; + } + + switch (flag) + { + case GET_HALT_PC: + return halt_PC; + + case GET_HALT_RA: + return halt_ra; + + case GET_HALT_PV: + return halt_pv; + + default: + return 0; + } +} + +/* + * Translate a PTE, returning TRUE if the page is _PAGE_VALID or _PAGE_PRESENT, + * whichever is appropriate for the machine type. If a physaddr pointer is + * passed in, don't print anything. + */ +static int +sw64_translate_pte(ulong pte, void *physaddr, ulonglong unused) +{ + int c, len1, len2, len3, others, page_present; + char buf[BUFSIZE]; + char buf2[BUFSIZE]; + char buf3[BUFSIZE]; + char ptebuf[BUFSIZE]; + char physbuf[BUFSIZE]; + char *arglist[MAXARGS]; + physaddr_t paddr; + + paddr = PTOB(pte >> 32); + page_present = (pte & _PAGE_VALID); + + if (physaddr) { + *((ulong *)physaddr) = paddr; + return page_present; + } + + sprintf(ptebuf, "%lx", pte); + len1 = MAX(strlen(ptebuf), strlen("PTE")); + fprintf(fp, "%s ", mkstring(buf, len1, CENTER|LJUST, "PTE")); + + if (!page_present && pte) { + swap_location(pte, buf); + if ((c = parse_line(buf, arglist)) != 3) + error(FATAL, "cannot determine swap location\n"); + + len2 = MAX(strlen(arglist[0]), strlen("SWAP")); + len3 = MAX(strlen(arglist[2]), strlen("OFFSET")); + + fprintf(fp, "%s %s\n", + mkstring(buf2, len2, CENTER|LJUST, "SWAP"), + mkstring(buf3, len3, CENTER|LJUST, "OFFSET")); + + strcpy(buf2, arglist[0]); + strcpy(buf3, arglist[2]); + fprintf(fp, "%s %s %s\n", + mkstring(ptebuf, len1, CENTER|RJUST, NULL), + mkstring(buf2, len2, CENTER|RJUST, NULL), + mkstring(buf3, len3, CENTER|RJUST, NULL)); + + return page_present; + } + + sprintf(physbuf, "%llx", paddr); + len2 = MAX(strlen(physbuf), strlen("PHYSICAL")); + fprintf(fp, "%s ", mkstring(buf, len2, CENTER|LJUST, "PHYSICAL")); + + fprintf(fp, "FLAGS\n"); + + fprintf(fp, "%s %s ", + mkstring(ptebuf, len1, CENTER|RJUST, NULL), + mkstring(physbuf, len2, CENTER|RJUST, NULL)); + fprintf(fp, "("); + others = 0; + + if (pte) { + if (pte & _PAGE_VALID) + fprintf(fp, "%sVALID", others++ ? "|" : ""); + if (pte & _PAGE_FOR) + fprintf(fp, "%sFOR", others++ ? "|" : ""); + if (pte & _PAGE_FOW) + fprintf(fp, "%sFOW", others++ ? "|" : ""); + if (pte & _PAGE_FOE) + fprintf(fp, "%sFOE", others++ ? "|" : ""); + if (pte & _PAGE_ASM) + fprintf(fp, "%sASM", others++ ? "|" : ""); + if (pte & _PAGE_KRE) + fprintf(fp, "%sKRE", others++ ? "|" : ""); + if (pte & _PAGE_URE) + fprintf(fp, "%sURE", others++ ? "|" : ""); + if (pte & _PAGE_KWE) + fprintf(fp, "%sKWE", others++ ? "|" : ""); + if (pte & _PAGE_UWE) + fprintf(fp, "%sUWE", others++ ? "|" : ""); + if (pte & _PAGE_DIRTY) + fprintf(fp, "%sDIRTY", others++ ? "|" : ""); + if (pte & _PAGE_ACCESSED) + fprintf(fp, "%sACCESSED", others++ ? "|" : ""); + } else { + fprintf(fp, "no mapping"); + } + + fprintf(fp, ")\n"); + + return page_present; +} + + +/* + * This is currently not machine-dependent, but eventually I'd prefer to use + * the HWPCB for the real physical memory size. + */ +static uint64_t +sw64_memory_size(void) +{ + return (generic_memory_size()); +} + +/* + * Determine where vmalloc'd memory starts. + */ +static ulong +sw64_vmalloc_start(void) +{ + return VMALLOC_START; +} + +/* + * SW64 tasks are all stacksize-aligned. + */ +static int +sw64_is_task_addr(ulong task) +{ + if (tt->flags & THREAD_INFO) + return IS_KVADDR(task); + else + return (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0)); +} + +/* + * Keep or reject a symbol from the kernel namelist. + */ +int +sw64_verify_symbol(const char *name, ulong value, char type) +{ + if (CRASHDEBUG(8) && name && strlen(name)) + fprintf(fp, "%016lx %s\n", value, name); + + return (name && strlen(name) && (value > MIN_SYMBOL_VALUE)); +} + +/* + * Override smp_num_cpus if possible and necessary. + */ +int +sw64_get_smp_cpus(void) +{ + int cpus; + + if ((cpus = get_cpus_present())) + return cpus; + else + return kt->cpus; +} + +/* + * Machine dependent command. + */ +void +sw64_cmd_mach(void) +{ + int c, cflag; + unsigned int radix; + + cflag = radix = 0; + + while ((c = getopt(argcnt, args, "cxd")) != EOF) { + switch(c) + { + case 'c': + cflag++; + break; + + case 'x': + if (radix == 10) + error(FATAL, + "-d and -x are mutually exclusive\n"); + radix = 16; + break; + + case 'd': + if (radix == 16) + error(FATAL, + "-d and -x are mutually exclusive\n"); + radix = 10; + break; + + default: + argerrs++; + break; + } + } + + if (argerrs) + cmd_usage(pc->curcmd, SYNOPSIS); + + if (cflag) + display_hwrpb(radix); + else + sw64_display_machine_stats(); +} + +/* + * "mach" command output. + */ +static void +sw64_display_machine_stats(void) +{ + struct new_utsname *uts; + char buf[BUFSIZE]; + ulong mhz; + + uts = &kt->utsname; + + fprintf(fp, " MACHINE TYPE: %s\n", uts->machine); + fprintf(fp, " MEMORY SIZE: %s\n", get_memory_size(buf)); + fprintf(fp, " CPUS: %d\n", kt->cpus); + fprintf(fp, " PROCESSOR SPEED: "); + if ((mhz = machdep->processor_speed())) + fprintf(fp, "%ld Mhz\n", mhz); + else + fprintf(fp, "(unknown)\n"); + fprintf(fp, " HZ: %d\n", machdep->hz); + fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE()); + fprintf(fp, " L1 CACHE SIZE: %d\n", l1_cache_size()); + fprintf(fp, "KERNEL VIRTUAL BASE: %lx\n", machdep->kvbase); + fprintf(fp, "KERNEL VMALLOC BASE: %lx\n", vt->vmalloc_start); + fprintf(fp, " KERNEL STACK SIZE: %ld\n", STACKSIZE()); +} + +/* + * Display the hwrpb_struct and each percpu_struct. + */ +static void +display_hwrpb(unsigned int radix) +{ + int cpu; + ulong hwrpb, percpu; + ulong processor_offset, processor_size; + + get_symbol_data("hwrpb", sizeof(void *), &hwrpb); + + readmem(hwrpb+OFFSET(hwrpb_struct_processor_offset), KVADDR, + &processor_offset, sizeof(ulong), + "hwrpb processor_offset", FAULT_ON_ERROR); + readmem(hwrpb+OFFSET(hwrpb_struct_processor_size), KVADDR, + &processor_size, sizeof(ulong), + "hwrpb processor_size", FAULT_ON_ERROR); + + fprintf(fp, "HWRPB:\n"); + dump_struct("hwrpb_struct", hwrpb, radix); + + for (cpu = 0; cpu < kt->cpus; cpu++) { + fprintf(fp, "\nCPU %d:\n", cpu); + percpu = hwrpb + processor_offset + (processor_size * cpu); + dump_struct("percpu_struct", percpu, radix); + } +} + +/* + * Perform any leftover pre-prompt machine-specific initialization tasks here. + */ +static void +sw64_post_init(void) +{ + modify_signame(7, "SIGEMT", NULL); + modify_signame(10, "SIGBUS", NULL); + modify_signame(12, "SIGSYS", NULL); + modify_signame(16, "SIGURG", NULL); + modify_signame(17, "SIGSTOP", NULL); + modify_signame(18, "SIGTSTP", NULL); + modify_signame(19, "SIGCONT", NULL); + modify_signame(20, "SIGCHLD", NULL); + modify_signame(23, "SIGIO", "SIGPOLL"); + modify_signame(29, "SIGINFO", "SIGPWR"); + modify_signame(30, "SIGUSR1", NULL); + modify_signame(31, "SIGUSR2", NULL); +} + + +#endif /* SW_64 */ diff --git a/task.c b/task.c index ebdb5be..f18ca98 100644 --- a/task.c +++ b/task.c @@ -8566,6 +8566,55 @@ clear_active_set(void) error(WARNING, \ "multiple active tasks have called die\n\n"); +#ifdef __sw_64__ +#define SEARCH_STACK_FOR_PANIC_DIE_AND_KEXEC_CALLERS() \ + while (fgets(buf, BUFSIZE, pc->tmpfile)) { \ + if (strstr(buf, " die+")) { \ + switch (die_task) \ + { \ + case NO_TASK: \ + die_task = task; \ + break; \ + default: \ + if (die_task != task) \ + die_task = NO_TASK+1; \ + break; \ + } \ + } \ + if (strstr(buf, " panic+")) { \ + switch (panic_task) \ + { \ + case NO_TASK: \ + panic_task = task; \ + if (XENDUMP_DUMPFILE()) \ + xendump_panic_hook(buf); \ + break; \ + default: \ + if (panic_task != task) \ + panic_task = NO_TASK+1; \ + break; \ + } \ + } \ + if (strstr(buf, " crash_kexec+") || \ + strstr(buf, " .crash_kexec+")) { \ + crash_kexec_task = task; \ + } \ + if (strstr(buf, " .crash_fadump+")) \ + crash_fadump_task = task; \ + if (strstr(buf, " machine_crash_shutdown+") || \ + strstr(buf, " .machine_crash_shutdown+")) { \ + crash_kexec_task = task; \ + } \ + if (strstr(buf, " xen_panic_event+") || \ + strstr(buf, " .xen_panic_event+")){ \ + xen_panic_task = task; \ + xendump_panic_hook(buf); \ + } \ + if (machine_type("IA64") && XENDUMP_DUMPFILE() && !xen_panic_task && \ + strstr(buf, " sysrq_handle_crashdump+")) \ + xen_sysrq_task = task; \ + } +#else #define SEARCH_STACK_FOR_PANIC_DIE_AND_KEXEC_CALLERS() \ while (fgets(buf, BUFSIZE, pc->tmpfile)) { \ if (strstr(buf, " die+")) { \ @@ -8613,7 +8662,7 @@ clear_active_set(void) strstr(buf, " sysrq_handle_crashdump+")) \ xen_sysrq_task = task; \ } - +#endif /* * Search the active set tasks for instances of die or panic calls. */