diff --git a/.gitignore b/.gitignore index b1cc9ae..b34502d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ crash-5.0.6.tar.gz /crash-7.2.9.tar.gz /crash-7.3.0.tar.gz /gdb-7.6.tar.gz +/gdb-10.2.tar.gz diff --git a/0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch b/0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch new file mode 100644 index 0000000..15e6c75 --- /dev/null +++ b/0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch @@ -0,0 +1,156 @@ +From 80334ed25820cc08d147de5da361f427885cdd9e Mon Sep 17 00:00:00 2001 +From: Aaron Tomlin +Date: Tue, 13 Jul 2021 14:24:49 +0100 +Subject: [PATCH 01/27] kmem: Add support to -S option to specify a range of + CPU-specific slab data + +With this patch, it is now possible for one to explicitly specify a range +of CPU-specific slab data to list. For example: + +Note: This is only applicable to a Linux kernel with Kconfig + CONFIG_SLUB enabled. The optional argument GNU extension + for getopt(3) is utilized; and, the CPU range must be + specified as expected + + crash> kmem -S=1,4 kmalloc-512 + CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME + ffff8d3f07c06c00 512 1916 3680 115 16k kmalloc-512 + CPU 1 KMEM_CACHE_CPU: + ffff8d461fa6f140 + CPU 1 SLAB: + SLAB MEMORY NODE TOTAL ALLOCATED FREE + fffff540df7c4000 ffff8d45df100000 0 32 8 24 + FREE / [ALLOCATED] + ffff8d45df100000 (cpu 1 cache) + [ffff8d45df100200] + ffff8d45df101000 (cpu 1 cache) + ...skipped ... + CPU 4 KMEM_CACHE_CPU: + ffff8d461fb2f140 + CPU 4 SLAB: + SLAB MEMORY NODE TOTAL ALLOCATED FREE + fffff540dfde3800 ffff8d45f78e0000 0 32 8 24 + FREE / [ALLOCATED] + [ffff8d45f78e0000] + ffff8d45f78e0200 (cpu 4 cache) + ffff8d45f78e0400 (cpu 4 cache) + ...skipped ... + +Signed-off-by: Aaron Tomlin +Signed-off-by: Kazuhito Hagio +--- + help.c | 5 ++++- + memory.c | 37 ++++++++++++++++++++++++++++++++++--- + 2 files changed, 38 insertions(+), 4 deletions(-) + +diff --git a/help.c b/help.c +index 99be7cb4e17c..6c262a3ffcbb 100644 +--- a/help.c ++++ b/help.c +@@ -6601,7 +6601,7 @@ char *help_kmem[] = { + "kmem", + "kernel memory", + "[-f|-F|-c|-C|-i|-v|-V|-n|-z|-o|-h] [-p | -m member[,member]]\n" +-" [[-s|-S|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]", ++" [[-s|-S|-S=cpu[s]|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]", + " This command displays information about the use of kernel memory.\n", + " -f displays the contents of the system free memory headers.", + " also verifies that the page count equals nr_free_pages.", +@@ -6649,6 +6649,9 @@ char *help_kmem[] = { + " slab data for each per-cpu slab is displayed, along with the", + " address of each kmem_cache_node, its count of full and partial", + " slabs, and a list of all tracked slabs.", ++" Note: one can specify the per-cpu slab data to be displayed;", ++" the cpu[s] can be given as \"1,3,5\", \"1-3\", \"1,3,5-7,10\",", ++" \"all\", or \"a\" (shortcut for \"all\").", + " -r displays the accumulated basic kmalloc() slab data of each", + " root slab cache and its children. The kernel must contain the", + " \"slab_root_caches\" list_head. (currently only available if", +diff --git a/memory.c b/memory.c +index cbe90eebe748..ca4c633e5074 100644 +--- a/memory.c ++++ b/memory.c +@@ -48,6 +48,7 @@ struct meminfo { /* general purpose memory information structure */ + int slab_offset; + char *reqname; + char *curname; ++ ulong *spec_cpumask; + ulong *addrlist; + int *kmem_bufctl; + ulong *cpudata[NR_CPUS]; +@@ -4851,10 +4852,13 @@ cmd_kmem(void) + struct meminfo meminfo; + ulonglong value[MAXARGS]; + char buf[BUFSIZE]; ++ char arg_buf[BUFSIZE]; + char *p1; +- int spec_addr, escape; ++ ulong *cpus; ++ int spec_addr, escape, choose_cpu; + +- spec_addr = 0; ++ cpus = NULL; ++ spec_addr = choose_cpu = 0; + sflag = Sflag = pflag = fflag = Fflag = Pflag = zflag = oflag = 0; + vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0; + gflag = hflag = rflag = 0; +@@ -4863,7 +4867,7 @@ cmd_kmem(void) + BZERO(&value[0], sizeof(ulonglong)*MAXARGS); + pc->curcmd_flags &= ~HEADER_PRINTED; + +- while ((c = getopt(argcnt, args, "gI:sSrFfm:pvczCinl:L:PVoh")) != EOF) { ++ while ((c = getopt(argcnt, args, "gI:sS::rFfm:pvczCinl:L:PVoh")) != EOF) { + switch(c) + { + case 'V': +@@ -4903,6 +4907,29 @@ cmd_kmem(void) + break; + + case 'S': ++ if (choose_cpu) ++ error(FATAL, "only one -S option allowed\n"); ++ /* Use the GNU extension with getopt(3) ... */ ++ if (optarg) { ++ if (!(vt->flags & KMALLOC_SLUB)) ++ error(FATAL, ++ "can only use -S=cpu(s) with a kernel \n" ++ "that is built with CONFIG_SLUB support.\n"); ++ if (optarg[0] != '=') ++ error(FATAL, ++ "CPU-specific slab data to be displayed " ++ "must be written as expected only e.g. -S=1,45.\n"); ++ /* Skip = ... */ ++ optarg++; ++ ++ choose_cpu = 1; ++ BZERO(arg_buf, BUFSIZE); ++ strcpy(arg_buf, optarg); ++ ++ cpus = get_cpumask_buf(); ++ make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL); ++ meminfo.spec_cpumask = cpus; ++ } + Sflag = 1; sflag = rflag = 0; + break; + +@@ -5185,6 +5212,8 @@ cmd_kmem(void) + meminfo.flags = VERBOSE; + vt->dump_kmem_cache(&meminfo); + } ++ if (choose_cpu) ++ FREEBUF(cpus); + } + + if (vflag == 1) +@@ -19083,6 +19112,8 @@ do_kmem_cache_slub(struct meminfo *si) + per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes); + + for (i = 0; i < kt->cpus; i++) { ++ if (si->spec_cpumask && !NUM_IN_BITMAP(si->spec_cpumask, i)) ++ continue; + if (hide_offline_cpu(i)) { + fprintf(fp, "CPU %d [OFFLINE]\n", i); + continue; +-- +2.30.2 + diff --git a/0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch b/0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch new file mode 100644 index 0000000..b6b37fc --- /dev/null +++ b/0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch @@ -0,0 +1,125 @@ +From 4631320e96f8a63c897fbbce4e87e3c47af40bc9 Mon Sep 17 00:00:00 2001 +From: Roman Bolshakov +Date: Thu, 17 Jun 2021 02:27:32 +0300 +Subject: [PATCH 02/27] diskdump: Fail readmem() early if dump is incomplete + +kdump format description [1] says: + + [...] zero page has its own offset not equal 0. So when reading page + from incomplete core, only the page lost by ENOSPACE errors has 0 in its + corresponding page descriptor's member offset. + +crash has special treatment for page descriptors with zero offset only if +DUMP_DH_COMPRESSED_INCOMPLETE is set in dump header. However, +makedumpfile places the flag after ENOSPC is hit and only if dump header +modification went without errors. + +In case if crashkernel environment was terminated early (e.g. by BMC) or +some other reason, DUMP_DH_COMPRESSED_INCOMPLETE won't be set on the +dump header. Then cache_page() would be performed on pages with +pd.offset == 0 and due to pd.size == 0 it'll skip read into +compressed_page and then non related pre-existing contents of +compressed_page will copied into page cache for the non-present page. + +Ultimately, it'll lead to a cryptic failure, like: + + crash: invalid kernel virtual address: 72288cacacf427f8 [...] + +The failure would be a bit cleaner if crash explicitly fails on the page +that is an outcome of incomplete dump: + + crash: page incomplete: kernel virtual address: c000003fff9d17e8 [...] + +Debugging level 8 would also produce exact offset from data_offset to +print descriptor value with ease: + + read_diskdump/cache_page: descriptor with zero offset found at paddr/pfn/pos: 3fff9d0000/3fff9d/743dd + +That helps in inspecting broken descriptor with hexdump or similar tools: + + hexdump -s (data_offset + pos * 0x18) -n 0x18 + +[1] https://github.com/makedumpfile/makedumpfile/blob/master/IMPLEMENTATION + +Signed-off-by: Roman Bolshakov +--- + defs.h | 1 + + diskdump.c | 16 +++++++++++----- + memory.c | 7 +++++++ + 3 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/defs.h b/defs.h +index c91177a245fd..eb1c71b5333a 100644 +--- a/defs.h ++++ b/defs.h +@@ -361,6 +361,7 @@ struct number_option { + #define READ_ERROR (-2) + #define WRITE_ERROR (-3) + #define PAGE_EXCLUDED (-4) ++#define PAGE_INCOMPLETE (-5) + + #define RESTART() (longjmp(pc->main_loop_env, 1)) + #define RESUME_FOREACH() (longjmp(pc->foreach_loop_env, 1)) +diff --git a/diskdump.c b/diskdump.c +index 668069585080..59b79e1bce95 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -1146,10 +1146,9 @@ cache_page(physaddr_t paddr) + if (FLAT_FORMAT()) { + if (!read_flattened_format(dd->dfd, pd.offset, dd->compressed_page, pd.size)) + return READ_ERROR; +- } else if (is_incomplete_dump() && (0 == pd.offset)) { ++ } else if (0 == pd.offset) { + /* +- * If the incomplete flag has been set in the header, +- * first check whether zero_excluded has been set. ++ * First check whether zero_excluded has been set. + */ + if (*diskdump_flags & ZERO_EXCLUDED) { + if (CRASHDEBUG(8)) +@@ -1158,8 +1157,15 @@ cache_page(physaddr_t paddr) + "paddr/pfn: %llx/%lx\n", + (ulonglong)paddr, pfn); + memset(dd->compressed_page, 0, dd->block_size); +- } else +- return READ_ERROR; ++ } else { ++ if (CRASHDEBUG(8)) ++ fprintf(fp, ++ "read_diskdump/cache_page: " ++ "descriptor with zero offset found at " ++ "paddr/pfn/pos: %llx/%lx/%lx\n", ++ (ulonglong)paddr, pfn, desc_pos); ++ return PAGE_INCOMPLETE; ++ } + } else { + if (lseek(dd->dfd, pd.offset, SEEK_SET) == failed) + return SEEK_ERROR; +diff --git a/memory.c b/memory.c +index ca4c633e5074..86c02c132890 100644 +--- a/memory.c ++++ b/memory.c +@@ -2213,6 +2213,7 @@ accessible(ulong kva) + #define READ_ERRMSG "read error: %s address: %llx type: \"%s\"\n" + #define WRITE_ERRMSG "write error: %s address: %llx type: \"%s\"\n" + #define PAGE_EXCLUDED_ERRMSG "page excluded: %s address: %llx type: \"%s\"\n" ++#define PAGE_INCOMPLETE_ERRMSG "page incomplete: %s address: %llx type: \"%s\"\n" + + #define RETURN_ON_PARTIAL_READ() \ + if ((error_handle & RETURN_PARTIAL) && (size < orig_size)) { \ +@@ -2378,6 +2379,12 @@ readmem(ulonglong addr, int memtype, void *buffer, long size, + error(INFO, PAGE_EXCLUDED_ERRMSG, memtype_string(memtype, 0), addr, type); + goto readmem_error; + ++ case PAGE_INCOMPLETE: ++ RETURN_ON_PARTIAL_READ(); ++ if (PRINT_ERROR_MESSAGE) ++ error(INFO, PAGE_INCOMPLETE_ERRMSG, memtype_string(memtype, 0), addr, type); ++ goto readmem_error; ++ + default: + break; + } +-- +2.30.2 + diff --git a/0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch b/0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch new file mode 100644 index 0000000..6296b59 --- /dev/null +++ b/0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch @@ -0,0 +1,36 @@ +From 41cda195c6421fbde72ed67b32b8c1ab3eb0c56f Mon Sep 17 00:00:00 2001 +From: Roman Bolshakov +Date: Thu, 17 Jun 2021 02:27:33 +0300 +Subject: [PATCH 03/27] netdump: Permit --zero_excluded for incomplete ELF + dumps + +DUMP_ELF_INCOMPLETE is set very late after ENOSPC error is hit by +makedumpfile. Any following error that prevents modification of ELF +header would result in effectively incomplete core that doesn't have the +flag. zero_excluded flag doesn't work for such kind of incomplete core. + +Signed-off-by: Roman Bolshakov +--- + netdump.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/netdump.c b/netdump.c +index aaea945aaca7..e8721d89f1a3 100644 +--- a/netdump.c ++++ b/netdump.c +@@ -819,10 +819,9 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr) + read_ret = read(nd->ndfd, bufptr, cnt); + if (read_ret != cnt) { + /* +- * If the incomplete flag has been set in the header, +- * first check whether zero_excluded has been set. ++ * First check whether zero_excluded has been set. + */ +- if (is_incomplete_dump() && (read_ret >= 0) && ++ if ((read_ret >= 0) && + (*diskdump_flags & ZERO_EXCLUDED)) { + if (CRASHDEBUG(8)) + fprintf(fp, "read_netdump: zero-fill: " +-- +2.30.2 + diff --git a/0004-diskdump-Print-total-number-of-dumpable-pages.patch b/0004-diskdump-Print-total-number-of-dumpable-pages.patch new file mode 100644 index 0000000..384e991 --- /dev/null +++ b/0004-diskdump-Print-total-number-of-dumpable-pages.patch @@ -0,0 +1,52 @@ +From 1425b0504b1e79d88a2d188d7e4c0e7fceba4501 Mon Sep 17 00:00:00 2001 +From: Roman Bolshakov +Date: Thu, 17 Jun 2021 02:27:34 +0300 +Subject: [PATCH 04/27] diskdump: Print total number of dumpable pages + +It's not clear how broken an incomplete dump from the existing debugging +prints. Aggregate number of valid pages helps to figure out approximate +size of the dump. Size of a complete dump is roughly: + + EXPECTED_CORE_SIZE = a few pages (kdump headers + bitmaps + descriptors) + + (total_valid_pages * block_size) * compression rate + +An incomplete core would be significantly smaller than: + + total_valid_pages * block_size + +Signed-off-by: Roman Bolshakov +--- + diskdump.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/diskdump.c b/diskdump.c +index 59b79e1bce95..0f9402248d51 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -74,6 +74,7 @@ struct diskdump_data { + ulong evictions; /* total evictions done */ + ulong cached_reads; + ulong *valid_pages; ++ int max_sect_len; /* highest bucket of valid_pages */ + ulong accesses; + ulong snapshot_task; + }; +@@ -877,6 +878,7 @@ restart: + } + + dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1); ++ dd->max_sect_len = max_sect_len; + for (i = 1; i < max_sect_len + 1; i++) { + dd->valid_pages[i] = dd->valid_pages[i - 1]; + for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++) +@@ -2089,6 +2091,7 @@ __diskdump_memory_dump(FILE *fp) + else + fprintf(fp, "\n"); + fprintf(fp, " valid_pages: %lx\n", (ulong)dd->valid_pages); ++ fprintf(fp, " total_valid_pages: %ld\n", dd->valid_pages[dd->max_sect_len]); + + return 0; + } +-- +2.30.2 + diff --git a/0005-diskdump-Introduce-read_pd.patch b/0005-diskdump-Introduce-read_pd.patch new file mode 100644 index 0000000..7752e6d --- /dev/null +++ b/0005-diskdump-Introduce-read_pd.patch @@ -0,0 +1,67 @@ +From 881f33d97cee9895796829d0cc969b51dd34d831 Mon Sep 17 00:00:00 2001 +From: Roman Bolshakov +Date: Thu, 17 Jun 2021 02:27:35 +0300 +Subject: [PATCH 05/27] diskdump: Introduce read_pd() + +Standalone function for reading of page descriptors is needed later for +of expected core size and detection of incomplete dumps. + +Signed-off-by: Roman Bolshakov +--- + diskdump.c | 33 ++++++++++++++++++++++++--------- + 1 file changed, 24 insertions(+), 9 deletions(-) + +diff --git a/diskdump.c b/diskdump.c +index 0f9402248d51..de3eeb2c720c 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -510,6 +510,27 @@ arm_kdump_header_adjust(int header_version) + } + #endif /* __i386__ && (ARM || MIPS) */ + ++/* ++ * Read page descriptor. ++ */ ++static int ++read_pd(int fd, off_t offset, page_desc_t *pd) ++{ ++ const off_t failed = (off_t)-1; ++ ++ if (FLAT_FORMAT()) { ++ if (!read_flattened_format(fd, offset, pd, sizeof(*pd))) ++ return READ_ERROR; ++ } else { ++ if (lseek(fd, offset, SEEK_SET) == failed) ++ return SEEK_ERROR; ++ if (read(fd, pd, sizeof(*pd)) != sizeof(*pd)) ++ return READ_ERROR; ++ } ++ ++ return 0; ++} ++ + static int + read_dump_header(char *file) + { +@@ -1130,15 +1151,9 @@ cache_page(physaddr_t paddr) + + (off_t)(desc_pos - 1)*sizeof(page_desc_t); + + /* read page descriptor */ +- if (FLAT_FORMAT()) { +- if (!read_flattened_format(dd->dfd, seek_offset, &pd, sizeof(pd))) +- return READ_ERROR; +- } else { +- if (lseek(dd->dfd, seek_offset, SEEK_SET) == failed) +- return SEEK_ERROR; +- if (read(dd->dfd, &pd, sizeof(pd)) != sizeof(pd)) +- return READ_ERROR; +- } ++ ret = read_pd(dd->dfd, seek_offset, &pd); ++ if (ret) ++ return ret; + + /* sanity check */ + if (pd.size > block_size) +-- +2.30.2 + diff --git a/0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch b/0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch new file mode 100644 index 0000000..1958878 --- /dev/null +++ b/0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch @@ -0,0 +1,66 @@ +From 44e5801d9016987b6b4ebd571bfde8ae3e75da7b Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Thu, 5 Aug 2021 15:19:37 +0200 +Subject: [PATCH 06/27] x86_64: Fix check for __per_cpu_offset initialization + +Since at least kernel v2.6.30 the __per_cpu_offset gets initialized to +__per_cpu_load. So first check if the __per_cpu_offset was set to a +proper value before reading any per cpu variable to prevent potential +bugs. + +[ kh: added check for the existence of __per_cpu_load ] + +Signed-off-by: Philipp Rudo +Signed-off-by: Kazuhito Hagio +--- + x86_64.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/x86_64.c b/x86_64.c +index 6eb7d6708db0..87cbeaeb4f06 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -1285,6 +1285,7 @@ x86_64_per_cpu_init(void) + struct machine_specific *ms; + struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp; + ulong hardirq_stack_ptr; ++ ulong __per_cpu_load = 0; + + ms = machdep->machspec; + +@@ -1326,7 +1327,12 @@ x86_64_per_cpu_init(void) + else if (!ms->stkinfo.isize) + ms->stkinfo.isize = 16384; + ++ if (kernel_symbol_exists("__per_cpu_load")) ++ __per_cpu_load = symbol_value("__per_cpu_load"); ++ + for (i = cpus = 0; i < NR_CPUS; i++) { ++ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load) ++ break; + if (!readmem(cpu_sp->value + kt->__per_cpu_offset[i], + KVADDR, &cpunumber, sizeof(int), + "cpu number (per_cpu)", QUIET|RETURN_ON_ERROR)) +@@ -5595,14 +5601,18 @@ x86_64_get_smp_cpus(void) + char *cpu_pda_buf; + ulong level4_pgt, cpu_pda_addr; + struct syment *sp; ++ ulong __per_cpu_load = 0; + + if (!VALID_STRUCT(x8664_pda)) { + if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) || + !(kt->flags & PER_CPU_OFF)) + return 1; + ++ if (kernel_symbol_exists("__per_cpu_load")) ++ __per_cpu_load = symbol_value("__per_cpu_load"); ++ + for (i = cpus = 0; i < NR_CPUS; i++) { +- if (kt->__per_cpu_offset[i] == 0) ++ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load) + break; + if (!readmem(sp->value + kt->__per_cpu_offset[i], + KVADDR, &cpunumber, sizeof(int), +-- +2.30.2 + diff --git a/0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch b/0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch new file mode 100644 index 0000000..366c234 --- /dev/null +++ b/0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch @@ -0,0 +1,77 @@ +From 4b34197508578bb43639e6d169fb91fb0489fa2b Mon Sep 17 00:00:00 2001 +From: James Hsu +Date: Wed, 18 Aug 2021 15:45:47 +0800 +Subject: [PATCH 07/27] arm64: Get CPU registers from ELF notes even without + crash_notes symbol + +Currently arm64 crash retrieves the CPU registers from crash_notes symbol +or ELF notes only when the symbol exists, but there are dumpfiles which +have the registers in ELF notes without the symbol. + +With the patch, crash can retrieve the registers from ELF notes without +the crash_notes symbol. + +Signed-off-by: James Hsu +Signed-off-by: Kazuhito Hagio +--- + arm64.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/arm64.c b/arm64.c +index d73d5c5a4fed..7069312671cf 100644 +--- a/arm64.c ++++ b/arm64.c +@@ -3698,14 +3698,48 @@ arm64_get_crash_notes(void) + { + struct machine_specific *ms = machdep->machspec; + ulong crash_notes; +- Elf64_Nhdr *note; ++ Elf64_Nhdr *note = NULL; + ulong offset; + char *buf, *p; + ulong *notes_ptrs; + ulong i, found; + +- if (!symbol_exists("crash_notes")) ++ if (!symbol_exists("crash_notes")) { ++ if (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE()) { ++ if (!(ms->panic_task_regs = calloc((size_t)kt->cpus, sizeof(struct arm64_pt_regs)))) ++ error(FATAL, "cannot calloc panic_task_regs space\n"); ++ ++ for (i = found = 0; i < kt->cpus; i++) { ++ if (DISKDUMP_DUMPFILE()) ++ note = diskdump_get_prstatus_percpu(i); ++ else if (KDUMP_DUMPFILE()) ++ note = netdump_get_prstatus_percpu(i); ++ ++ if (!note) { ++ error(WARNING, "cpu %d: cannot find NT_PRSTATUS note\n", i); ++ continue; ++ } ++ ++ /* ++ * Find correct location of note data. This contains elf_prstatus ++ * structure which has registers etc. for the crashed task. ++ */ ++ offset = sizeof(Elf64_Nhdr); ++ offset = roundup(offset + note->n_namesz, 4); ++ p = (char *)note + offset; /* start of elf_prstatus */ ++ ++ BCOPY(p + OFFSET(elf_prstatus_pr_reg), &ms->panic_task_regs[i], ++ sizeof(struct arm64_pt_regs)); ++ ++ found++; ++ } ++ if (!found) { ++ free(ms->panic_task_regs); ++ ms->panic_task_regs = NULL; ++ } ++ } + return; ++ } + + crash_notes = symbol_value("crash_notes"); + +-- +2.30.2 + diff --git a/0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch b/0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch new file mode 100644 index 0000000..0ff0f94 --- /dev/null +++ b/0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch @@ -0,0 +1,34 @@ +From 3db5fff2e9d7b8762d1bd46d8d2c47ba4c7e374f Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani +Date: Thu, 26 Aug 2021 02:31:08 +0530 +Subject: [PATCH 08/27] .gitignore: Add cscope, ctags & compile_commands.json + +Add cscope, ctags & compile_commands.json in .gitignore file. + +Signed-off-by: Ritesh Harjani +--- + .gitignore | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/.gitignore b/.gitignore +index 5b2ba1d34012..b39832fa71df 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -14,3 +14,14 @@ gdb-7.6/ + extensions/defs.h + extensions/*.so + extensions/eppic ++ ++# cscope files ++cscope.* ++ncscope.* ++ ++# ctags files ++tags ++TAGS ++ ++# Clang's compilation database file ++/compile_commands.json +-- +2.30.2 + diff --git a/0009-ppc64-Add-MMU-type-info-in-machdep-command.patch b/0009-ppc64-Add-MMU-type-info-in-machdep-command.patch new file mode 100644 index 0000000..817b4b3 --- /dev/null +++ b/0009-ppc64-Add-MMU-type-info-in-machdep-command.patch @@ -0,0 +1,28 @@ +From 15765867c0f1d937db5ec06f51adb6bfd13354ea Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani +Date: Thu, 26 Aug 2021 02:31:10 +0530 +Subject: [PATCH 09/27] ppc64: Add MMU type info in machdep command + +This adds MMU type info in "machdep" command. + +Signed-off-by: Ritesh Harjani +--- + ppc64.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ppc64.c b/ppc64.c +index f368bf8e1a08..975caa53b812 100644 +--- a/ppc64.c ++++ b/ppc64.c +@@ -3027,6 +3027,8 @@ ppc64_display_machine_stats(void) + else + fprintf(fp, "(unknown)\n"); + fprintf(fp, " HZ: %d\n", machdep->hz); ++ fprintf(fp, " MMU: %s\n", machdep->flags & RADIX_MMU ++ ? "RADIX" : "HASH"); + 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); +-- +2.30.2 + diff --git a/0010-mod-fix-module-object-file-lookup.patch b/0010-mod-fix-module-object-file-lookup.patch new file mode 100644 index 0000000..bc1d0b7 --- /dev/null +++ b/0010-mod-fix-module-object-file-lookup.patch @@ -0,0 +1,48 @@ +From cf0c8d10e1870d89b39f40382634db51aa8fcf2c Mon Sep 17 00:00:00 2001 +From: Hari Bathini +Date: Fri, 3 Sep 2021 17:33:42 +0530 +Subject: [PATCH 10/27] mod: fix module object file lookup + +On systems where vmlinux file is not under /usr/lib/debug/lib/modules +directory, 'mod -s|-S' command may fail to find the module's object +file with the below error: + + mod: cannot find or load object file for sd_mod module + +Fix it by trying all possible module object file extentions while +searching for the object file under /usr/lib/debug/lib/modules +directory. + +Signed-off-by: Naveen N. Rao +Signed-off-by: Hari Bathini +--- + kernel.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/kernel.c b/kernel.c +index 36fdea29b1cb..b2c8a0ccb7ab 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -4796,7 +4796,18 @@ module_objfile_search(char *modref, char *filename, char *tree) + + sprintf(dir, "%s/%s", DEFAULT_REDHAT_DEBUG_LOCATION, + kt->utsname.release); +- retbuf = search_directory_tree(dir, file, 0); ++ if (!(retbuf = search_directory_tree(dir, file, 0))) { ++ switch (kt->flags & (KMOD_V1|KMOD_V2)) ++ { ++ case KMOD_V2: ++ sprintf(file, "%s.ko", modref); ++ retbuf = search_directory_tree(dir, file, 0); ++ if (!retbuf) { ++ sprintf(file, "%s.ko.debug", modref); ++ retbuf = search_directory_tree(dir, file, 0); ++ } ++ } ++ } + + if (!retbuf && (env = getenv("CRASH_MODULE_PATH"))) { + sprintf(dir, "%s", env); +-- +2.30.2 + diff --git a/0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch b/0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch new file mode 100644 index 0000000..4e5ca8e --- /dev/null +++ b/0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch @@ -0,0 +1,265 @@ +From 7f38d1baf794823355ee100b3a1914155d4190f2 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Mon, 27 Sep 2021 09:45:42 +0900 +Subject: [PATCH 11/27] diskdump: Add support for reading dumpfiles compressed + by Zstandard + +Add support for reading dumpfiles compressed by Zstandard (zstd) +using makedumpfile. + +To build crash with zstd support, type "make zstd". + +Signed-off-by: Kazuhito Hagio +--- + Makefile | 4 ++++ + README | 4 ++-- + configure.c | 24 +++++++++++++++++++++--- + defs.h | 4 ++++ + diskdump.c | 37 +++++++++++++++++++++++++++++++++++++ + diskdump.h | 1 + + help.c | 4 ++-- + 7 files changed, 71 insertions(+), 7 deletions(-) + +diff --git a/Makefile b/Makefile +index ece13069a029..eae023c54bdd 100644 +--- a/Makefile ++++ b/Makefile +@@ -333,6 +333,10 @@ snappy: make_configure + @./configure -x snappy ${CONF_TARGET_FLAG} -w -b + @make --no-print-directory gdb_merge + ++zstd: make_configure ++ @./configure -x zstd ${CONF_TARGET_FLAG} -w -b ++ @make --no-print-directory gdb_merge ++ + valgrind: make_configure + @./configure -x valgrind ${CONF_TARGET_FLAG} -w -b + @make --no-print-directory gdb_merge +diff --git a/README b/README +index 50179742e620..4962f272074b 100644 +--- a/README ++++ b/README +@@ -102,8 +102,8 @@ + Traditionally when vmcores are compressed via the makedumpfile(8) facility + the libz compression library is used, and by default the crash utility + only supports libz. Recently makedumpfile has been enhanced to optionally +- use either the LZO or snappy compression libraries. To build crash with +- either or both of those libraries, type "make lzo" or "make snappy". ++ use the LZO, snappy or zstd compression libraries. To build crash with any ++ or all of those libraries, type "make lzo", "make snappy" or "make zstd". + + crash supports valgrind Memcheck tool on the crash's custom memory allocator. + To build crash with this feature enabled, type "make valgrind" and then run +diff --git a/configure.c b/configure.c +index e8f619a3c061..b691a139b960 100644 +--- a/configure.c ++++ b/configure.c +@@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial) + * - enter -DSNAPPY in the CFLAGS.extra file + * - enter -lsnappy in the LDFLAGS.extra file + * ++ * For zstd: ++ * - enter -DZSTD in the CFLAGS.extra file ++ * - enter -lzstd in the LDFLAGS.extra file ++ * + * For valgrind: + * - enter -DVALGRIND in the CFLAGS.extra file + */ +@@ -1746,6 +1750,7 @@ add_extra_lib(char *option) + { + int lzo, add_DLZO, add_llzo2; + int snappy, add_DSNAPPY, add_lsnappy; ++ int zstd, add_DZSTD, add_lzstd; + int valgrind, add_DVALGRIND; + char *cflags, *ldflags; + FILE *fp_cflags, *fp_ldflags; +@@ -1754,6 +1759,7 @@ add_extra_lib(char *option) + + lzo = add_DLZO = add_llzo2 = 0; + snappy = add_DSNAPPY = add_lsnappy = 0; ++ zstd = add_DZSTD = add_lzstd = 0; + valgrind = add_DVALGRIND = 0; + + ldflags = get_extra_flags("LDFLAGS.extra", NULL); +@@ -1775,13 +1781,21 @@ add_extra_lib(char *option) + add_lsnappy++; + } + ++ if (strcmp(option, "zstd") == 0) { ++ zstd++; ++ if (!cflags || !strstr(cflags, "-DZSTD")) ++ add_DZSTD++; ++ if (!ldflags || !strstr(ldflags, "-lzstd")) ++ add_lzstd++; ++ } ++ + if (strcmp(option, "valgrind") == 0) { + valgrind++; + if (!cflags || !strstr(cflags, "-DVALGRIND")) + add_DVALGRIND++; + } + +- if ((lzo || snappy) && ++ if ((lzo || snappy || zstd) && + file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) { + perror("diskdump.o"); + return; +@@ -1806,24 +1820,28 @@ add_extra_lib(char *option) + return; + } + +- if (add_DLZO || add_DSNAPPY || add_DVALGRIND) { ++ if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) { + while (fgets(inbuf, 512, fp_cflags)) + ; + if (add_DLZO) + fputs("-DLZO\n", fp_cflags); + if (add_DSNAPPY) + fputs("-DSNAPPY\n", fp_cflags); ++ if (add_DZSTD) ++ fputs("-DZSTD\n", fp_cflags); + if (add_DVALGRIND) + fputs("-DVALGRIND\n", fp_cflags); + } + +- if (add_llzo2 || add_lsnappy) { ++ if (add_llzo2 || add_lsnappy || add_lzstd) { + while (fgets(inbuf, 512, fp_ldflags)) + ; + if (add_llzo2) + fputs("-llzo2\n", fp_ldflags); + if (add_lsnappy) + fputs("-lsnappy\n", fp_ldflags); ++ if (add_lzstd) ++ fputs("-lzstd\n", fp_ldflags); + } + + fclose(fp_cflags); +diff --git a/defs.h b/defs.h +index eb1c71b5333a..b2e94722c92b 100644 +--- a/defs.h ++++ b/defs.h +@@ -54,6 +54,9 @@ + #ifdef SNAPPY + #include + #endif ++#ifdef ZSTD ++#include ++#endif + + #ifndef ATTRIBUTE_UNUSED + #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +@@ -327,6 +330,7 @@ struct number_option { + #define NO_ELF_NOTES (0x20) + #define LZO_SUPPORTED (0x40) + #define SNAPPY_SUPPORTED (0x80) ++#define ZSTD_SUPPORTED (0x100) + #define DISKDUMP_VALID() (dd->flags & DISKDUMP_LOCAL) + #define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL) + #define KDUMP_SPLIT() (dd->flags & DUMPFILE_SPLIT) +diff --git a/diskdump.c b/diskdump.c +index de3eeb2c720c..112f769f8949 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -1001,6 +1001,9 @@ is_diskdump(char *file) + #ifdef SNAPPY + dd->flags |= SNAPPY_SUPPORTED; + #endif ++#ifdef ZSTD ++ dd->flags |= ZSTD_SUPPORTED; ++#endif + + pc->read_vmcoreinfo = vmcoreinfo_read_string; + +@@ -1124,6 +1127,9 @@ cache_page(physaddr_t paddr) + const int block_size = dd->block_size; + const off_t failed = (off_t)-1; + ulong retlen; ++#ifdef ZSTD ++ static ZSTD_DCtx *dctx = NULL; ++#endif + + for (i = found = 0; i < DISKDUMP_CACHED_PAGES; i++) { + if (DISKDUMP_VALID_PAGE(dd->page_cache_hdr[i].pg_flags)) +@@ -1251,6 +1257,33 @@ cache_page(physaddr_t paddr) + ret); + return READ_ERROR; + } ++#endif ++ } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) { ++ ++ if (!(dd->flags & ZSTD_SUPPORTED)) { ++ error(INFO, "%s: uncompess failed: no zstd compression support\n", ++ DISKDUMP_VALID() ? "diskdump" : "compressed kdump"); ++ return READ_ERROR; ++ } ++#ifdef ZSTD ++ if (!dctx) { ++ dctx = ZSTD_createDCtx(); ++ if (!dctx) { ++ error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n", ++ DISKDUMP_VALID() ? "diskdump" : "compressed kdump"); ++ return READ_ERROR; ++ } ++ } ++ ++ retlen = ZSTD_decompressDCtx(dctx, ++ dd->page_cache_hdr[i].pg_bufptr, block_size, ++ dd->compressed_page, pd.size); ++ if (ZSTD_isError(retlen) || (retlen != block_size)) { ++ error(INFO, "%s: uncompress failed: %d (%s)\n", ++ DISKDUMP_VALID() ? "diskdump" : "compressed kdump", ++ retlen, ZSTD_getErrorName(retlen)); ++ return READ_ERROR; ++ } + #endif + } else + memcpy(dd->page_cache_hdr[i].pg_bufptr, +@@ -1806,6 +1839,8 @@ __diskdump_memory_dump(FILE *fp) + fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : ""); + if (dd->flags & SNAPPY_SUPPORTED) + fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : ""); ++ if (dd->flags & ZSTD_SUPPORTED) ++ fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : ""); + fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : ""); + fprintf(fp, " dfd: %d\n", dd->dfd); + fprintf(fp, " ofp: %lx\n", (ulong)dd->ofp); +@@ -1872,6 +1907,8 @@ __diskdump_memory_dump(FILE *fp) + fprintf(fp, "DUMP_DH_COMPRESSED_LZO"); + if (dh->status & DUMP_DH_COMPRESSED_SNAPPY) + fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY"); ++ if (dh->status & DUMP_DH_COMPRESSED_ZSTD) ++ fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD"); + if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE) + fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE"); + if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP) +diff --git a/diskdump.h b/diskdump.h +index 28713407b841..c152c7b86616 100644 +--- a/diskdump.h ++++ b/diskdump.h +@@ -86,6 +86,7 @@ struct kdump_sub_header { + #define DUMP_DH_COMPRESSED_SNAPPY 0x4 /* page is compressed with snappy */ + #define DUMP_DH_COMPRESSED_INCOMPLETE 0x8 /* dumpfile is incomplete */ + #define DUMP_DH_EXCLUDED_VMEMMAP 0x10 /* unused vmemmap pages are excluded */ ++#define DUMP_DH_COMPRESSED_ZSTD 0x20 /* page is compressed with zstd */ + + /* descriptor of each page for vmcore */ + typedef struct page_desc { +diff --git a/help.c b/help.c +index 6c262a3ffcbb..f34838d59908 100644 +--- a/help.c ++++ b/help.c +@@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY, + " Traditionally when vmcores are compressed via the makedumpfile(8) facility", + " the libz compression library is used, and by default the crash utility", + " only supports libz. Recently makedumpfile has been enhanced to optionally", +-" use either the LZO or snappy compression libraries. To build crash with", +-" either or both of those libraries, type \"make lzo\" or \"make snappy\".", ++" use the LZO, snappy or zstd compression libraries. To build crash with any", ++" or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".", + "", + " crash supports valgrind Memcheck tool on the crash's custom memory allocator.", + " To build crash with this feature enabled, type \"make valgrind\" and then run", +-- +2.30.2 + diff --git a/0012-Update-to-gdb-10.2.patch b/0012-Update-to-gdb-10.2.patch new file mode 100644 index 0000000..802511f --- /dev/null +++ b/0012-Update-to-gdb-10.2.patch @@ -0,0 +1,10136 @@ +From 9fab193edb34ddf30282b5ac137f7d8078198938 Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Tue, 17 Aug 2021 17:14:59 +0800 +Subject: [PATCH 12/27] Update to gdb-10.2 + +Main changes: +[1] update gdb-7.6.patch to gdb-10.2.patch, and keep all functionality + and good compatibility +[2] remove unneeded patches(gdb-7.6-proc_service.h.patch and + gdb-7.6-ppc64le-support.patch) +[3] to make the c++ compiler happy, add the extern "C" to eliminate + compilation issues, also add CXXFLAGS=-m32 to generate proper + 32bit object files +[4] the parameter types of some functions are changed, eg, the set of + prettyprint variables +[5] eliminate error_hook() and SJLJ while running in C++ code (after + gdb_command_funnel()) use try-catch mechanism instead +[6] request_types() is redone to do not call GNU_GET_NEXT_DATATYPE multiple + times but single usage of GNU_ITERATE_DATATYPES with proper callback + instead. Complete iteration happens on C++ side now. +[7] remove "struct global_iterator" from request structure, but add + several fields (including callback pointer) to be able to perform + iteration on C++ side +[8] type of "linux_banner" symbol is reported as 'D' by new gdb as its + section ".rodata" marked as writable in vmlinux +[9] BFD API has changed. +[10] the deprecated_command_loop_hook got deprecated. So, call crash + main_loop() directly from gdb captured_main() +[11] remove previously used hooks for that in target.c. Add crash_target + for gdb to provide target operations such as xfer_partial to read + and write crash dump memory. + +Signed-off-by: Alexey Makhalov +Signed-off-by: Lianbo Jiang +--- + Makefile | 17 +- + configure.c | 28 +- + crash_target.c | 104 + + defs.h | 41 +- + gdb-10.2.patch | 1582 +++++++++++ + gdb-7.6-ppc64le-support.patch | 4950 --------------------------------- + gdb-7.6-proc_service.h.patch | 67 - + gdb-7.6.patch | 2558 ----------------- + gdb_interface.c | 74 +- + help.c | 1 + + kernel.c | 2 +- + main.c | 1 - + symbols.c | 123 +- + tools.c | 2 +- + x86_64.c | 3 +- + 15 files changed, 1832 insertions(+), 7721 deletions(-) + create mode 100644 crash_target.c + create mode 100644 gdb-10.2.patch + delete mode 100644 gdb-7.6-ppc64le-support.patch + delete mode 100644 gdb-7.6-proc_service.h.patch + delete mode 100644 gdb-7.6.patch + +diff --git a/Makefile b/Makefile +index eae023c54bdd..4fd8b7818664 100644 +--- a/Makefile ++++ b/Makefile +@@ -182,6 +182,9 @@ GDB_7.3.1_OFILES=${GDB}/gdb/symtab.o + GDB_7.6_FILES= + GDB_7.6_OFILES=${GDB}/gdb/symtab.o + ++GDB_10.2_FILES= ++GDB_10.2_OFILES=${GDB}/gdb/symtab.o ++ + # + # GDB_FLAGS is passed up from the gdb Makefile. + # +@@ -207,7 +210,7 @@ TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \ + ${EXTENSION_SOURCE_FILES} ${MEMORY_DRIVER_FILES} + CSCOPE_FILES=${SOURCE_FILES} + +-READLINE_DIRECTORY=./${GDB}/readline ++READLINE_DIRECTORY=./${GDB}/readline/readline + BFD_DIRECTORY=./${GDB}/bfd + GDB_INCLUDE_DIRECTORY=./${GDB}/include + +@@ -266,18 +269,6 @@ gdb_unzip: + gdb_patch: + if [ -f ${GDB}.patch ] && [ -s ${GDB}.patch ]; then \ + patch -p0 < ${GDB}.patch; cp ${GDB}.patch ${GDB}; fi +- if [ "${ARCH}" = "ppc64le" ] && [ -f ${GDB}-ppc64le-support.patch ]; then \ +- patch -d ${GDB} -p1 -F0 < ${GDB}-ppc64le-support.patch ; \ +- fi +- if [ "${ARCH}" = "x86_64" ] && [ "${TARGET}" = "PPC64" ] && [ -f ${GDB}-ppc64le-support.patch ]; then \ +- patch -d ${GDB} -p1 -F0 < ${GDB}-ppc64le-support.patch ; \ +- fi +- if [ -f /usr/include/proc_service.h ]; then \ +- grep 'extern ps_err_e ps_get_thread_area (struct' /usr/include/proc_service.h; \ +- if [ $$? -eq 0 ]; then \ +- patch -p0 < ${GDB}-proc_service.h.patch; \ +- fi; \ +- fi + + library: make_build_data ${OBJECT_FILES} + ar -rs ${PROGRAM}lib.a ${OBJECT_FILES} +diff --git a/configure.c b/configure.c +index b691a139b960..51888519c18c 100644 +--- a/configure.c ++++ b/configure.c +@@ -161,13 +161,13 @@ void add_extra_lib(char *); + + #define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS=" + #define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux" +-#define GDB_TARGET_ARM_ON_X86_64 "GDB_CONF_FLAGS=--target=arm-elf-linux CFLAGS=-m32" +-#define GDB_TARGET_X86_ON_X86_64 "GDB_CONF_FLAGS=--target=i686-pc-linux-gnu CFLAGS=-m32" +-#define GDB_TARGET_PPC_ON_PPC64 "GDB_CONF_FLAGS=--target=ppc-elf-linux CFLAGS=-m32" ++#define GDB_TARGET_ARM_ON_X86_64 "GDB_CONF_FLAGS=--target=arm-elf-linux CFLAGS=-m32 CXXFLAGS=-m32" ++#define GDB_TARGET_X86_ON_X86_64 "GDB_CONF_FLAGS=--target=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32" ++#define GDB_TARGET_PPC_ON_PPC64 "GDB_CONF_FLAGS=--target=ppc-elf-linux CFLAGS=-m32 CXXFLAGS=-m32" + #define GDB_TARGET_ARM64_ON_X86_64 "GDB_CONF_FLAGS=--target=aarch64-elf-linux" /* TBD */ + #define GDB_TARGET_PPC64_ON_X86_64 "GDB_CONF_FLAGS=--target=powerpc64le-unknown-linux-gnu" + #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" ++#define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32 CXXFLAGS=-m32" + + /* + * The original plan was to allow the use of a particular version +@@ -182,9 +182,10 @@ void add_extra_lib(char *); + #define GDB_7_0 (3) + #define GDB_7_3_1 (4) + #define GDB_7_6 (5) +-#define SUPPORTED_GDB_VERSIONS (GDB_7_6 + 1) ++#define GDB_10_2 (6) ++#define SUPPORTED_GDB_VERSIONS (GDB_10_2 + 1) + +-int default_gdb = GDB_7_6; ++int default_gdb = GDB_10_2; + + struct supported_gdb_version { + char *GDB; +@@ -249,6 +250,15 @@ struct supported_gdb_version { + "GDB_FLAGS=-DGDB_7_6", + "GPLv3" + }, ++ { ++ "GDB=gdb-10.2", ++ "10.2", ++ "GDB_FILES=${GDB_10.2_FILES}", ++ "GDB_OFILES=${GDB_10.2_OFILES}", ++ "GDB_PATCH_FILES=gdb-10.2.patch", ++ "GDB_FLAGS=-DGDB_10_2", ++ "GPLv3" ++ }, + }; + + #define DAEMON 0x1 +@@ -1514,6 +1524,12 @@ setup_gdb_defaults(void) + fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN); + return store_gdb_defaults(sp); + } ++ if (strcmp(buf, "10.2") == 0) { ++ fclose(fp); ++ sp = &supported_gdb_versions[GDB_10_2]; ++ fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN); ++ return store_gdb_defaults(sp); ++ } + + } + +diff --git a/crash_target.c b/crash_target.c +new file mode 100644 +index 000000000000..a123329019f5 +--- /dev/null ++++ b/crash_target.c +@@ -0,0 +1,104 @@ ++/* ++ * crash_target.c ++ * ++ * Copyright (c) 2021 VMware, 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 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. ++ * ++ * Author: Alexey Makhalov ++ */ ++ ++#include ++#include "top.h" ++#include "target.h" ++#include "inferior.h" ++#include "regcache.h" ++#include "gdbarch.h" ++ ++void crash_target_init (void); ++ ++extern "C" int gdb_readmem_callback(unsigned long, void *, int, int); ++extern "C" int crash_get_nr_cpus(void); ++ ++ ++/* The crash target. */ ++ ++static const target_info crash_target_info = { ++ "crash", ++ N_("Local core dump file"), ++ N_("Use a built-in crash instance as a target.") ++}; ++ ++class crash_target final : public process_stratum_target ++{ ++public: ++ ++ const target_info &info () const override ++ { return crash_target_info; } ++ ++ enum target_xfer_status xfer_partial (enum target_object object, ++ const char *annex, ++ gdb_byte *readbuf, ++ const gdb_byte *writebuf, ++ ULONGEST offset, ULONGEST len, ++ ULONGEST *xfered_len) override; ++ ++ bool has_all_memory () override { return true; } ++ bool has_memory () override { return true; } ++ bool has_stack () override { return true; } ++ bool has_registers () override { return false; } ++ bool thread_alive (ptid_t ptid) override { return true; } ++ std::string pid_to_str (ptid_t ptid) override ++ { return string_printf ("CPU %ld", ptid.tid ()); } ++ ++}; ++ ++ ++enum target_xfer_status ++crash_target::xfer_partial (enum target_object object, const char *annex, ++ gdb_byte *readbuf, const gdb_byte *writebuf, ++ ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) ++{ ++ if (object != TARGET_OBJECT_MEMORY && object != TARGET_OBJECT_STACK_MEMORY ++ && object != TARGET_OBJECT_CODE_MEMORY) ++ return TARGET_XFER_E_IO; ++ ++ if (gdb_readmem_callback(offset, (void *)(readbuf ? readbuf : writebuf), len, !readbuf)) ++ { ++ *xfered_len = len; ++ return TARGET_XFER_OK; ++ } ++ ++ return TARGET_XFER_E_IO; ++} ++ ++#define CRASH_INFERIOR_PID 1 ++ ++void ++crash_target_init (void) ++{ ++ int nr_cpus = crash_get_nr_cpus(); ++ crash_target *target = new crash_target (); ++ ++ /* Own the target until it is successfully pushed. */ ++ target_ops_up target_holder (target); ++ ++ push_target (std::move (target_holder)); ++ ++ inferior_appeared (current_inferior (), CRASH_INFERIOR_PID); ++ for (int i = 0; i < nr_cpus; i++) ++ { ++ thread_info *thread = add_thread_silent (target, ++ ptid_t(CRASH_INFERIOR_PID, 0, i)); ++ if (!i) ++ switch_to_thread (thread); ++ } ++} +diff --git a/defs.h b/defs.h +index b2e94722c92b..db0bd9ca9fe8 100644 +--- a/defs.h ++++ b/defs.h +@@ -515,7 +515,6 @@ struct program_context { + struct sigaction gdb_sigaction; /* gdb's SIGINT sigaction. */ + jmp_buf main_loop_env; /* longjmp target default */ + jmp_buf foreach_loop_env; /* longjmp target within foreach */ +- jmp_buf gdb_interface_env; /* longjmp target for gdb error catch */ + struct termios termios_orig; /* non-raw settings */ + struct termios termios_raw; /* while gathering command input */ + int ncmds; /* number of commands in menu */ +@@ -2586,7 +2585,7 @@ struct datatype_member { /* minimal definition of a structure/union */ + long member_size; + int member_typecode; + ulong flags; +- char *tagname; /* tagname and value for enums */ ++ const char *tagname; /* tagname and value for enums */ + long value; + ulong vaddr; + }; +@@ -4727,7 +4726,7 @@ struct gnu_request { + long member_length; + int member_typecode; + long value; +- char *tagname; ++ const char *tagname; + ulong pc; + ulong sp; + ulong ra; +@@ -4739,13 +4738,10 @@ struct gnu_request { + ulong task; + ulong debug; + struct stack_hook *hookp; +- struct global_iterator { +- int finished; +- int block_index; +- struct symtab *symtab; +- struct symbol *sym; +- struct objfile *obj; +- } global_iterator; ++ ulong lowest; ++ ulong highest; ++ void (*callback) (struct gnu_request *req, void *data); ++ void *callback_data; + struct load_module *lm; + char *member_main_type_name; + char *member_main_type_tag_name; +@@ -4775,7 +4771,7 @@ struct gnu_request { + #define GNU_USER_PRINT_OPTION (16) + #define GNU_SET_CRASH_BLOCK (17) + #define GNU_GET_FUNCTION_RANGE (18) +-#define GNU_GET_NEXT_DATATYPE (19) ++#define GNU_ITERATE_DATATYPES (19) + #define GNU_LOOKUP_STRUCT_CONTENTS (20) + #define GNU_DEBUG_COMMAND (100) + /* +@@ -4800,14 +4796,15 @@ struct gnu_request { + /* + * function prototypes required by modified gdb source files. + */ +-int console(char *, ...); +-int gdb_CRASHDEBUG(ulong); ++extern "C" int console(const char *, ...); ++extern "C" int gdb_CRASHDEBUG(ulong); + int gdb_readmem_callback(ulong, void *, int, int); + void patch_load_module(struct objfile *objfile, struct minimal_symbol *msymbol); +-int patch_kernel_symbol(struct gnu_request *); ++extern "C" int patch_kernel_symbol(struct gnu_request *); + struct syment *symbol_search(char *); + int gdb_line_number_callback(ulong, ulong, ulong); + int gdb_print_callback(ulong); ++extern "C" int same_file(char *, char *); + #endif + + #ifndef GDB_COMMON +@@ -4821,8 +4818,8 @@ enum type_code { + TYPE_CODE_STRUCT, /* C struct or Pascal record */ + TYPE_CODE_UNION, /* C union or Pascal variant part */ + TYPE_CODE_ENUM, /* Enumeration type */ +-#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) || defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) +-#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) ++#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) || defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_2) ++#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_2) + TYPE_CODE_FLAGS, /* Bit flags type */ + #endif + TYPE_CODE_FUNC, /* Function type */ +@@ -5099,7 +5096,7 @@ void exec_args_input_file(struct command_table_entry *, struct args_input_file * + FILE *set_error(char *); + int __error(int, char *, ...); + #define error __error /* avoid conflict with gdb error() */ +-int console(char *, ...); ++int console(const char *, ...); + void create_console_device(char *); + int console_off(void); + int console_on(int); +@@ -5489,9 +5486,7 @@ int file_dump(ulong, ulong, ulong, int, int); + #define DUMP_DENTRY_ONLY 0x4 + #define DUMP_EMPTY_FILE 0x8 + #define DUMP_FILE_NRPAGES 0x10 +-#endif /* !GDB_COMMON */ + int same_file(char *, char *); +-#ifndef GDB_COMMON + int cleanup_memory_driver(void); + + +@@ -7182,10 +7177,10 @@ void gdb_readnow_warning(void); + int gdb_set_crash_scope(ulong, char *); + extern int *gdb_output_format; + extern unsigned int *gdb_print_max; +-extern int *gdb_prettyprint_structs; +-extern int *gdb_prettyprint_arrays; +-extern int *gdb_repeat_count_threshold; +-extern int *gdb_stop_print_at_null; ++extern unsigned char *gdb_prettyprint_structs; ++extern unsigned char *gdb_prettyprint_arrays; ++extern unsigned int *gdb_repeat_count_threshold; ++extern unsigned char *gdb_stop_print_at_null; + extern unsigned int *gdb_output_radix; + + /* +diff --git a/gdb-10.2.patch b/gdb-10.2.patch +new file mode 100644 +index 000000000000..4f8d418b17ed +--- /dev/null ++++ b/gdb-10.2.patch +@@ -0,0 +1,1582 @@ ++ ++# 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 uninintended 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. ++ ++--- 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@ ++ ++-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 +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) ++ } ++ } ++ +++#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 @@ 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) +++ { +++ 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 @@ 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 +++ ++ } ++ ++ 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 +++ ++ /* 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 +++ ++ /* 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); +++#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()); +++ +++ 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 @@ 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 +++ */ +++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 ++--- 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; +++ +++ 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 +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); +++ +++ 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, ++--- 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; +++ } +++} +++#endif +++ ++ /* Then try in the global debugfile directories. ++ ++ Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will ++@@ -1568,6 +1606,14 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) ++ } ++ } ++ +++#ifdef CRASH_MERGE +++ if (debugfile.empty ()) { +++ char *name_copy; +++ name_copy = check_specified_kernel_debug_file(); +++ return std::string (name_copy); +++ } +++#endif +++ ++ 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 ++ ++ 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); ++ ++ 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). */ ++ +++#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,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" +++ +++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 *); +++ +++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); +++ } +++} +++ +++ +++/* +++ * General purpose routine for determining datatypes. +++ */ +++ +++static void +++gdb_get_datatype(struct gnu_request *req) +++{ +++ register struct type *type; +++ register 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) { +++ if (req->flags & GNU_PRINT_ENUMERATORS) +++ dump_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->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; +++ +++ case OP_TYPE: +++ if (gdb_CRASHDEBUG(2)) +++ 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->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 +++dump_enum(struct type *type, struct gnu_request *req) +++{ +++ register int i; +++ int len; +++ 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"); +++ +++ 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++; +++ } +++ 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) +++{ +++ register 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) +++{ +++ register 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 (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++; +++ } +++} +++ +++/* +++ * 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[80]; +++ +++ 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")) { +++ sprintf(buf, " -s %s 0x%lx", secname, +++ lm->mod_section_data[i].offset + lm->mod_base); +++ strcat(req->buf, buf); +++ } +++ } +++ } +++ } +++ +++ if (gdb_CRASHDEBUG(1)) +++ fprintf_filtered(gdb_stdout, "%s\n", req->buf); +++ +++ 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)); +++ } +++} +++ +++/* +++ * Walk through all minimal_symbols, patching their values with the +++ * correct addresses. +++ */ +++static void +++gdb_patch_symbol_values(struct gnu_request *req) +++{ +++ 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; +++} +++ +++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; +++ +++ // 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; +++ } +++ +++ if (m->code == TYPE_CODE_PTR && m->target_type) +++ m = m->target_type->main_type; +++ if (m->name) +++ n = m->name; +++ else +++ continue; +++ +++ if (strstr(n, type_name)) +++ return 1; +++ } +++ +++ return 0; +++} +++ +++static void +++iterate_datatypes (struct gnu_request *req) +++{ +++ for (objfile *objfile : current_program_space->objfiles ()) +++ { +++ if (objfile->sf) +++ objfile->sf->qf->expand_all_symtabs(objfile); +++ +++ for (compunit_symtab *cust : objfile->compunits ()) +++ { +++ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); +++ +++ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i) +++ { +++ const struct block *b = BLOCKVECTOR_BLOCK (bv, i); +++ struct block_iterator iter; +++ struct symbol *sym; +++ +++ 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 ++--- 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; ++ ++-private: ++ /* Sets the internal stream to FILE, and saves the FILE's file ++ descriptor in M_FD. */ ++ void set_stream (FILE *file); +++private: ++ ++ /* 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) ++ ++ #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 */ ++ ++ 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))); ++ #else ++-extern int rl_message (); +++extern int rl_message (void); ++ #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 ++ ++ #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 (); ++--- gdb-10.2/readline/readline/util.c.orig +++++ gdb-10.2/readline/readline/util.c ++@@ -487,10 +487,13 @@ _rl_trace (va_alist) ++ ++ if (_rl_tracefp == 0) ++ _rl_tropen (); +++ if (!_rl_tracefp) +++ goto out; ++ vfprintf (_rl_tracefp, format, args); ++ fprintf (_rl_tracefp, "\n"); ++ fflush (_rl_tracefp); ++ +++out: ++ va_end (args); ++ } ++ ++@@ -513,16 +516,17 @@ _rl_tropen (void) ++ 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; ++ } ++ ++ int ++ _rl_trclose (void) ++ { ++- int r; +++ int r = 0; ++ ++- r = fclose (_rl_tracefp); +++ if (_rl_tracefp) +++ r = fclose (_rl_tracefp); ++ _rl_tracefp = 0; ++ return r; ++ } +diff --git a/gdb-7.6-ppc64le-support.patch b/gdb-7.6-ppc64le-support.patch +deleted file mode 100644 +index 26230580c183..000000000000 +--- a/gdb-7.6-ppc64le-support.patch ++++ /dev/null +@@ -1,4950 +0,0 @@ +- +-# +-# gdb-7.6-ppc64_sysv_abi_push_float.patch +-# +- +-From: Tiago Daitx +-Date: Mon Apr 1 04:05:35 2013 +0000 +-Git-commit: d81e75c0756f21d2c3d45ce86d8b45c65f01ef67 +-References: ppc64le enablement +- +-gdb/ChangeLog +-2013-03-01 Tiago Stürmer Daitx +- +- * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function. +- (ppc64_sysv_abi_push_dummy_call): Handle complex arguments. +- +-Acked-by: Petr Tesarik +- +---- +- gdb/ChangeLog | 5 + +- gdb/ppc-sysv-tdep.c | 196 +++++++++++++++++++++++++++++++++------------------- +- 2 files changed, 131 insertions(+), 70 deletions(-) +- +---- a/gdb/ChangeLog +-+++ b/gdb/ChangeLog +-@@ -1,3 +1,8 @@ +-+2013-03-31 Tiago Stürmer Daitx +-+ +-+ * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function. +-+ (ppc64_sysv_abi_push_dummy_call): Handle complex arguments. +-+ +- 2013-04-26 Joel Brobecker +- +- * NEWS: Change "since GDB 7.5" into "in GDB 7.6". +---- a/gdb/ppc-sysv-tdep.c +-+++ b/gdb/ppc-sysv-tdep.c +-@@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADD +- return 1; +- } +- +-+/* Push a float in either registers, or in the stack. Using the ppc 64 bit +-+ SysV ABI. +-+ +-+ This implements a dumbed down version of the ABI. It always writes +-+ values to memory, GPR and FPR, even when not necessary. Doing this +-+ greatly simplifies the logic. */ +-+ +-+static void +-+ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache, +-+ struct gdbarch_tdep *tdep, struct type *type, +-+ const bfd_byte *val, int freg, int greg, +-+ CORE_ADDR gparam) +-+{ +-+ gdb_byte regval[MAX_REGISTER_SIZE]; +-+ const gdb_byte *p; +-+ +-+ if (TYPE_LENGTH (type) <= 8) +-+ { +-+ /* Version 1.7 of the 64-bit PowerPC ELF ABI says: +-+ +-+ "Single precision floating point values are mapped to +-+ the first word in a single doubleword." +-+ +-+ And version 1.9 says: +-+ +-+ "Single precision floating point values are mapped to +-+ the second word in a single doubleword." +-+ +-+ GDB then writes single precision floating point values +-+ at both words in a doubleword, to support both ABIs. */ +-+ if (TYPE_LENGTH (type) == 4) +-+ { +-+ memcpy (regval, val, 4); +-+ memcpy (regval + 4, val, 4); +-+ p = regval; +-+ } +-+ else +-+ p = val; +-+ +-+ /* Write value in the stack's parameter save area. */ +-+ write_memory (gparam, p, 8); +-+ +-+ /* Floats and Doubles go in f1 .. f13. They also consume a left aligned +-+ GREG, and can end up in memory. */ +-+ if (freg <= 13) +-+ { +-+ struct type *regtype; +-+ +-+ regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg); +-+ convert_typed_floating (val, type, regval, regtype); +-+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); +-+ } +-+ if (greg <= 10) +-+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); +-+ } +-+ else +-+ { +-+ /* IBM long double stored in two doublewords of the +-+ parameter save area and corresponding registers. */ +-+ if (!tdep->soft_float && freg <= 13) +-+ { +-+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val); +-+ if (freg <= 12) +-+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1, +-+ val + 8); +-+ } +-+ if (greg <= 10) +-+ { +-+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val); +-+ if (greg <= 9) +-+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1, +-+ val + 8); +-+ } +-+ write_memory (gparam, val, TYPE_LENGTH (type)); +-+ } +-+} +-+ +- /* Pass the arguments in either registers, or in the stack. Using the +- ppc 64 bit SysV ABI. +- +-@@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct g +- +- if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) +- { +-- /* Floats and Doubles go in f1 .. f13. They also +-- consume a left aligned GREG,, and can end up in +-- memory. */ +- if (write_pass) +-- { +-- gdb_byte regval[MAX_REGISTER_SIZE]; +-- const gdb_byte *p; +-- +-- /* Version 1.7 of the 64-bit PowerPC ELF ABI says: +-- +-- "Single precision floating point values are mapped to +-- the first word in a single doubleword." +-- +-- And version 1.9 says: +-- +-- "Single precision floating point values are mapped to +-- the second word in a single doubleword." +-- +-- GDB then writes single precision floating point values +-- at both words in a doubleword, to support both ABIs. */ +-- if (TYPE_LENGTH (type) == 4) +-- { +-- memcpy (regval, val, 4); +-- memcpy (regval + 4, val, 4); +-- p = regval; +-- } +-- else +-- p = val; +-- +-- /* Write value in the stack's parameter save area. */ +-- write_memory (gparam, p, 8); +-- +-- if (freg <= 13) +-- { +-- struct type *regtype +-- = register_type (gdbarch, tdep->ppc_fp0_regnum); +-- +-- convert_typed_floating (val, type, regval, regtype); +-- regcache_cooked_write (regcache, +-- tdep->ppc_fp0_regnum + freg, +-- regval); +-- } +-- if (greg <= 10) +-- regcache_cooked_write (regcache, +-- tdep->ppc_gp0_regnum + greg, +-- regval); +-- } +-+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, +-+ val, freg, greg, gparam); +- +- freg++; +- greg++; +-@@ -1276,35 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct g +- && (gdbarch_long_double_format (gdbarch) +- == floatformats_ibm_long_double)) +- { +-- /* IBM long double stored in two doublewords of the +-- parameter save area and corresponding registers. */ +- if (write_pass) +-+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, +-+ val, freg, greg, gparam); +-+ freg += 2; +-+ greg += 2; +-+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); +-+ } +-+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX +-+ && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16)) +-+ { +-+ int i; +-+ +-+ for (i = 0; i < 2; i++) +- { +-- if (!tdep->soft_float && freg <= 13) +-- { +-- regcache_cooked_write (regcache, +-- tdep->ppc_fp0_regnum + freg, +-- val); +-- if (freg <= 12) +-- regcache_cooked_write (regcache, +-- tdep->ppc_fp0_regnum + freg + 1, +-- val + 8); +-- } +-- if (greg <= 10) +-+ if (write_pass) +- { +-- regcache_cooked_write (regcache, +-- tdep->ppc_gp0_regnum + greg, +-- val); +-- if (greg <= 9) +-- regcache_cooked_write (regcache, +-- tdep->ppc_gp0_regnum + greg + 1, +-- val + 8); +-+ struct type *target_type; +-+ +-+ target_type = check_typedef (TYPE_TARGET_TYPE (type)); +-+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, +-+ target_type, val + i * +-+ TYPE_LENGTH (target_type), +-+ freg, greg, gparam); +- } +-- write_memory (gparam, val, TYPE_LENGTH (type)); +-+ freg++; +-+ greg++; +-+ /* Always consume parameter stack space. */ +-+ gparam = align_up (gparam + 8, tdep->wordsize); +-+ } +-+ } +-+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX +-+ && TYPE_LENGTH (type) == 32 +-+ && (gdbarch_long_double_format (gdbarch) +-+ == floatformats_ibm_long_double)) +-+ { +-+ int i; +-+ +-+ for (i = 0; i < 2; i++) +-+ { +-+ struct type *target_type; +-+ +-+ target_type = check_typedef (TYPE_TARGET_TYPE (type)); +-+ if (write_pass) +-+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, +-+ target_type, val + i * +-+ TYPE_LENGTH (target_type), +-+ freg, greg, gparam); +-+ freg += 2; +-+ greg += 2; +-+ gparam = align_up (gparam + TYPE_LENGTH (target_type), +-+ tdep->wordsize); +- } +-- freg += 2; +-- greg += 2; +-- gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); +- } +- else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT +- && TYPE_LENGTH (type) <= 8) +- +- +- +-# +-# gdb-7.6-bound_minimal_symbol.patch +-# +- +-From: Tom Tromey +-Date: Mon Apr 8 19:59:09 2013 +0000 +-Git-commit: 7cbd4a934e9cf3808e1199c62e65b4c25b24b4e5 +-References: ppc64le enablement +- +- * minsyms.h (struct bound_minimal_symbol): New. +- (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. +- Remove objfile argument. +- (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): +- Return bound_minimal_symbol. +- * minsyms.c (lookup_minimal_symbol_by_pc_1) +- (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): +- Return bound_minimal_symbol. +- (in_gnu_ifunc_stub): Update. +- (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. +- Remove 'objfile_p' argument. +- (lookup_solib_trampoline_symbol_by_pc): Update. +- * ada-tasks.c, amd64-windows-tdep.c, arm-tdep.c, +- arm-wince-tdep.c, block.c, blockframe.c, breakpoint.c, btrace.c, +- c-valprint.c, dwarf2loc.c, elfread.c, frame.c, frv-tdep.c, +- glibc-tdep.c, gnu-v2-abi.c, gnu-v3-abi.c, hppa-hpux-tdep.c, +- i386-tdep.c, ia64-tdep.c, infcall.c, infcmd.c, jit.c, +- linux-fork.c, m32c-tdep.c, m68hc11-tdep.c, maint.c, +- mips-tdep.c, p-valprint.c, parse.c, ppc-linux-tdep.c, +- ppc-sysv-tdep.c, printcmd.c, rs6000-tdep.c, sh64-tdep.c, +- stack.c, symtab.c, tui/tui-disasm.c: Update. +- +-Acked-by: Petr Tesarik +- +---- +- gdb/ChangeLog | 24 +++++++++++++++++++ +- gdb/ada-tasks.c | 6 ++-- +- gdb/amd64-windows-tdep.c | 12 +++++---- +- gdb/arm-tdep.c | 23 +++++++++--------- +- gdb/arm-wince-tdep.c | 14 +++++------ +- gdb/block.c | 5 ++-- +- gdb/blockframe.c | 8 +++--- +- gdb/breakpoint.c | 6 ++-- +- gdb/btrace.c | 8 +++--- +- gdb/c-valprint.c | 14 +++++------ +- gdb/coff-pe-read.c | 19 ++++++--------- +- gdb/dwarf2loc.c | 51 ++++++++++++++++++++++++------------------ +- gdb/elfread.c | 10 ++++---- +- gdb/frame.c | 2 - +- gdb/frv-tdep.c | 8 +++--- +- gdb/glibc-tdep.c | 11 ++++----- +- gdb/gnu-v2-abi.c | 6 ++-- +- gdb/gnu-v3-abi.c | 4 +-- +- gdb/hppa-hpux-tdep.c | 37 +++++++++++++++++------------- +- gdb/i386-tdep.c | 10 ++++---- +- gdb/ia64-tdep.c | 4 +-- +- gdb/infcall.c | 6 ++-- +- gdb/infcmd.c | 6 ++-- +- gdb/jit.c | 18 ++++++++------ +- gdb/linux-fork.c | 6 ++-- +- gdb/m32c-tdep.c | 15 ++++++------ +- gdb/m68hc11-tdep.c | 8 +++--- +- gdb/maint.c | 10 ++++---- +- gdb/minsyms.c | 57 ++++++++++++++++++++++++++++++++--------------- +- gdb/minsyms.h | 32 ++++++++++++++++++-------- +- gdb/mips-tdep.c | 48 +++++++++++++++++++-------------------- +- gdb/p-valprint.c | 13 +++++----- +- gdb/parse.c | 7 +++-- +- gdb/ppc-linux-tdep.c | 9 ++++--- +- gdb/ppc-sysv-tdep.c | 7 +++-- +- gdb/printcmd.c | 5 ++-- +- gdb/rs6000-tdep.c | 16 ++++++------- +- gdb/sh64-tdep.c | 6 ++-- +- gdb/stack.c | 28 ++++++++++++----------- +- gdb/symtab.c | 23 +++++++++--------- +- gdb/tui/tui-disasm.c | 2 - +- 41 files changed, 345 insertions(+), 259 deletions(-) +- +---- a/gdb/ChangeLog +-+++ b/gdb/ChangeLog +-@@ -1,3 +1,27 @@ +-+2013-04-08 Tom Tromey +-+ +-+ * minsyms.h (struct bound_minimal_symbol): New. +-+ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. +-+ Remove objfile argument. +-+ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): +-+ Return bound_minimal_symbol. +-+ * minsyms.c (lookup_minimal_symbol_by_pc_1) +-+ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc): +-+ Return bound_minimal_symbol. +-+ (in_gnu_ifunc_stub): Update. +-+ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol. +-+ Remove 'objfile_p' argument. +-+ (lookup_solib_trampoline_symbol_by_pc): Update. +-+ * ada-tasks.c, amd64-windows-tdep.c, arm-tdep.c, +-+ arm-wince-tdep.c, block.c, blockframe.c, breakpoint.c, btrace.c, +-+ c-valprint.c, dwarf2loc.c, elfread.c, frame.c, frv-tdep.c, +-+ glibc-tdep.c, gnu-v2-abi.c, gnu-v3-abi.c, hppa-hpux-tdep.c, +-+ i386-tdep.c, ia64-tdep.c, infcall.c, infcmd.c, jit.c, +-+ linux-fork.c, m32c-tdep.c, m68hc11-tdep.c, maint.c, +-+ mips-tdep.c, p-valprint.c, parse.c, ppc-linux-tdep.c, +-+ ppc-sysv-tdep.c, printcmd.c, rs6000-tdep.c, sh64-tdep.c, +-+ stack.c, symtab.c, tui/tui-disasm.c: Update. +-+ +- 2013-03-31 Tiago Stürmer Daitx +- +- * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function. +---- a/gdb/ada-tasks.c +-+++ b/gdb/ada-tasks.c +-@@ -635,12 +635,12 @@ read_atcb (CORE_ADDR task_id, struct ada +- sizeof (task_info->name) - 1); +- else +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (task_id); +-- if (msym) +-+ if (msym.minsym) +- { +-- const char *full_name = SYMBOL_LINKAGE_NAME (msym); +-+ const char *full_name = SYMBOL_LINKAGE_NAME (msym.minsym); +- const char *task_name = full_name; +- const char *p; +- +---- a/gdb/amd64-windows-tdep.c +-+++ b/gdb/amd64-windows-tdep.c +-@@ -140,14 +140,14 @@ amd64_skip_main_prologue (struct gdbarch +- +- if (target_read_memory (pc + 1, buf, sizeof buf) == 0) +- { +-- struct minimal_symbol *s; +-+ struct bound_minimal_symbol s; +- CORE_ADDR call_dest; +- +- call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); +- s = lookup_minimal_symbol_by_pc (call_dest); +-- if (s != NULL +-- && SYMBOL_LINKAGE_NAME (s) != NULL +-- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) +-+ if (s.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL +-+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) +- pc += 5; +- } +- } +-@@ -175,7 +175,9 @@ amd64_windows_skip_trampoline_code (stru +- CORE_ADDR indirect_addr = pc + offset + 6; +- +- struct minimal_symbol *indsym +-- = indirect_addr ? lookup_minimal_symbol_by_pc (indirect_addr) : NULL; +-+ = (indirect_addr +-+ ? lookup_minimal_symbol_by_pc (indirect_addr).minsym +-+ : NULL); +- const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : NULL; +- +- if (symname) +---- a/gdb/arm-tdep.c +-+++ b/gdb/arm-tdep.c +-@@ -381,7 +381,7 @@ arm_find_mapping_symbol (CORE_ADDR memad +- int +- arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- char type; +- struct displaced_step_closure* dsc +- = get_displaced_step_closure_by_addr(memaddr); +-@@ -423,8 +423,8 @@ arm_pc_is_thumb (struct gdbarch *gdbarch +- +- /* Thumb functions have a "special" bit set in minimal symbols. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-- return (MSYMBOL_IS_SPECIAL (sym)); +-+ if (sym.minsym) +-+ return (MSYMBOL_IS_SPECIAL (sym.minsym)); +- +- /* If the user wants to override the fallback mode, let them. */ +- if (strcmp (arm_fallback_mode_string, "arm") == 0) +-@@ -468,14 +468,14 @@ static int +- skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb) +- { +- enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (pc); +-- if (msym != NULL +-- && SYMBOL_VALUE_ADDRESS (msym) == pc +-- && SYMBOL_LINKAGE_NAME (msym) != NULL) +-+ if (msym.minsym != NULL +-+ && SYMBOL_VALUE_ADDRESS (msym.minsym) == pc +-+ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL) +- { +-- const char *name = SYMBOL_LINKAGE_NAME (msym); +-+ const char *name = SYMBOL_LINKAGE_NAME (msym.minsym); +- +- /* The GNU linker's Thumb call stub to foo is named +- __foo_from_thumb. */ +-@@ -1284,7 +1284,7 @@ arm_skip_stack_protector(CORE_ADDR pc, s +- { +- enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); +- unsigned int basereg; +-- struct minimal_symbol *stack_chk_guard; +-+ struct bound_minimal_symbol stack_chk_guard; +- int offset; +- int is_thumb = arm_pc_is_thumb (gdbarch, pc); +- CORE_ADDR addr; +-@@ -1299,8 +1299,9 @@ arm_skip_stack_protector(CORE_ADDR pc, s +- /* If name of symbol doesn't start with '__stack_chk_guard', this +- instruction sequence is not for stack protector. If symbol is +- removed, we conservatively think this sequence is for stack protector. */ +-- if (stack_chk_guard +-- && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard), "__stack_chk_guard", +-+ if (stack_chk_guard.minsym +-+ && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard.minsym), +-+ "__stack_chk_guard", +- strlen ("__stack_chk_guard")) != 0) +- return pc; +- +---- a/gdb/arm-wince-tdep.c +-+++ b/gdb/arm-wince-tdep.c +-@@ -43,7 +43,7 @@ arm_pe_skip_trampoline_code (struct fram +- struct gdbarch *gdbarch = get_frame_arch (frame); +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- ULONGEST indirect; +-- struct minimal_symbol *indsym; +-+ struct bound_minimal_symbol indsym; +- const char *symname; +- CORE_ADDR next_pc; +- +-@@ -62,10 +62,10 @@ arm_pe_skip_trampoline_code (struct fram +- return 0; +- +- indsym = lookup_minimal_symbol_by_pc (indirect); +-- if (indsym == NULL) +-+ if (indsym.minsym == NULL) +- return 0; +- +-- symname = SYMBOL_LINKAGE_NAME (indsym); +-+ symname = SYMBOL_LINKAGE_NAME (indsym.minsym); +- if (symname == NULL || strncmp (symname, "__imp_", 6) != 0) +- return 0; +- +-@@ -100,11 +100,11 @@ arm_wince_skip_main_prologue (struct gdb +- +- long offset = sign_extend (this_instr & 0x000fffff, 23) << 2; +- CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU; +-- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); +-+ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); +- +-- if (s != NULL +-- && SYMBOL_LINKAGE_NAME (s) != NULL +-- && strcmp (SYMBOL_LINKAGE_NAME (s), "__gccmain") == 0) +-+ if (s.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL +-+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__gccmain") == 0) +- pc += 4; +- } +- +---- a/gdb/block.c +-+++ b/gdb/block.c +-@@ -208,7 +208,7 @@ call_site_for_pc (struct gdbarch *gdbarc +- +- if (slot == NULL) +- { +-- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc); +-+ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); +- +- /* DW_TAG_gnu_call_site will be missing just if GCC could not determine +- the call target. */ +-@@ -216,7 +216,8 @@ call_site_for_pc (struct gdbarch *gdbarc +- _("DW_OP_GNU_entry_value resolving cannot find " +- "DW_TAG_GNU_call_site %s in %s"), +- paddress (gdbarch, pc), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym))); +- } +- +- return *slot; +---- a/gdb/blockframe.c +-+++ b/gdb/blockframe.c +-@@ -88,7 +88,7 @@ CORE_ADDR +- get_pc_function_start (CORE_ADDR pc) +- { +- struct block *bl; +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- +- bl = block_for_pc (pc); +- if (bl) +-@@ -103,9 +103,9 @@ get_pc_function_start (CORE_ADDR pc) +- } +- +- msymbol = lookup_minimal_symbol_by_pc (pc); +-- if (msymbol) +-+ if (msymbol.minsym) +- { +-- CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol); +-+ CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol.minsym); +- +- if (find_pc_section (fstart)) +- return fstart; +-@@ -218,7 +218,7 @@ find_pc_partial_function_gnu_ifunc (CORE +- && section == cache_pc_function_section) +- goto return_cached_value; +- +-- msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section); +-+ msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section).minsym; +- ALL_OBJFILES (objfile) +- { +- if (objfile->sf) +---- a/gdb/breakpoint.c +-+++ b/gdb/breakpoint.c +-@@ -9824,14 +9824,14 @@ resolve_sal_pc (struct symtab_and_line * +- if we have line numbers but no functions (as can +- happen in assembly source). */ +- +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- struct cleanup *old_chain = save_current_space_and_thread (); +- +- switch_to_program_space_and_thread (sal->pspace); +- +- msym = lookup_minimal_symbol_by_pc (sal->pc); +-- if (msym) +-- sal->section = SYMBOL_OBJ_SECTION (msym); +-+ if (msym.minsym) +-+ sal->section = SYMBOL_OBJ_SECTION (msym.minsym); +- +- do_cleanups (old_chain); +- } +---- a/gdb/btrace.c +-+++ b/gdb/btrace.c +-@@ -272,7 +272,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr +- for (idx = 0; VEC_iterate (btrace_inst_s, itrace, idx, binst); ++idx) +- { +- struct symtab_and_line sal; +-- struct minimal_symbol *mfun; +-+ struct bound_minimal_symbol mfun; +- struct symbol *fun; +- const char *filename; +- CORE_ADDR pc; +-@@ -285,7 +285,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr +- fun = find_pc_function (pc); +- mfun = lookup_minimal_symbol_by_pc (pc); +- +-- if (fun == NULL && mfun == NULL) +-+ if (fun == NULL && mfun.minsym == NULL) +- { +- DEBUG_FTRACE ("no symbol at %u, pc=%s", idx, +- core_addr_to_string_nz (pc)); +-@@ -293,11 +293,11 @@ compute_ftrace (VEC (btrace_inst_s) *itr +- } +- +- /* If we're switching functions, we start over. */ +-- if (ftrace_function_switched (bfun, mfun, fun)) +-+ if (ftrace_function_switched (bfun, mfun.minsym, fun)) +- { +- bfun = VEC_safe_push (btrace_func_s, ftrace, NULL); +- +-- ftrace_init_func (bfun, mfun, fun, idx); +-+ ftrace_init_func (bfun, mfun.minsym, fun, idx); +- ftrace_debug (bfun, "init"); +- } +- +---- a/gdb/c-valprint.c +-+++ b/gdb/c-valprint.c +-@@ -310,18 +310,18 @@ c_val_print (struct type *type, const gd +- CORE_ADDR vt_address = unpack_pointer (type, +- valaddr +- + embedded_offset); +-- struct minimal_symbol *msymbol = +-- lookup_minimal_symbol_by_pc (vt_address); +-+ struct bound_minimal_symbol msymbol = +-+ lookup_minimal_symbol_by_pc (vt_address); +- +- /* If 'symbol_print' is set, we did the work above. */ +- if (!options->symbol_print +-- && (msymbol != NULL) +-- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) +-+ && (msymbol.minsym != NULL) +-+ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym))) +- { +- if (want_space) +- fputs_filtered (" ", stream); +- fputs_filtered (" <", stream); +-- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); +-+ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream); +- fputs_filtered (">", stream); +- want_space = 1; +- } +-@@ -337,8 +337,8 @@ c_val_print (struct type *type, const gd +- if (want_space) +- fputs_filtered (" ", stream); +- +-- if (msymbol != NULL) +-- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), +-+ if (msymbol.minsym != NULL) +-+ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym), +- block, VAR_DOMAIN, +- &is_this_fld); +- +---- a/gdb/coff-pe-read.c +-+++ b/gdb/coff-pe-read.c +-@@ -203,8 +203,7 @@ add_pe_forwarded_sym (const char *sym_na +- const char *dll_name, struct objfile *objfile) +- { +- CORE_ADDR vma; +-- struct objfile *forward_objfile; +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- short section; +- enum minimal_symbol_type msymtype; +- int dll_name_len = strlen (dll_name); +-@@ -218,20 +217,18 @@ add_pe_forwarded_sym (const char *sym_na +- forward_func_name); +- +- +-- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, +-- &forward_objfile); +-+ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); +- +-- if (!msymbol) +-+ if (!msymbol.minsym) +- { +- int i; +- +- for (i = 0; i < forward_dll_name_len; i++) +- forward_qualified_name[i] = tolower (forward_qualified_name[i]); +-- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, +-- &forward_objfile); +-+ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name); +- } +- +-- if (!msymbol) +-+ if (!msymbol.minsym) +- { +- if (debug_coff_pe_read) +- fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in" +-@@ -246,9 +243,9 @@ add_pe_forwarded_sym (const char *sym_na +- " \"%s\" in dll \"%s\", pointing to \"%s\"\n"), +- sym_name, dll_name, forward_qualified_name); +- +-- vma = SYMBOL_VALUE_ADDRESS (msymbol); +-- section = SYMBOL_SECTION (msymbol); +-- msymtype = MSYMBOL_TYPE (msymbol); +-+ vma = SYMBOL_VALUE_ADDRESS (msymbol.minsym); +-+ section = SYMBOL_SECTION (msymbol.minsym); +-+ msymtype = MSYMBOL_TYPE (msymbol.minsym); +- +- /* Generate a (hopefully unique) qualified name using the first part +- of the dll name, e.g. KERNEL32!AddAtomA. This matches the style +---- a/gdb/dwarf2loc.c +-+++ b/gdb/dwarf2loc.c +-@@ -500,19 +500,20 @@ call_site_to_target_addr (struct gdbarch +- dwarf_block = FIELD_DWARF_BLOCK (call_site->target); +- if (dwarf_block == NULL) +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); +- throw_error (NO_ENTRY_VALUE_ERROR, +- _("DW_AT_GNU_call_site_target is not specified " +- "at %s in %s"), +- paddress (call_site_gdbarch, call_site->pc), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym))); +- +- } +- if (caller_frame == NULL) +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); +- throw_error (NO_ENTRY_VALUE_ERROR, +-@@ -520,7 +521,8 @@ call_site_to_target_addr (struct gdbarch +- "requires known frame which is currently not " +- "available at %s in %s"), +- paddress (call_site_gdbarch, call_site->pc), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym))); +- +- } +- caller_arch = get_frame_arch (caller_frame); +-@@ -547,7 +549,7 @@ call_site_to_target_addr (struct gdbarch +- msym = lookup_minimal_symbol (physname, NULL, NULL); +- if (msym == NULL) +- { +-- msym = lookup_minimal_symbol_by_pc (call_site->pc - 1); +-+ msym = lookup_minimal_symbol_by_pc (call_site->pc - 1).minsym; +- throw_error (NO_ENTRY_VALUE_ERROR, +- _("Cannot find function \"%s\" for a call site target " +- "at %s in %s"), +-@@ -643,14 +645,15 @@ func_verify_no_selftailcall (struct gdba +- +- if (target_addr == verify_addr) +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (verify_addr); +- throw_error (NO_ENTRY_VALUE_ERROR, +- _("DW_OP_GNU_entry_value resolving has found " +- "function \"%s\" at %s can call itself via tail " +- "calls"), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym), +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym)), +- paddress (gdbarch, verify_addr)); +- } +- +-@@ -674,10 +677,11 @@ static void +- tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site) +- { +- CORE_ADDR addr = call_site->pc; +-- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (addr - 1); +-+ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); +- +- fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym))); +- +- } +- +-@@ -907,7 +911,7 @@ call_site_find_chain_1 (struct gdbarch * +- +- if (retval == NULL) +- { +-- struct minimal_symbol *msym_caller, *msym_callee; +-+ struct bound_minimal_symbol msym_caller, msym_callee; +- +- msym_caller = lookup_minimal_symbol_by_pc (caller_pc); +- msym_callee = lookup_minimal_symbol_by_pc (callee_pc); +-@@ -915,11 +919,11 @@ call_site_find_chain_1 (struct gdbarch * +- _("There are no unambiguously determinable intermediate " +- "callers or callees between caller function \"%s\" at %s " +- "and callee function \"%s\" at %s"), +-- (msym_caller == NULL +-- ? "???" : SYMBOL_PRINT_NAME (msym_caller)), +-+ (msym_caller.minsym == NULL +-+ ? "???" : SYMBOL_PRINT_NAME (msym_caller.minsym)), +- paddress (gdbarch, caller_pc), +-- (msym_callee == NULL +-- ? "???" : SYMBOL_PRINT_NAME (msym_callee)), +-+ (msym_callee.minsym == NULL +-+ ? "???" : SYMBOL_PRINT_NAME (msym_callee.minsym)), +- paddress (gdbarch, callee_pc)); +- } +- +-@@ -1011,7 +1015,8 @@ dwarf_expr_reg_to_entry_parameter (struc +- caller_frame = get_prev_frame (frame); +- if (gdbarch != frame_unwind_arch (frame)) +- { +-- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr); +-+ struct bound_minimal_symbol msym +-+ = lookup_minimal_symbol_by_pc (func_addr); +- struct gdbarch *caller_gdbarch = frame_unwind_arch (frame); +- +- throw_error (NO_ENTRY_VALUE_ERROR, +-@@ -1019,18 +1024,21 @@ dwarf_expr_reg_to_entry_parameter (struc +- "(of %s (%s)) does not match caller gdbarch %s"), +- gdbarch_bfd_arch_info (gdbarch)->printable_name, +- paddress (gdbarch, func_addr), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym), +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym)), +- gdbarch_bfd_arch_info (caller_gdbarch)->printable_name); +- } +- +- if (caller_frame == NULL) +- { +-- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr); +-+ struct bound_minimal_symbol msym +-+ = lookup_minimal_symbol_by_pc (func_addr); +- +- throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_GNU_entry_value resolving " +- "requires caller of %s (%s)"), +- paddress (gdbarch, func_addr), +-- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); +-+ (msym.minsym == NULL ? "???" +-+ : SYMBOL_PRINT_NAME (msym.minsym))); +- } +- caller_pc = get_frame_pc (caller_frame); +- call_site = call_site_for_pc (gdbarch, caller_pc); +-@@ -1040,8 +1048,8 @@ dwarf_expr_reg_to_entry_parameter (struc +- { +- struct minimal_symbol *target_msym, *func_msym; +- +-- target_msym = lookup_minimal_symbol_by_pc (target_addr); +-- func_msym = lookup_minimal_symbol_by_pc (func_addr); +-+ target_msym = lookup_minimal_symbol_by_pc (target_addr).minsym; +-+ func_msym = lookup_minimal_symbol_by_pc (func_addr).minsym; +- throw_error (NO_ENTRY_VALUE_ERROR, +- _("DW_OP_GNU_entry_value resolving expects callee %s at %s " +- "but the called frame is for %s at %s"), +-@@ -1064,7 +1072,8 @@ dwarf_expr_reg_to_entry_parameter (struc +- } +- if (iparams == call_site->parameter_count) +- { +-- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc); +-+ struct minimal_symbol *msym +-+ = lookup_minimal_symbol_by_pc (caller_pc).minsym; +- +- /* DW_TAG_GNU_call_site_parameter will be missing just if GCC could not +- determine its value. */ +---- a/gdb/elfread.c +-+++ b/gdb/elfread.c +-@@ -735,7 +735,7 @@ elf_gnu_ifunc_cache_eq (const void *a_vo +- static int +- elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- asection *sect; +- struct objfile *objfile; +- htab_t htab; +-@@ -743,13 +743,13 @@ elf_gnu_ifunc_record_cache (const char * +- void **slot; +- +- msym = lookup_minimal_symbol_by_pc (addr); +-- if (msym == NULL) +-+ if (msym.minsym == NULL) +- return 0; +-- if (SYMBOL_VALUE_ADDRESS (msym) != addr) +-+ if (SYMBOL_VALUE_ADDRESS (msym.minsym) != addr) +- return 0; +- /* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL. */ +-- sect = SYMBOL_OBJ_SECTION (msym)->the_bfd_section; +-- objfile = SYMBOL_OBJ_SECTION (msym)->objfile; +-+ sect = SYMBOL_OBJ_SECTION (msym.minsym)->the_bfd_section; +-+ objfile = SYMBOL_OBJ_SECTION (msym.minsym)->objfile; +- +- /* If .plt jumps back to .plt the symbol is still deferred for later +- resolution and it has no use for GDB. Besides ".text" this symbol can +---- a/gdb/frame.c +-+++ b/gdb/frame.c +-@@ -1678,7 +1678,7 @@ get_prev_frame_1 (struct frame_info *thi +- +- /* gcc -fsplit-stack __morestack can continue the stack anywhere. */ +- this_pc_in_block = get_frame_address_in_block (this_frame); +-- morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block); +-+ morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym; +- if (morestack_msym) +- morestack_name = SYMBOL_LINKAGE_NAME (morestack_msym); +- if (!morestack_name || strcmp (morestack_name, "__morestack") != 0) +---- a/gdb/frv-tdep.c +-+++ b/gdb/frv-tdep.c +-@@ -1072,7 +1072,7 @@ frv_skip_main_prologue (struct gdbarch * +- { +- LONGEST displ; +- CORE_ADDR call_dest; +-- struct minimal_symbol *s; +-+ struct bound_minimal_symbol s; +- +- displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff); +- if ((displ & 0x00800000) != 0) +-@@ -1081,9 +1081,9 @@ frv_skip_main_prologue (struct gdbarch * +- call_dest = pc + 4 * displ; +- s = lookup_minimal_symbol_by_pc (call_dest); +- +-- if (s != NULL +-- && SYMBOL_LINKAGE_NAME (s) != NULL +-- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) +-+ if (s.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL +-+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) +- { +- pc += 4; +- return pc; +---- a/gdb/glibc-tdep.c +-+++ b/gdb/glibc-tdep.c +-@@ -53,19 +53,18 @@ glibc_skip_solib_resolver (struct gdbarc +- of GNU/Linux will provide a portable, efficient interface for +- debugging programs that use shared libraries. */ +- +-- struct objfile *objfile; +-- struct minimal_symbol *resolver +-- = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve", &objfile); +-+ struct bound_minimal_symbol resolver +-+ = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve"); +- +-- if (resolver) +-+ if (resolver.minsym) +- { +- /* The dynamic linker began using this name in early 2005. */ +- struct minimal_symbol *fixup +-- = lookup_minimal_symbol ("_dl_fixup", NULL, objfile); +-+ = lookup_minimal_symbol ("_dl_fixup", NULL, resolver.objfile); +- +- /* This is the name used in older versions. */ +- if (! fixup) +-- fixup = lookup_minimal_symbol ("fixup", NULL, objfile); +-+ fixup = lookup_minimal_symbol ("fixup", NULL, resolver.objfile); +- +- if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) +- return frame_unwind_caller_pc (get_current_frame ()); +---- a/gdb/gnu-v2-abi.c +-+++ b/gdb/gnu-v2-abi.c +-@@ -191,7 +191,7 @@ gnuv2_value_rtti_type (struct value *v, +- struct type *known_type; +- struct type *rtti_type; +- CORE_ADDR vtbl; +-- struct minimal_symbol *minsym; +-+ struct bound_minimal_symbol minsym; +- char *demangled_name, *p; +- const char *linkage_name; +- struct type *btype; +-@@ -245,8 +245,8 @@ gnuv2_value_rtti_type (struct value *v, +- +- /* Try to find a symbol that is the vtable. */ +- minsym=lookup_minimal_symbol_by_pc(vtbl); +-- if (minsym==NULL +-- || (linkage_name=SYMBOL_LINKAGE_NAME (minsym))==NULL +-+ if (minsym.minsym==NULL +-+ || (linkage_name=SYMBOL_LINKAGE_NAME (minsym.minsym))==NULL +- || !is_vtable_name (linkage_name)) +- return NULL; +- +---- a/gdb/gnu-v3-abi.c +-+++ b/gdb/gnu-v3-abi.c +-@@ -306,7 +306,7 @@ gnuv3_rtti_type (struct value *value, +- /* Find the linker symbol for this vtable. */ +- vtable_symbol +- = lookup_minimal_symbol_by_pc (value_address (vtable) +-- + value_embedded_offset (vtable)); +-+ + value_embedded_offset (vtable)).minsym; +- if (! vtable_symbol) +- return NULL; +- +-@@ -988,7 +988,7 @@ gnuv3_skip_trampoline (struct frame_info +- real_stop_pc = stop_pc; +- +- /* Find the linker symbol for this potential thunk. */ +-- thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc); +-+ thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc).minsym; +- section = find_pc_section (real_stop_pc); +- if (thunk_sym == NULL || section == NULL) +- return 0; +---- a/gdb/hppa-hpux-tdep.c +-+++ b/gdb/hppa-hpux-tdep.c +-@@ -89,7 +89,7 @@ hppa32_hpux_in_solib_call_trampoline (st +- CORE_ADDR pc, char *name) +- { +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +-- struct minimal_symbol *minsym; +-+ struct bound_minimal_symbol minsym; +- struct unwind_table_entry *u; +- +- /* First see if PC is in one of the two C-library trampolines. */ +-@@ -98,7 +98,8 @@ hppa32_hpux_in_solib_call_trampoline (st +- return 1; +- +- minsym = lookup_minimal_symbol_by_pc (pc); +-- if (minsym && strcmp (SYMBOL_LINKAGE_NAME (minsym), ".stub") == 0) +-+ if (minsym.minsym +-+ && strcmp (SYMBOL_LINKAGE_NAME (minsym.minsym), ".stub") == 0) +- return 1; +- +- /* Get the unwind descriptor corresponding to PC, return zero +-@@ -174,16 +175,16 @@ hppa64_hpux_in_solib_call_trampoline (st +- step. If it does, then assume we are not in a stub and return. +- +- Finally peek at the instructions to see if they look like a stub. */ +-- struct minimal_symbol *minsym; +-+ struct bound_minimal_symbol minsym; +- asection *sec; +- CORE_ADDR addr; +- int insn; +- +- minsym = lookup_minimal_symbol_by_pc (pc); +-- if (! minsym) +-+ if (! minsym.minsym) +- return 0; +- +-- sec = SYMBOL_OBJ_SECTION (minsym)->the_bfd_section; +-+ sec = SYMBOL_OBJ_SECTION (minsym.minsym)->the_bfd_section; +- +- if (bfd_get_section_vma (sec->owner, sec) <= pc +- && pc < (bfd_get_section_vma (sec->owner, sec) +-@@ -311,7 +312,7 @@ hppa_hpux_skip_trampoline_code (struct f +- int word_size = gdbarch_ptr_bit (gdbarch) / 8; +- long orig_pc = pc; +- long prev_inst, curr_inst, loc; +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- struct unwind_table_entry *u; +- +- /* Addresses passed to dyncall may *NOT* be the actual address +-@@ -366,10 +367,12 @@ hppa_hpux_skip_trampoline_code (struct f +- /*--------------------------------------------------------------------------*/ +- msym = lookup_minimal_symbol_by_pc (pc); +- +-- if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline) +-+ if (msym.minsym == NULL +-+ || MSYMBOL_TYPE (msym.minsym) != mst_solib_trampoline) +- return orig_pc == pc ? 0 : pc & ~0x3; +- +-- else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline) +-+ else if (msym.minsym != NULL +-+ && MSYMBOL_TYPE (msym.minsym) == mst_solib_trampoline) +- { +- struct objfile *objfile; +- struct minimal_symbol *msymbol; +-@@ -384,7 +387,7 @@ hppa_hpux_skip_trampoline_code (struct f +- { +- if (MSYMBOL_TYPE (msymbol) == mst_text +- && strcmp (SYMBOL_LINKAGE_NAME (msymbol), +-- SYMBOL_LINKAGE_NAME (msym)) == 0) +-+ SYMBOL_LINKAGE_NAME (msym.minsym)) == 0) +- { +- function_found = 1; +- break; +-@@ -401,7 +404,7 @@ hppa_hpux_skip_trampoline_code (struct f +- should be mst_text. So we need to fix the msym, and also +- get out of this function. */ +- { +-- MSYMBOL_TYPE (msym) = mst_text; +-+ MSYMBOL_TYPE (msym.minsym) = mst_text; +- return orig_pc == pc ? 0 : pc & ~0x3; +- } +- } +-@@ -472,21 +475,22 @@ hppa_hpux_skip_trampoline_code (struct f +- (curr_inst == 0xeaa0d000) || +- (curr_inst == 0xeaa0d002)) +- { +-- struct minimal_symbol *stubsym, *libsym; +-+ struct bound_minimal_symbol stubsym; +-+ struct minimal_symbol *libsym; +- +- stubsym = lookup_minimal_symbol_by_pc (loc); +-- if (stubsym == NULL) +-+ if (stubsym.minsym == NULL) +- { +- warning (_("Unable to find symbol for 0x%lx"), loc); +- return orig_pc == pc ? 0 : pc & ~0x3; +- } +- +-- libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym), +-+ libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym.minsym), +- NULL, NULL); +- if (libsym == NULL) +- { +- warning (_("Unable to find library symbol for %s."), +-- SYMBOL_PRINT_NAME (stubsym)); +-+ SYMBOL_PRINT_NAME (stubsym.minsym)); +- return orig_pc == pc ? 0 : pc & ~0x3; +- } +- +-@@ -1025,7 +1029,8 @@ static CORE_ADDR +- hppa_hpux_find_import_stub_for_addr (CORE_ADDR funcaddr) +- { +- struct objfile *objfile; +-- struct minimal_symbol *funsym, *stubsym; +-+ struct bound_minimal_symbol funsym; +-+ struct minimal_symbol *stubsym; +- CORE_ADDR stubaddr; +- +- funsym = lookup_minimal_symbol_by_pc (funcaddr); +-@@ -1034,7 +1039,7 @@ hppa_hpux_find_import_stub_for_addr (COR +- ALL_OBJFILES (objfile) +- { +- stubsym = lookup_minimal_symbol_solib_trampoline +-- (SYMBOL_LINKAGE_NAME (funsym), objfile); +-+ (SYMBOL_LINKAGE_NAME (funsym.minsym), objfile); +- +- if (stubsym) +- { +---- a/gdb/i386-tdep.c +-+++ b/gdb/i386-tdep.c +-@@ -1687,15 +1687,15 @@ i386_skip_main_prologue (struct gdbarch +- { +- /* Make sure address is computed correctly as a 32bit +- integer even if CORE_ADDR is 64 bit wide. */ +-- struct minimal_symbol *s; +-+ struct bound_minimal_symbol s; +- CORE_ADDR call_dest; +- +- call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); +- call_dest = call_dest & 0xffffffffU; +- s = lookup_minimal_symbol_by_pc (call_dest); +-- if (s != NULL +-- && SYMBOL_LINKAGE_NAME (s) != NULL +-- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) +-+ if (s.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL +-+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) +- pc += 5; +- } +- } +-@@ -3352,7 +3352,7 @@ i386_pe_skip_trampoline_code (struct fra +- unsigned long indirect = +- read_memory_unsigned_integer (pc + 2, 4, byte_order); +- struct minimal_symbol *indsym = +-- indirect ? lookup_minimal_symbol_by_pc (indirect) : 0; +-+ indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0; +- const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0; +- +- if (symname) +---- a/gdb/ia64-tdep.c +-+++ b/gdb/ia64-tdep.c +-@@ -3651,11 +3651,11 @@ ia64_convert_from_func_ptr_addr (struct +- /* There are also descriptors embedded in vtables. */ +- if (s) +- { +-- struct minimal_symbol *minsym; +-+ struct bound_minimal_symbol minsym; +- +- minsym = lookup_minimal_symbol_by_pc (addr); +- +-- if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym))) +-+ if (minsym.minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym.minsym))) +- return read_memory_unsigned_integer (addr, 8, byte_order); +- } +- +---- a/gdb/infcall.c +-+++ b/gdb/infcall.c +-@@ -355,10 +355,10 @@ get_function_name (CORE_ADDR funaddr, ch +- +- { +- /* Try the minimal symbols. */ +-- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr); +-+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr); +- +-- if (msymbol) +-- return SYMBOL_PRINT_NAME (msymbol); +-+ if (msymbol.minsym) +-+ return SYMBOL_PRINT_NAME (msymbol.minsym); +- } +- +- { +---- a/gdb/infcmd.c +-+++ b/gdb/infcmd.c +-@@ -1332,12 +1332,12 @@ until_next_command (int from_tty) +- +- if (!func) +- { +-- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); +-+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); +- +-- if (msymbol == NULL) +-+ if (msymbol.minsym == NULL) +- error (_("Execution is not within a known function.")); +- +-- tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol); +-+ tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol.minsym); +- tp->control.step_range_end = pc; +- } +- else +---- a/gdb/jit.c +-+++ b/gdb/jit.c +-@@ -1016,8 +1016,8 @@ static int +- jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, +- struct jit_program_space_data *ps_data) +- { +-- struct minimal_symbol *reg_symbol, *desc_symbol; +-- struct objfile *objf; +-+ struct bound_minimal_symbol reg_symbol; +-+ struct minimal_symbol *desc_symbol; +- struct jit_objfile_data *objf_data; +- CORE_ADDR addr; +- +-@@ -1025,19 +1025,21 @@ jit_breakpoint_re_set_internal (struct g +- { +- /* Lookup the registration symbol. If it is missing, then we +- assume we are not attached to a JIT. */ +-- reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name, &objf); +-- if (reg_symbol == NULL || SYMBOL_VALUE_ADDRESS (reg_symbol) == 0) +-+ reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name); +-+ if (reg_symbol.minsym == NULL +-+ || SYMBOL_VALUE_ADDRESS (reg_symbol.minsym) == 0) +- return 1; +- +-- desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, objf); +-+ desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, +-+ reg_symbol.objfile); +- if (desc_symbol == NULL || SYMBOL_VALUE_ADDRESS (desc_symbol) == 0) +- return 1; +- +-- objf_data = get_jit_objfile_data (objf); +-- objf_data->register_code = reg_symbol; +-+ objf_data = get_jit_objfile_data (reg_symbol.objfile); +-+ objf_data->register_code = reg_symbol.minsym; +- objf_data->descriptor = desc_symbol; +- +-- ps_data->objfile = objf; +-+ ps_data->objfile = reg_symbol.objfile; +- } +- else +- objf_data = get_jit_objfile_data (ps_data->objfile); +---- a/gdb/linux-fork.c +-+++ b/gdb/linux-fork.c +-@@ -592,11 +592,11 @@ info_checkpoints_command (char *arg, int +- printf_filtered (_(", line %d"), sal.line); +- if (!sal.symtab && !sal.line) +- { +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- msym = lookup_minimal_symbol_by_pc (pc); +-- if (msym) +-- printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym)); +-+ if (msym.minsym) +-+ printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym.minsym)); +- } +- +- putchar_filtered ('\n'); +---- a/gdb/m32c-tdep.c +-+++ b/gdb/m32c-tdep.c +-@@ -2457,14 +2457,15 @@ m32c_m16c_address_to_pointer (struct gdb +- struct minimal_symbol *tramp_msym; +- +- /* Try to find a linker symbol at this address. */ +-- struct minimal_symbol *func_msym = lookup_minimal_symbol_by_pc (addr); +-+ struct bound_minimal_symbol func_msym +-+ = lookup_minimal_symbol_by_pc (addr); +- +-- if (! func_msym) +-+ if (! func_msym.minsym) +- error (_("Cannot convert code address %s to function pointer:\n" +- "couldn't find a symbol at that address, to find trampoline."), +- paddress (gdbarch, addr)); +- +-- func_name = SYMBOL_LINKAGE_NAME (func_msym); +-+ func_name = SYMBOL_LINKAGE_NAME (func_msym.minsym); +- tramp_name = xmalloc (strlen (func_name) + 5); +- strcpy (tramp_name, func_name); +- strcat (tramp_name, ".plt"); +-@@ -2535,11 +2536,11 @@ m32c_m16c_pointer_to_address (struct gdb +- { +- /* See if there is a minimal symbol at that address whose name is +- "NAME.plt". */ +-- struct minimal_symbol *ptr_msym = lookup_minimal_symbol_by_pc (ptr); +-+ struct bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr); +- +-- if (ptr_msym) +-+ if (ptr_msym.minsym) +- { +-- const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym); +-+ const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym.minsym); +- int len = strlen (ptr_msym_name); +- +- if (len > 4 +-@@ -2572,7 +2573,7 @@ m32c_m16c_pointer_to_address (struct gdb +- { +- ptr_msym = lookup_minimal_symbol_by_pc ((aspace << 16) | ptr); +- +-- if (ptr_msym) +-+ if (ptr_msym.minsym) +- ptr |= aspace << 16; +- } +- } +---- a/gdb/m68hc11-tdep.c +-+++ b/gdb/m68hc11-tdep.c +-@@ -587,18 +587,18 @@ m68hc11_analyze_instruction (struct gdba +- static enum insn_return_kind +- m68hc11_get_return_insn (CORE_ADDR pc) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT +- function is stored by elfread.c in the high bit of the info field. +- Use this to decide which instruction the function uses to return. */ +- sym = lookup_minimal_symbol_by_pc (pc); +-- if (sym == 0) +-+ if (sym.minsym == 0) +- return RETURN_RTS; +- +-- if (MSYMBOL_IS_RTC (sym)) +-+ if (MSYMBOL_IS_RTC (sym.minsym)) +- return RETURN_RTC; +-- else if (MSYMBOL_IS_RTI (sym)) +-+ else if (MSYMBOL_IS_RTI (sym.minsym)) +- return RETURN_RTI; +- else +- return RETURN_RTS; +---- a/gdb/maint.c +-+++ b/gdb/maint.c +-@@ -445,7 +445,7 @@ maintenance_translate_address (char *arg +- CORE_ADDR address; +- struct obj_section *sect; +- char *p; +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- struct objfile *objfile; +- +- if (arg == NULL || *arg == 0) +-@@ -480,13 +480,13 @@ maintenance_translate_address (char *arg +- else +- sym = lookup_minimal_symbol_by_pc (address); +- +-- if (sym) +-+ if (sym.minsym) +- { +-- const char *symbol_name = SYMBOL_PRINT_NAME (sym); +-+ const char *symbol_name = SYMBOL_PRINT_NAME (sym.minsym); +- const char *symbol_offset +-- = pulongest (address - SYMBOL_VALUE_ADDRESS (sym)); +-+ = pulongest (address - SYMBOL_VALUE_ADDRESS (sym.minsym)); +- +-- sect = SYMBOL_OBJ_SECTION(sym); +-+ sect = SYMBOL_OBJ_SECTION(sym.minsym); +- if (sect != NULL) +- { +- const char *section_name; +---- a/gdb/minsyms.c +-+++ b/gdb/minsyms.c +-@@ -474,7 +474,7 @@ lookup_minimal_symbol_solib_trampoline ( +- there are text and trampoline symbols at the same address. +- Otherwise prefer mst_text symbols. */ +- +--static struct minimal_symbol * +-+static struct bound_minimal_symbol +- lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, +- struct obj_section *section, +- int want_trampoline) +-@@ -485,6 +485,8 @@ lookup_minimal_symbol_by_pc_section_1 (C +- struct objfile *objfile; +- struct minimal_symbol *msymbol; +- struct minimal_symbol *best_symbol = NULL; +-+ struct objfile *best_objfile = NULL; +-+ struct bound_minimal_symbol result; +- enum minimal_symbol_type want_type, other_type; +- +- want_type = want_trampoline ? mst_solib_trampoline : mst_text; +-@@ -690,14 +692,18 @@ lookup_minimal_symbol_by_pc_section_1 (C +- SYMBOL_VALUE_ADDRESS (&msymbol[hi])))) +- { +- best_symbol = &msymbol[hi]; +-+ best_objfile = objfile; +- } +- } +- } +- } +-- return (best_symbol); +-+ +-+ result.minsym = best_symbol; +-+ result.objfile = best_objfile; +-+ return result; +- } +- +--struct minimal_symbol * +-+struct bound_minimal_symbol +- lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section) +- { +- if (section == NULL) +-@@ -707,17 +713,31 @@ lookup_minimal_symbol_by_pc_section (COR +- debugging) always returns NULL making the call somewhat useless. */ +- section = find_pc_section (pc); +- if (section == NULL) +-- return NULL; +-+ { +-+ struct bound_minimal_symbol result; +-+ +-+ memset (&result, 0, sizeof (result)); +-+ return result; +-+ } +- } +- return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); +- } +- +- /* See minsyms.h. */ +- +--struct minimal_symbol * +-+struct bound_minimal_symbol +- lookup_minimal_symbol_by_pc (CORE_ADDR pc) +- { +-- return lookup_minimal_symbol_by_pc_section (pc, NULL); +-+ struct obj_section *section = find_pc_section (pc); +-+ +-+ if (section == NULL) +-+ { +-+ struct bound_minimal_symbol result; +-+ +-+ memset (&result, 0, sizeof (result)); +-+ return result; +-+ } +-+ return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); +- } +- +- /* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver. */ +-@@ -725,9 +745,9 @@ lookup_minimal_symbol_by_pc (CORE_ADDR p +- int +- in_gnu_ifunc_stub (CORE_ADDR pc) +- { +-- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); +-+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); +- +-- return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc; +-+ return msymbol.minsym && MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc; +- } +- +- /* See elf_gnu_ifunc_resolve_addr for its real implementation. */ +-@@ -785,10 +805,10 @@ const struct gnu_ifunc_fns *gnu_ifunc_fn +- +- /* See minsyms.h. */ +- +--struct minimal_symbol * +--lookup_minimal_symbol_and_objfile (const char *name, +-- struct objfile **objfile_p) +-+struct bound_minimal_symbol +-+lookup_minimal_symbol_and_objfile (const char *name) +- { +-+ struct bound_minimal_symbol result; +- struct objfile *objfile; +- unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; +- +-@@ -802,13 +822,15 @@ lookup_minimal_symbol_and_objfile (const +- { +- if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) +- { +-- *objfile_p = objfile; +-- return msym; +-+ result.minsym = msym; +-+ result.objfile = objfile; +-+ return result; +- } +- } +- } +- +-- return 0; +-+ memset (&result, 0, sizeof (result)); +-+ return result; +- } +- +- +-@@ -1287,14 +1309,15 @@ static struct minimal_symbol * +- lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc) +- { +- struct obj_section *section = find_pc_section (pc); +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- +- if (section == NULL) +- return NULL; +- msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1); +- +-- if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) +-- return msymbol; +-+ if (msymbol.minsym != NULL +-+ && MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) +-+ return msymbol.minsym; +- return NULL; +- } +- +---- a/gdb/minsyms.h +-+++ b/gdb/minsyms.h +-@@ -20,6 +20,23 @@ +- #ifndef MINSYMS_H +- #define MINSYMS_H +- +-+/* Several lookup functions return both a minimal symbol and the +-+ objfile in which it is found. This structure is used in these +-+ cases. */ +-+ +-+struct bound_minimal_symbol +-+{ +-+ /* The minimal symbol that was found, or NULL if no minimal symbol +-+ was found. */ +-+ +-+ struct minimal_symbol *minsym; +-+ +-+ /* If MINSYM is not NULL, then this is the objfile in which the +-+ symbol is defined. */ +-+ +-+ struct objfile *objfile; +-+}; +-+ +- /* This header declares most of the API for dealing with minimal +- symbols and minimal symbol tables. A few things are declared +- elsewhere; see below. +-@@ -169,12 +186,9 @@ struct minimal_symbol *lookup_minimal_sy +- struct objfile *); +- +- /* Find the minimal symbol named NAME, and return both the minsym +-- struct and its objfile. This only checks the linkage name. Sets +-- *OBJFILE_P and returns the minimal symbol, if it is found. If it +-- is not found, returns NULL. */ +-+ struct and its objfile. This only checks the linkage name. */ +- +--struct minimal_symbol *lookup_minimal_symbol_and_objfile (const char *, +-- struct objfile **); +-+struct bound_minimal_symbol lookup_minimal_symbol_and_objfile (const char *); +- +- /* Look through all the current minimal symbol tables and find the +- first minimal symbol that matches NAME and has text type. If OBJF +-@@ -213,10 +227,10 @@ struct minimal_symbol *lookup_minimal_sy +- If SECTION is NULL, this uses the result of find_pc_section +- instead. +- +-- Returns a pointer to the minimal symbol if such a symbol is found, +-- or NULL if PC is not in a suitable range. */ +-+ The result has a non-NULL 'minsym' member if such a symbol is +-+ found, or NULL if PC is not in a suitable range. */ +- +--struct minimal_symbol *lookup_minimal_symbol_by_pc_section +-+struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section +- (CORE_ADDR, +- struct obj_section *); +- +-@@ -226,7 +240,7 @@ struct minimal_symbol *lookup_minimal_sy +- This is a wrapper that calls lookup_minimal_symbol_by_pc_section +- with a NULL section argument. */ +- +--struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR); +-+struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR); +- +- /* Iterate over all the minimal symbols in the objfile OBJF which +- match NAME. Both the ordinary and demangled names of each symbol +---- a/gdb/mips-tdep.c +-+++ b/gdb/mips-tdep.c +-@@ -1115,15 +1115,15 @@ show_mask_address (struct ui_file *file, +- int +- mips_pc_is_mips (CORE_ADDR memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* Flags indicating that this is a MIPS16 or microMIPS function is +- stored by elfread.c in the high bit of the info field. Use this +- to decide if the function is standard MIPS. Otherwise if bit 0 +- of the address is clear, then this is a standard MIPS function. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-- return msymbol_is_mips (sym); +-+ if (sym.minsym) +-+ return msymbol_is_mips (sym.minsym); +- else +- return is_mips_addr (memaddr); +- } +-@@ -1133,15 +1133,15 @@ mips_pc_is_mips (CORE_ADDR memaddr) +- int +- mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* A flag indicating that this is a MIPS16 function is stored by +- elfread.c in the high bit of the info field. Use this to decide +- if the function is MIPS16. Otherwise if bit 0 of the address is +- set, then ELF file flags will tell if this is a MIPS16 function. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-- return msymbol_is_mips16 (sym); +-+ if (sym.minsym) +-+ return msymbol_is_mips16 (sym.minsym); +- else +- return is_mips16_addr (gdbarch, memaddr); +- } +-@@ -1151,7 +1151,7 @@ mips_pc_is_mips16 (struct gdbarch *gdbar +- int +- mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* A flag indicating that this is a microMIPS function is stored by +- elfread.c in the high bit of the info field. Use this to decide +-@@ -1159,8 +1159,8 @@ mips_pc_is_micromips (struct gdbarch *gd +- is set, then ELF file flags will tell if this is a microMIPS +- function. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-- return msymbol_is_micromips (sym); +-+ if (sym.minsym) +-+ return msymbol_is_micromips (sym.minsym); +- else +- return is_micromips_addr (gdbarch, memaddr); +- } +-@@ -1171,7 +1171,7 @@ mips_pc_is_micromips (struct gdbarch *gd +- static enum mips_isa +- mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* A flag indicating that this is a MIPS16 or a microMIPS function +- is stored by elfread.c in the high bit of the info field. Use +-@@ -1179,11 +1179,11 @@ mips_pc_isa (struct gdbarch *gdbarch, CO +- MIPS. Otherwise if bit 0 of the address is set, then ELF file +- flags will tell if this is a MIPS16 or a microMIPS function. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-+ if (sym.minsym) +- { +-- if (msymbol_is_micromips (sym)) +-+ if (msymbol_is_micromips (sym.minsym)) +- return ISA_MICROMIPS; +-- else if (msymbol_is_mips16 (sym)) +-+ else if (msymbol_is_mips16 (sym.minsym)) +- return ISA_MIPS16; +- else +- return ISA_MIPS; +-@@ -3582,7 +3582,7 @@ mips_stub_frame_sniffer (const struct fr +- gdb_byte dummy[4]; +- struct obj_section *s; +- CORE_ADDR pc = get_frame_address_in_block (this_frame); +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- +- /* Use the stub unwinder for unreadable code. */ +- if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) +-@@ -3602,9 +3602,9 @@ mips_stub_frame_sniffer (const struct fr +- /* Calling a PIC function from a non-PIC function passes through a +- stub. The stub for foo is named ".pic.foo". */ +- msym = lookup_minimal_symbol_by_pc (pc); +-- if (msym != NULL +-- && SYMBOL_LINKAGE_NAME (msym) != NULL +-- && strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) == 0) +-+ if (msym.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL +-+ && strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0) +- return 1; +- +- return 0; +-@@ -7626,7 +7626,7 @@ mips_skip_pic_trampoline_code (struct fr +- { +- struct gdbarch *gdbarch = get_frame_arch (frame); +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +-- struct minimal_symbol *msym; +-+ struct bound_minimal_symbol msym; +- int i; +- gdb_byte stub_code[16]; +- int32_t stub_words[4]; +-@@ -7635,18 +7635,18 @@ mips_skip_pic_trampoline_code (struct fr +- instructions inserted before foo or a three instruction sequence +- which jumps to foo. */ +- msym = lookup_minimal_symbol_by_pc (pc); +-- if (msym == NULL +-- || SYMBOL_VALUE_ADDRESS (msym) != pc +-- || SYMBOL_LINKAGE_NAME (msym) == NULL +-- || strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) != 0) +-+ if (msym.minsym == NULL +-+ || SYMBOL_VALUE_ADDRESS (msym.minsym) != pc +-+ || SYMBOL_LINKAGE_NAME (msym.minsym) == NULL +-+ || strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0) +- return 0; +- +- /* A two-instruction header. */ +-- if (MSYMBOL_SIZE (msym) == 8) +-+ if (MSYMBOL_SIZE (msym.minsym) == 8) +- return pc + 8; +- +- /* A three-instruction (plus delay slot) trampoline. */ +-- if (MSYMBOL_SIZE (msym) == 16) +-+ if (MSYMBOL_SIZE (msym.minsym) == 16) +- { +- if (target_read_memory (pc, stub_code, 16) != 0) +- return 0; +---- a/gdb/p-valprint.c +-+++ b/gdb/p-valprint.c +-@@ -221,18 +221,18 @@ pascal_val_print (struct type *type, con +- /* Print vtbl's nicely. */ +- CORE_ADDR vt_address = unpack_pointer (type, +- valaddr + embedded_offset); +-- struct minimal_symbol *msymbol = +-+ struct bound_minimal_symbol msymbol = +- lookup_minimal_symbol_by_pc (vt_address); +- +- /* If 'symbol_print' is set, we did the work above. */ +- if (!options->symbol_print +-- && (msymbol != NULL) +-- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) +-+ && (msymbol.minsym != NULL) +-+ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym))) +- { +- if (want_space) +- fputs_filtered (" ", stream); +- fputs_filtered ("<", stream); +-- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); +-+ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream); +- fputs_filtered (">", stream); +- want_space = 1; +- } +-@@ -247,8 +247,9 @@ pascal_val_print (struct type *type, con +- if (want_space) +- fputs_filtered (" ", stream); +- +-- if (msymbol != NULL) +-- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block, +-+ if (msymbol.minsym != NULL) +-+ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym), +-+ block, +- VAR_DOMAIN, &is_this_fld); +- +- if (wsym) +---- a/gdb/parse.c +-+++ b/gdb/parse.c +-@@ -508,13 +508,14 @@ write_exp_msymbol (struct minimal_symbol +- pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target); +- if (pc != addr) +- { +-- struct minimal_symbol *ifunc_msym = lookup_minimal_symbol_by_pc (pc); +-+ struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc); +- +- /* In this case, assume we have a code symbol instead of +- a data symbol. */ +- +-- if (ifunc_msym != NULL && MSYMBOL_TYPE (ifunc_msym) == mst_text_gnu_ifunc +-- && SYMBOL_VALUE_ADDRESS (ifunc_msym) == pc) +-+ if (ifunc_msym.minsym != NULL +-+ && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc +-+ && SYMBOL_VALUE_ADDRESS (ifunc_msym.minsym) == pc) +- { +- /* A function descriptor has been resolved but PC is still in the +- STT_GNU_IFUNC resolver body (such as because inferior does not +---- a/gdb/ppc-linux-tdep.c +-+++ b/gdb/ppc-linux-tdep.c +-@@ -332,7 +332,7 @@ static struct ppc_insn_pattern powerpc32 +- static int +- powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* Check whether PC is in the dynamic linker. This also checks +- whether it is in the .plt section, used by non-PIC executables. */ +-@@ -341,9 +341,10 @@ powerpc_linux_in_dynsym_resolve_code (CO +- +- /* Check if we are in the resolver. */ +- sym = lookup_minimal_symbol_by_pc (pc); +-- if (sym != NULL +-- && (strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink") == 0 +-- || strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink_PLTresolve") == 0)) +-+ if (sym.minsym != NULL +-+ && (strcmp (SYMBOL_LINKAGE_NAME (sym.minsym), "__glink") == 0 +-+ || strcmp (SYMBOL_LINKAGE_NAME (sym.minsym), +-+ "__glink_PLTresolve") == 0)) +- return 1; +- +- return 0; +---- a/gdb/ppc-sysv-tdep.c +-+++ b/gdb/ppc-sysv-tdep.c +-@@ -1076,12 +1076,13 @@ static int +- convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr) +- { +- struct obj_section *dot_fn_section; +-- struct minimal_symbol *dot_fn; +-+ struct bound_minimal_symbol dot_fn; +- struct minimal_symbol *fn; +-+ +- /* Find the minimal symbol that corresponds to CODE_ADDR (should +- have a name of the form ".FN"). */ +- dot_fn = lookup_minimal_symbol_by_pc (code_addr); +-- if (dot_fn == NULL || SYMBOL_LINKAGE_NAME (dot_fn)[0] != '.') +-+ if (dot_fn.minsym == NULL || SYMBOL_LINKAGE_NAME (dot_fn.minsym)[0] != '.') +- return 0; +- /* Get the section that contains CODE_ADDR. Need this for the +- "objfile" that it contains. */ +-@@ -1092,7 +1093,7 @@ convert_code_addr_to_desc_addr (CORE_ADD +- address. Only look for the minimal symbol in ".FN"'s object file +- - avoids problems when two object files (i.e., shared libraries) +- contain a minimal symbol with the same name. */ +-- fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL, +-+ fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn.minsym) + 1, NULL, +- dot_fn_section->objfile); +- if (fn == NULL) +- return 0; +---- a/gdb/printcmd.c +-+++ b/gdb/printcmd.c +-@@ -668,7 +668,7 @@ build_address_symbolic (struct gdbarch * +- save some memory, but for many debug format--ELF/DWARF or +- anything/stabs--it would be inconvenient to eliminate those minimal +- symbols anyway). */ +-- msymbol = lookup_minimal_symbol_by_pc_section (addr, section); +-+ msymbol = lookup_minimal_symbol_by_pc_section (addr, section).minsym; +- symbol = find_pc_sect_function (addr, section); +- +- if (symbol) +-@@ -1166,7 +1166,8 @@ sym_info (char *arg, int from_tty) +- +- if (obj_section_addr (osect) <= sect_addr +- && sect_addr < obj_section_endaddr (osect) +-- && (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, osect))) +-+ && (msymbol +-+ = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym)) +- { +- const char *obj_name, *mapped, *sec_name, *msym_name; +- char *loc_string; +---- a/gdb/rs6000-tdep.c +-+++ b/gdb/rs6000-tdep.c +-@@ -2152,15 +2152,15 @@ rs6000_skip_main_prologue (struct gdbarc +- { +- CORE_ADDR displ = op & BL_DISPLACEMENT_MASK; +- CORE_ADDR call_dest = pc + 4 + displ; +-- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); +-+ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); +- +- /* We check for ___eabi (three leading underscores) in addition +- to __eabi in case the GCC option "-fleading-underscore" was +- used to compile the program. */ +-- if (s != NULL +-- && SYMBOL_LINKAGE_NAME (s) != NULL +-- && (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0 +-- || strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0)) +-+ if (s.minsym != NULL +-+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL +-+ && (strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0 +-+ || strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0)) +- pc += 4; +- } +- return pc; +-@@ -2226,7 +2226,7 @@ rs6000_skip_trampoline_code (struct fram +- unsigned int ii, op; +- int rel; +- CORE_ADDR solib_target_pc; +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- +- static unsigned trampoline_code[] = +- { +-@@ -2242,9 +2242,9 @@ rs6000_skip_trampoline_code (struct fram +- +- /* Check for bigtoc fixup code. */ +- msymbol = lookup_minimal_symbol_by_pc (pc); +-- if (msymbol +-+ if (msymbol.minsym +- && rs6000_in_solib_return_trampoline (gdbarch, pc, +-- SYMBOL_LINKAGE_NAME (msymbol))) +-+ SYMBOL_LINKAGE_NAME (msymbol.minsym))) +- { +- /* Double-check that the third instruction from PC is relative "b". */ +- op = read_memory_integer (pc + 8, 4, byte_order); +---- a/gdb/sh64-tdep.c +-+++ b/gdb/sh64-tdep.c +-@@ -237,7 +237,7 @@ sh64_elf_make_msymbol_special (asymbol * +- static int +- pc_is_isa32 (bfd_vma memaddr) +- { +-- struct minimal_symbol *sym; +-+ struct bound_minimal_symbol sym; +- +- /* If bit 0 of the address is set, assume this is a +- ISA32 (shmedia) address. */ +-@@ -248,8 +248,8 @@ pc_is_isa32 (bfd_vma memaddr) +- the high bit of the info field. Use this to decide if the function is +- ISA16 or ISA32. */ +- sym = lookup_minimal_symbol_by_pc (memaddr); +-- if (sym) +-- return MSYMBOL_IS_SPECIAL (sym); +-+ if (sym.minsym) +-+ return MSYMBOL_IS_SPECIAL (sym.minsym); +- else +- return 0; +- } +---- a/gdb/stack.c +-+++ b/gdb/stack.c +-@@ -1036,23 +1036,25 @@ find_frame_funname (struct frame_info *f +- changed (and we'll create a find_pc_minimal_function or some +- such). */ +- +-- struct minimal_symbol *msymbol = NULL; +-+ struct bound_minimal_symbol msymbol; +- +- /* Don't attempt to do this for inlined functions, which do not +- have a corresponding minimal symbol. */ +- if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func))) +- msymbol +- = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame)); +-+ else +-+ memset (&msymbol, 0, sizeof (msymbol)); +- +-- if (msymbol != NULL +-- && (SYMBOL_VALUE_ADDRESS (msymbol) +-+ if (msymbol.minsym != NULL +-+ && (SYMBOL_VALUE_ADDRESS (msymbol.minsym) +- > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) +- { +- /* We also don't know anything about the function besides +- its address and name. */ +- func = 0; +-- *funname = SYMBOL_PRINT_NAME (msymbol); +-- *funlang = SYMBOL_LANGUAGE (msymbol); +-+ *funname = SYMBOL_PRINT_NAME (msymbol.minsym); +-+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); +- } +- else +- { +-@@ -1079,17 +1081,17 @@ find_frame_funname (struct frame_info *f +- } +- else +- { +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- CORE_ADDR pc; +- +- if (!get_frame_address_in_block_if_available (frame, &pc)) +- return; +- +- msymbol = lookup_minimal_symbol_by_pc (pc); +-- if (msymbol != NULL) +-+ if (msymbol.minsym != NULL) +- { +-- *funname = SYMBOL_PRINT_NAME (msymbol); +-- *funlang = SYMBOL_LANGUAGE (msymbol); +-+ *funname = SYMBOL_PRINT_NAME (msymbol.minsym); +-+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); +- } +- } +- } +-@@ -1423,13 +1425,13 @@ frame_info (char *addr_exp, int from_tty +- } +- else if (frame_pc_p) +- { +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- +- msymbol = lookup_minimal_symbol_by_pc (frame_pc); +-- if (msymbol != NULL) +-+ if (msymbol.minsym != NULL) +- { +-- funname = SYMBOL_PRINT_NAME (msymbol); +-- funlang = SYMBOL_LANGUAGE (msymbol); +-+ funname = SYMBOL_PRINT_NAME (msymbol.minsym); +-+ funlang = SYMBOL_LANGUAGE (msymbol.minsym); +- } +- } +- calling_frame_info = get_prev_frame (fi); +---- a/gdb/symtab.c +-+++ b/gdb/symtab.c +-@@ -956,7 +956,7 @@ find_pc_sect_symtab_via_partial (CORE_AD +- /* If we know that this is not a text address, return failure. This is +- necessary because we loop based on texthigh and textlow, which do +- not include the data ranges. */ +-- msymbol = lookup_minimal_symbol_by_pc_section (pc, section); +-+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym; +- if (msymbol +- && (MSYMBOL_TYPE (msymbol) == mst_data +- || MSYMBOL_TYPE (msymbol) == mst_bss +-@@ -2088,7 +2088,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struc +- addresses, which do not include the data ranges, and because +- we call find_pc_sect_psymtab which has a similar restriction based +- on the partial_symtab's texthigh and textlow. */ +-- msymbol = lookup_minimal_symbol_by_pc_section (pc, section); +-+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym; +- if (msymbol +- && (MSYMBOL_TYPE (msymbol) == mst_data +- || MSYMBOL_TYPE (msymbol) == mst_bss +-@@ -2219,7 +2219,7 @@ find_pc_sect_line (CORE_ADDR pc, struct +- struct linetable_entry *item; +- struct symtab_and_line val; +- struct blockvector *bv; +-- struct minimal_symbol *msymbol; +-+ struct bound_minimal_symbol msymbol; +- struct minimal_symbol *mfunsym; +- struct objfile *objfile; +- +-@@ -2305,11 +2305,12 @@ find_pc_sect_line (CORE_ADDR pc, struct +- * infinite recursion. +- */ +- msymbol = lookup_minimal_symbol_by_pc (pc); +-- if (msymbol != NULL) +-- if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) +-+ if (msymbol.minsym != NULL) +-+ if (MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) +- { +-- mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol), +-- NULL); +-+ mfunsym +-+ = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol.minsym), +-+ NULL); +- if (mfunsym == NULL) +- /* I eliminated this warning since it is coming out +- * in the following situation: +-@@ -2325,7 +2326,7 @@ find_pc_sect_line (CORE_ADDR pc, struct +- ; +- /* fall through */ +- else if (SYMBOL_VALUE_ADDRESS (mfunsym) +-- == SYMBOL_VALUE_ADDRESS (msymbol)) +-+ == SYMBOL_VALUE_ADDRESS (msymbol.minsym)) +- /* Avoid infinite recursion */ +- /* See above comment about why warning is commented out. */ +- /* warning ("In stub for %s; unable to find real function/line info", +-@@ -2838,7 +2839,7 @@ skip_prologue_sal (struct symtab_and_lin +- else +- { +- struct minimal_symbol *msymbol +-- = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); +-+ = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section).minsym; +- +- if (msymbol == NULL) +- { +-@@ -2894,8 +2895,8 @@ skip_prologue_sal (struct symtab_and_lin +- if (skip && start_sal.pc != pc +- && (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end +- && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) +-- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) +-- == lookup_minimal_symbol_by_pc_section (pc, section)))) +-+ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym +-+ == lookup_minimal_symbol_by_pc_section (pc, section).minsym))) +- { +- /* First pc of next line */ +- pc = start_sal.end; +---- a/gdb/tui/tui-disasm.c +-+++ b/gdb/tui/tui-disasm.c +-@@ -121,7 +121,7 @@ tui_find_disassembly_address (struct gdb +- pos = max_lines - 1; +- do { +- new_low -= 1 * max_lines; +-- msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0); +-+ msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0).minsym; +- +- if (msymbol) +- new_low = SYMBOL_VALUE_ADDRESS (msymbol); +- +- +-# +-# gdb-7.6-add-powerpc64le-linux.patch +-# +- +-From: Alan Modra +-Date: Thu Apr 25 13:22:52 2013 +0000 +-Git-commit: 49926cd0c84887c581110fb2a471b21ff19048d2 +-References: ppc64le enablement +- +-bfd/ +- * config.bfd: Add powerpc64le-linux. +- +-Acked-by: Petr Tesarik +- +---- +- bfd/ChangeLog | 4 ++++ +- bfd/config.bfd | 3 ++- +- 2 files changed, 6 insertions(+), 1 deletion(-) +- +---- a/bfd/ChangeLog +-+++ b/bfd/ChangeLog +-@@ -1,3 +1,7 @@ +-+2013-04-25 Alan Modra +-+ +-+ * config.bfd: Add powerpc64le-linux. +-+ +- 2013-03-08 Venkataramanan Kumar +- +- * elf64-aarch64.c (elf_backend_can_gc_sections): Enable gc-section +---- a/bfd/config.bfd +-+++ b/bfd/config.bfd +-@@ -1242,7 +1242,8 @@ case "${targ}" in +- targ_selvecs="bfd_elf64_powerpcle_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" +- want64=true +- ;; +-- powerpc64le-*-elf* | powerpcle-*-elf64*) +-+ powerpc64le-*-elf* | powerpcle-*-elf64* | powerpc64le-*-linux* | \ +-+ powerpc64le-*-*bsd*) +- targ_defvec=bfd_elf64_powerpcle_vec +- targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpcle_vec bfd_elf32_powerpc_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" +- want64=true +- +- +-# +-# gdb-7.6-update-autoconf-2013-04-24.patch +-# +- +-From: Jan-Benedict Glaw +-Date: Mon Apr 29 15:13:53 2013 +0000 +-Git-commit: 5dad867ccace0a74c90b729372c9c01392756875 +-References: ppc64le enablement +- +- * config.guess: Update from config repo. +- * config.sub: Ditto. +- +-Acked-by: Petr Tesarik +- +---- +- ChangeLog | 5 +++++ +- config.guess | 25 +++++++++++++++++-------- +- config.sub | 23 +++++++++++------------ +- 3 files changed, 33 insertions(+), 20 deletions(-) +- +---- a/ChangeLog +-+++ b/ChangeLog +-@@ -1,3 +1,8 @@ +-+2013-04-29 Jan-Benedict Glaw +-+ +-+ * config.guess: Update from config repo. +-+ * config.sub: Ditto. +-+ +- 2013-02-15 Yufeng Zhang +- +- * configure.ac: Sync with GCC repo. +---- a/config.guess +-+++ b/config.guess +-@@ -1,10 +1,8 @@ +- #! /bin/sh +- # Attempt to guess a canonical system name. +--# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +--# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +--# 2011, 2012, 2013 Free Software Foundation, Inc. +-+# Copyright 1992-2013 Free Software Foundation, Inc. +- +--timestamp='2012-12-30' +-+timestamp='2013-04-24' +- +- # This file is free software; you can redistribute it and/or modify it +- # under the terms of the GNU General Public License as published by +-@@ -52,9 +50,7 @@ version="\ +- GNU config.guess ($timestamp) +- +- Originally written by Per Bothner. +--Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +--2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +--2012, 2013 Free Software Foundation, Inc. +-+Copyright 1992-2013 Free Software Foundation, Inc. +- +- This is free software; see the source for copying conditions. There is NO +- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +-@@ -887,6 +883,9 @@ EOF +- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi +- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} +- exit ;; +-+ arc:Linux:*:* | arceb:Linux:*:*) +-+ echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ exit ;; +- arm*:Linux:*:*) +- eval $set_cc_for_build +- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ +-@@ -925,6 +924,11 @@ EOF +- #ifdef __dietlibc__ +- LIBC=dietlibc +- #endif +-+ #else +-+ #include +-+ #ifdef __UCLIBC__ +-+ LIBC=uclibc +-+ #endif +- EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" +-@@ -957,6 +961,9 @@ EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } +- ;; +-+ or1k:Linux:*:*) +-+ echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ exit ;; +- or32:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu +- exit ;; +-@@ -999,7 +1006,9 @@ EOF +- echo ${UNAME_MACHINE}-dec-linux-gnu +- exit ;; +- x86_64:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ LIBC=gnu +-+ test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- xtensa*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu +---- a/config.sub +-+++ b/config.sub +-@@ -1,10 +1,8 @@ +- #! /bin/sh +- # Configuration validation subroutine script. +--# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +--# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +--# 2011, 2012, 2013 Free Software Foundation, Inc. +-+# Copyright 1992-2013 Free Software Foundation, Inc. +- +--timestamp='2013-01-11' +-+timestamp='2013-04-24' +- +- # This file is free software; you can redistribute it and/or modify it +- # under the terms of the GNU General Public License as published by +-@@ -70,9 +68,7 @@ Report bugs and patches to +-Date: Tue Jun 4 02:44:35 2013 +0000 +-Git-commit: 845d47080b7d7e068e4ec3d11fe6e27b403ac6e3 +-References: ppc64le enablement +- +- * ppc-tdep.h (ppc_insns_match_pattern): Update prototype. +- * rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian. +- (ppc_insns_match_pattern): Add frame param. Avoid multiple +- target mem reads on optional insns. +- * ppc-linux-tdep.c (ppc_skip_trampoline_code): Update +- ppc_insns_match_pattern calls. +- * ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3): +- Add match for power7 thread safety insns, and new order of +- std 2,40(1) insn. Correct code shown for _dl_runtime_resolve +- invocation in comment, and update rest of comment. +- (PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN, +- PPC64_STANDARD_LINKAGE3_LEN): Delete. +- (ppc64_standard_linkage2_target): Update insn offsets. +- (ppc64_skip_trampoline_code): Use a single insn buffer. Match newer +- stubs first. Update calls. +- +-Acked-by: Petr Tesarik +- +---- +- gdb/ChangeLog | 18 ++++++ +- gdb/ppc-linux-tdep.c | 4 - +- gdb/ppc-tdep.h | 4 - +- gdb/ppc64-tdep.c | 140 ++++++++++++++++++++++++++++++--------------------- +- gdb/rs6000-tdep.c | 35 +++++++----- +- 5 files changed, 128 insertions(+), 73 deletions(-) +- +---- a/gdb/ChangeLog +-+++ b/gdb/ChangeLog +-@@ -1,3 +1,21 @@ +-+2013-06-04 Alan Modra +-+ +-+ * ppc-tdep.h (ppc_insns_match_pattern): Update prototype. +-+ * rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian. +-+ (ppc_insns_match_pattern): Add frame param. Avoid multiple +-+ target mem reads on optional insns. +-+ * ppc-linux-tdep.c (ppc_skip_trampoline_code): Update +-+ ppc_insns_match_pattern calls. +-+ * ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3): +-+ Add match for power7 thread safety insns, and new order of +-+ std 2,40(1) insn. Correct code shown for _dl_runtime_resolve +-+ invocation in comment, and update rest of comment. +-+ (PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN, +-+ PPC64_STANDARD_LINKAGE3_LEN): Delete. +-+ (ppc64_standard_linkage2_target): Update insn offsets. +-+ (ppc64_skip_trampoline_code): Use a single insn buffer. Match newer +-+ stubs first. Update calls. +-+ +- 2013-04-08 Tom Tromey +- +- * minsyms.h (struct bound_minimal_symbol): New. +---- a/gdb/ppc-linux-tdep.c +-+++ b/gdb/ppc-linux-tdep.c +-@@ -361,7 +361,7 @@ ppc_skip_trampoline_code (struct frame_i +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- CORE_ADDR target = 0; +- +-- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub, insnbuf)) +-+ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf)) +- { +- /* Insn pattern is +- lis r11, xxxx +-@@ -373,7 +373,7 @@ ppc_skip_trampoline_code (struct frame_i +- target = read_memory_unsigned_integer (target, 4, byte_order); +- } +- +-- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf)) +-+ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf)) +- { +- /* Insn pattern is +- lwz r11, xxxx(r30) +---- a/gdb/ppc-tdep.h +-+++ b/gdb/ppc-tdep.h +-@@ -300,9 +300,9 @@ struct ppc_insn_pattern +- int optional; /* If non-zero, this insn may be absent. */ +- }; +- +--extern int ppc_insns_match_pattern (CORE_ADDR pc, +-+extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc, +- struct ppc_insn_pattern *pattern, +-- unsigned int *insn); +-+ unsigned int *insns); +- extern CORE_ADDR ppc_insn_d_field (unsigned int insn); +- +- extern CORE_ADDR ppc_insn_ds_field (unsigned int insn); +---- a/gdb/ppc64-tdep.c +-+++ b/gdb/ppc64-tdep.c +-@@ -59,9 +59,10 @@ ppc64_desc_entry_point (struct gdbarch * +- return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order); +- } +- +--/* Pattern for the standard linkage function. These are built by +-- build_plt_stub in elf64-ppc.c, whose GLINK argument is always +-- zero. */ +-+/* Patterns for the standard linkage functions. These are built by +-+ build_plt_stub in bfd/elf64-ppc.c. */ +-+ +-+/* Old PLT call stub. */ +- +- static struct ppc_insn_pattern ppc64_standard_linkage1[] = +- { +-@@ -95,15 +96,23 @@ static struct ppc_insn_pattern ppc64_sta +- { 0, 0, 0 } +- }; +- +--#define PPC64_STANDARD_LINKAGE1_LEN ARRAY_SIZE (ppc64_standard_linkage1) +-+/* Current PLT call stub to access PLT entries more than +/- 32k from r2. +-+ Also supports older stub with different placement of std 2,40(1), +-+ a stub that omits the std 2,40(1), and both versions of power7 +-+ thread safety read barriers. Note that there are actually two more +-+ instructions following "cmpldi r2, 0", "bnectr+" and "b ", +-+ but there isn't any need to match them. */ +- +- static struct ppc_insn_pattern ppc64_standard_linkage2[] = +- { +-+ /* std r2, 40(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +-+ +- /* addis r12, r2, */ +- { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, +- +-- /* std r2, 40(r1) */ +-- { -1, insn_ds (62, 2, 1, 40, 0), 0 }, +-+ /* std r2, 40(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +- +- /* ld r11, (r12) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, +-@@ -114,24 +123,33 @@ static struct ppc_insn_pattern ppc64_sta +- /* mtctr r11 */ +- { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, +- +-+ /* xor r11, r11, r11 */ +-+ { -1, 0x7d6b5a78, 1 }, +-+ +-+ /* add r12, r12, r11 */ +-+ { -1, 0x7d8c5a14, 1 }, +-+ +- /* ld r2, (r12) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 }, +- +- /* ld r11, (r12) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 }, +- +-- /* bctr */ +-- { -1, 0x4e800420, 0 }, +-+ /* bctr */ +-+ { -1, 0x4e800420, 1 }, +-+ +-+ /* cmpldi r2, 0 */ +-+ { -1, 0x28220000, 1 }, +- +- { 0, 0, 0 } +- }; +- +--#define PPC64_STANDARD_LINKAGE2_LEN ARRAY_SIZE (ppc64_standard_linkage2) +-+/* Current PLT call stub to access PLT entries within +/- 32k of r2. */ +- +- static struct ppc_insn_pattern ppc64_standard_linkage3[] = +- { +-- /* std r2, 40(r1) */ +-- { -1, insn_ds (62, 2, 1, 40, 0), 0 }, +-+ /* std r2, 40(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +- +- /* ld r11, (r2) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 }, +-@@ -142,56 +160,71 @@ static struct ppc_insn_pattern ppc64_sta +- /* mtctr r11 */ +- { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 }, +- +-+ /* xor r11, r11, r11 */ +-+ { -1, 0x7d6b5a78, 1 }, +-+ +-+ /* add r2, r2, r11 */ +-+ { -1, 0x7c425a14, 1 }, +-+ +- /* ld r11, (r2) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, +- +- /* ld r2, (r2) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, +- +-- /* bctr */ +-- { -1, 0x4e800420, 0 }, +-+ /* bctr */ +-+ { -1, 0x4e800420, 1 }, +-+ +-+ /* cmpldi r2, 0 */ +-+ { -1, 0x28220000, 1 }, +- +- { 0, 0, 0 } +- }; +- +--#define PPC64_STANDARD_LINKAGE3_LEN ARRAY_SIZE (ppc64_standard_linkage3) +-- +- /* When the dynamic linker is doing lazy symbol resolution, the first +- call to a function in another object will go like this: +- +- - The user's function calls the linkage function: +- +-- 100007c4: 4b ff fc d5 bl 10000498 +-- 100007c8: e8 41 00 28 ld r2,40(r1) +-+ 100003d4: 4b ff ff ad bl 10000380 +-+ 100003d8: e8 41 00 28 ld r2,40(r1) +- +-- - The linkage function loads the entry point (and other stuff) from +-- the function descriptor in the PLT, and jumps to it: +-+ - The linkage function loads the entry point and toc pointer from +-+ the function descriptor in the PLT, and jumps to it: +- +-- 10000498: 3d 82 00 00 addis r12,r2,0 +-- 1000049c: f8 41 00 28 std r2,40(r1) +-- 100004a0: e9 6c 80 98 ld r11,-32616(r12) +-- 100004a4: e8 4c 80 a0 ld r2,-32608(r12) +-- 100004a8: 7d 69 03 a6 mtctr r11 +-- 100004ac: e9 6c 80 a8 ld r11,-32600(r12) +-- 100004b0: 4e 80 04 20 bctr +-+ : +-+ 10000380: f8 41 00 28 std r2,40(r1) +-+ 10000384: e9 62 80 78 ld r11,-32648(r2) +-+ 10000388: 7d 69 03 a6 mtctr r11 +-+ 1000038c: e8 42 80 80 ld r2,-32640(r2) +-+ 10000390: 28 22 00 00 cmpldi r2,0 +-+ 10000394: 4c e2 04 20 bnectr+ +-+ 10000398: 48 00 03 a0 b 10000738 +- +- - But since this is the first time that PLT entry has been used, it +-- sends control to its glink entry. That loads the number of the +-- PLT entry and jumps to the common glink0 code: +-+ sends control to its glink entry. That loads the number of the +-+ PLT entry and jumps to the common glink0 code: +- +-- 10000c98: 38 00 00 00 li r0,0 +-- 10000c9c: 4b ff ff dc b 10000c78 +-+ : +-+ 10000738: 38 00 00 01 li r0,1 +-+ 1000073c: 4b ff ff bc b 100006f8 <__glink_PLTresolve> +- +- - The common glink0 code then transfers control to the dynamic +-- linker's fixup code: +-+ linker's fixup code: +- +-- 10000c78: e8 41 00 28 ld r2,40(r1) +-- 10000c7c: 3d 82 00 00 addis r12,r2,0 +-- 10000c80: e9 6c 80 80 ld r11,-32640(r12) +-- 10000c84: e8 4c 80 88 ld r2,-32632(r12) +-- 10000c88: 7d 69 03 a6 mtctr r11 +-- 10000c8c: e9 6c 80 90 ld r11,-32624(r12) +-- 10000c90: 4e 80 04 20 bctr +-+ 100006f0: 0000000000010440 .quad plt0 - (. + 16) +-+ <__glink_PLTresolve>: +-+ 100006f8: 7d 88 02 a6 mflr r12 +-+ 100006fc: 42 9f 00 05 bcl 20,4*cr7+so,10000700 +-+ 10000700: 7d 68 02 a6 mflr r11 +-+ 10000704: e8 4b ff f0 ld r2,-16(r11) +-+ 10000708: 7d 88 03 a6 mtlr r12 +-+ 1000070c: 7d 82 5a 14 add r12,r2,r11 +-+ 10000710: e9 6c 00 00 ld r11,0(r12) +-+ 10000714: e8 4c 00 08 ld r2,8(r12) +-+ 10000718: 7d 69 03 a6 mtctr r11 +-+ 1000071c: e9 6c 00 10 ld r11,16(r12) +-+ 10000720: 4e 80 04 20 bctr +- +- Eventually, this code will figure out how to skip all of this, +- including the dynamic linker. At the moment, we just get through +-@@ -234,8 +267,8 @@ ppc64_standard_linkage2_target (struct f +- CORE_ADDR desc +- = ((CORE_ADDR) get_frame_register_unsigned (frame, +- tdep->ppc_gp0_regnum + 2) +-- + (ppc_insn_d_field (insn[0]) << 16) +-- + ppc_insn_ds_field (insn[2])); +-+ + (ppc_insn_d_field (insn[1]) << 16) +-+ + ppc_insn_ds_field (insn[3])); +- +- /* The first word of the descriptor is the entry point. Return that. */ +- return ppc64_desc_entry_point (gdbarch, desc); +-@@ -266,23 +299,20 @@ ppc64_standard_linkage3_target (struct f +- CORE_ADDR +- ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) +- { +-- unsigned int ppc64_standard_linkage1_insn[PPC64_STANDARD_LINKAGE1_LEN]; +-- unsigned int ppc64_standard_linkage2_insn[PPC64_STANDARD_LINKAGE2_LEN]; +-- unsigned int ppc64_standard_linkage3_insn[PPC64_STANDARD_LINKAGE3_LEN]; +-+#define MAX(a,b) ((a) > (b) ? (a) : (b)) +-+ unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), +-+ ARRAY_SIZE (ppc64_standard_linkage2)), +-+ ARRAY_SIZE (ppc64_standard_linkage3)) - 1]; +- CORE_ADDR target; +- +-- if (ppc_insns_match_pattern (pc, ppc64_standard_linkage1, +-- ppc64_standard_linkage1_insn)) +-- pc = ppc64_standard_linkage1_target (frame, pc, +-- ppc64_standard_linkage1_insn); +-- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage2, +-- ppc64_standard_linkage2_insn)) +-- pc = ppc64_standard_linkage2_target (frame, pc, +-- ppc64_standard_linkage2_insn); +-- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage3, +-- ppc64_standard_linkage3_insn)) +-- pc = ppc64_standard_linkage3_target (frame, pc, +-- ppc64_standard_linkage3_insn); +-+ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) +-+ && (insns[8] != 0 || insns[9] != 0)) +-+ pc = ppc64_standard_linkage3_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) +-+ && (insns[10] != 0 || insns[11] != 0)) +-+ pc = ppc64_standard_linkage2_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns)) +-+ pc = ppc64_standard_linkage1_target (frame, pc, insns); +- else +- return 0; +- +---- a/gdb/rs6000-tdep.c +-+++ b/gdb/rs6000-tdep.c +-@@ -4238,14 +4238,15 @@ show_powerpc_exact_watchpoints (struct u +- fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value); +- } +- +--/* Read a PPC instruction from memory. PPC instructions are always +-- big-endian, no matter what endianness the program is running in, so +-- we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer. */ +-+/* Read a PPC instruction from memory. */ +- +- static unsigned int +--read_insn (CORE_ADDR pc) +-+read_insn (struct frame_info *frame, CORE_ADDR pc) +- { +-- return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG); +-+ struct gdbarch *gdbarch = get_frame_arch (frame); +-+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +-+ +-+ return read_memory_unsigned_integer (pc, 4, byte_order); +- } +- +- /* Return non-zero if the instructions at PC match the series +-@@ -4262,19 +4263,25 @@ read_insn (CORE_ADDR pc) +- i'th instruction in memory. */ +- +- int +--ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern, +-- unsigned int *insn) +-+ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc, +-+ struct ppc_insn_pattern *pattern, +-+ unsigned int *insns) +- { +- int i; +-+ unsigned int insn; +- +-- for (i = 0; pattern[i].mask; i++) +-+ for (i = 0, insn = 0; pattern[i].mask; i++) +- { +-- insn[i] = read_insn (pc); +-- if ((insn[i] & pattern[i].mask) == pattern[i].data) +-- pc += 4; +-- else if (pattern[i].optional) +-- insn[i] = 0; +-- else +-+ if (insn == 0) +-+ insn = read_insn (frame, pc); +-+ insns[i] = 0; +-+ if ((insn & pattern[i].mask) == pattern[i].data) +-+ { +-+ insns[i] = insn; +-+ pc += 4; +-+ insn = 0; +-+ } +-+ else if (!pattern[i].optional) +- return 0; +- } +- +- +-# +-# gdb-7.6-floatformat.patch +-# +- +-From: DJ Delorie +-Date: Tue Aug 20 06:02:53 2013 +0000 +-Git-commit: 21290977cbdd41c6f4e7b297e63901ad491acadd +-References: ppc64le enablement +- +-merge from gcc +- +-Acked-by: Petr Tesarik +- +---- +- include/ChangeLog | 10 ++++++++++ +- include/dwarf2.def | 3 +++ +- include/floatformat.h | 3 ++- +- libiberty/ChangeLog | 6 ++++++ +- libiberty/floatformat.c | 13 +++++++++++-- +- 5 files changed, 32 insertions(+), 3 deletions(-) +- +---- a/include/ChangeLog +-+++ b/include/ChangeLog +-@@ -1,3 +1,13 @@ +-+2013-08-20 Alan Modra +-+ +-+ * floatformat.h (floatformat_ibm_long_double): Delete. +-+ (floatformat_ibm_long_double_big): Declare. +-+ (floatformat_ibm_long_double_little): Declare. +-+ +-+2013-08-19 Dehao Chen +-+ +-+ * dwarf2.def (DW_AT_GNU_discriminator): New attribute. +-+ +- 2013-03-12 Sebastian Huber +- +- * opcode/nios2.h: Edit comment. +---- a/include/dwarf2.def +-+++ b/include/dwarf2.def +-@@ -390,6 +390,9 @@ DW_AT (DW_AT_GNU_ranges_base, 0x2132) +- DW_AT (DW_AT_GNU_addr_base, 0x2133) +- DW_AT (DW_AT_GNU_pubnames, 0x2134) +- DW_AT (DW_AT_GNU_pubtypes, 0x2135) +-+/* Attribute for discriminator. +-+ See http://gcc.gnu.org/wiki/Discriminator */ +-+DW_AT (DW_AT_GNU_discriminator, 0x2136) +- /* VMS extensions. */ +- DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201) +- /* GNAT extensions. */ +---- a/include/floatformat.h +-+++ b/include/floatformat.h +-@@ -128,7 +128,8 @@ extern const struct floatformat floatfor +- extern const struct floatformat floatformat_ia64_quad_big; +- extern const struct floatformat floatformat_ia64_quad_little; +- /* IBM long double (double+double). */ +--extern const struct floatformat floatformat_ibm_long_double; +-+extern const struct floatformat floatformat_ibm_long_double_big; +-+extern const struct floatformat floatformat_ibm_long_double_little; +- +- /* Convert from FMT to a double. +- FROM is the address of the extended float. +---- a/libiberty/ChangeLog +-+++ b/libiberty/ChangeLog +-@@ -1,3 +1,9 @@ +-+2013-08-20 Alan Modra +-+ +-+ * floatformat.c (floatformat_ibm_long_double): Rename to.. +-+ (floatformat_ibm_long_double_big): ..this. +-+ (floatformat_ibm_long_double_little): New. +-+ +- 2013-03-01 Andreas Schwab +- +- * obstacks.texi (Obstacks): Trim @node to only contain the +---- a/libiberty/floatformat.c +-+++ b/libiberty/floatformat.c +-@@ -371,14 +371,23 @@ floatformat_ibm_long_double_is_valid (co +- } +- } +- +--const struct floatformat floatformat_ibm_long_double = +-+const struct floatformat floatformat_ibm_long_double_big = +- { +- floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52, +- floatformat_intbit_no, +-- "floatformat_ibm_long_double", +-+ "floatformat_ibm_long_double_big", +- floatformat_ibm_long_double_is_valid, +- &floatformat_ieee_double_big +- }; +-+ +-+const struct floatformat floatformat_ibm_long_double_little = +-+{ +-+ floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52, +-+ floatformat_intbit_no, +-+ "floatformat_ibm_long_double_little", +-+ floatformat_ibm_long_double_is_valid, +-+ &floatformat_ieee_double_little +-+}; +- +- +- #ifndef min +- +-# +-# gdb-7.6-ppc64-ELFv2-trampoline-match.patch +-# +- +-From: Alan Modra +-Date: Mon Nov 11 14:14:40 2013 +1030 +-Git-commit: ef1bc9e72fd2f0310ac3113acc41e1c115e3ac79 +-References: ppc64le enablement +- +-PowerPC64 ELFv2 trampoline match +- +-ELFv2 needs different plt call stubs to ELFv1, register usage differs +-too. When I added these to ld I changed register usage in the ELFv1 +-stubs as well, simplifying the linker code and (perhaps) future +-maintenance. All well and good, but this means gdb needs to cope with +-more stub variants. This patch also handles skipping over addis/addi +-setting up r2 in ELFv2 global entry code. We want breakpoints to be +-set past this point to catch calls via the local entry point. +- +- * ppc64-tdep.c (ppc64_plt_entry_point): Renamed from.. +- (ppc64_desc_entry_point): ..this. Update comments here and at +- call points. +- (ppc64_standard_linkage1, ppc64_standard_linkage2, +- ppc64_standard_linkage3): Update comments. +- (ppc64_standard_linkage4, ppc64_standard_linkage5, +- (ppc64_standard_linkage6, ppc64_standard_linkage7): New insn +- patterns. +- (ppc64_standard_linkage4_target): New function. +- (ppc64_skip_trampoline_code): Skip ELFv2 patterns too. +- * rs6000-tdep.c (skip_prologue): Skip ELFv2 r2 setup. Correct +- nop match. Fix comment wrap. +- +-Acked-by: Petr Tesarik +- +---- +- gdb/ChangeLog | 15 ++++ +- gdb/ppc64-tdep.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++-------- +- gdb/rs6000-tdep.c | 20 ++++- +- 3 files changed, 203 insertions(+), 33 deletions(-) +- +---- a/gdb/ChangeLog +-+++ b/gdb/ChangeLog +-@@ -1,3 +1,18 @@ +-+2013-11-15 Alan Modra +-+ +-+ * ppc64-tdep.c (ppc64_plt_entry_point): Renamed from.. +-+ (ppc64_desc_entry_point): ..this. Update comments here and at +-+ call points. +-+ (ppc64_standard_linkage1, ppc64_standard_linkage2, +-+ ppc64_standard_linkage3): Update comments. +-+ (ppc64_standard_linkage4, ppc64_standard_linkage5, +-+ (ppc64_standard_linkage6, ppc64_standard_linkage7): New insn +-+ patterns. +-+ (ppc64_standard_linkage4_target): New function. +-+ (ppc64_skip_trampoline_code): Skip ELFv2 patterns too. +-+ * rs6000-tdep.c (skip_prologue): Skip ELFv2 r2 setup. Correct +-+ nop match. Fix comment wrap. +-+ +- 2013-06-04 Alan Modra +- +- * ppc-tdep.h (ppc_insns_match_pattern): Update prototype. +---- a/gdb/ppc64-tdep.c +-+++ b/gdb/ppc64-tdep.c +-@@ -48,21 +48,21 @@ +- | (((spr) & 0x3e0) << 6) \ +- | (((xo) & 0x3ff) << 1)) +- +--/* If DESC is the address of a 64-bit PowerPC FreeBSD function +-- descriptor, return the descriptor's entry point. */ +-+/* If PLT is the address of a 64-bit PowerPC PLT entry, +-+ return the function's entry point. */ +- +- static CORE_ADDR +--ppc64_desc_entry_point (struct gdbarch *gdbarch, CORE_ADDR desc) +-+ppc64_plt_entry_point (struct gdbarch *gdbarch, CORE_ADDR plt) +- { +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +-- /* The first word of the descriptor is the entry point. */ +-- return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order); +-+ /* The first word of the PLT entry is the function entry point. */ +-+ return (CORE_ADDR) read_memory_unsigned_integer (plt, 8, byte_order); +- } +- +- /* Patterns for the standard linkage functions. These are built by +- build_plt_stub in bfd/elf64-ppc.c. */ +- +--/* Old PLT call stub. */ +-+/* Old ELFv1 PLT call stub. */ +- +- static struct ppc_insn_pattern ppc64_standard_linkage1[] = +- { +-@@ -96,7 +96,7 @@ static struct ppc_insn_pattern ppc64_sta +- { 0, 0, 0 } +- }; +- +--/* Current PLT call stub to access PLT entries more than +/- 32k from r2. +-+/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. +- Also supports older stub with different placement of std 2,40(1), +- a stub that omits the std 2,40(1), and both versions of power7 +- thread safety read barriers. Note that there are actually two more +-@@ -144,7 +144,7 @@ static struct ppc_insn_pattern ppc64_sta +- { 0, 0, 0 } +- }; +- +--/* Current PLT call stub to access PLT entries within +/- 32k of r2. */ +-+/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. */ +- +- static struct ppc_insn_pattern ppc64_standard_linkage3[] = +- { +-@@ -181,6 +181,128 @@ static struct ppc_insn_pattern ppc64_sta +- { 0, 0, 0 } +- }; +- +-+/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2. +-+ A more modern variant of ppc64_standard_linkage2 differing in +-+ register usage. */ +-+ +-+static struct ppc_insn_pattern ppc64_standard_linkage4[] = +-+ { +-+ /* std r2, 40(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +-+ +-+ /* addis r11, r2, */ +-+ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, +-+ +-+ /* ld r12, (r11) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, +-+ +-+ /* addi r11, r11, */ +-+ { insn_d (-1, -1, -1, 0), insn_d (14, 11, 11, 0), 1 }, +-+ +-+ /* mtctr r12 */ +-+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, +-+ +-+ /* xor r2, r12, r12 */ +-+ { -1, 0x7d826278, 1 }, +-+ +-+ /* add r11, r11, r2 */ +-+ { -1, 0x7d6b1214, 1 }, +-+ +-+ /* ld r2, (r11) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 11, 0, 0), 0 }, +-+ +-+ /* ld r11, (r11) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 11, 0, 0), 1 }, +-+ +-+ /* bctr */ +-+ { -1, 0x4e800420, 1 }, +-+ +-+ /* cmpldi r2, 0 */ +-+ { -1, 0x28220000, 1 }, +-+ +-+ { 0, 0, 0 } +-+ }; +-+ +-+/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. +-+ A more modern variant of ppc64_standard_linkage3 differing in +-+ register usage. */ +-+ +-+static struct ppc_insn_pattern ppc64_standard_linkage5[] = +-+ { +-+ /* std r2, 40(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +-+ +-+ /* ld r12, (r2) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, +-+ +-+ /* addi r2, r2, */ +-+ { insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 }, +-+ +-+ /* mtctr r12 */ +-+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, +-+ +-+ /* xor r11, r12, r12 */ +-+ { -1, 0x7d8b6278, 1 }, +-+ +-+ /* add r2, r2, r11 */ +-+ { -1, 0x7c425a14, 1 }, +-+ +-+ /* ld r11, (r2) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 }, +-+ +-+ /* ld r2, (r2) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 }, +-+ +-+ /* bctr */ +-+ { -1, 0x4e800420, 1 }, +-+ +-+ /* cmpldi r2, 0 */ +-+ { -1, 0x28220000, 1 }, +-+ +-+ { 0, 0, 0 } +-+ }; +-+ +-+/* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2. */ +-+ +-+static struct ppc_insn_pattern ppc64_standard_linkage6[] = +-+ { +-+ /* std r2, 24(r1) */ +-+ { -1, insn_ds (62, 2, 1, 24, 0), 1 }, +-+ +-+ /* addis r11, r2, */ +-+ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 }, +-+ +-+ /* ld r12, (r11) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 }, +-+ +-+ /* mtctr r12 */ +-+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, +-+ +-+ /* bctr */ +-+ { -1, 0x4e800420, 0 }, +-+ +-+ { 0, 0, 0 } +-+ }; +-+ +-+/* ELFv2 PLT call stub to access PLT entries within +/- 32k of r2. */ +-+ +-+static struct ppc_insn_pattern ppc64_standard_linkage7[] = +-+ { +-+ /* std r2, 24(r1) */ +-+ { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +-+ +-+ /* ld r12, (r2) */ +-+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, +-+ +-+ /* mtctr r12 */ +-+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, +-+ +-+ /* bctr */ +-+ { -1, 0x4e800420, 0 }, +-+ +-+ { 0, 0, 0 } +-+ }; +-+ +- /* When the dynamic linker is doing lazy symbol resolution, the first +- call to a function in another object will go like this: +- +-@@ -243,16 +365,14 @@ ppc64_standard_linkage1_target (struct f +- struct gdbarch *gdbarch = get_frame_arch (frame); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +-- /* The address of the function descriptor this linkage function +-- references. */ +-- CORE_ADDR desc +-+ /* The address of the PLT entry this linkage function references. */ +-+ CORE_ADDR plt +- = ((CORE_ADDR) get_frame_register_unsigned (frame, +- tdep->ppc_gp0_regnum + 2) +- + (ppc_insn_d_field (insn[0]) << 16) +- + ppc_insn_ds_field (insn[2])); +- +-- /* The first word of the descriptor is the entry point. Return that. */ +-- return ppc64_desc_entry_point (gdbarch, desc); +-+ return ppc64_plt_entry_point (gdbarch, plt); +- } +- +- static CORE_ADDR +-@@ -262,16 +382,14 @@ ppc64_standard_linkage2_target (struct f +- struct gdbarch *gdbarch = get_frame_arch (frame); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +-- /* The address of the function descriptor this linkage function +-- references. */ +-- CORE_ADDR desc +-+ /* The address of the PLT entry this linkage function references. */ +-+ CORE_ADDR plt +- = ((CORE_ADDR) get_frame_register_unsigned (frame, +- tdep->ppc_gp0_regnum + 2) +- + (ppc_insn_d_field (insn[1]) << 16) +- + ppc_insn_ds_field (insn[3])); +- +-- /* The first word of the descriptor is the entry point. Return that. */ +-- return ppc64_desc_entry_point (gdbarch, desc); +-+ return ppc64_plt_entry_point (gdbarch, plt); +- } +- +- static CORE_ADDR +-@@ -281,15 +399,28 @@ ppc64_standard_linkage3_target (struct f +- struct gdbarch *gdbarch = get_frame_arch (frame); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +-- /* The address of the function descriptor this linkage function +-- references. */ +-- CORE_ADDR desc +-+ /* The address of the PLT entry this linkage function references. */ +-+ CORE_ADDR plt +- = ((CORE_ADDR) get_frame_register_unsigned (frame, +- tdep->ppc_gp0_regnum + 2) +- + ppc_insn_ds_field (insn[1])); +- +-- /* The first word of the descriptor is the entry point. Return that. */ +-- return ppc64_desc_entry_point (gdbarch, desc); +-+ return ppc64_plt_entry_point (gdbarch, plt); +-+} +-+ +-+static CORE_ADDR +-+ppc64_standard_linkage4_target (struct frame_info *frame, +-+ CORE_ADDR pc, unsigned int *insn) +-+{ +-+ struct gdbarch *gdbarch = get_frame_arch (frame); +-+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +-+ +-+ CORE_ADDR plt +-+ = ((CORE_ADDR) get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 2) +-+ + (ppc_insn_d_field (insn[1]) << 16) +-+ + ppc_insn_ds_field (insn[2])); +-+ +-+ return ppc64_plt_entry_point (gdbarch, plt); +- } +- +- +-@@ -300,13 +431,27 @@ CORE_ADDR +- ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) +- { +- #define MAX(a,b) ((a) > (b) ? (a) : (b)) +-- unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), +-- ARRAY_SIZE (ppc64_standard_linkage2)), +-- ARRAY_SIZE (ppc64_standard_linkage3)) - 1]; +-+ unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), +-+ ARRAY_SIZE (ppc64_standard_linkage2)), +-+ MAX (ARRAY_SIZE (ppc64_standard_linkage3), +-+ ARRAY_SIZE (ppc64_standard_linkage4))), +-+ MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), +-+ ARRAY_SIZE (ppc64_standard_linkage6)), +-+ ARRAY_SIZE (ppc64_standard_linkage7))) - 1]; +- CORE_ADDR target; +- +-- if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) +-- && (insns[8] != 0 || insns[9] != 0)) +-+ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns)) +-+ pc = ppc64_standard_linkage3_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns)) +-+ pc = ppc64_standard_linkage4_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns) +-+ && (insns[8] != 0 || insns[9] != 0)) +-+ pc = ppc64_standard_linkage3_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns) +-+ && (insns[9] != 0 || insns[10] != 0)) +-+ pc = ppc64_standard_linkage4_target (frame, pc, insns); +-+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) +-+ && (insns[8] != 0 || insns[9] != 0)) +- pc = ppc64_standard_linkage3_target (frame, pc, insns); +- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) +- && (insns[10] != 0 || insns[11] != 0)) +---- a/gdb/rs6000-tdep.c +-+++ b/gdb/rs6000-tdep.c +-@@ -1616,7 +1616,19 @@ skip_prologue (struct gdbarch *gdbarch, +- continue; +- +- } +-- else if ((op & 0xffff0000) == 0x60000000) +-+ else if ((op & 0xffff0000) == 0x3c4c0000 +-+ || (op & 0xffff0000) == 0x3c400000 +-+ || (op & 0xffff0000) == 0x38420000) +-+ { +-+ /* . 0: addis 2,12,.TOC.-0b@ha +-+ . addi 2,2,.TOC.-0b@l +-+ or +-+ . lis 2,.TOC.@ha +-+ . addi 2,2,.TOC.@l +-+ used by ELFv2 global entry points to set up r2. */ +-+ continue; +-+ } +-+ else if (op == 0x60000000) +- { +- /* nop */ +- /* Allow nops in the prologue, but do not consider them to +-@@ -1627,8 +1639,7 @@ skip_prologue (struct gdbarch *gdbarch, +- +- } +- else if ((op & 0xffff0000) == 0x3c000000) +-- { /* addis 0,0,NUM, used +-- for >= 32k frames */ +-+ { /* addis 0,0,NUM, used for >= 32k frames */ +- fdata->offset = (op & 0x0000ffff) << 16; +- fdata->frameless = 0; +- r0_contains_arg = 0; +-@@ -1636,8 +1647,7 @@ skip_prologue (struct gdbarch *gdbarch, +- +- } +- else if ((op & 0xffff0000) == 0x60000000) +-- { /* ori 0,0,NUM, 2nd ha +-- lf of >= 32k frames */ +-+ { /* ori 0,0,NUM, 2nd half of >= 32k frames */ +- fdata->offset |= (op & 0x0000ffff); +- fdata->frameless = 0; +- r0_contains_arg = 0; +- +-# +-# gdb-7.6-update-autoconf-2013-06-10.patch +-# +- +-From: Alan Modra +-Date: Sat Nov 23 08:55:31 2013 +1030 +-Git-commit: f3f51a69187bd04f61373f54afd359e595d18011 +-References: ppc64le enablement +- +-Import config.sub and config.guess from upstream. +- +-Acked-by: Petr Tesarik +- +---- +- ChangeLog | 4 + +- config.guess | 144 ++++++++++++++++++++++++++++++++--------------------------- +- config.sub | 17 ++++-- +- 3 files changed, 94 insertions(+), 71 deletions(-) +- +---- a/ChangeLog +-+++ b/ChangeLog +-@@ -1,3 +1,7 @@ +-+2013-11-23 Alan Modra +-+ +-+ * config.sub, config.guess: Import from upstream. +-+ +- 2013-04-29 Jan-Benedict Glaw +- +- * config.guess: Update from config repo. +---- a/config.guess +-+++ b/config.guess +-@@ -2,7 +2,7 @@ +- # Attempt to guess a canonical system name. +- # Copyright 1992-2013 Free Software Foundation, Inc. +- +--timestamp='2013-04-24' +-+timestamp='2013-06-10' +- +- # This file is free software; you can redistribute it and/or modify it +- # under the terms of the GNU General Public License as published by +-@@ -132,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` | +- UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +- UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +- +-+case "${UNAME_SYSTEM}" in +-+Linux|GNU|GNU/*) +-+ # If the system lacks a compiler, then just pick glibc. +-+ # We could probably try harder. +-+ LIBC=gnu +-+ +-+ eval $set_cc_for_build +-+ cat <<-EOF > $dummy.c +-+ #include +-+ #if defined(__UCLIBC__) +-+ LIBC=uclibc +-+ #elif defined(__dietlibc__) +-+ LIBC=dietlibc +-+ #else +-+ LIBC=gnu +-+ #endif +-+ EOF +-+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +-+ ;; +-+esac +-+ +- # Note: order is significant - the case branches are not exclusive. +- +- case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +-@@ -853,21 +874,21 @@ EOF +- exit ;; +- *:GNU:*:*) +- # the GNU system +-- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` +-+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` +- exit ;; +- *:GNU/*:*:*) +- # other systems with GNU libc and userland +-- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu +-+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} +- exit ;; +- i*86:Minix:*:*) +- echo ${UNAME_MACHINE}-pc-minix +- exit ;; +- aarch64:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- aarch64_be:Linux:*:*) +- UNAME_MACHINE=aarch64_be +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- alpha:Linux:*:*) +- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in +-@@ -880,67 +901,54 @@ EOF +- EV68*) UNAME_MACHINE=alphaev68 ;; +- esac +- objdump --private-headers /bin/sh | grep -q ld.so.1 +-- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi +-- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} +-+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arc:Linux:*:* | arceb:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arm*:Linux:*:*) +- eval $set_cc_for_build +- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_EABI__ +- then +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- else +- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_PCS_VFP +- then +-- echo ${UNAME_MACHINE}-unknown-linux-gnueabi +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi +- else +-- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf +- fi +- fi +- exit ;; +- avr32*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- cris:Linux:*:*) +-- echo ${UNAME_MACHINE}-axis-linux-gnu +-+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- crisv32:Linux:*:*) +-- echo ${UNAME_MACHINE}-axis-linux-gnu +-+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- frv:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- hexagon:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:Linux:*:*) +-- LIBC=gnu +-- eval $set_cc_for_build +-- sed 's/^ //' << EOF >$dummy.c +-- #ifdef __dietlibc__ +-- LIBC=dietlibc +-- #endif +-- #else +-- #include +-- #ifdef __UCLIBC__ +-- LIBC=uclibc +-- #endif +--EOF +-- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +-- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" +-+ echo ${UNAME_MACHINE}-pc-linux-${LIBC} +- exit ;; +- ia64:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m32r*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m68*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- mips:Linux:*:* | mips64:Linux:*:*) +- eval $set_cc_for_build +-@@ -959,59 +967,63 @@ EOF +- #endif +- EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +-- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } +-+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } +- ;; +- or1k:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- or32:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- padre:Linux:*:*) +-- echo sparc-unknown-linux-gnu +-+ echo sparc-unknown-linux-${LIBC} +- exit ;; +- parisc64:Linux:*:* | hppa64:Linux:*:*) +-- echo hppa64-unknown-linux-gnu +-+ echo hppa64-unknown-linux-${LIBC} +- exit ;; +- parisc:Linux:*:* | hppa:Linux:*:*) +- # Look for CPU level +- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in +-- PA7*) echo hppa1.1-unknown-linux-gnu ;; +-- PA8*) echo hppa2.0-unknown-linux-gnu ;; +-- *) echo hppa-unknown-linux-gnu ;; +-+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; +-+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; +-+ *) echo hppa-unknown-linux-${LIBC} ;; +- esac +- exit ;; +- ppc64:Linux:*:*) +-- echo powerpc64-unknown-linux-gnu +-+ echo powerpc64-unknown-linux-${LIBC} +- exit ;; +- ppc:Linux:*:*) +-- echo powerpc-unknown-linux-gnu +-+ echo powerpc-unknown-linux-${LIBC} +-+ exit ;; +-+ ppc64le:Linux:*:*) +-+ echo powerpc64le-unknown-linux-${LIBC} +-+ exit ;; +-+ ppcle:Linux:*:*) +-+ echo powerpcle-unknown-linux-${LIBC} +- exit ;; +- s390:Linux:*:* | s390x:Linux:*:*) +-- echo ${UNAME_MACHINE}-ibm-linux +-+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC} +- exit ;; +- sh64*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sh*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sparc:Linux:*:* | sparc64:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- tile*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- vax:Linux:*:*) +-- echo ${UNAME_MACHINE}-dec-linux-gnu +-+ echo ${UNAME_MACHINE}-dec-linux-${LIBC} +- exit ;; +- x86_64:Linux:*:*) +-- LIBC=gnu +-- test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- xtensa*:Linux:*:*) +-- echo ${UNAME_MACHINE}-unknown-linux-gnu +-+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:DYNIX/ptx:4*:*) +- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. +-@@ -1244,19 +1256,21 @@ EOF +- exit ;; +- *:Darwin:*:*) +- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown +-- case $UNAME_PROCESSOR in +-- i386) +-- eval $set_cc_for_build +-- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +-- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +-- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +-- grep IS_64BIT_ARCH >/dev/null +-- then +-- UNAME_PROCESSOR="x86_64" +-- fi +-- fi ;; +-- unknown) UNAME_PROCESSOR=powerpc ;; +-- esac +-+ eval $set_cc_for_build +-+ if test "$UNAME_PROCESSOR" = unknown ; then +-+ UNAME_PROCESSOR=powerpc +-+ fi +-+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +-+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +-+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +-+ grep IS_64BIT_ARCH >/dev/null +-+ then +-+ case $UNAME_PROCESSOR in +-+ i386) UNAME_PROCESSOR=x86_64 ;; +-+ powerpc) UNAME_PROCESSOR=powerpc64 ;; +-+ esac +-+ fi +-+ fi +- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} +- exit ;; +- *:procnto*:*:* | *:QNX:[0123456789]*:*) +---- a/config.sub +-+++ b/config.sub +-@@ -2,7 +2,7 @@ +- # Configuration validation subroutine script. +- # Copyright 1992-2013 Free Software Foundation, Inc. +- +--timestamp='2013-04-24' +-+timestamp='2013-10-01' +- +- # This file is free software; you can redistribute it and/or modify it +- # under the terms of the GNU General Public License as published by +-@@ -257,7 +257,7 @@ case $basic_machine in +- | avr | avr32 \ +- | be32 | be64 \ +- | bfin \ +-- | c4x | clipper \ +-+ | c4x | c8051 | clipper \ +- | d10v | d30v | dlx | dsp16xx \ +- | epiphany \ +- | fido | fr30 | frv \ +-@@ -265,6 +265,7 @@ case $basic_machine in +- | hexagon \ +- | i370 | i860 | i960 | ia64 \ +- | ip2k | iq2000 \ +-+ | k1om \ +- | le32 | le64 \ +- | lm32 \ +- | m32c | m32r | m32rle | m68000 | m68k | m88k \ +-@@ -324,7 +325,7 @@ case $basic_machine in +- c6x) +- basic_machine=tic6x-unknown +- ;; +-- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) +-+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) +- basic_machine=$basic_machine-unknown +- os=-none +- ;; +-@@ -372,7 +373,7 @@ case $basic_machine in +- | be32-* | be64-* \ +- | bfin-* | bs2000-* \ +- | c[123]* | c30-* | [cjt]90-* | c4x-* \ +-- | clipper-* | craynv-* | cydra-* \ +-+ | c8051-* | clipper-* | craynv-* | cydra-* \ +- | d10v-* | d30v-* | dlx-* \ +- | elxsi-* \ +- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +-@@ -381,6 +382,7 @@ case $basic_machine in +- | hexagon-* \ +- | i*86-* | i860-* | i960-* | ia64-* \ +- | ip2k-* | iq2000-* \ +-+ | k1om-* \ +- | le32-* | le64-* \ +- | lm32-* \ +- | m32c-* | m32r-* | m32rle-* \ +-@@ -794,7 +796,7 @@ case $basic_machine in +- os=-mingw64 +- ;; +- mingw32) +-- basic_machine=i386-pc +-+ basic_machine=i686-pc +- os=-mingw32 +- ;; +- mingw32ce) +-@@ -830,7 +832,7 @@ case $basic_machine in +- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` +- ;; +- msys) +-- basic_machine=i386-pc +-+ basic_machine=i686-pc +- os=-msys +- ;; +- mvs) +-@@ -1546,6 +1548,9 @@ case $basic_machine in +- c4x-* | tic4x-*) +- os=-coff +- ;; +-+ c8051-*) +-+ os=-elf +-+ ;; +- hexagon-*) +- os=-elf +- ;; +- +-# +-# gdb-7.6-ppc64le.patch +-# +- +-From: Ulrich Weigand +-References: ppc64le enablement +-Patch-mainline: not yet +- +-Signed-off-by: Ulrich Weigand +-Signed-off-by: Petr Tesarik +- +---- +- gdb/auxv.c | 1 +- gdb/configure.host | 4 +- gdb/configure.tgt | 2 +- gdb/doublest.c | 49 +- +- gdb/gdbarch.c | 33 + +- gdb/gdbarch.h | 6 +- gdb/gdbarch.sh | 1 +- gdb/gdbtypes.c | 4 +- gdb/infrun.c | 4 +- gdb/ppc-linux-tdep.c | 60 ++- +- gdb/ppc-sysv-tdep.c | 534 ++++++++++++++++++++++++--- +- gdb/ppc-tdep.h | 11 +- gdb/ppc64-tdep.c | 2 +- gdb/rs6000-tdep.c | 43 +- +- gdb/symtab.c | 2 +- gdb/testsuite/gdb.arch/altivec-regs.exp | 2 +- gdb/testsuite/gdb.arch/powerpc-d128-regs.exp | 2 +- gdb/testsuite/gdb.arch/vsx-regs.exp | 39 + +- gdb/testsuite/gdb.base/sigbpt.exp | 2 +- gdb/testsuite/gdb.base/step-bt.exp | 2 +- include/elf/common.h | 1 +- include/elf/ppc64.h | 54 ++ +- 22 files changed, 752 insertions(+), 106 deletions(-) +- +---- a/gdb/ppc64-tdep.c +-+++ b/gdb/ppc64-tdep.c +-@@ -289,7 +289,7 @@ static struct ppc_insn_pattern ppc64_sta +- static struct ppc_insn_pattern ppc64_standard_linkage7[] = +- { +- /* std r2, 24(r1) */ +-- { -1, insn_ds (62, 2, 1, 40, 0), 1 }, +-+ { -1, insn_ds (62, 2, 1, 24, 0), 1 }, +- +- /* ld r12, (r2) */ +- { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 }, +---- a/gdb/rs6000-tdep.c +-+++ b/gdb/rs6000-tdep.c +-@@ -48,6 +48,7 @@ +- +- #include "elf-bfd.h" +- #include "elf/ppc.h" +-+#include "elf/ppc64.h" +- +- #include "solib-svr4.h" +- #include "ppc-tdep.h" +-@@ -2672,10 +2673,10 @@ dfp_pseudo_register_read (struct gdbarch +- else +- { +- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum + +-- 2 * reg_index + 1, buffer + 8); +-+ 2 * reg_index + 1, buffer); +- if (status == REG_VALID) +- status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum + +-- 2 * reg_index, buffer); +-+ 2 * reg_index, buffer + 8); +- } +- +- return status; +-@@ -2701,9 +2702,9 @@ dfp_pseudo_register_write (struct gdbarc +- else +- { +- regcache_raw_write (regcache, tdep->ppc_fp0_regnum + +-- 2 * reg_index + 1, buffer + 8); +-+ 2 * reg_index + 1, buffer); +- regcache_raw_write (regcache, tdep->ppc_fp0_regnum + +-- 2 * reg_index, buffer); +-+ 2 * reg_index, buffer + 8); +- } +- } +- +-@@ -2781,7 +2782,8 @@ efpr_pseudo_register_read (struct gdbarc +- int reg_index = reg_nr - tdep->ppc_efpr0_regnum; +- +- /* Read the portion that overlaps the VMX register. */ +-- return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0, +-+ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; +-+ return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset, +- register_size (gdbarch, reg_nr), buffer); +- } +- +-@@ -2794,7 +2796,8 @@ efpr_pseudo_register_write (struct gdbar +- int reg_index = reg_nr - tdep->ppc_efpr0_regnum; +- +- /* Write the portion that overlaps the VMX register. */ +-- regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0, +-+ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; +-+ regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset, +- register_size (gdbarch, reg_nr), buffer); +- } +- +-@@ -3550,6 +3553,7 @@ rs6000_gdbarch_init (struct gdbarch_info +- enum auto_boolean soft_float_flag = powerpc_soft_float_global; +- int soft_float; +- enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; +-+ enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; +- int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0, +- have_vsx = 0; +- int tdesc_wordsize = -1; +-@@ -3856,6 +3860,21 @@ rs6000_gdbarch_init (struct gdbarch_info +- } +- +- #ifdef HAVE_ELF +-+ if (from_elf_exec) +-+ { +-+ switch (elf_elfheader (info.abfd)->e_flags & EF_PPC64_ABI) +-+ { +-+ case 1: +-+ elf_abi = POWERPC_ELF_V1; +-+ break; +-+ case 2: +-+ elf_abi = POWERPC_ELF_V2; +-+ break; +-+ default: +-+ break; +-+ } +-+ } +-+ +- if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec) +- { +- switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, +-@@ -3892,6 +3911,15 @@ rs6000_gdbarch_init (struct gdbarch_info +- } +- #endif +- +-+ /* Default to ELFv2 ABI on 64-bit little-endian, and ELFv1 otherwise. */ +-+ if (elf_abi == POWERPC_ELF_AUTO) +-+ { +-+ if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE) +-+ elf_abi = POWERPC_ELF_V2; +-+ else +-+ elf_abi = POWERPC_ELF_V1; +-+ } +-+ +- if (soft_float_flag == AUTO_BOOLEAN_TRUE) +- soft_float = 1; +- else if (soft_float_flag == AUTO_BOOLEAN_FALSE) +-@@ -3934,6 +3962,8 @@ rs6000_gdbarch_init (struct gdbarch_info +- meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform +- separate word size check. */ +- tdep = gdbarch_tdep (arches->gdbarch); +-+ if (tdep && tdep->elf_abi != elf_abi) +-+ continue; +- if (tdep && tdep->soft_float != soft_float) +- continue; +- if (tdep && tdep->vector_abi != vector_abi) +-@@ -3956,6 +3986,7 @@ rs6000_gdbarch_init (struct gdbarch_info +- +- tdep = XCALLOC (1, struct gdbarch_tdep); +- tdep->wordsize = wordsize; +-+ tdep->elf_abi = elf_abi; +- tdep->soft_float = soft_float; +- tdep->vector_abi = vector_abi; +- +---- a/gdb/auxv.c +-+++ b/gdb/auxv.c +-@@ -441,6 +441,7 @@ fprint_target_auxv (struct ui_file *file +- TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec); +- TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str); +- TAG (AT_RANDOM, _("Address of 16 random bytes"), hex); +-+ TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), hex); +- TAG (AT_EXECFN, _("File name of executable"), str); +- TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec); +- TAG (AT_SYSINFO, _("Special system info/entry points"), hex); +---- a/gdb/configure.host +-+++ b/gdb/configure.host +-@@ -129,18 +129,18 @@ mips64*-*-openbsd*) gdb_host=obsd64 ;; +- powerpc-*-aix* | rs6000-*-*) +- gdb_host=aix ;; +- powerpc*-*-freebsd*) gdb_host=fbsd ;; +--powerpc-*-linux*) gdb_host=linux ;; +- powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu) +- gdb_host=nbsd ;; +- powerpc-*-openbsd*) gdb_host=obsd ;; +- +--powerpc64-*-linux*) gdb_host=ppc64-linux +-+powerpc64*-*-linux*) gdb_host=ppc64-linux +- # Support 'pseudo-native' debugging on the Cell BE +- if test "${target_cpu}" = "spu"; then +- gdb_host=spu-linux +- gdb_native=yes +- fi +- ;; +-+powerpc*-*-linux*) gdb_host=linux ;; +- +- s390*-*-*) gdb_host=s390 ;; +- +---- a/gdb/configure.tgt +-+++ b/gdb/configure.tgt +-@@ -421,7 +421,7 @@ powerpc-*-aix* | rs6000-*-*) +- ppc-sysv-tdep.o solib-svr4.o \ +- ravenscar-thread.o ppc-ravenscar-thread.o" +- ;; +--powerpc-*-linux* | powerpc64-*-linux*) +-+powerpc*-*-linux*) +- # Target: PowerPC running Linux +- gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \ +- ppc64-tdep.o solib-svr4.o solib-spu.o \ +---- a/gdb/doublest.c +-+++ b/gdb/doublest.c +-@@ -190,7 +190,8 @@ convert_floatformat_to_doublest (const s +- { +- double dto; +- +-- floatformat_to_double (fmt, from, &dto); +-+ floatformat_to_double (fmt->split_half ? fmt->split_half : fmt, +-+ from, &dto); +- *to = (DOUBLEST) dto; +- return; +- } +-@@ -561,6 +562,11 @@ floatformat_is_negative (const struct fl +- gdb_assert (fmt->totalsize +- <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); +- +-+ /* An IBM long double (a two element array of double) always takes the +-+ sign of the first double. */ +-+ if (fmt->split_half) +-+ fmt = fmt->split_half; +-+ +- order = floatformat_normalize_byteorder (fmt, uval, newfrom); +- +- if (order != fmt->byteorder) +-@@ -587,6 +593,13 @@ floatformat_classify (const struct float +- gdb_assert (fmt->totalsize +- <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); +- +-+ /* An IBM long double (a two element array of double) can be classified +-+ by looking at the first double. inf and nan are specified as +-+ ignoring the second double. zero and subnormal will always have +-+ the second double 0.0 if the long double is correctly rounded. */ +-+ if (fmt->split_half) +-+ fmt = fmt->split_half; +-+ +- order = floatformat_normalize_byteorder (fmt, uval, newfrom); +- +- if (order != fmt->byteorder) +-@@ -669,6 +682,16 @@ floatformat_mantissa (const struct float +- gdb_assert (fmt->totalsize +- <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); +- +-+ /* For IBM long double (a two element array of double), return the +-+ mantissa of the first double. The problem with returning the +-+ actual mantissa from both doubles is that there can be an +-+ arbitrary number of implied 0's or 1's between the mantissas +-+ of the first and second double. In any case, this function +-+ is only used for dumping out nans, and a nan is specified to +-+ ignore the value in the second double. */ +-+ if (fmt->split_half) +-+ fmt = fmt->split_half; +-+ +- order = floatformat_normalize_byteorder (fmt, uval, newfrom); +- +- if (order != fmt->byteorder) +-@@ -926,27 +949,3 @@ convert_typed_floating (const void *from +- floatformat_from_doublest (to_fmt, &d, to); +- } +- } +-- +--const struct floatformat *floatformat_ieee_single[BFD_ENDIAN_UNKNOWN]; +--const struct floatformat *floatformat_ieee_double[BFD_ENDIAN_UNKNOWN]; +--const struct floatformat *floatformat_ieee_quad[BFD_ENDIAN_UNKNOWN]; +--const struct floatformat *floatformat_arm_ext[BFD_ENDIAN_UNKNOWN]; +--const struct floatformat *floatformat_ia64_spill[BFD_ENDIAN_UNKNOWN]; +-- +--extern void _initialize_doublest (void); +-- +--extern void +--_initialize_doublest (void) +--{ +-- floatformat_ieee_single[BFD_ENDIAN_LITTLE] = &floatformat_ieee_single_little; +-- floatformat_ieee_single[BFD_ENDIAN_BIG] = &floatformat_ieee_single_big; +-- floatformat_ieee_double[BFD_ENDIAN_LITTLE] = &floatformat_ieee_double_little; +-- floatformat_ieee_double[BFD_ENDIAN_BIG] = &floatformat_ieee_double_big; +-- floatformat_arm_ext[BFD_ENDIAN_LITTLE] +-- = &floatformat_arm_ext_littlebyte_bigword; +-- floatformat_arm_ext[BFD_ENDIAN_BIG] = &floatformat_arm_ext_big; +-- floatformat_ia64_spill[BFD_ENDIAN_LITTLE] = &floatformat_ia64_spill_little; +-- floatformat_ia64_spill[BFD_ENDIAN_BIG] = &floatformat_ia64_spill_big; +-- floatformat_ieee_quad[BFD_ENDIAN_LITTLE] = &floatformat_ia64_quad_little; +-- floatformat_ieee_quad[BFD_ENDIAN_BIG] = &floatformat_ia64_quad_big; +--} +---- a/gdb/gdbarch.c +-+++ b/gdb/gdbarch.c +-@@ -200,6 +200,7 @@ struct gdbarch +- gdbarch_return_in_first_hidden_param_p_ftype *return_in_first_hidden_param_p; +- gdbarch_skip_prologue_ftype *skip_prologue; +- gdbarch_skip_main_prologue_ftype *skip_main_prologue; +-+ gdbarch_skip_entrypoint_ftype *skip_entrypoint; +- gdbarch_inner_than_ftype *inner_than; +- gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc; +- gdbarch_remote_breakpoint_from_pc_ftype *remote_breakpoint_from_pc; +-@@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch = +- default_return_in_first_hidden_param_p, /* return_in_first_hidden_param_p */ +- 0, /* skip_prologue */ +- 0, /* skip_main_prologue */ +-+ 0, /* skip_entrypoint */ +- 0, /* inner_than */ +- 0, /* breakpoint_from_pc */ +- default_remote_breakpoint_from_pc, /* remote_breakpoint_from_pc */ +-@@ -672,6 +674,7 @@ verify_gdbarch (struct gdbarch *gdbarch) +- if (gdbarch->skip_prologue == 0) +- fprintf_unfiltered (log, "\n\tskip_prologue"); +- /* Skip verify of skip_main_prologue, has predicate. */ +-+ /* Skip verify of skip_entrypoint, has predicate. */ +- if (gdbarch->inner_than == 0) +- fprintf_unfiltered (log, "\n\tinner_than"); +- if (gdbarch->breakpoint_from_pc == 0) +-@@ -1285,6 +1288,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s +- "gdbarch_dump: single_step_through_delay = <%s>\n", +- host_address_to_string (gdbarch->single_step_through_delay)); +- fprintf_unfiltered (file, +-+ "gdbarch_dump: gdbarch_skip_entrypoint_p() = %d\n", +-+ gdbarch_skip_entrypoint_p (gdbarch)); +-+ fprintf_unfiltered (file, +-+ "gdbarch_dump: skip_entrypoint = <%s>\n", +-+ host_address_to_string (gdbarch->skip_entrypoint)); +-+ fprintf_unfiltered (file, +- "gdbarch_dump: gdbarch_skip_main_prologue_p() = %d\n", +- gdbarch_skip_main_prologue_p (gdbarch)); +- fprintf_unfiltered (file, +-@@ -2635,6 +2644,30 @@ set_gdbarch_skip_main_prologue (struct g +- } +- +- int +-+gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch) +-+{ +-+ gdb_assert (gdbarch != NULL); +-+ return gdbarch->skip_entrypoint != NULL; +-+} +-+ +-+CORE_ADDR +-+gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip) +-+{ +-+ gdb_assert (gdbarch != NULL); +-+ gdb_assert (gdbarch->skip_entrypoint != NULL); +-+ if (gdbarch_debug >= 2) +-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_entrypoint called\n"); +-+ return gdbarch->skip_entrypoint (gdbarch, ip); +-+} +-+ +-+void +-+set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, +-+ gdbarch_skip_entrypoint_ftype skip_entrypoint) +-+{ +-+ gdbarch->skip_entrypoint = skip_entrypoint; +-+} +-+ +-+int +- gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs) +- { +- gdb_assert (gdbarch != NULL); +---- a/gdb/gdbarch.h +-+++ b/gdb/gdbarch.h +-@@ -487,6 +487,12 @@ typedef CORE_ADDR (gdbarch_skip_main_pro +- extern CORE_ADDR gdbarch_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR ip); +- extern void set_gdbarch_skip_main_prologue (struct gdbarch *gdbarch, gdbarch_skip_main_prologue_ftype *skip_main_prologue); +- +-+extern int gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch); +-+ +-+typedef CORE_ADDR (gdbarch_skip_entrypoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); +-+extern CORE_ADDR gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip); +-+extern void set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, gdbarch_skip_entrypoint_ftype *skip_entrypoint); +-+ +- typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs); +- extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs); +- extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than); +---- a/gdb/gdbarch.sh +-+++ b/gdb/gdbarch.sh +-@@ -527,6 +527,7 @@ m:int:return_in_first_hidden_param_p:str +- +- m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 +- M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip +-+M:CORE_ADDR:skip_entrypoint:CORE_ADDR ip:ip +- f:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0 +- m:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: +- # Return the adjusted address and kind to use for Z0/Z1 packets. +---- a/gdb/gdbtypes.c +-+++ b/gdb/gdbtypes.c +-@@ -107,8 +107,8 @@ const struct floatformat *floatformats_v +- &floatformat_vax_d +- }; +- const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = { +-- &floatformat_ibm_long_double, +-- &floatformat_ibm_long_double +-+ &floatformat_ibm_long_double_big, +-+ &floatformat_ibm_long_double_little +- }; +- +- /* Should opaque types be resolved? */ +---- a/gdb/infrun.c +-+++ b/gdb/infrun.c +-@@ -3139,6 +3139,10 @@ fill_in_stop_func (struct gdbarch *gdbar +- ecs->stop_func_start +- += gdbarch_deprecated_function_start_offset (gdbarch); +- +-+ if (gdbarch_skip_entrypoint_p (gdbarch)) +-+ ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch, +-+ ecs->stop_func_start); +-+ +- ecs->stop_func_filled_in = 1; +- } +- } +---- a/gdb/ppc-linux-tdep.c +-+++ b/gdb/ppc-linux-tdep.c +-@@ -44,6 +44,7 @@ +- #include "observer.h" +- #include "auxv.h" +- #include "elf/common.h" +-+#include "elf/ppc64.h" +- #include "exceptions.h" +- #include "arch-utils.h" +- #include "spu-tdep.h" +-@@ -876,6 +877,43 @@ ppc_linux_core_read_description (struct +- } +- } +- +-+/* If the ELF symbol has a local entry point, use it as SYMBOL_VALUE_ADDRESS +-+ for the msymbol. This matches the DWARF function start if present. */ +-+ +-+static void +-+ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) +-+{ +-+ elf_symbol_type *elf_sym = (elf_symbol_type *)sym; +-+ switch (PPC64_LOCAL_ENTRY_OFFSET (elf_sym->internal_elf_sym.st_other)) +-+ { +-+ default: +-+ break; +-+ case 8: +-+ MSYMBOL_TARGET_FLAG_1 (msym) = 1; +-+ break; +-+ } +-+} +-+ +-+static CORE_ADDR +-+ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc) +-+{ +-+ struct bound_minimal_symbol fun; +-+ int local_entry_offset = 0; +-+ +-+ fun = lookup_minimal_symbol_by_pc (pc); +-+ if (fun.minsym == NULL) +-+ return pc; +-+ +-+ if (MSYMBOL_TARGET_FLAG_1 (fun.minsym)) +-+ local_entry_offset = 8; +-+ +-+ if (SYMBOL_VALUE_ADDRESS (fun.minsym) <= pc +-+ && pc < SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset) +-+ return SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset; +-+ +-+ return pc; +-+} +-+ +- /* Implementation of `gdbarch_stap_is_single_operand', as defined in +- gdbarch.h. */ +- +-@@ -1332,13 +1370,23 @@ ppc_linux_init_abi (struct gdbarch_info +- +- if (tdep->wordsize == 8) +- { +-- /* Handle PPC GNU/Linux 64-bit function pointers (which are really +-- function descriptors). */ +-- set_gdbarch_convert_from_func_ptr_addr +-- (gdbarch, ppc64_convert_from_func_ptr_addr); +-+ if (tdep->elf_abi == POWERPC_ELF_V1) +-+ { +-+ /* Handle PPC GNU/Linux 64-bit function pointers (which are really +-+ function descriptors). */ +-+ set_gdbarch_convert_from_func_ptr_addr +-+ (gdbarch, ppc64_convert_from_func_ptr_addr); +- +-- set_gdbarch_elf_make_msymbol_special (gdbarch, +-- ppc64_elf_make_msymbol_special); +-+ set_gdbarch_elf_make_msymbol_special +-+ (gdbarch, ppc64_elf_make_msymbol_special); +-+ } +-+ else +-+ { +-+ set_gdbarch_elf_make_msymbol_special +-+ (gdbarch, ppc_elfv2_elf_make_msymbol_special); +-+ +-+ set_gdbarch_skip_entrypoint (gdbarch, ppc_elfv2_skip_entrypoint); +-+ } +- +- /* Shared library handling. */ +- set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); +---- a/gdb/ppc-sysv-tdep.c +-+++ b/gdb/ppc-sysv-tdep.c +-@@ -610,42 +610,48 @@ ppc_sysv_abi_push_dummy_call (struct gdb +- } +- +- /* Handle the return-value conventions for Decimal Floating Point values +-- in both ppc32 and ppc64, which are the same. */ +--static int +-+ in both ppc32 and ppc64, which are the same. INDEX specifies which +-+ part of a multi-part return value is to be handled. */ +-+static void +- get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype, +- struct regcache *regcache, gdb_byte *readbuf, +-- const gdb_byte *writebuf) +-+ const gdb_byte *writebuf, int index) +- { +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +-+ int offset = index * TYPE_LENGTH (valtype); +- +- gdb_assert (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT); +- +- /* 32-bit and 64-bit decimal floats in f1. */ +- if (TYPE_LENGTH (valtype) <= 8) +- { +-+ int regnum = tdep->ppc_fp0_regnum + 1 + index; +-+ +- if (writebuf != NULL) +- { +- gdb_byte regval[MAX_REGISTER_SIZE]; +- const gdb_byte *p; +- +- /* 32-bit decimal float is right aligned in the doubleword. */ +-- if (TYPE_LENGTH (valtype) == 4) +-+ if (TYPE_LENGTH (valtype) == 4 +-+ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) +- { +-- memcpy (regval + 4, writebuf, 4); +-+ memcpy (regval + 4, writebuf + offset, 4); +- p = regval; +- } +- else +-- p = writebuf; +-+ p = writebuf + offset; +- +-- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p); +-+ regcache_cooked_write (regcache, regnum, p); +- } +- if (readbuf != NULL) +- { +-- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf); +-+ regcache_cooked_read (regcache, regnum, readbuf); +- +- /* Left align 32-bit decimal float. */ +-- if (TYPE_LENGTH (valtype) == 4) +-- memcpy (readbuf, readbuf + 4, 4); +-+ if (TYPE_LENGTH (valtype) == 4 +-+ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) +-+ memcpy (readbuf + offset, readbuf + offset + 4, 4); +- } +- } +- /* 128-bit decimal floats in f2,f3. */ +-@@ -653,24 +659,27 @@ get_decimal_float_return_value (struct g +- { +- if (writebuf != NULL || readbuf != NULL) +- { +-- int i; +-+ int i, regnum; +- +- for (i = 0; i < 2; i++) +- { +-+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) +-+ regnum = tdep->ppc_fp0_regnum + 2 + i + 2 * index; +-+ else +-+ regnum = tdep->ppc_fp0_regnum + 3 - i + 2 * index; +-+ +- if (writebuf != NULL) +-- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2 + i, +-- writebuf + i * 8); +-+ regcache_cooked_write (regcache, regnum, +-+ writebuf + offset + i * 8); +- if (readbuf != NULL) +-- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2 + i, +-- readbuf + i * 8); +-+ regcache_cooked_read (regcache, regnum, +-+ readbuf + offset + i * 8); +- } +- } +- } +- else +- /* Can't happen. */ +- internal_error (__FILE__, __LINE__, _("Unknown decimal float size.")); +-- +-- return RETURN_VALUE_REGISTER_CONVENTION; +- } +- +- /* Handle the return-value conventions specified by the SysV 32-bit +-@@ -802,8 +811,11 @@ do_ppc_sysv_return_value (struct gdbarch +- return RETURN_VALUE_REGISTER_CONVENTION; +- } +- if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && !tdep->soft_float) +-- return get_decimal_float_return_value (gdbarch, type, regcache, readbuf, +-- writebuf); +-+ { +-+ get_decimal_float_return_value (gdbarch, type, regcache, +-+ readbuf, writebuf, 0); +-+ return RETURN_VALUE_REGISTER_CONVENTION; +-+ } +- else if ((TYPE_CODE (type) == TYPE_CODE_INT +- || TYPE_CODE (type) == TYPE_CODE_CHAR +- || TYPE_CODE (type) == TYPE_CODE_BOOL +-@@ -1102,6 +1114,156 @@ convert_code_addr_to_desc_addr (CORE_ADD +- return 1; +- } +- +-+/* Walk down the type tree of TYPE counting consecutive base elements. +-+ If *FIELD_TYPE is NULL, then set it to the first valid floating point +-+ or vector type. If a non-floating point or vector type is found, or +-+ if a floating point or vector type that doesn't match a non-NULL +-+ *FIELD_TYPE is found, then return -1, otherwise return the count in the +-+ sub-tree. */ +-+ +-+static LONGEST +-+ppc64_aggregate_candidate (struct type *type, +-+ struct type **field_type) +-+{ +-+ type = check_typedef (type); +-+ +-+ switch (TYPE_CODE (type)) +-+ { +-+ case TYPE_CODE_FLT: +-+ case TYPE_CODE_DECFLOAT: +-+ if (!*field_type) +-+ *field_type = type; +-+ if (TYPE_CODE (*field_type) == TYPE_CODE (type) +-+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) +-+ return 1; +-+ break; +-+ +-+ case TYPE_CODE_COMPLEX: +-+ type = TYPE_TARGET_TYPE (type); +-+ if (TYPE_CODE (type) == TYPE_CODE_FLT +-+ || TYPE_CODE (type) == TYPE_CODE_DECFLOAT) +-+ { +-+ if (!*field_type) +-+ *field_type = type; +-+ if (TYPE_CODE (*field_type) == TYPE_CODE (type) +-+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) +-+ return 2; +-+ } +-+ break; +-+ +-+ case TYPE_CODE_ARRAY: +-+ if (TYPE_VECTOR (type)) +-+ { +-+ if (!*field_type) +-+ *field_type = type; +-+ if (TYPE_CODE (*field_type) == TYPE_CODE (type) +-+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type)) +-+ return 1; +-+ } +-+ else +-+ { +-+ LONGEST count, low_bound, high_bound; +-+ +-+ count = ppc64_aggregate_candidate +-+ (TYPE_TARGET_TYPE (type), field_type); +-+ if (count == -1) +-+ return -1; +-+ +-+ if (!get_array_bounds (type, &low_bound, &high_bound)) +-+ return -1; +-+ count *= high_bound - low_bound; +-+ +-+ /* There must be no padding. */ +-+ if (count == 0) +-+ return TYPE_LENGTH (type) == 0 ? 0 : -1; +-+ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type)) +-+ return -1; +-+ +-+ return count; +-+ } +-+ break; +-+ +-+ case TYPE_CODE_STRUCT: +-+ case TYPE_CODE_UNION: +-+ { +-+ LONGEST count = 0; +-+ int i; +-+ +-+ for (i = 0; i < TYPE_NFIELDS (type); i++) +-+ { +-+ LONGEST sub_count; +-+ +-+ if (field_is_static (&TYPE_FIELD (type, i))) +-+ continue; +-+ +-+ sub_count = ppc64_aggregate_candidate +-+ (TYPE_FIELD_TYPE (type, i), field_type); +-+ if (sub_count == -1) +-+ return -1; +-+ +-+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT) +-+ count += sub_count; +-+ else +-+ count = max (count, sub_count); +-+ } +-+ +-+ /* There must be no padding. */ +-+ if (count == 0) +-+ return TYPE_LENGTH (type) == 0 ? 0 : -1; +-+ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type)) +-+ return -1; +-+ +-+ return count; +-+ } +-+ break; +-+ +-+ default: +-+ break; +-+ } +-+ +-+ return -1; +-+} +-+ +-+/* If an argument of type TYPE is a homogeneous float or vector aggregate +-+ that shall be passed in FP/vector registers according to the ELFv2 ABI, +-+ return the homogeneous element type in *ELT_TYPE and the number of +-+ elements in *N_ELTS, and return non-zero. Otherwise, return zero. */ +-+ +-+static int +-+ppc64_elfv2_abi_homogeneous_aggregate (struct type *type, +-+ struct type **elt_type, int *n_elts) +-+{ +-+ /* Complex types at the top level are treated separately. However, +-+ complex types can be elements of homogeneous aggregates. */ +-+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT +-+ || TYPE_CODE (type) == TYPE_CODE_UNION +-+ || (TYPE_CODE (type) == TYPE_CODE_ARRAY && !TYPE_VECTOR (type))) +-+ { +-+ struct type *field_type = NULL; +-+ LONGEST field_count = ppc64_aggregate_candidate (type, &field_type); +-+ +-+ if (field_count > 0) +-+ { +-+ int n_regs = ((TYPE_CODE (field_type) == TYPE_CODE_FLT +-+ || TYPE_CODE (field_type) == TYPE_CODE_DECFLOAT)? +-+ (TYPE_LENGTH (field_type) + 7) >> 3 : 1); +-+ +-+ /* The ELFv2 ABI allows homogeneous aggregates to occupy +-+ up to 8 registers. */ +-+ if (field_count * n_regs <= 8) +-+ { +-+ if (elt_type) +-+ *elt_type = field_type; +-+ if (n_elts) +-+ *n_elts = (int) field_count; +-+ return 1; +-+ } +-+ } +-+ } +-+ +-+ return 0; +-+} +-+ +- /* Push a float in either registers, or in the stack. Using the ppc 64 bit +- SysV ABI. +- +-@@ -1143,6 +1305,8 @@ ppc64_sysv_abi_push_float (struct gdbarc +- +- /* Write value in the stack's parameter save area. */ +- write_memory (gparam, p, 8); +-+ if (greg <= 10) +-+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, p); +- +- /* Floats and Doubles go in f1 .. f13. They also consume a left aligned +- GREG, and can end up in memory. */ +-@@ -1154,8 +1318,6 @@ ppc64_sysv_abi_push_float (struct gdbarc +- convert_typed_floating (val, type, regval, regtype); +- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); +- } +-- if (greg <= 10) +-- regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); +- } +- else +- { +-@@ -1268,9 +1430,13 @@ ppc64_sysv_abi_push_dummy_call (struct g +- to their corresponding regions. */ +- refparam = align_down (sp - refparam_size, 16); +- gparam = align_down (refparam - gparam_size, 16); +-- /* Add in space for the TOC, link editor double word, +-- compiler double word, LR save area, CR save area. */ +-- sp = align_down (gparam - 48, 16); +-+ /* Add in space for the TOC, link editor double word (v1 only), +-+ compiler double word (v1 only), LR save area, CR save area, +-+ and backchain. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V1) +-+ sp = align_down (gparam - 48, 16); +-+ else +-+ sp = align_down (gparam - 32, 16); +- } +- +- /* If the function is returning a `struct', then there is an +-@@ -1375,7 +1541,8 @@ ppc64_sysv_abi_push_dummy_call (struct g +- +- /* 32-bit decimal floats are right aligned in the +- doubleword. */ +-- if (TYPE_LENGTH (type) == 4) +-+ if (TYPE_LENGTH (type) == 4 +-+ && byte_order == BFD_ENDIAN_BIG) +- { +- memcpy (regval + 4, val, 4); +- p = regval; +-@@ -1407,10 +1574,21 @@ ppc64_sysv_abi_push_dummy_call (struct g +- { +- /* Make sure freg is even. */ +- freg += freg & 1; +-- regcache_cooked_write (regcache, +-- tdep->ppc_fp0_regnum + freg, val); +-- regcache_cooked_write (regcache, +-- tdep->ppc_fp0_regnum + freg + 1, val + 8); +-+ +-+ if (byte_order == BFD_ENDIAN_BIG) +-+ { +-+ regcache_cooked_write (regcache, +-+ tdep->ppc_fp0_regnum + freg, val); +-+ regcache_cooked_write (regcache, +-+ tdep->ppc_fp0_regnum + freg + 1, val + 8); +-+ } +-+ else +-+ { +-+ regcache_cooked_write (regcache, +-+ tdep->ppc_fp0_regnum + freg + 1, val); +-+ regcache_cooked_write (regcache, +-+ tdep->ppc_fp0_regnum + freg, val + 8); +-+ } +- } +- +- write_memory (gparam, val, TYPE_LENGTH (type)); +-@@ -1587,8 +1765,9 @@ ppc64_sysv_abi_push_dummy_call (struct g +- ULONGEST word = unpack_long (type, val); +- /* Convert any function code addresses into +- descriptors. */ +-- if (TYPE_CODE (type) == TYPE_CODE_PTR +-- || TYPE_CODE (type) == TYPE_CODE_REF) +-+ if (tdep->elf_abi == POWERPC_ELF_V1 +-+ && (TYPE_CODE (type) == TYPE_CODE_PTR +-+ || TYPE_CODE (type) == TYPE_CODE_REF)) +- { +- struct type *target_type; +- target_type = check_typedef (TYPE_TARGET_TYPE (type)); +-@@ -1613,6 +1792,9 @@ ppc64_sysv_abi_push_dummy_call (struct g +- } +- else +- { +-+ struct type *elt_type; +-+ int n_elts; +-+ +- int byte; +- for (byte = 0; byte < TYPE_LENGTH (type); +- byte += tdep->wordsize) +-@@ -1630,7 +1812,7 @@ ppc64_sysv_abi_push_dummy_call (struct g +- versions before 3.4 implemented this +- incorrectly; see +- . */ +-- if (byte == 0) +-+ if (byte_order == BFD_ENDIAN_BIG && byte == 0) +- memcpy (regval + tdep->wordsize - len, +- val + byte, len); +- else +-@@ -1649,7 +1831,7 @@ ppc64_sysv_abi_push_dummy_call (struct g +- value to memory. Fortunately, doing this +- simplifies the code. */ +- int len = TYPE_LENGTH (type); +-- if (len < tdep->wordsize) +-+ if (byte_order == BFD_ENDIAN_BIG && len < tdep->wordsize) +- write_memory (gparam + tdep->wordsize - len, val, len); +- else +- write_memory (gparam, val, len); +-@@ -1705,6 +1887,132 @@ ppc64_sysv_abi_push_dummy_call (struct g +- } +- } +- } +-+ /* In the ELFv2 ABI, homogeneous floating-point or vector +-+ aggregates are passed in registers. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V2 +-+ && ppc64_elfv2_abi_homogeneous_aggregate (type, +-+ &elt_type, &n_elts)) +-+ { +-+ int i; +-+ for (i = 0; i < n_elts; i++) +-+ { +-+ const gdb_byte *elt_val +-+ = val + i * TYPE_LENGTH (elt_type); +-+ +-+ switch (TYPE_CODE (elt_type)) +-+ { +-+ case TYPE_CODE_FLT: +-+ if (TYPE_LENGTH (elt_type) <= 8) +-+ { +-+ if (write_pass && freg <= 13) +-+ { +-+ int fregnum = tdep->ppc_fp0_regnum + freg; +-+ gdb_byte regval[MAX_REGISTER_SIZE]; +-+ struct type *regtype +-+ = register_type (gdbarch, fregnum); +-+ convert_typed_floating (elt_val, elt_type, +-+ regval, regtype); +-+ regcache_cooked_write (regcache, +-+ fregnum, regval); +-+ } +-+ freg++; +-+ } +-+ else if (TYPE_LENGTH (elt_type) == 16 +-+ && (gdbarch_long_double_format (gdbarch) +-+ == floatformats_ibm_long_double)) +-+ { +-+ if (write_pass && freg <= 13) +-+ { +-+ int fregnum = tdep->ppc_fp0_regnum + freg; +-+ regcache_cooked_write (regcache, +-+ fregnum, elt_val); +-+ if (freg <= 12) +-+ regcache_cooked_write (regcache, +-+ fregnum + 1, +-+ elt_val + 8); +-+ } +-+ freg += 2; +-+ } +-+ break; +-+ +-+ case TYPE_CODE_DECFLOAT: +-+ if (TYPE_LENGTH (elt_type) <= 8) +-+ { +-+ if (write_pass && freg <= 13) +-+ { +-+ int fregnum = tdep->ppc_fp0_regnum + freg; +-+ gdb_byte regval[MAX_REGISTER_SIZE]; +-+ const gdb_byte *p; +-+ +-+ /* 32-bit decimal floats are right aligned +-+ in the doubleword. */ +-+ if (TYPE_LENGTH (elt_type) == 4 +-+ && byte_order == BFD_ENDIAN_BIG) +-+ { +-+ memcpy (regval + 4, elt_val, 4); +-+ p = regval; +-+ } +-+ else +-+ p = elt_val; +-+ +-+ regcache_cooked_write (regcache, fregnum, p); +-+ } +-+ freg++; +-+ } +-+ else if (TYPE_LENGTH (elt_type) == 16) +-+ { +-+ /* Make sure freg is even. */ +-+ freg += freg & 1; +-+ +-+ if (write_pass && freg <= 12) +-+ { +-+ int fregnum = tdep->ppc_fp0_regnum + freg; +-+ if (byte_order == BFD_ENDIAN_BIG) +-+ { +-+ regcache_cooked_write (regcache, +-+ fregnum, +-+ elt_val); +-+ regcache_cooked_write (regcache, +-+ fregnum + 1, +-+ elt_val + 8); +-+ } +-+ else +-+ { +-+ regcache_cooked_write (regcache, +-+ fregnum + 1, +-+ elt_val); +-+ regcache_cooked_write (regcache, +-+ fregnum, +-+ elt_val + 8); +-+ } +-+ } +-+ freg += 2; +-+ } +-+ break; +-+ +-+ case TYPE_CODE_ARRAY: +-+ gdb_assert (TYPE_VECTOR (type)); +-+ +-+ if (tdep->vector_abi == POWERPC_VEC_ALTIVEC +-+ && TYPE_LENGTH (elt_type) == 16) +-+ { +-+ if (write_pass && vreg <= 13) +-+ { +-+ int vregnum = tdep->ppc_vr0_regnum + vreg; +-+ regcache_cooked_write (regcache, +-+ vregnum, elt_val); +-+ } +-+ vreg++; +-+ } +-+ break; +-+ +-+ default: +-+ internal_error (__FILE__, __LINE__, +-+ _("Unknown element type.")); +-+ break; +-+ } +-+ } +-+ } +- /* Always consume parameter stack space. */ +- gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); +- } +-@@ -1733,24 +2041,31 @@ ppc64_sysv_abi_push_dummy_call (struct g +- breakpoint. */ +- regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); +- +-- /* Use the func_addr to find the descriptor, and use that to find +-- the TOC. If we're calling via a function pointer, the pointer +-- itself identifies the descriptor. */ +-- { +-- struct type *ftype = check_typedef (value_type (function)); +-- CORE_ADDR desc_addr = value_as_address (function); +-- +-- if (TYPE_CODE (ftype) == TYPE_CODE_PTR +-- || convert_code_addr_to_desc_addr (func_addr, &desc_addr)) +-- { +-- /* The TOC is the second double word in the descriptor. */ +-- CORE_ADDR toc = +-- read_memory_unsigned_integer (desc_addr + tdep->wordsize, +-- tdep->wordsize, byte_order); +-- regcache_cooked_write_unsigned (regcache, +-- tdep->ppc_gp0_regnum + 2, toc); +-- } +-- } +-+ /* In the ELFv1 ABI, use the func_addr to find the descriptor, and use +-+ that to find the TOC. If we're calling via a function pointer, +-+ the pointer itself identifies the descriptor. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V1) +-+ { +-+ struct type *ftype = check_typedef (value_type (function)); +-+ CORE_ADDR desc_addr = value_as_address (function); +-+ +-+ if (TYPE_CODE (ftype) == TYPE_CODE_PTR +-+ || convert_code_addr_to_desc_addr (func_addr, &desc_addr)) +-+ { +-+ /* The TOC is the second double word in the descriptor. */ +-+ CORE_ADDR toc = +-+ read_memory_unsigned_integer (desc_addr + tdep->wordsize, +-+ tdep->wordsize, byte_order); +-+ regcache_cooked_write_unsigned (regcache, +-+ tdep->ppc_gp0_regnum + 2, toc); +-+ } +-+ } +-+ +-+ /* In the ELFv2 ABI, we need to pass the target address in r12 since +-+ we may be calling a global entry point. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V2) +-+ regcache_cooked_write_unsigned (regcache, +-+ tdep->ppc_gp0_regnum + 12, func_addr); +- +- return sp; +- } +-@@ -1775,6 +2090,8 @@ ppc64_sysv_abi_return_value (struct gdba +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- struct type *func_type = function ? value_type (function) : NULL; +- int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0; +-+ struct type *elt_type; +-+ int n_elts; +- +- /* This function exists to support a calling convention that +- requires floating-point registers. It shouldn't be used on +-@@ -1799,8 +2116,11 @@ ppc64_sysv_abi_return_value (struct gdba +- return RETURN_VALUE_REGISTER_CONVENTION; +- } +- if (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT) +-- return get_decimal_float_return_value (gdbarch, valtype, regcache, readbuf, +-- writebuf); +-+ { +-+ get_decimal_float_return_value (gdbarch, valtype, regcache, +-+ readbuf, writebuf, 0); +-+ return RETURN_VALUE_REGISTER_CONVENTION; +-+ } +- /* Integers in r3. */ +- if ((TYPE_CODE (valtype) == TYPE_CODE_INT +- || TYPE_CODE (valtype) == TYPE_CODE_ENUM +-@@ -2019,6 +2339,114 @@ ppc64_sysv_abi_return_value (struct gdba +- } +- } +- return RETURN_VALUE_REGISTER_CONVENTION; +-+ } +-+ /* In the ELFv2 ABI, homogeneous floating-point or vector +-+ aggregates are returned in registers. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V2 +-+ && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &elt_type, &n_elts)) +-+ { +-+ int i; +-+ for (i = 0; i < n_elts; i++) +-+ { +-+ int offset = i * TYPE_LENGTH (elt_type); +-+ +-+ switch (TYPE_CODE (elt_type)) +-+ { +-+ case TYPE_CODE_FLT: +-+ if (TYPE_LENGTH (elt_type) <= 8) +-+ { +-+ int regnum = tdep->ppc_fp0_regnum + 1 + i; +-+ gdb_byte regval[MAX_REGISTER_SIZE]; +-+ struct type *regtype = register_type (gdbarch, regnum); +-+ if (writebuf != NULL) +-+ { +-+ convert_typed_floating (writebuf + offset, elt_type, +-+ regval, regtype); +-+ regcache_cooked_write (regcache, regnum, regval); +-+ } +-+ if (readbuf != NULL) +-+ { +-+ regcache_cooked_read (regcache, regnum, regval); +-+ convert_typed_floating (regval, regtype, +-+ readbuf + offset, elt_type); +-+ } +-+ } +-+ else +-+ { +-+ int j, nregs = (TYPE_LENGTH (elt_type) + 7) / 8; +-+ for (j = 0; j < nregs; j++) +-+ { +-+ int regnum = tdep->ppc_fp0_regnum + 1 + nregs * i + j; +-+ +-+ if (writebuf != NULL) +-+ regcache_cooked_write (regcache, regnum, +-+ writebuf + offset + j * 8); +-+ if (readbuf != NULL) +-+ regcache_cooked_read (regcache, regnum, +-+ readbuf + offset + j * 8); +-+ } +-+ } +-+ break; +-+ +-+ case TYPE_CODE_DECFLOAT: +-+ get_decimal_float_return_value (gdbarch, elt_type, regcache, +-+ readbuf, writebuf, i); +-+ break; +-+ +-+ case TYPE_CODE_ARRAY: +-+ { +-+ int regnum = tdep->ppc_vr0_regnum + 2 + i; +-+ gdb_assert (TYPE_VECTOR (elt_type)); +-+ +-+ if (writebuf != NULL) +-+ regcache_cooked_write (regcache, regnum, writebuf + offset); +-+ if (readbuf != NULL) +-+ regcache_cooked_read (regcache, regnum, readbuf + offset); +-+ } +-+ break; +-+ } +-+ } +-+ return RETURN_VALUE_REGISTER_CONVENTION; +-+ } +-+ /* In the ELFv2 ABI, aggregate types of up to 16 bytes are +-+ returned in registers r3:r4. */ +-+ if (tdep->elf_abi == POWERPC_ELF_V2 +-+ && TYPE_LENGTH (valtype) <= 16 +-+ && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT +-+ || TYPE_CODE (valtype) == TYPE_CODE_UNION +-+ || (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && !TYPE_VECTOR (valtype)))) +-+ { +-+ int n_regs = (TYPE_LENGTH (valtype) + tdep->wordsize - 1) / tdep->wordsize; +-+ int i; +-+ +-+ for (i = 0; i < n_regs; i++) +-+ { +-+ gdb_byte regval[MAX_REGISTER_SIZE]; +-+ int regnum = tdep->ppc_gp0_regnum + 3 + i; +-+ int offset = i * tdep->wordsize; +-+ int len = TYPE_LENGTH (valtype) - offset; +-+ if (len > tdep->wordsize) +-+ len = tdep->wordsize; +-+ +-+ if (writebuf != NULL) +-+ { +-+ memset (regval, 0, sizeof regval); +-+ if (byte_order == BFD_ENDIAN_BIG && offset == 0) +-+ memcpy (regval + tdep->wordsize - len, writebuf, len); +-+ else +-+ memcpy (regval, writebuf + offset, len); +-+ regcache_cooked_write (regcache, regnum, regval); +-+ } +-+ if (readbuf != NULL) +-+ { +-+ regcache_cooked_read (regcache, regnum, regval); +-+ if (byte_order == BFD_ENDIAN_BIG && offset == 0) +-+ memcpy (readbuf, regval + tdep->wordsize - len, len); +-+ else +-+ memcpy (readbuf + offset, regval, len); +-+ } +-+ } +-+ return RETURN_VALUE_REGISTER_CONVENTION; +- } +- return RETURN_VALUE_STRUCT_CONVENTION; +- } +---- a/gdb/ppc-tdep.h +-+++ b/gdb/ppc-tdep.h +-@@ -182,6 +182,15 @@ extern void ppc_collect_vsxregset (const +- +- /* Private data that this module attaches to struct gdbarch. */ +- +-+/* ELF ABI version used by the inferior. */ +-+enum powerpc_elf_abi +-+{ +-+ POWERPC_ELF_AUTO, +-+ POWERPC_ELF_V1, +-+ POWERPC_ELF_V2, +-+ POWERPC_ELF_LAST +-+}; +-+ +- /* Vector ABI used by the inferior. */ +- enum powerpc_vector_abi +- { +-@@ -197,6 +206,8 @@ struct gdbarch_tdep +- int wordsize; /* Size in bytes of fixed-point word. */ +- int soft_float; /* Avoid FP registers for arguments? */ +- +-+ enum powerpc_elf_abi elf_abi; /* ELF ABI version. */ +-+ +- /* How to pass vector arguments. Never set to AUTO or LAST. */ +- enum powerpc_vector_abi vector_abi; +- +---- a/gdb/symtab.c +-+++ b/gdb/symtab.c +-@@ -2881,6 +2881,8 @@ skip_prologue_sal (struct symtab_and_lin +- +- /* Skip "first line" of function (which is actually its prologue). */ +- pc += gdbarch_deprecated_function_start_offset (gdbarch); +-+ if (gdbarch_skip_entrypoint_p (gdbarch)) +-+ pc = gdbarch_skip_entrypoint (gdbarch, pc); +- if (skip) +- pc = gdbarch_skip_prologue (gdbarch, pc); +- +---- a/gdb/testsuite/gdb.arch/altivec-regs.exp +-+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp +-@@ -118,7 +118,7 @@ gdb_test "info reg vscr" "vscr.*0x1\t1" +- if {$endianness == "big"} { +- set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.." +- } else { +-- set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.." +-+ set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.." +- } +- +- for {set i 0} {$i < 32} {incr i 1} { +---- a/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp +-+++ b/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp +-@@ -20,7 +20,7 @@ +- +- # Testcase for ppc decimal128 pseudo-registers. +- +--if ![istarget "powerpc64-*"] then { +-+if ![istarget "powerpc64*-*"] then { +- verbose "Skipping powerpc Decimal128 pseudo-registers testcase." +- return +- } +---- a/gdb/testsuite/gdb.arch/vsx-regs.exp +-+++ b/gdb/testsuite/gdb.arch/vsx-regs.exp +-@@ -58,19 +58,46 @@ if ![runto_main] then { +- gdb_suppress_tests +- } +- +-+send_gdb "show endian\n" +-+set endianness "" +-+gdb_expect { +-+ -re "(The target endianness is set automatically .currently )(big|little)( endian.*)$gdb_prompt $" { +-+ pass "endianness" +-+ set endianness $expect_out(2,string) +-+ } +-+ -re ".*$gdb_prompt $" { +-+ fail "couldn't get endianness" +-+ } +-+ timeout { fail "(timeout) endianness" } +-+} +-+ +- # Data sets used throughout the test +- +--set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.." +-+if {$endianness == "big"} { +-+ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.." +-+ +-+ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +-+ +-+ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." +- +--set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +-+ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." +- +--set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." +-+ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +- +--set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.." +-+ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +-+} else { +-+ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x0, 0x1., v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x0, 0x0, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x0, 0x0, 0x0, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.." +- +--set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +-+ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x1, 0x1, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.." +- +--set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.." +-+ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.." +-+ +-+ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.." +-+ +-+ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.." +-+ +-+ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.." +-+} +- +- set float_register ".raw 0xdeadbeefdeadbeef." +- +---- a/gdb/testsuite/gdb.base/sigbpt.exp +-+++ b/gdb/testsuite/gdb.base/sigbpt.exp +-@@ -82,7 +82,7 @@ gdb_test "break keeper" +- set bowler_addrs bowler +- set segv_addr none +- gdb_test {display/i $pc} +--gdb_test "advance *bowler" "bowler.*" "advance to the bowler" +-+gdb_test "advance bowler" "bowler.*" "advance to the bowler" +- set test "stepping to fault" +- set signame "SIGSEGV" +- gdb_test_multiple "stepi" "$test" { +---- a/gdb/testsuite/gdb.base/step-bt.exp +-+++ b/gdb/testsuite/gdb.base/step-bt.exp +-@@ -32,7 +32,7 @@ gdb_start +- gdb_reinitialize_dir $srcdir/$subdir +- gdb_load ${binfile} +- +--gdb_test "break *hello" \ +-+gdb_test "break hello" \ +- "Breakpoint.*at.* file .*$srcfile, line .*" \ +- "breakpoint at first instruction of hello()" +- +---- a/include/elf/common.h +-+++ b/include/elf/common.h +-@@ -954,6 +954,7 @@ +- #define AT_BASE_PLATFORM 24 /* String identifying real platform, +- may differ from AT_PLATFORM. */ +- #define AT_RANDOM 25 /* Address of 16 random bytes. */ +-+#define AT_HWCAP2 26 /* Extension of AT_HWCAP. */ +- #define AT_EXECFN 31 /* Filename of executable. */ +- /* Pointer to the global system page used for system calls and other +- nice things. */ +---- a/include/elf/ppc64.h +-+++ b/include/elf/ppc64.h +-@@ -164,6 +164,60 @@ END_RELOC_NUMBERS (R_PPC64_max) +- #define IS_PPC64_TLS_RELOC(R) \ +- ((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) +- +-+ +-+/* e_flags bits specifying ABI. +-+ 1 for original function descriptor using ABI, +-+ 2 for revised ABI without function descriptors, +-+ 0 for unspecified or not using any features affected by the differences. */ +-+#define EF_PPC64_ABI 3 +-+ +-+/* The ELFv2 ABI uses three bits in the symbol st_other field of a +-+ function definition to specify the number of instructions between a +-+ function's global entry point and local entry point. +-+ The global entry point is used when it is necessary to set up the +-+ toc pointer (r2) for the function. Callers must enter the global +-+ entry point with r12 set to the global entry point address. On +-+ return from the function, r2 may have a different value to that +-+ which it had on entry. +-+ The local entry point is used when r2 is known to already be valid +-+ for the function. There is no requirement on r12 when using the +-+ local entry point, and on return r2 will contain the same value as +-+ at entry. +-+ A value of zero in these bits means that the function has a single +-+ entry point with no requirement on r12 or r2, and that on return r2 +-+ will contain the same value as at entry. +-+ Values of one and seven are reserved. */ +-+#define STO_PPC64_LOCAL_BIT 5 +-+#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) +-+ +-+// 3 bit other field to bytes. +-+static inline unsigned int +-+ppc64_decode_local_entry(unsigned int other) +-+{ +-+ return ((1 << other) >> 2) << 2; +-+} +-+ +-+// bytes to field value. +-+static inline unsigned int +-+ppc64_encode_local_entry(unsigned int val) +-+{ +-+ return (val >= 4 * 4 +-+ ? (val >= 8 * 4 +-+ ? (val >= 16 * 4 ? 6 : 5) +-+ : 4) +-+ : (val >= 2 * 4 +-+ ? 3 +-+ : (val >= 1 * 4 ? 2 : 0))); +-+} +-+ +-+/* st_other to number of bytes. */ +-+#define PPC64_LOCAL_ENTRY_OFFSET(other) \ +-+ ppc64_decode_local_entry (((other) & STO_PPC64_LOCAL_MASK) \ +-+ >> STO_PPC64_LOCAL_BIT) +-+/* number of bytes to st_other. */ +-+#define PPC64_SET_LOCAL_ENTRY_OFFSET(val) \ +-+ ppc64_encode_local_entry (val) << STO_PPC64_LOCAL_BIT +-+ +- /* Specify the start of the .glink section. */ +- #define DT_PPC64_GLINK DT_LOPROC +- +diff --git a/gdb-7.6-proc_service.h.patch b/gdb-7.6-proc_service.h.patch +deleted file mode 100644 +index e4a788ee7498..000000000000 +--- a/gdb-7.6-proc_service.h.patch ++++ /dev/null +@@ -1,67 +0,0 @@ +---- gdb-7.6/gdb/gdb_proc_service.h.orig +-+++ gdb-7.6/gdb/gdb_proc_service.h +-@@ -115,7 +115,7 @@ extern pid_t ps_getpid (struct ps_procha +- /* Fetch the special per-thread address associated with the given LWP. +- This call is only used on a few platforms (most use a normal register). +- The meaning of the `int' parameter is machine-dependent. */ +--extern ps_err_e ps_get_thread_area (const struct ps_prochandle *, +-+extern ps_err_e ps_get_thread_area (struct ps_prochandle *, +- lwpid_t, int, psaddr_t *); +- +- +---- gdb-7.6/gdb/amd64-linux-nat.c.orig +-+++ gdb-7.6/gdb/amd64-linux-nat.c +-@@ -493,7 +493,7 @@ amd64_linux_new_fork (struct lwp_info *p +- a request for a thread's local storage address. */ +- +- ps_err_e +--ps_get_thread_area (const struct ps_prochandle *ph, +-+ps_get_thread_area (struct ps_prochandle *ph, +- lwpid_t lwpid, int idx, void **base) +- { +- if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32) +---- gdb-7.6/gdb/aarch64-linux-nat.c.orig +-+++ gdb-7.6/gdb/aarch64-linux-nat.c +-@@ -750,7 +750,7 @@ aarch64_linux_new_fork (struct lwp_info +- storage (or its descriptor). */ +- +- ps_err_e +--ps_get_thread_area (const struct ps_prochandle *ph, +-+ps_get_thread_area (struct ps_prochandle *ph, +- lwpid_t lwpid, int idx, void **base) +- { +- struct iovec iovec; +---- gdb-7.6/gdb/arm-linux-nat.c.orig +-+++ gdb-7.6/gdb/arm-linux-nat.c +-@@ -613,7 +613,7 @@ supply_fpregset (struct regcache *regcac +- /* Fetch the thread-local storage pointer for libthread_db. */ +- +- ps_err_e +--ps_get_thread_area (const struct ps_prochandle *ph, +-+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) +---- gdb-7.6/gdb/i386-linux-nat.c.orig +-+++ gdb-7.6/gdb/i386-linux-nat.c +-@@ -849,7 +849,7 @@ i386_linux_new_fork (struct lwp_info *pa +- storage (or its descriptor). */ +- +- ps_err_e +--ps_get_thread_area (const struct ps_prochandle *ph, +-+ps_get_thread_area (struct ps_prochandle *ph, +- lwpid_t lwpid, int idx, void **base) +- { +- /* NOTE: cagney/2003-08-26: The definition of this buffer is found +---- gdb-7.6/gdb/mips-linux-nat.c.orig +-+++ gdb-7.6/gdb/mips-linux-nat.c +-@@ -154,7 +154,7 @@ mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store) +- /* Fetch the thread-local storage pointer for libthread_db. */ +- +- ps_err_e +--ps_get_thread_area (const struct ps_prochandle *ph, +-+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) +- +diff --git a/gdb-7.6.patch b/gdb-7.6.patch +deleted file mode 100644 +index 106d164992d0..000000000000 +--- a/gdb-7.6.patch ++++ /dev/null +@@ -1,2558 +0,0 @@ +- +-# 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 uninintended 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. +- +-# The gdb-7.6-ppc64le-support.patch will have modified both files below +-# during the initial build, so continue previous behavior. +- +-if [ "$1" = "PPC64" ] +-then +- exit 0 +-fi +- +-tar xvzmf gdb-7.6.tar.gz \ +- gdb-7.6/gdb/symtab.c \ +- gdb-7.6/gdb/printcmd.c +- +-exit 0 +- +---- gdb-7.6/libiberty/Makefile.in.orig +-+++ gdb-7.6/libiberty/Makefile.in +-@@ -175,6 +175,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) \ +-@@ -206,7 +207,7 @@ CONFIGURED_OFILES = ./asprintf.$(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-7.6/opcodes/i386-dis.c.orig +-+++ gdb-7.6/opcodes/i386-dis.c +-@@ -11510,6 +11510,10 @@ print_insn (bfd_vma pc, disassemble_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-7.6/gdb/dwarf2read.c.orig +-+++ gdb-7.6/gdb/dwarf2read.c +-@@ -2670,7 +2670,11 @@ read_index_from_section (struct objfile +- 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."), +-@@ -2689,7 +2693,11 @@ read_index_from_section (struct objfile +- "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-7.6/gdb/amd64-linux-nat.c.orig +-+++ gdb-7.6/gdb/amd64-linux-nat.c +-@@ -45,6 +45,17 @@ +- /* ezannoni-2003-07-09: I think this is fixed. The extraneous defs have +- been removed from ptrace.h in the kernel. However, better safe than +- sorry. */ +-+#ifdef CRASH_MERGE +-+/* +-+ * When compiling within a 2.6.25-based Fedora build environment with +-+ * gcc 4.3, four new "typedef unsigned int u32;" declarations were +-+ * required due to a new ptrace_bts_config structure declaration in +-+ * "asm-x86/ptrace-abi.h" that used u32 members, but u32 is defined in +-+ * "asm-x86/types.h" within a __KERNEL__ section. They've been changed +-+ * to __u32, but this patch remains for building in that environment. +-+ */ +-+typedef unsigned int u32; +-+#endif +- #include +- #include +- #include "gdb_proc_service.h" +---- gdb-7.6/gdb/symfile.c.orig +-+++ gdb-7.6/gdb/symfile.c +-@@ -693,7 +693,26 @@ default_symfile_offsets (struct 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 (abfd, cur_sec) != 0) +-+ if (bfd_section_vma (abfd, 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_get_section_name (abfd, cur_sec), "__k", 3) != 0) +- break; +- +- if (cur_sec == NULL) +-@@ -1122,6 +1141,12 @@ symbol_file_add_with_addrs_or_offsets (b +- error (_("Not confirmed.")); +- +- objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0)); +-+#ifdef CRASH_MERGE +-+ if (add_flags & SYMFILE_MAINLINE) { +-+ extern struct objfile *gdb_kernel_objfile; +-+ gdb_kernel_objfile = objfile; +-+ } +-+#endif +- +- if (parent) +- add_separate_debug_objfile (objfile, parent); +-@@ -1484,6 +1509,9 @@ find_separate_debug_file (const char *di +- VEC (char_ptr) *debugdir_vec; +- struct cleanup *back_to; +- int ix; +-+#ifdef CRASH_MERGE +-+ extern int check_specified_module_tree(char *, char *); +-+#endif +- +- /* Set I to max (strlen (canon_dir), strlen (dir)). */ +- i = strlen (dir); +-@@ -1513,6 +1541,15 @@ find_separate_debug_file (const char *di +- if (separate_debug_file_exists (debugfile, crc32, objfile)) +- return debugfile; +- +-+#ifdef CRASH_MERGE +-+{ +-+ if (check_specified_module_tree(objfile->name, debugfile) && +-+ 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 +-@@ -1583,6 +1620,10 @@ find_separate_debug_file_by_debuglink (s +- char *debugfile; +- unsigned long crc32; +- struct cleanup *cleanups; +-+#ifdef CRASH_MERGE +-+ char *name_copy; +-+ extern char *check_specified_kernel_debug_file(); +-+#endif +- +- debuglink = get_debug_link_info (objfile, &crc32); +- +-@@ -1635,6 +1676,12 @@ find_separate_debug_file_by_debuglink (s +- } +- +- do_cleanups (cleanups); +-+#ifdef CRASH_MERGE +-+ if (debugfile == NULL) { +-+ name_copy = check_specified_kernel_debug_file(); +-+ return (name_copy ? xstrdup(name_copy) : NULL); +-+ } +-+#endif +- return debugfile; +- } +- +-@@ -2409,8 +2456,10 @@ add_symbol_file_command (char *args, int +- so we can't determine what section names are valid. */ +- } +- +-+#ifndef CRASH_MERGE +- if (from_tty && (!query ("%s", ""))) +- error (_("Not confirmed.")); +-+#endif +- +- symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0, +- section_addrs, flags); +-@@ -3690,6 +3739,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); +- +- return (*objfile->sf->sym_relocate) (objfile, sectp, buf); +---- gdb-7.6/gdb/cli/cli-cmds.c.orig +-+++ gdb-7.6/gdb/cli/cli-cmds.c +-@@ -466,6 +466,10 @@ show_script_ext_mode (struct ui_file *fi +- If SEARCH_PATH is non-zero, and the file isn't found in cwd, +- search for it in the source search path. */ +- +-+#ifdef CRASH_MERGE +-+static int crash_from_tty = 0; +-+#endif +-+ +- int +- find_and_open_script (const char *script_file, int search_path, +- FILE **streamp, char **full_pathp) +-@@ -508,6 +512,32 @@ find_and_open_script (const char *script +- return 0; +- } +- +-+#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 = *streamp; +-+ int fd = fileno (stream); +-+ if (fstat (fd, &statbuf) < 0) +-+ { +-+ perror_with_name (*full_pathp); +-+ fclose (stream); +-+ return 0; +-+ } +-+ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH)) +-+ { +-+ extern void untrusted_file(FILE *, char *); +-+ untrusted_file(NULL, *full_pathp); +-+ fclose (stream); +-+ return 0; +-+ } +-+ } +-+#endif +-+ +- return 1; +- } +- +-@@ -566,7 +596,11 @@ source_script_with_search (const char *f +- If the source command was invoked interactively, throw an +- error. Otherwise (e.g. if it was invoked by a script), +- silently ignore the error. */ +-+#ifdef CRASH_MERGE +-+ if (from_tty > 0) +-+#else +- if (from_tty) +-+#endif +- perror_with_name (file); +- else +- return; +-@@ -589,7 +623,14 @@ source_script_with_search (const char *f +- void +- source_script (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 the source_verbose global variable to its previous state +---- gdb-7.6/gdb/psymtab.c.orig +-+++ gdb-7.6/gdb/psymtab.c +-@@ -305,10 +305,14 @@ find_pc_sect_psymtab (struct objfile *ob +- struct minimal_symbol *msymbol) +- { +- struct partial_symtab *pst; +-+#ifdef CRASH_MERGE +-+ extern int gdb_line_number_callback(unsigned long, unsigned long, unsigned long); +-+#endif +- +- /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity +- than the later used TEXTLOW/TEXTHIGH one. */ +- +-+#ifndef __i386__ +- if (objfile->psymtabs_addrmap != NULL) +- { +- pst = addrmap_find (objfile->psymtabs_addrmap, pc); +-@@ -343,6 +347,7 @@ find_pc_sect_psymtab (struct objfile *ob +- } +- +- next: +-+#endif +- +- /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs +- which still have no corresponding full SYMTABs read. But it is not +-@@ -361,7 +366,12 @@ find_pc_sect_psymtab (struct objfile *ob +- +- 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->textlow, pst->texthigh)) +-+#else +- if (best_pst != NULL) +-+#endif +- return best_pst; +- } +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -1198,7 +1198,9 @@ demangle_for_lookup (const char *name, e +- doesn't affect these calls since they are looking for a known +- 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 symbol * +- lookup_symbol_in_language (const char *name, const struct block *block, +- const domain_enum domain, enum language lang, +-@@ -1212,17 +1214,30 @@ lookup_symbol_in_language (const char *n +- is_a_field_of_this); +- do_cleanups (cleanup); +- +-+#ifdef CRASH_MERGE +-+ if (returnval && (domain == VAR_DOMAIN)) +-+ gdb_bait_and_switch((char *)modified_name, returnval); +-+#endif +-+ +- return returnval; +- } +- +- /* Behave like lookup_symbol_in_language, but performed with the +- current language. */ +- +-+#ifdef CRASH_MERGE +-+static struct block *gdb_get_crash_block(void); +-+#endif +-+ +- struct 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); +-@@ -5100,3 +5115,662 @@ When enabled, debugging messages are pri +- +- observer_attach_executable_changed (symtab_observer_executable_changed); +- } +-+ +-+#ifdef CRASH_MERGE +-+#include "gdb-stabs.h" +-+#include "version.h" +-+#define GDB_COMMON +-+#include "../../defs.h" +-+ +-+static void get_member_data(struct gnu_request *, struct type *); +-+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 *); +-+extern void replace_ui_file_FILE(struct ui_file *, FILE *); +-+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 *); +-+void gdb_command_funnel(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)) +-+ +-+/* +-+ * All commands from above come through here. +-+ */ +-+void +-+gdb_command_funnel(struct gnu_request *req) +-+{ +-+ struct symbol *sym; +-+ +-+ if (req->command != GNU_VERSION) { +-+ replace_ui_file_FILE(gdb_stdout, req->fp); +-+ replace_ui_file_FILE(gdb_stderr, req->fp); +-+ do_cleanups(all_cleanups()); +-+ } +-+ +-+ 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; +-+ +-+ 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 symbol *sym; +-+ CORE_ADDR pc; +-+ +-+#define LASTCHAR(s) (s[strlen(s)-1]) +-+ +-+ /* +-+ * Prime the addrmap pump. +-+ */ +-+ if (req->name) +-+ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0); +-+ +-+ pc = req->addr; +-+ +-+ sal = find_pc_line(pc, 0); +-+ +-+ if (!sal.symtab) { +-+ req->buf[0] = '\0'; +-+ return; +-+ } +-+ +-+ if (sal.symtab->filename && sal.symtab->dirname) { +-+ if (sal.symtab->filename[0] == '/') +-+ sprintf(req->buf, "%s: %d", +-+ sal.symtab->filename, sal.line); +-+ else +-+ sprintf(req->buf, "%s%s%s: %d", +-+ sal.symtab->dirname, +-+ LASTCHAR(sal.symtab->dirname) == '/' ? "" : "/", +-+ sal.symtab->filename, sal.line); +-+ } +-+} +-+ +-+ +-+/* +-+ * General purpose routine for determining datatypes. +-+ */ +-+ +-+static void +-+gdb_get_datatype(struct gnu_request *req) +-+{ +-+ register struct cleanup *old_chain = NULL; +-+ register struct type *type; +-+ register struct type *typedef_type; +-+ struct expression *expr; +-+ struct symbol *sym; +-+ register int i; +-+ struct field *nextfield; +-+ 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); +-+ if (sym) { +-+ req->typecode = TYPE_CODE(sym->type); +-+ req->length = TYPE_LENGTH(sym->type); +-+ if (req->member) +-+ get_member_data(req, sym->type); +-+ +-+ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) { +-+ if (req->flags & GNU_PRINT_ENUMERATORS) +-+ dump_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); +-+ +-+ old_chain = make_cleanup(free_current_contents, &expr); +-+ +-+ +-+ switch (expr->elts[0].opcode) +-+ { +-+ case OP_VAR_VALUE: +-+ if (gdb_CRASHDEBUG(2)) +-+ console("expr->elts[0].opcode: OP_VAR_VALUE\n"); +-+ type = expr->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->elts[2].symbol); +-+ req->tagname = (char *)TYPE_TAG_NAME(type); +-+ if (!req->tagname) { +-+ val = evaluate_type(expr); +-+ eval_enum(value_type(val), req); +-+ } +-+ } +-+ break; +-+ +-+ case OP_TYPE: +-+ if (gdb_CRASHDEBUG(2)) +-+ console("expr->elts[0].opcode: OP_TYPE\n"); +-+ type = expr->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->member) +-+ get_member_data(req, type); +-+ +-+ break; +-+ +-+ default: +-+ if (gdb_CRASHDEBUG(2)) +-+ console("expr->elts[0].opcode: %d (?)\n", +-+ expr->elts[0].opcode); +-+ break; +-+ +-+ } +-+ +-+ do_cleanups(old_chain); +-+} +-+ +-+/* +-+ * 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) +-+{ +-+ register int i; +-+ int len; +-+ int 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"); +-+ +-+ for (i = 0; i < len; i++) { +-+ fprintf_filtered(gdb_stdout, " %s", +-+ TYPE_FIELD_NAME (type, i)); +-+ if (lastval != TYPE_FIELD_BITPOS (type, i)) { +-+ fprintf_filtered (gdb_stdout, " = %d", +-+ TYPE_FIELD_BITPOS (type, i)); +-+ lastval = TYPE_FIELD_BITPOS (type, i); +-+ } else +-+ fprintf_filtered(gdb_stdout, " = %d", lastval); +-+ fprintf_filtered(gdb_stdout, "\n"); +-+ lastval++; +-+ } +-+ 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) +-+{ +-+ register int i; +-+ int len; +-+ int lastval; +-+ +-+ len = TYPE_NFIELDS (type); +-+ lastval = 0; +-+ +-+ for (i = 0; i < len; i++) { +-+ if (lastval != TYPE_FIELD_BITPOS (type, i)) { +-+ lastval = TYPE_FIELD_BITPOS (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) +-+{ +-+ register short i; +-+ struct field *nextfield; +-+ short nfields; +-+ struct type *typedef_type; +-+ +-+ req->member_offset = -1; +-+ +-+ nfields = TYPE_MAIN_TYPE(type)->nfields; +-+ nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields; +-+ +-+ if (nfields == 0) { +-+ 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 (STREQ(req->member, nextfield->name)) { +-+ req->member_offset = nextfield->loc.bitpos; +-+ req->member_length = TYPE_LENGTH(nextfield->type); +-+ req->member_typecode = TYPE_CODE(nextfield->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; +-+ register struct cmd_list_element *c; +-+ +-+ req->value = FALSE; +-+ c = lookup_cmd(&req->name, cmdlist, "", 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) +-+{ +-+ register struct objfile *loaded_objfile = NULL; +-+ register struct objfile *objfile; +-+ register struct minimal_symbol *m; +-+ struct load_module *lm; +-+ int external, subsequent, found; +-+ off_t offset; +-+ ulong value, adjusted; +-+ struct symbol *sym; +-+ struct expression *expr; +-+ struct cleanup *old_chain; +-+ int i; +-+ int allsect = 0; +-+ char *secname; +-+ char buf[80]; +-+ +-+ gdb_current_load_module = lm = (struct load_module *)req->addr; +-+ +-+ req->name = lm->mod_namelist; +-+ gdb_delete_symbol_file(req); +-+ +-+ 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); +-+ } +-+ } +-+ } +-+ } +-+ +-+ if (gdb_CRASHDEBUG(1)) +-+ fprintf_filtered(gdb_stdout, "%s\n", req->buf); +-+ +-+ execute_command(req->buf, FALSE); +-+ +-+ ALL_OBJFILES(objfile) { +-+ if (same_file(objfile->name, lm->mod_namelist)) { +-+ loaded_objfile = objfile; +-+ break; +-+ } +-+ } +-+ +-+ if (!loaded_objfile) +-+ req->flags |= GNU_COMMAND_FAILED; +-+} +-+ +-+static void +-+gdb_delete_symbol_file(struct gnu_request *req) +-+{ +-+ register struct objfile *objfile; +-+ +-+ ALL_OBJFILES(objfile) { +-+ if (STREQ(objfile->name, req->name) || +-+ same_file(objfile->name, req->name)) { +-+ free_objfile(objfile); +-+ break; +-+ } +-+ } +-+ +-+ if (gdb_CRASHDEBUG(2)) { +-+ fprintf_filtered(gdb_stdout, "current object files:\n"); +-+ ALL_OBJFILES(objfile) +-+ fprintf_filtered(gdb_stdout, " %s\n", objfile->name); +-+ } +-+} +-+ +-+/* +-+ * Walk through all minimal_symbols, patching their values with the +-+ * correct addresses. +-+ */ +-+static void +-+gdb_patch_symbol_values(struct gnu_request *req) +-+{ +-+ struct minimal_symbol *msymbol; +-+ struct objfile *objfile; +-+ +-+ req->name = PATCH_KERNEL_SYMBOLS_START; +-+ patch_kernel_symbol(req); +-+ +-+ ALL_MSYMBOLS (objfile, msymbol) +-+ { +-+ req->name = (char *)msymbol->ginfo.name; +-+ req->addr = (ulong)(&SYMBOL_VALUE_ADDRESS(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; +-+} +-+ +-+static void +-+gdb_get_symbol_type(struct gnu_request *req) +-+{ +-+ struct expression *expr; +-+ struct value *val; +-+ struct cleanup *old_chain = NULL; +-+ struct type *type; +-+ struct type *target_type; +-+ +-+ req->typecode = TYPE_CODE_UNDEF; +-+ +-+ expr = parse_expression (req->name); +-+ old_chain = make_cleanup (free_current_contents, &expr); +-+ val = evaluate_type (expr); +-+ +-+ type = value_type(val); +-+ +-+ req->type_name = (char *)TYPE_MAIN_TYPE(type)->name; +-+ req->typecode = TYPE_MAIN_TYPE(type)->code; +-+ req->length = type->length; +-+ 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); +-+ +-+ do_cleanups (old_chain); +-+} +-+ +-+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 minimal_symbol *msym; +-+ struct block *block; +-+ +-+ if ((gdb_merge_flags & KERNEL_SYMBOLS_PATCHED) && +-+ (msym = lookup_minimal_symbol(name, NULL, gdb_kernel_objfile))) { +-+ if (sym->aclass == LOC_BLOCK) { +-+ block = (struct block *)SYMBOL_BLOCK_VALUE(sym); +-+ BLOCK_START(block) = SYMBOL_VALUE_ADDRESS(msym); +-+ } else +-+ SYMBOL_VALUE_ADDRESS(sym) = SYMBOL_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.prettyprint_structs; +-+ if (strcmp(req->name, "prettyprint_arrays") == 0) +-+ req->addr = (ulong)&user_print_options.prettyprint_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 struct block * +-+gdb_get_crash_block(void) +-+{ +-+ if (crash_text_scope) +-+ return block_for_pc(crash_text_scope); +-+ else +-+ return NULL; +-+} +-+#endif +---- gdb-7.6/gdb/c-typeprint.c.orig +-+++ gdb-7.6/gdb/c-typeprint.c +-@@ -1097,7 +1097,8 @@ c_type_print_base (struct type *type, st +- fprintf_filtered (stream, "static "); +- c_print_type (TYPE_FIELD_TYPE (type, i), +- TYPE_FIELD_NAME (type, i), +-- stream, show - 1, level + 4, +-+ stream, strlen(TYPE_FIELD_NAME (type, i)) ? +-+ show - 1 : show, level + 4, +- &local_flags); +- if (!field_is_static (&TYPE_FIELD (type, i)) +- && TYPE_FIELD_PACKED (type, i)) +---- gdb-7.6/gdb/xml-syscall.c.orig +-+++ gdb-7.6/gdb/xml-syscall.c +-@@ -38,7 +38,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-7.6/gdb/exceptions.c.orig +-+++ gdb-7.6/gdb/exceptions.c +-@@ -218,6 +218,10 @@ exceptions_state_mc_action_iter_1 (void) +- +- /* Return EXCEPTION to the nearest containing catch_errors(). */ +- +-+#ifdef CRASH_MERGE +-+void (*error_hook) (void) ATTRIBUTE_NORETURN; +-+#endif +-+ +- void +- throw_exception (struct gdb_exception exception) +- { +-@@ -225,6 +229,13 @@ throw_exception (struct gdb_exception ex +- immediate_quit = 0; +- +- do_cleanups (all_cleanups ()); +-+#ifdef CRASH_MERGE +-+ if (error_hook) { +-+ fprintf_filtered(gdb_stderr, "%s\n", exception.message); +-+ (*error_hook)(); +-+ } else +-+ fprintf_filtered(gdb_stderr, "gdb called without error_hook: %s\n", exception.message); +-+#endif +- +- /* Jump to the containing catch_errors() call, communicating REASON +- to that call via setjmp's return value. Note that REASON can't +---- gdb-7.6/gdb/valprint.h.orig +-+++ gdb-7.6/gdb/valprint.h +-@@ -152,11 +152,17 @@ extern void print_function_pointer_addre +- struct gdbarch *gdbarch, +- CORE_ADDR address, +- struct ui_file *stream); +-- +-+#ifdef CRASH_MERGE +-+extern int valprint_read_string (CORE_ADDR addr, int len, int width, +-+ unsigned int fetchlimit, +-+ enum bfd_endian byte_order, gdb_byte **buffer, +-+ int *bytes_read); +-+#else +- extern int read_string (CORE_ADDR addr, int len, int width, +- unsigned int fetchlimit, +- enum bfd_endian byte_order, gdb_byte **buffer, +- int *bytes_read); +-+#endif +- +- extern void val_print_optimized_out (struct ui_file *stream); +- +---- gdb-7.6/gdb/target.c.orig +-+++ gdb-7.6/gdb/target.c +-@@ -1779,6 +1779,13 @@ target_xfer_partial (struct target_ops * +- int +- target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) +- { +-+#ifdef CRASH_MERGE +-+ extern int gdb_readmem_callback(unsigned long, void *, int, int); +-+ if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 0)) +-+ return 0; +-+ else +-+ return EIO; +-+#endif +- /* Dispatch to the topmost target, not the flattened current_target. +- Memory accesses check target->to_has_(all_)memory, and the +- flattened target doesn't inherit those. */ +-@@ -1814,6 +1821,13 @@ target_read_stack (CORE_ADDR memaddr, gd +- int +- target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) +- { +-+#ifdef CRASH_MERGE +-+ extern int gdb_readmem_callback(unsigned long, void *, int, int); +-+ if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 1)) +-+ return 0; +-+ else +-+ return EIO; +-+#endif +- /* Dispatch to the topmost target, not the flattened current_target. +- Memory accesses check target->to_has_(all_)memory, and the +- flattened target doesn't inherit those. */ +---- gdb-7.6/gdb/printcmd.c.orig +-+++ gdb-7.6/gdb/printcmd.c +-@@ -1001,11 +1001,62 @@ print_command_1 (char *exp, int voidprin +- } +- +- static void +-+print_command_2 (char *exp, int inspect, int voidprint) +-+{ +-+ struct expression *expr; +-+ struct cleanup *old_chain = 0; +-+ char format = 0; +-+ struct value *val; +-+ struct format_data fmt; +-+ int cleanup = 0; +-+ +-+ if (exp && *exp == '/') +-+ { +-+ exp++; +-+ fmt = decode_format (&exp, last_format, 0); +-+ validate_format (fmt, "print"); +-+ last_format = format = fmt.format; +-+ } +-+ else +-+ { +-+ fmt.count = 1; +-+ fmt.format = 0; +-+ fmt.size = 0; +-+ fmt.raw = 0; +-+ } +-+ +-+ if (exp && *exp) +-+ { +-+ expr = parse_expression (exp); +-+ old_chain = make_cleanup (free_current_contents, &expr); +-+ cleanup = 1; +-+ val = evaluate_expression (expr); +-+ } +-+ else +-+ val = access_value_history (0); +-+ +-+ printf_filtered ("%d %d %d %d %d %d\n", +-+ TYPE_CODE (check_typedef(value_type (val))), +-+ TYPE_UNSIGNED (check_typedef(value_type (val))), +-+ TYPE_LENGTH (check_typedef(value_type(val))), +-+ value_offset (val), value_bitpos (val), value_bitsize(val)); +-+ +-+ if (cleanup) +-+ do_cleanups (old_chain); +-+} +-+ +-+static void +- print_command (char *exp, int from_tty) +- { +- print_command_1 (exp, 1); +- } +- +-+static void +-+printm_command (char *exp, int from_tty) +-+{ +-+ print_command_2 (exp, 0, 1); +-+} +-+ +- /* Same as print, except it doesn't print void results. */ +- static void +- call_command (char *exp, int from_tty) +-@@ -2593,6 +2644,12 @@ EXP may be preceded with /FMT, where FMT +- but no count or size letter (see \"x\" command).")); +- set_cmd_completer (c, expression_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, +---- gdb-7.6/gdb/ui-file.c.orig +-+++ gdb-7.6/gdb/ui-file.c +-@@ -671,6 +671,17 @@ gdb_fopen (char *name, char *mode) +- return stdio_file_new (f, 1); +- } +- +-+#ifdef CRASH_MERGE +-+void +-+replace_ui_file_FILE(struct ui_file *file, FILE *fp) +-+{ +-+ struct stdio_file *stdio_file; +-+ +-+ stdio_file = (struct stdio_file *)ui_file_data(file); +-+ stdio_file->file = fp; +-+} +-+#endif +-+ +- /* ``struct ui_file'' implementation that maps onto two ui-file objects. */ +- +- static ui_file_write_ftype tee_file_write; +---- gdb-7.6/gdb/main.c.orig +-+++ gdb-7.6/gdb/main.c +-@@ -806,7 +806,7 @@ captured_main (void *data) +- { +- print_gdb_version (gdb_stdout); +- wrap_here (""); +-- printf_filtered ("\n"); +-+ printf_filtered ("\n\n"); +- exit (0); +- } +- +-@@ -853,6 +853,13 @@ captured_main (void *data) +- } +- } +- +-+#ifdef CRASH_MERGE +-+{ +-+ extern void update_gdb_hooks(void); +-+ 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 +-@@ -880,7 +887,11 @@ captured_main (void *data) +- processed; it sets global parameters, which are independent of +- what file you are debugging or what directory you are in. */ +- if (system_gdbinit && !inhibit_gdbinit) +-+#ifdef CRASH_MERGE +-+ catch_command_errors (source_script, system_gdbinit, -1, RETURN_MASK_ALL); +-+#else +- catch_command_errors (source_script, system_gdbinit, 0, RETURN_MASK_ALL); +-+#endif +- +- /* Read and execute $HOME/.gdbinit file, if it exists. This is done +- *before* all the command line arguments are processed; it sets +-@@ -888,7 +899,11 @@ captured_main (void *data) +- debugging or what directory you are in. */ +- +- if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit) +-+#ifdef CRASH_MERGE +-+ catch_command_errors (source_script, home_gdbinit, -1, RETURN_MASK_ALL); +-+#else +- catch_command_errors (source_script, home_gdbinit, 0, RETURN_MASK_ALL); +-+#endif +- +- /* Process '-ix' and '-iex' options early. */ +- for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++) +-@@ -929,8 +944,12 @@ captured_main (void *data) +- catch_command_errors returns non-zero on success! */ +- if (catch_command_errors (exec_file_attach, execarg, +- !batch_flag, RETURN_MASK_ALL)) +-+#ifdef CRASH_MERGE +-+ catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL); +-+#else +- catch_command_errors (symbol_file_add_main, symarg, +- !batch_flag, RETURN_MASK_ALL); +-+#endif +- } +- else +- { +-@@ -992,8 +1011,12 @@ captured_main (void *data) +- { +- auto_load_local_gdbinit_loaded = 1; +- +-+#ifdef CRASH_MERGE +-+ catch_command_errors (source_script, local_gdbinit, -1, RETURN_MASK_ALL); +-+#else +- catch_command_errors (source_script, local_gdbinit, 0, +- RETURN_MASK_ALL); +-+#endif +- } +- } +- +-@@ -1039,6 +1062,12 @@ captured_main (void *data) +- while (1) +- { +- catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); +-+#ifdef CRASH_MERGE +-+ { +-+ int console(char *, ...); +-+ console("\n"); +-+ } +-+#endif +- } +- /* No exit -- exit is through quit_command. */ +- } +-@@ -1053,6 +1082,23 @@ gdb_main (struct captured_main_args *arg +- 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.use_windows = 0; +-+ 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 +---- gdb-7.6/gdb/valprint.c.orig +-+++ gdb-7.6/gdb/valprint.c +-@@ -1768,8 +1768,13 @@ partial_memory_read (CORE_ADDR memaddr, +- this function instead? */ +- +- int +-+#ifdef CRASH_MERGE +-+valprint_read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, +-+ enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read) +-+#else +- read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, +- enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read) +-+#endif +- { +- int found_nul; /* Non-zero if we found the nul char. */ +- int errcode; /* Errno returned from bad reads. */ +-@@ -2472,8 +2477,13 @@ val_print_string (struct type *elttype, +- fetchlimit = (len == -1 ? options->print_max : min (len, +- options->print_max)); +- +-+#ifdef CRASH_MERGE +-+ errcode = valprint_read_string (addr, len, width, fetchlimit, byte_order, +-+ &buffer, &bytes_read); +-+#else +- errcode = read_string (addr, len, width, fetchlimit, byte_order, +- &buffer, &bytes_read); +-+#endif +- old_chain = make_cleanup (xfree, buffer); +- +- addr += bytes_read; +---- gdb-7.6/gdb/Makefile.in.orig +-+++ gdb-7.6/gdb/Makefile.in +-@@ -422,7 +422,7 @@ CONFIG_UNINSTALL = @CONFIG_UNINSTALL@ +- # 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)/common -I$(srcdir)/config \ +- -DLOCALEDIR="\"$(localedir)\"" $(DEFS) +- +-@@ -934,7 +934,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $ +- +- TSOBS = inflow.o +- +--SUBDIRS = doc @subdirs@ data-directory $(GNULIB_BUILDDIR) +-+SUBDIRS = build_no_subdirs +- CLEANDIRS = $(SUBDIRS) +- +- # List of subdirectories in the build tree that must exist. +-@@ -969,8 +969,8 @@ generated_files = config.h observer.h ob +- $(COMPILE) $< +- $(POSTCOMPILE) +- +--all: gdb$(EXEEXT) $(CONFIG_ALL) +-- @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do +-+all: gdb$(EXEEXT) +-+ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do +- +- installcheck: +- +-@@ -1172,15 +1172,16 @@ 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) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS) +-- rm -f gdb$(EXEEXT) +-+ @rm -f gdb$(EXEEXT) +-+ @(cd ../..; make --no-print-directory GDB_FLAGS=-DGDB_7_6 library) +- $(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) +- +- # Convenience rule to handle recursion. +- $(LIBGNU) $(GNULIB_H): all-lib +- all-lib: $(GNULIB_BUILDDIR)/Makefile +-- @$(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=$(GNULIB_BUILDDIR) subdir_do +-+ @$(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=$(GNULIB_BUILDDIR) subdir_do -s +- .PHONY: all-lib +- +- # Convenience rule to handle recursion. +-@@ -1389,12 +1390,12 @@ $(srcdir)/copying.c: @MAINTAINER_MODE_TR +- mv $(srcdir)/copying.tmp $(srcdir)/copying.c +- +- version.c: Makefile version.in +-- rm -f version.c-tmp version.c +-- echo '#include "version.h"' >> version.c-tmp +-- echo 'const char version[] = "'"`sed q ${srcdir}/version.in`"'";' >> version.c-tmp +-- echo 'const char host_name[] = "$(host_alias)";' >> version.c-tmp +-- echo 'const char target_name[] = "$(target_alias)";' >> version.c-tmp +-- mv version.c-tmp version.c +-+ @rm -f version.c-tmp version.c +-+ @echo '#include "version.h"' >> version.c-tmp +-+ @echo 'const char version[] = "'"`sed q ${srcdir}/version.in`"'";' >> version.c-tmp +-+ @echo 'const char host_name[] = "$(host_alias)";' >> version.c-tmp +-+ @echo 'const char target_name[] = "$(target_alias)";' >> version.c-tmp +-+ @mv version.c-tmp version.c +- +- observer.h: observer.sh doc/observer.texi +- ${srcdir}/observer.sh h ${srcdir}/doc/observer.texi observer.h +---- gdb-7.6/gdb/c-lang.c.orig +-+++ gdb-7.6/gdb/c-lang.c +-@@ -307,7 +307,11 @@ c_get_string (struct value *value, gdb_b +- { +- CORE_ADDR addr = value_as_address (value); +- +-+#ifdef CRASH_MERGE +-+ err = valprint_read_string (addr, *length, width, fetchlimit, +-+#else +- err = read_string (addr, *length, width, fetchlimit, +-+#endif +- byte_order, buffer, length); +- if (err) +- { +---- gdb-7.6/readline/rltypedefs.h.orig +-+++ gdb-7.6/readline/rltypedefs.h +-@@ -31,10 +31,10 @@ extern "C" { +- #if !defined (_FUNCTION_DEF) +- # define _FUNCTION_DEF +- +--typedef int Function (); +--typedef void VFunction (); +--typedef char *CPFunction (); +--typedef char **CPPFunction (); +-+typedef int Function (void); +-+typedef void VFunction (void); +-+typedef char *CPFunction (void); +-+typedef char **CPPFunction (void); +- +- #endif /* _FUNCTION_DEF */ +- +---- gdb-7.6/readline/readline.h.orig +-+++ gdb-7.6/readline/readline.h +-@@ -378,7 +378,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))); +- #else +--extern int rl_message (); +-+extern int rl_message (void); +- #endif +- +- extern int rl_show_char PARAMS((int)); +---- gdb-7.6/readline/misc.c.orig +-+++ gdb-7.6/readline/misc.c +-@@ -405,7 +405,7 @@ _rl_history_set_point () +- +- #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 */ +- +- if (rl_editing_mode == emacs_mode) +---- gdb-7.6/Makefile.in.orig +-+++ gdb-7.6/Makefile.in +-@@ -342,6 +342,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@ +-@@ -407,6 +410,9 @@ GNATBIND = @GNATBIND@ +- GNATMAKE = @GNATMAKE@ +- +- CFLAGS = @CFLAGS@ +-+ifeq (${CRASH_TARGET}, PPC64) +-+CFLAGS += -m64 -fPIC +-+endif +- LDFLAGS = @LDFLAGS@ +- LIBCFLAGS = $(CFLAGS) +- CXXFLAGS = @CXXFLAGS@ +---- gdb-7.6/gdb/defs.h.orig +-+++ gdb-7.6/gdb/defs.h +-@@ -802,4 +802,8 @@ enum block_enum +- +- #include "utils.h" +- +-+#ifdef CRASH_MERGE +-+extern int gdb_main_entry(int, char **); +-+extern void replace_ui_file_FILE(struct ui_file *, FILE *); +-+#endif +- #endif /* #ifndef DEFS_H */ +---- gdb-7.6/bfd/elflink.c.orig +-+++ gdb-7.6/bfd/elflink.c +-@@ -4730,7 +4730,7 @@ error_free_dyn: +- struct elf_link_hash_entry *hlook; +- asection *slook; +- bfd_vma vlook; +-- size_t i, j, idx; +-+ size_t i, j, idx = 0; +- +- hlook = weaks; +- weaks = hlook->u.weakdef; +---- gdb-7.6/gdb/s390-nat.c.orig +-+++ gdb-7.6/gdb/s390-nat.c +-@@ -37,6 +37,8 @@ +- #include +- #include +- +-+#include +-+ +- #ifndef HWCAP_S390_HIGH_GPRS +- #define HWCAP_S390_HIGH_GPRS 512 +- #endif +---- gdb-7.6/gdb/printcmd.c.orig +-+++ gdb-7.6/gdb/printcmd.c +-@@ -573,11 +573,21 @@ print_address_symbolic (struct gdbarch * +- int unmapped = 0; +- int offset = 0; +- int line = 0; +-+#ifdef CRASH_MERGE +-+ extern int gdb_print_callback(unsigned long); +-+#endif +- +- /* Throw away both name and filename. */ +- struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name); +- make_cleanup (free_current_contents, &filename); +- +-+#ifdef CRASH_MERGE +-+ if (!gdb_print_callback(addr)) { +-+ do_cleanups (cleanup_chain); +-+ return 0; +-+ } +-+#endif +-+ +- if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset, +- &filename, &line, &unmapped)) +- { +---- gdb-7.6/bfd/bfd-in.h.orig +-+++ gdb-7.6/bfd/bfd-in.h +-@@ -294,9 +294,6 @@ typedef struct bfd_section *sec_ptr; +- +- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) +- +--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) +- /* Find the address one past the end of SEC. */ +- #define bfd_get_section_limit(bfd, sec) \ +- (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ +-@@ -519,7 +516,6 @@ extern void warn_deprecated (const char +- +- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) +- +--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) +- +- extern bfd_boolean bfd_cache_close +- (bfd *abfd); +---- gdb-7.6/bfd/bfd-in2.h.orig +-+++ gdb-7.6/bfd/bfd-in2.h +-@@ -301,9 +301,6 @@ typedef struct bfd_section *sec_ptr; +- +- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) +- +--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) +- /* Find the address one past the end of SEC. */ +- #define bfd_get_section_limit(bfd, sec) \ +- (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ +-@@ -526,7 +523,6 @@ extern void warn_deprecated (const char +- +- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) +- +--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) +- +- extern bfd_boolean bfd_cache_close +- (bfd *abfd); +-@@ -1572,6 +1568,32 @@ struct relax_table { +- int size; +- }; +- +-+/* Note: the following are provided as inline functions rather than macros +-+ because not all callers use the return value. A macro implementation +-+ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some +-+ compilers will complain about comma expressions that have no effect. */ +-+static inline bfd_boolean +-+bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val) +-+{ +-+ ptr->userdata = val; +-+ return TRUE; +-+} +-+ +-+static inline bfd_boolean +-+bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val) +-+{ +-+ ptr->vma = ptr->lma = val; +-+ ptr->user_set_vma = TRUE; +-+ return TRUE; +-+} +-+ +-+static inline bfd_boolean +-+bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val) +-+{ +-+ ptr->alignment_power = val; +-+ return TRUE; +-+} +-+ +- /* These sections are global, and are managed by BFD. The application +- and target back end are not permitted to change the values in +- these sections. */ +-@@ -6095,6 +6117,14 @@ struct bfd +- unsigned int selective_search : 1; +- }; +- +-+/* See note beside bfd_set_section_userdata. */ +-+static inline bfd_boolean +-+bfd_set_cacheable (bfd * abfd, bfd_boolean val) +-+{ +-+ abfd->cacheable = val; +-+ return TRUE; +-+} +-+ +- typedef enum bfd_error +- { +- bfd_error_no_error = 0, +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5405,7 +5405,7 @@ dump_enum(struct type *type, struct gnu_ +- { +- register int i; +- int len; +-- int lastval; +-+ long long lastval; +- +- len = TYPE_NFIELDS (type); +- lastval = 0; +-@@ -5418,12 +5418,12 @@ dump_enum(struct type *type, struct gnu_ +- for (i = 0; i < len; i++) { +- fprintf_filtered(gdb_stdout, " %s", +- TYPE_FIELD_NAME (type, i)); +-- if (lastval != TYPE_FIELD_BITPOS (type, i)) { +-- fprintf_filtered (gdb_stdout, " = %d", +-- TYPE_FIELD_BITPOS (type, i)); +-- lastval = TYPE_FIELD_BITPOS (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, " = %d", lastval); +-+ fprintf_filtered(gdb_stdout, " = %s", plongest(lastval)); +- fprintf_filtered(gdb_stdout, "\n"); +- lastval++; +- } +---- gdb-7.6/gdb/aarch64-linux-nat.c.orig +-+++ gdb-7.6/gdb/aarch64-linux-nat.c +-@@ -32,6 +32,7 @@ +- #include "elf/common.h" +- +- #include +-+#include +- #include +- +- #include "gregset.h" +---- gdb-7.6/sim/igen/Makefile.in.orig +-+++ gdb-7.6/sim/igen/Makefile.in +-@@ -117,7 +117,7 @@ IGEN_OBJS=\ +- gen.o +- +- igen: igen.o $(IGEN_OBJS) +-- $(CC_FOR_BUILD) $(BUILD_LDFLAGS) -o igen igen.o $(IGEN_OBJS) $(LIBIBERTY_LIB) +-+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o igen igen.o $(IGEN_OBJS) $(LIBIBERTY_LIB) +- +- igen.o: igen.c misc.h filter_host.h lf.h table.h ld-decode.h ld-cache.h ld-insn.h filter.h gen-model.h gen-itable.h gen-icache.h gen-idecode.h gen-engine.h gen-semantics.h gen-support.h gen.h igen.h +- $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/igen.c +---- gdb-7.6/sim/mips/cp1.c.orig +-+++ gdb-7.6/sim/mips/cp1.c +-@@ -1359,7 +1359,7 @@ fp_rsqrt2(sim_cpu *cpu, +- /* Conversion operations. */ +- +- uword64 +--convert (sim_cpu *cpu, +-+sim_mips_convert (sim_cpu *cpu, +- address_word cia, +- int rm, +- uword64 op, +---- gdb-7.6/sim/mips/sim-main.h.orig +-+++ gdb-7.6/sim/mips/sim-main.h +-@@ -770,8 +770,8 @@ unsigned64 fp_nmadd (SIM_STATE, unsigned64 op1, unsigned64 op2, +- unsigned64 fp_nmsub (SIM_STATE, unsigned64 op1, unsigned64 op2, +- unsigned64 op3, FP_formats fmt); +- #define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt) +--unsigned64 convert (SIM_STATE, int rm, unsigned64 op, FP_formats from, FP_formats to); +--#define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to) +-+unsigned64 sim_mips_convert (SIM_STATE, int rm, unsigned64 op, FP_formats from, FP_formats to); +-+#define Convert(rm,op,from,to) sim_mips_convert (SIM_ARGS, rm, op, from, to) +- unsigned64 convert_ps (SIM_STATE, int rm, unsigned64 op, FP_formats from, +- FP_formats to); +- #define ConvertPS(rm,op,from,to) convert_ps (SIM_ARGS, rm, op, from, to) +- +---- gdb-7.6/readline/util.c +-+++ gdb-7.6/readline/util.c +-@@ -493,10 +493,13 @@ _rl_trace (va_alist) +- +- if (_rl_tracefp == 0) +- _rl_tropen (); +-+ if (!_rl_tracefp) +-+ goto out; +- vfprintf (_rl_tracefp, format, args); +- fprintf (_rl_tracefp, "\n"); +- fflush (_rl_tracefp); +- +-+out: +- va_end (args); +- } +- +-@@ -509,16 +512,17 @@ _rl_tropen () +- fclose (_rl_tracefp); +- sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid()); +- unlink(fnbuf); +-- _rl_tracefp = fopen (fnbuf, "w+"); +-+ _rl_tracefp = fopen (fnbuf, "w+xe"); +- return _rl_tracefp != 0; +- } +- +- int +- _rl_trclose () +- { +-- int r; +-+ int r = 0; +- +-- r = fclose (_rl_tracefp); +-+ if (_rl_tracefp) +-+ r = fclose (_rl_tracefp); +- _rl_tracefp = 0; +- return r; +- } +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5447,9 +5447,9 @@ eval_enum(struct type *type, struct gnu_ +- lastval = 0; +- +- for (i = 0; i < len; i++) { +-- if (lastval != TYPE_FIELD_BITPOS (type, i)) { +-- lastval = TYPE_FIELD_BITPOS (type, 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; +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5236,6 +5236,12 @@ gdb_command_funnel(struct gnu_request *r +- gdb_set_crash_block(req); +- break; +- +-+ case GNU_GET_FUNCTION_RANGE: +-+ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0); +-+ if (!find_pc_partial_function(req->pc, NULL, &req->addr, &req->addr2)) +-+ req->flags |= GNU_COMMAND_FAILED; +-+ break; +-+ +- default: +- req->flags |= GNU_COMMAND_FAILED; +- break; +---- gdb-7.6/opcodes/i386-dis.c.orig +-+++ gdb-7.6/opcodes/i386-dis.c +-@@ -11300,6 +11300,29 @@ get_sib (disassemble_info *info) +- } +- } +- +-+static char * +-+check_for_extensions(struct dis_private *priv) +-+{ +-+ unsigned char ModRM; +-+ +-+ if ((priv->the_buffer[0] == 0x66) && +-+ (priv->the_buffer[1] == 0x0f) && +-+ (priv->the_buffer[2] == 0xae)) { +-+ ModRM = priv->the_buffer[3]; +-+ if (ModRM == 0xf8) +-+ return "pcommit"; +-+ +-+ switch ((ModRM >> 3)) +-+ { +-+ case 0x6: +-+ return "clwb"; +-+ case 0x7: +-+ return "clflushopt"; +-+ } +-+ } +-+ return NULL; +-+} +-+ +- static int +- print_insn (bfd_vma pc, disassemble_info *info) +- { +-@@ -11312,6 +11335,7 @@ print_insn (bfd_vma pc, disassemble_info +- struct dis_private priv; +- int prefix_length; +- int default_prefixes; +-+ char *extension; +- +- priv.orig_sizeflag = AFLAG | DFLAG; +- if ((info->mach & bfd_mach_i386_i386) != 0) +-@@ -11575,6 +11599,7 @@ print_insn (bfd_vma pc, disassemble_info +- need_vex = 0; +- need_vex_reg = 0; +- vex_w_done = 0; +-+ extension = NULL; +- +- if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE) +- { +-@@ -11610,9 +11635,14 @@ print_insn (bfd_vma pc, disassemble_info +- name = prefix_name (all_prefixes[i], priv.orig_sizeflag); +- if (name == NULL) +- name = INTERNAL_DISASSEMBLER_ERROR; +-- (*info->fprintf_func) (info->stream, "%s", name); +-- return 1; +-- } +-+ if ((extension = check_for_extensions(&priv))) { +-+ strcpy(obuf, extension); +-+ obufp = &obuf[strlen(obuf)]; +-+ } else { +-+ (*info->fprintf_func) (info->stream, "%s", name); +-+ return 1; +-+ } +-+ } +- } +- +- /* Check if the REX prefix is used. */ +-@@ -11637,7 +11667,7 @@ print_insn (bfd_vma pc, disassemble_info +- all_prefixes[last_data_prefix] = 0; +- +- prefix_length = 0; +-- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++) +-+ for (i = 0; !extension && i < (int) ARRAY_SIZE (all_prefixes); i++) +- if (all_prefixes[i]) +- { +- const char *name; +-@@ -11655,7 +11685,8 @@ print_insn (bfd_vma pc, disassemble_info +- return MAX_CODE_LENGTH; +- } +- +-- obufp = mnemonicendp; +-+ if (!extension) +-+ obufp = mnemonicendp; +- for (i = strlen (obuf) + prefix_length; i < 6; i++) +- oappend (" "); +- oappend (" "); +---- gdb-7.6/bfd/coff-i386.c.orig +-+++ gdb-7.6/bfd/coff-i386.c +-@@ -141,7 +141,7 @@ coff_i386_reloc (bfd *abfd, +- #define DOIT(x) \ +- x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) +- +-- if (diff != 0) +-+ if (diff != 0) +- { +- reloc_howto_type *howto = reloc_entry->howto; +- unsigned char *addr = (unsigned char *) data + reloc_entry->address; +---- gdb-7.6/bfd/coff-x86_64.c.orig +-+++ gdb-7.6/bfd/coff-x86_64.c +-@@ -139,7 +139,7 @@ coff_amd64_reloc (bfd *abfd, +- #define DOIT(x) \ +- x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) +- +-- if (diff != 0) +-+ if (diff != 0) +- { +- reloc_howto_type *howto = reloc_entry->howto; +- unsigned char *addr = (unsigned char *) data + reloc_entry->address; +---- gdb-7.6/opcodes/arm-dis.c.orig +-+++ gdb-7.6/opcodes/arm-dis.c +-@@ -2103,7 +2103,7 @@ print_insn_coprocessor (bfd_vma pc, +- +- /* Is ``imm'' a negative number? */ +- if (imm & 0x40) +-- imm |= (-1 << 7); +-+ imm -= 0x80; +- +- func (stream, "%d", imm); +- } +-diff -up gdb-7.6/bfd/elf64-ppc.c.orig gdb-7.6/bfd/elf64-ppc.c +---- gdb-7.6/bfd/elf64-ppc.c.orig 2016-02-02 11:04:25.436527347 -0500 +-+++ gdb-7.6/bfd/elf64-ppc.c 2016-02-02 11:11:51.926468454 -0500 +-@@ -11743,7 +11743,7 @@ ppc64_elf_size_stubs (struct bfd_link_in +- stub_sec = stub_sec->next) +- if ((stub_sec->flags & SEC_LINKER_CREATED) == 0) +- stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1) +-- & (-1 << htab->plt_stub_align)); +-+ & -(1 << htab->plt_stub_align)); +- +- for (stub_sec = htab->stub_bfd->sections; +- stub_sec != NULL; +-@@ -12093,7 +12093,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_ +- stub_sec = stub_sec->next) +- if ((stub_sec->flags & SEC_LINKER_CREATED) == 0) +- stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1) +-- & (-1 << htab->plt_stub_align)); +-+ & -(1 << htab->plt_stub_align)); +- +- for (stub_sec = htab->stub_bfd->sections; +- stub_sec != NULL; +---- gdb-7.6/include/opcode/ppc.h.orig +-+++ gdb-7.6/include/opcode/ppc.h +-@@ -278,7 +278,7 @@ extern const unsigned int num_powerpc_op +- /* Use with the shift field of a struct powerpc_operand to indicate +- that BITM and SHIFT cannot be used to determine where the operand +- goes in the insn. */ +--#define PPC_OPSHIFT_INV (-1 << 31) +-+#define PPC_OPSHIFT_INV (-1U << 31) +- +- /* Values defined for the flags field of a struct powerpc_operand. */ +- +---- gdb-7.6/opcodes/mips-dis.c.orig +-+++ gdb-7.6/opcodes/mips-dis.c +-@@ -245,18 +245,6 @@ static const char * const mips_cp0_names +- "c0_taglo", "c0_taghi", "c0_errorepc", "$31" +- }; +- +--static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] = +--{ +-- { 24, 2, "c0_iab" }, +-- { 24, 3, "c0_iabm" }, +-- { 24, 4, "c0_dab" }, +-- { 24, 5, "c0_dabm" }, +-- { 24, 6, "c0_dvb" }, +-- { 24, 7, "c0_dvbm" }, +-- { 25, 1, "c0_perfcnt,1" }, +-- { 25, 2, "c0_perfcnt,2" } +--}; +-- +- static const char * const mips_cp0_names_mips3264[32] = +- { +- "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", +---- gdb-7.6/gdb/ada-lang.c.orig +-+++ gdb-7.6/gdb/ada-lang.c +-@@ -10503,7 +10503,7 @@ ada_evaluate_subexp (struct type *expect +- } +- else +- arg1 = ada_value_struct_elt (arg1, &exp->elts[pc + 2].string, 0); +-- arg1 = unwrap_value (arg1); +-+ arg1 = unwrap_value (arg1); +- return ada_to_fixed_value (arg1); +- +- case OP_TYPE: +---- gdb-7.6/gdb/linux-record.c.orig +-+++ gdb-7.6/gdb/linux-record.c +-@@ -112,7 +112,7 @@ record_linux_sockaddr (struct regcache * +- "memory at addr = 0x%s len = %d.\n", +- phex_nz (len, tdep->size_pointer), +- tdep->size_int); +-- return -1; +-+ return -1; +- } +- addrlen = (int) extract_unsigned_integer (a, tdep->size_int, byte_order); +- if (addrlen <= 0 || addrlen > tdep->size_sockaddr) +-@@ -150,7 +150,7 @@ record_linux_msghdr (struct regcache *re +- "len = %d.\n", +- phex_nz (addr, tdep->size_pointer), +- tdep->size_msghdr); +-- return -1; +-+ return -1; +- } +- +- /* msg_name msg_namelen */ +-@@ -186,7 +186,7 @@ record_linux_msghdr (struct regcache *re +- "len = %d.\n", +- phex_nz (addr,tdep->size_pointer), +- tdep->size_iovec); +-- return -1; +-+ return -1; +- } +- tmpaddr = (CORE_ADDR) extract_unsigned_integer (iov, +- tdep->size_pointer, +-@@ -948,7 +948,7 @@ Do you want to stop the program?"), +- "memory at addr = 0x%s len = %d.\n", +- OUTPUT_REG (tmpulongest, tdep->arg2), +- tdep->size_ulong); +-- return -1; +-+ return -1; +- } +- tmpulongest = extract_unsigned_integer (a, tdep->size_ulong, +- byte_order); +---- gdb-7.6/gdb/inflow.c.orig +-+++ gdb-7.6/gdb/inflow.c +-@@ -391,7 +391,7 @@ terminal_ours_1 (int output_only) +- if (tinfo->run_terminal != NULL || gdb_has_a_terminal () == 0) +- return; +- +-- { +-+ { +- #ifdef SIGTTOU +- /* Ignore this signal since it will happen when we try to set the +- pgrp. */ +---- gdb-7.6/gdb/printcmd.c.orig +-+++ gdb-7.6/gdb/printcmd.c +-@@ -1045,7 +1045,7 @@ print_command_2 (char *exp, int inspect, +- else +- val = access_value_history (0); +- +-- printf_filtered ("%d %d %d %d %d %d\n", +-+ printf_filtered ("%d %d %d %d %d %d\n", +- TYPE_CODE (check_typedef(value_type (val))), +- TYPE_UNSIGNED (check_typedef(value_type (val))), +- TYPE_LENGTH (check_typedef(value_type(val))), +---- gdb-7.6/gdb/c-typeprint.c.orig +-+++ gdb-7.6/gdb/c-typeprint.c +-@@ -1293,7 +1293,7 @@ c_type_print_base (struct type *type, st +- if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0) +- fprintf_filtered (stream, "\n"); +- +-- for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++) +-+ for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++) +- { +- struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i); +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5139,6 +5139,8 @@ static void get_user_print_option_addres +- extern int get_frame_offset(CORE_ADDR); +- static void gdb_set_crash_block(struct gnu_request *); +- void gdb_command_funnel(struct gnu_request *); +-+static long lookup_struct_contents(struct gnu_request *); +-+static void iterate_datatypes(struct gnu_request *); +- +- struct objfile *gdb_kernel_objfile = { 0 }; +- +-@@ -5242,6 +5244,14 @@ gdb_command_funnel(struct gnu_request *r +- req->flags |= GNU_COMMAND_FAILED; +- break; +- +-+ case GNU_LOOKUP_STRUCT_CONTENTS: +-+ req->value = lookup_struct_contents(req); +-+ break; +-+ +-+ case GNU_GET_NEXT_DATATYPE: +-+ iterate_datatypes(req); +-+ break; +-+ +- default: +- req->flags |= GNU_COMMAND_FAILED; +- break; +-@@ -5779,4 +5789,135 @@ gdb_get_crash_block(void) +- 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; +-+ +-+ // 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; +-+ } +-+ +-+ if (m->code == TYPE_CODE_PTR && m->target_type) +-+ m = m->target_type->main_type; +-+ if (m->name) +-+ n = m->name; +-+ else if (m->tag_name) +-+ n = m->tag_name; +-+ else +-+ continue; +-+ +-+ if (strstr(n, type_name)) +-+ return 1; +-+ } +-+ +-+ return 0; +-+} +-+ +-+static void +-+iterate_datatypes (struct gnu_request *req) +-+{ +-+ static struct block_iterator bi; // Keeping this static will simplify code +-+ struct block *b; +-+ int do_return = 0; +-+ struct global_iterator *gi = &req->global_iterator; +-+ +-+ if (gi->finished) +-+ return; +-+ +-+ if (gi->obj == NULL) +-+ { +-+ gi->obj = current_program_space->objfiles; +-+ gi->symtab = NULL; +-+ do_return = 1; // The initial case - we don't need to make next step. +-+ } +-+ +-+ for (; gi->obj; gi->obj = gi->obj->next, gi->symtab = NULL) +-+ { +-+ if (gi->symtab == NULL) +-+ { +-+ // Symtab `symtab` is nullified for every objfile +-+ if (gi->obj->sf) +-+ gi->obj->sf->qf->expand_all_symtabs(gi->obj); +-+ gi->symtab = gi->obj->symtabs; +-+ gi->sym = NULL; +-+ } +-+ +-+ for (; gi->symtab; gi->symtab = gi->symtab->next, gi->block_index = -1) +-+ { +-+ if (!gi->symtab->primary) +-+ continue; +-+ +-+ if (gi->block_index == -1) +-+ { +-+ gi->block_index = GLOBAL_BLOCK; +-+ gi->sym = NULL; +-+ } +-+ for (; gi->block_index <= STATIC_BLOCK; gi->block_index++, gi->sym = NULL) +-+ { +-+ if (!gi->sym) +-+ { +-+ b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(gi->symtab), gi->block_index); +-+ gi->sym = block_iterator_first(b, &bi); +-+ } +-+ for (; gi->sym; gi->sym = block_iterator_next(&bi)) +-+ { +-+ QUIT; +-+ +-+ if (SYMBOL_CLASS (gi->sym) != LOC_TYPEDEF) +-+ continue; +-+ +-+ // Iteration 1 (do_return == 0): initialization +-+ // Iteration 2 (do_return == 1): iterate symbol +-+ if (do_return++ == 0) +-+ continue; +-+ +-+ // Yield the current symbol and its size +-+ req->addr = (ulong)(gi->sym->type->main_type); +-+ req->name = (char *)(gi->sym->ginfo.name); +-+ req->length = gi->sym->type->length; +-+ +-+ return; +-+ } +-+ } +-+ } +-+ } +-+ gi->finished = 1; +-+} +- #endif +---- gdb-7.6/bfd/elf64-s390.c.orig +-+++ gdb-7.6/bfd/elf64-s390.c +-@@ -323,10 +323,10 @@ elf_s390_reloc_name_lookup (bfd *abfd AT +- && strcasecmp (elf_howto_table[i].name, r_name) == 0) +- return &elf_howto_table[i]; +- +-- if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0) +-- return &elf64_s390_vtinherit_howto; +-- if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0) +-- return &elf64_s390_vtentry_howto; +-+ if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0) +-+ return &elf64_s390_vtinherit_howto; +-+ if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0) +-+ return &elf64_s390_vtentry_howto; +- +- return NULL; +- } +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5122,7 +5122,7 @@ When enabled, debugging messages are pri +- #define GDB_COMMON +- #include "../../defs.h" +- +--static void get_member_data(struct gnu_request *, struct type *); +-+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 *); +-@@ -5327,7 +5327,7 @@ gdb_get_datatype(struct gnu_request *req +- req->typecode = TYPE_CODE(sym->type); +- req->length = TYPE_LENGTH(sym->type); +- if (req->member) +-- get_member_data(req, sym->type); +-+ get_member_data(req, sym->type, 0, 1); +- +- if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) { +- if (req->flags & GNU_PRINT_ENUMERATORS) +-@@ -5397,7 +5397,7 @@ gdb_get_datatype(struct gnu_request *req +- } +- +- if (req->member) +-- get_member_data(req, type); +-+ get_member_data(req, type, 0, 1); +- +- break; +- +-@@ -5480,7 +5480,7 @@ eval_enum(struct type *type, struct gnu_ +- * member field, and when found, return its relevant data. +- */ +- static void +--get_member_data(struct gnu_request *req, struct type *type) +-+get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first) +- { +- register short i; +- struct field *nextfield; +-@@ -5492,7 +5492,7 @@ get_member_data(struct gnu_request *req, +- nfields = TYPE_MAIN_TYPE(type)->nfields; +- nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields; +- +-- if (nfields == 0) { +-+ if (nfields == 0 && is_first /* The first call */) { +- struct type *newtype; +- newtype = lookup_transparent_type(req->name); +- if (newtype) { +-@@ -5505,13 +5505,18 @@ get_member_data(struct gnu_request *req, +- +- for (i = 0; i < nfields; i++) { +- if (STREQ(req->member, nextfield->name)) { +-- req->member_offset = nextfield->loc.bitpos; +-+ req->member_offset = offset + nextfield->loc.bitpos; +- req->member_length = TYPE_LENGTH(nextfield->type); +- req->member_typecode = TYPE_CODE(nextfield->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++; +- } +-@@ -5706,7 +5711,7 @@ gdb_get_symbol_type(struct gnu_request * +- } +- +- if (req->member) +-- get_member_data(req, type); +-+ get_member_data(req, type, 0, 1); +- +- do_cleanups (old_chain); +- } +-diff -up gdb-7.6/bfd/configure.orig gdb-7.6/bfd/configure +---- gdb-7.6/bfd/configure.orig 2017-02-17 17:19:51.654898822 -0500 +-+++ gdb-7.6/bfd/configure 2017-02-17 17:19:57.922038757 -0500 +-@@ -12193,7 +12193,7 @@ fi +- +- NO_WERROR= +- if test "${ERROR_ON_WARNING}" = yes ; then +-- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror" +-+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS" +- NO_WERROR="-Wno-error" +- fi +- +-diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure +---- gdb-7.6/opcodes/configure.orig 2017-02-17 17:19:08.849943016 -0500 +-+++ gdb-7.6/opcodes/configure 2017-02-17 17:19:23.256264699 -0500 +-@@ -11539,7 +11539,7 @@ fi +- +- NO_WERROR= +- if test "${ERROR_ON_WARNING}" = yes ; then +-- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror" +-+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS" +- NO_WERROR="-Wno-error" +- fi +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5266,6 +5266,7 @@ gdb_get_line_number(struct gnu_request * +- { +- struct symtab_and_line sal; +- struct symbol *sym; +-+ struct objfile *objfile; +- CORE_ADDR pc; +- +- #define LASTCHAR(s) (s[strlen(s)-1]) +-@@ -5281,8 +5282,22 @@ gdb_get_line_number(struct gnu_request * +- sal = find_pc_line(pc, 0); +- +- if (!sal.symtab) { +-- req->buf[0] = '\0'; +-- return; +-+ /* +-+ * 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 && sal.symtab->dirname) { +-@@ -5557,7 +5572,6 @@ struct load_module *gdb_current_load_mod +- static void +- gdb_add_symbol_file(struct gnu_request *req) +- { +-- register struct objfile *loaded_objfile = NULL; +- register struct objfile *objfile; +- register struct minimal_symbol *m; +- struct load_module *lm; +-@@ -5576,6 +5590,7 @@ gdb_add_symbol_file(struct gnu_request * +- +- 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++) { +-@@ -5623,12 +5638,15 @@ gdb_add_symbol_file(struct gnu_request * +- +- ALL_OBJFILES(objfile) { +- if (same_file(objfile->name, lm->mod_namelist)) { +-- loaded_objfile = objfile; +-+ if (objfile->separate_debug_objfile) +-+ lm->loaded_objfile = objfile->separate_debug_objfile; +-+ else +-+ lm->loaded_objfile = objfile; +- break; +- } +- } +- +-- if (!loaded_objfile) +-+ if (!lm->loaded_objfile) +- req->flags |= GNU_COMMAND_FAILED; +- } +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5500,7 +5500,7 @@ get_member_data(struct gnu_request *req, +- register short i; +- struct field *nextfield; +- short nfields; +-- struct type *typedef_type; +-+ struct type *typedef_type, *target_type; +- +- req->member_offset = -1; +- +-@@ -5523,6 +5523,13 @@ get_member_data(struct gnu_request *req, +- 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); +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -5727,6 +5727,7 @@ gdb_get_symbol_type(struct gnu_request * +- 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) { +---- gdb-7.6/gdb/common/linux-ptrace.c.orig +-+++ gdb-7.6/gdb/common/linux-ptrace.c +-@@ -108,14 +108,14 @@ linux_ptrace_test_ret_to_nx (void) +- ".globl linux_ptrace_test_ret_to_nx_instr;" +- "linux_ptrace_test_ret_to_nx_instr:" +- "ret" +-- : : "r" (return_address) : "%esp", "memory"); +-+ : : "r" (return_address) : "memory"); +- #elif defined __x86_64__ +- asm volatile ("pushq %0;" +- ".globl linux_ptrace_test_ret_to_nx_instr;" +- "linux_ptrace_test_ret_to_nx_instr:" +- "ret" +- : : "r" ((uint64_t) (uintptr_t) return_address) +-- : "%rsp", "memory"); +-+ : "memory"); +- #else +- # error "!__i386__ && !__x86_64__" +- #endif +---- gdb-7.6/gdb/features/aarch64.c.orig +-+++ gdb-7.6/gdb/features/aarch64.c +-@@ -5,7 +5,6 @@ +- #include "osabi.h" +- #include "target-descriptions.h" +- +--struct target_desc *tdesc_aarch64; +- static void +- initialize_tdesc_aarch64 (void) +- { +---- gdb-7.6/gdb/aarch64-linux-nat.c.orig +-+++ gdb-7.6/gdb/aarch64-linux-nat.c +-@@ -37,6 +37,7 @@ +- +- #include "gregset.h" +- +-+extern struct target_desc *tdesc_aarch64; +- #include "features/aarch64.c" +- +- /* Defines ps_err_e, struct ps_prochandle. */ +---- gdb-7.6/gdb/aarch64-tdep.c.orig +-+++ gdb-7.6/gdb/aarch64-tdep.c +-@@ -52,6 +52,7 @@ +- #include "gdb_assert.h" +- #include "vec.h" +- +-+struct target_desc *tdesc_aarch64; +- #include "features/aarch64.c" +- #include "features/aarch64-without-fpu.c" +- +---- gdb-7.6/gdb/symtab.c.orig +-+++ gdb-7.6/gdb/symtab.c +-@@ -2080,7 +2080,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) +- struct symtab *s = NULL; +- struct symtab *best_s = NULL; +- struct objfile *objfile; +-- CORE_ADDR distance = 0; +-+ CORE_ADDR distance = 0, start, end; +- struct minimal_symbol *msymbol; +- +- /* If we know that this is not a text address, return failure. This is +-@@ -2117,10 +2117,20 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) +- bv = BLOCKVECTOR (s); +- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); +- +-- if (BLOCK_START (b) <= pc +-- && BLOCK_END (b) > pc +-- && (distance == 0 +-- || BLOCK_END (b) - BLOCK_START (b) < distance)) +-+ start = BLOCK_START (b); +-+ end = BLOCK_END (b); +-+ +-+ /* +-+ * If we have an addrmap mapping code addresses to blocks, and pc +-+ * is in the range [start, end), let's use it. +-+ */ +-+ if ((pc >= start && pc < end) && BLOCKVECTOR_MAP (bv)) { +-+ if (addrmap_find (BLOCKVECTOR_MAP (bv), pc)) +-+ return s; +-+ } +-+ +-+ if ((pc >= start && pc < end) && ((distance == 0) +-+ || (end - start < distance))) +- { +- /* For an objfile that has its functions reordered, +- find_pc_psymtab will find the proper partial symbol table +---- gdb-7.6/gdb/mips-tdep.c.orig +-+++ gdb-7.6/gdb/mips-tdep.c +-@@ -3261,6 +3261,16 @@ restart: +- /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra. */ +- set_reg_offset (gdbarch, this_cache, reg, sp + low_word); +- } +-+ else if (((inst & 0xFFE08020) == 0xeba00020) /* gssq reg,reg,offset($sp) */ +-+ && regsize_is_64_bits) +-+ { +-+ reg = (inst >> 16) & 0x1F; +-+ low_word = ((((inst >> 6) & 0x1FF) ^ 0x100) - 0x100) << 4; +-+ set_reg_offset (gdbarch, this_cache, reg, sp + low_word); +-+ reg = inst & 0x1F; +-+ low_word = (((((inst >> 6) & 0x1FF) ^ 0x100) - 0x100) << 4) + 8; +-+ set_reg_offset (gdbarch, this_cache, reg, sp + low_word); +-+ } +- else if (high_word == 0x27be) /* addiu $30,$sp,size */ +- { +- /* Old gcc frame, r30 is virtual frame pointer. */ +diff --git a/gdb_interface.c b/gdb_interface.c +index 1f10006a2d63..93fc8baef2c6 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -17,18 +17,21 @@ + + #include "defs.h" + ++#ifndef GDB_10_2 + static void exit_after_gdb_info(void); ++#endif + static int is_restricted_command(char *, ulong); + static void strip_redirection(char *); + int get_frame_offset(ulong); + + int *gdb_output_format; + unsigned int *gdb_print_max; +-int *gdb_prettyprint_structs; +-int *gdb_prettyprint_arrays; +-int *gdb_repeat_count_threshold; +-int *gdb_stop_print_at_null; ++unsigned char *gdb_prettyprint_structs; ++unsigned char *gdb_prettyprint_arrays; ++unsigned int *gdb_repeat_count_threshold; ++unsigned char *gdb_stop_print_at_null; + unsigned int *gdb_output_radix; ++static void gdb_error_debug(void); + + static ulong gdb_user_print_option_address(char *); + +@@ -68,10 +71,12 @@ gdb_main_loop(int argc, char **argv) + } + + optind = 0; ++#ifndef GDB_10_2 + #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; ++#endif + #endif + gdb_main_entry(argc, argv); + } +@@ -117,22 +122,26 @@ void + display_gdb_banner(void) + { + optind = 0; ++#ifndef GDB_10_2 + #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; ++#endif + #endif + args[0] = "gdb"; + args[1] = "-version"; + gdb_main_entry(2, args); + } + ++#ifndef GDB_10_2 + static void + exit_after_gdb_info(void) + { + fprintf(fp, "\n"); + clean_exit(0); + } ++#endif + + /* + * Stash a copy of the gdb version locally. This can be called before +@@ -186,13 +195,13 @@ gdb_session_init(void) + gdb_user_print_option_address("output_format"); + gdb_print_max = (unsigned int *) + gdb_user_print_option_address("print_max"); +- gdb_prettyprint_structs = (int *) ++ gdb_prettyprint_structs = (unsigned char *) + gdb_user_print_option_address("prettyprint_structs"); +- gdb_prettyprint_arrays = (int *) ++ gdb_prettyprint_arrays = (unsigned char *) + gdb_user_print_option_address("prettyprint_arrays"); +- gdb_repeat_count_threshold = (int *) ++ gdb_repeat_count_threshold = (unsigned int *) + gdb_user_print_option_address("repeat_count_threshold"); +- gdb_stop_print_at_null = (int *) ++ gdb_stop_print_at_null = (unsigned char *) + gdb_user_print_option_address("stop_print_at_null"); + gdb_output_radix = (unsigned int *) + gdb_user_print_option_address("output_radix"); +@@ -291,6 +300,7 @@ retry: + sprintf(req->buf, "set width 0"); + gdb_interface(req); + ++#if 0 + /* + * Patch gdb's symbol values with the correct values from either + * the System.map or non-debug vmlinux, whichever is in effect. +@@ -303,6 +313,9 @@ retry: + if (req->flags & GNU_COMMAND_FAILED) + error(FATAL, "patching of gdb symbol values failed\n"); + } else if (!(pc->flags & SILENT)) ++#else ++ if (!(pc->flags & SILENT)) ++#endif + fprintf(fp, "\n"); + + +@@ -364,19 +377,6 @@ gdb_interface(struct gnu_request *req) + pc->cur_req = req; + pc->cur_gdb_cmd = req->command; + +- if (req->flags & GNU_RETURN_ON_ERROR) { +- error_hook = gdb_error_hook; +- if (setjmp(pc->gdb_interface_env)) { +- pc->last_gdb_cmd = pc->cur_gdb_cmd; +- pc->cur_gdb_cmd = 0; +- pc->cur_req = NULL; +- req->flags |= GNU_COMMAND_FAILED; +- pc->flags &= ~IN_GDB; +- return; +- } +- } else +- error_hook = NULL; +- + if (CRASHDEBUG(2)) + dump_gnu_request(req, IN_GDB); + +@@ -400,10 +400,12 @@ gdb_interface(struct gnu_request *req) + SIGACTION(SIGINT, restart, &pc->sigaction, NULL); + SIGACTION(SIGSEGV, SIG_DFL, &pc->sigaction, NULL); + ++ if (req->flags & GNU_COMMAND_FAILED) ++ gdb_error_debug(); ++ + if (CRASHDEBUG(2)) + dump_gnu_request(req, !IN_GDB); + +- error_hook = NULL; + pc->last_gdb_cmd = pc->cur_gdb_cmd; + pc->cur_gdb_cmd = 0; + pc->cur_req = NULL; +@@ -627,8 +629,6 @@ restore_gdb_sanity(void) + *gdb_prettyprint_structs = 1; /* these may piss somebody off... */ + *gdb_repeat_count_threshold = 0x7fffffff; + +- error_hook = NULL; +- + if (st->flags & ADD_SYMBOL_FILE) { + error(INFO, + "%s\n gdb add-symbol-file command failed\n", +@@ -948,8 +948,8 @@ gdb_print_callback(ulong addr) + /* + * Used by gdb_interface() to catch gdb-related errors, if desired. + */ +-void +-gdb_error_hook(void) ++static void ++gdb_error_debug(void) + { + char buf1[BUFSIZE]; + char buf2[BUFSIZE]; +@@ -969,13 +969,6 @@ gdb_error_hook(void) + gdb_command_string(pc->cur_gdb_cmd, buf1, TRUE), buf2); + } + +-#ifdef GDB_7_6 +- do_cleanups(all_cleanups()); +-#else +- do_cleanups(NULL); +-#endif +- +- longjmp(pc->gdb_interface_env, 1); + } + + +@@ -1036,6 +1029,7 @@ gdb_set_crash_scope(ulong vaddr, char *arg) + req->addr = vaddr; + req->flags = 0; + req->addr2 = 0; ++ req->fp = pc->nullfp; + gdb_command_funnel(req); + + if (CRASHDEBUG(1)) +@@ -1065,4 +1059,18 @@ get_frame_offset(ulong pc) + } + #endif /* !ALPHA */ + ++unsigned long crash_get_kaslr_offset(void); ++unsigned long crash_get_kaslr_offset(void) ++{ ++ return kt->relocate * -1; ++} ++ ++/* Callbacks for crash_target */ ++int crash_get_nr_cpus(void); ++ ++int crash_get_nr_cpus(void) ++{ ++ /* Just CPU #0 */ ++ return 1; ++} + +diff --git a/help.c b/help.c +index f34838d59908..e67fde0018ab 100644 +--- a/help.c ++++ b/help.c +@@ -8302,6 +8302,7 @@ char *version_info[] = { + "Copyright (C) 2005, 2011, 2020-2021 NEC Corporation", + "Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.", + "Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.", ++"Copyright (C) 2015, 2021 VMware, Inc.", + "This program 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. Enter \"help copying\" to see the conditions.", +diff --git a/kernel.c b/kernel.c +index b2c8a0ccb7ab..6b586dbb05c1 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -1052,7 +1052,7 @@ verify_version(void) + + if (!(sp = symbol_search("linux_banner"))) + error(FATAL, "linux_banner symbol does not exist?\n"); +- else if ((sp->type == 'R') || (sp->type == 'r') || ++ else if ((sp->type == 'R') || (sp->type == 'r') || (sp->type == 'D') || + (machine_type("ARM") && sp->type == 'T') || + (machine_type("ARM64"))) + linux_banner = symbol_value("linux_banner"); +diff --git a/main.c b/main.c +index 388ac46c3834..71c59d28dc68 100644 +--- a/main.c ++++ b/main.c +@@ -1704,7 +1704,6 @@ dump_program_context(void) + fprintf(fp, " gdb_sigaction: %lx\n", (ulong)&pc->gdb_sigaction); + fprintf(fp, " main_loop_env: %lx\n", (ulong)&pc->main_loop_env); + fprintf(fp, " foreach_loop_env: %lx\n", (ulong)&pc->foreach_loop_env); +- fprintf(fp, "gdb_interface_env: %lx\n", (ulong)&pc->gdb_interface_env); + fprintf(fp, " termios_orig: %lx\n", (ulong)&pc->termios_orig); + fprintf(fp, " termios_raw: %lx\n", (ulong)&pc->termios_raw); + fprintf(fp, " ncmds: %d\n", pc->ncmds); +diff --git a/symbols.c b/symbols.c +index bf6d94db84af..7ffac2ee8b49 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -17,7 +17,7 @@ + + #include "defs.h" + #include +-#ifdef GDB_7_6 ++#if defined(GDB_7_6) || defined(GDB_10_2) + #define __CONFIG_H__ 1 + #include "config.h" + #endif +@@ -34,7 +34,7 @@ static int compare_mods(const void *, const void *); + static int compare_prios(const void *v1, const void *v2); + static int compare_size_name(const void *, const void *); + struct type_request; +-static void append_struct_symbol (struct type_request *, struct gnu_request *); ++static void append_struct_symbol (struct gnu_request *, void *); + static void request_types(ulong, ulong, char *); + static asection *get_kernel_section(char *); + static char * get_section(ulong vaddr, char *buf); +@@ -278,7 +278,7 @@ check_gnu_debuglink(bfd *bfd) + return FALSE; + } + +- debuglink_size = bfd_section_size(bfd, sect); ++ debuglink_size = bfd_section_size(sect); + + contents = GETBUF(debuglink_size); + +@@ -443,7 +443,7 @@ separate_debug_file_exists(const char *name, unsigned long crc, int *exists) + #ifdef GDB_5_3 + file_crc = calc_crc32(file_crc, buffer, count); + #else +-#ifdef GDB_7_6 ++#if defined(GDB_7_6) || defined(GDB_10_2) + file_crc = bfd_calc_gnu_debuglink_crc32(file_crc, + (unsigned char *)buffer, count); + #else +@@ -524,9 +524,9 @@ get_text_init_space(void) + return; + } + +- kt->stext_init = (ulong)bfd_get_section_vma(st->bfd, section); ++ kt->stext_init = (ulong)bfd_section_vma(section); + kt->etext_init = kt->stext_init + +- (ulong)bfd_section_size(st->bfd, section); ++ (ulong)bfd_section_size(section); + + if (kt->relocate) { + kt->stext_init -= kt->relocate; +@@ -2864,10 +2864,8 @@ is_kernel_text(ulong value) + for (i = 0; i < st->bfd->section_count; i++, sec++) { + section = *sec; + if (section->flags & SEC_CODE) { +- start = (ulong)bfd_get_section_vma(st->bfd, +- section); +- end = start + (ulong)bfd_section_size(st->bfd, +- section); ++ start = (ulong)bfd_section_vma(section); ++ end = start + (ulong)bfd_section_size(section); + + if (kt->flags2 & KASLR) { + start += (kt->relocate * -1); +@@ -3470,8 +3468,8 @@ dump_symbol_table(void) + section = *sec; + fprintf(fp, "%25s vma: %.*lx size: %ld\n", + section->name, VADDR_PRLEN, +- (ulong)bfd_get_section_vma(st->bfd, section), +- (ulong)bfd_section_size(st->bfd, section)); ++ (ulong)bfd_section_vma(section), ++ (ulong)bfd_section_size(section)); + } + fprintf(fp, "\n downsized: "); + if (st->downsized.name) { +@@ -4363,12 +4361,11 @@ get_section(ulong vaddr, char *buf) + sec = (asection **)st->sections; + for (i = 0; i < st->bfd->section_count; i++, sec++) { + section = *sec; +- start = (ulong)bfd_get_section_vma(st->bfd, section); +- end = start + (ulong)bfd_section_size(st->bfd, section); ++ start = (ulong)bfd_section_vma(section); ++ end = start + (ulong)bfd_section_size(section); + + if ((vaddr >= start) && (vaddr < end)) { +- strcpy(buf, bfd_get_section_name(st->bfd, +- section)); ++ strcpy(buf, bfd_section_name(section)); + break; + } + } +@@ -6996,10 +6993,11 @@ compare_size_name(const void *va, const void *vb) { + } + + static void +-append_struct_symbol (struct type_request *treq, struct gnu_request *req) ++append_struct_symbol (struct gnu_request *req, void *data) + { + int i; + long s; ++ struct type_request *treq = (struct type_request *)data; + + for (i = 0; i < treq->idx; i++) + if (treq->types[i].name == req->name) +@@ -7037,22 +7035,13 @@ request_types(ulong lowest, ulong highest, char *member_name) + request.type_name = member_name; + #endif + +- while (!request.global_iterator.finished) { +- request.command = GNU_GET_NEXT_DATATYPE; +- gdb_interface(&request); +- if (highest && +- !(lowest <= request.length && request.length <= highest)) +- continue; +- +- if (member_name) { +- request.command = GNU_LOOKUP_STRUCT_CONTENTS; +- gdb_interface(&request); +- if (!request.value) +- continue; +- } +- +- append_struct_symbol(&typereq, &request); +- } ++ request.command = GNU_ITERATE_DATATYPES; ++ request.lowest = lowest; ++ request.highest = highest; ++ request.member = member_name; ++ request.callback = append_struct_symbol; ++ request.callback_data = (void *)&typereq; ++ gdb_interface(&request); + + qsort(typereq.types, typereq.idx, sizeof(struct type_info), compare_size_name); + +@@ -11192,39 +11181,39 @@ section_header_info(bfd *bfd, asection *section, void *reqptr) + sec++; + *sec = section; + +- if (STREQ(bfd_get_section_name(bfd, section), ".text.init") || +- STREQ(bfd_get_section_name(bfd, section), ".init.text")) { ++ if (STREQ(bfd_section_name(section), ".text.init") || ++ STREQ(bfd_section_name(section), ".init.text")) { + kt->stext_init = (ulong) +- bfd_get_section_vma(bfd, section); ++ bfd_section_vma(section); + kt->etext_init = kt->stext_init + +- (ulong)bfd_section_size(bfd, section); ++ (ulong)bfd_section_size(section); + } + +- if (STREQ(bfd_get_section_name(bfd, section), ".text")) { ++ if (STREQ(bfd_section_name(section), ".text")) { + st->first_section_start = (ulong) +- bfd_get_section_vma(bfd, section); ++ bfd_section_vma(section); + } +- if (STREQ(bfd_get_section_name(bfd, section), ".text") || +- STREQ(bfd_get_section_name(bfd, section), ".data")) { +- if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD)) ++ if (STREQ(bfd_section_name(section), ".text") || ++ STREQ(bfd_section_name(section), ".data")) { ++ if (!(bfd_section_flags(section) & SEC_LOAD)) + st->flags |= NO_SEC_LOAD; +- if (!(bfd_get_section_flags(bfd, section) & ++ if (!(bfd_section_flags(section) & + SEC_HAS_CONTENTS)) + st->flags |= NO_SEC_CONTENTS; + } +- if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) { ++ if (STREQ(bfd_section_name(section), ".eh_frame")) { + st->dwarf_eh_frame_file_offset = (off_t)section->filepos; +- st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section); ++ st->dwarf_eh_frame_size = (ulong)bfd_section_size(section); + } +- if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame")) { ++ if (STREQ(bfd_section_name(section), ".debug_frame")) { + st->dwarf_debug_frame_file_offset = (off_t)section->filepos; +- st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section); ++ st->dwarf_debug_frame_size = (ulong)bfd_section_size(section); + } + + if (st->first_section_start != 0) { + section_end_address = +- (ulong) bfd_get_section_vma(bfd, section) + +- (ulong) bfd_section_size(bfd, section); ++ (ulong) bfd_section_vma(section) + ++ (ulong) bfd_section_size(section); + if (section_end_address > st->last_section_end) + st->last_section_end = section_end_address; + } +@@ -11236,21 +11225,21 @@ section_header_info(bfd *bfd, asection *section, void *reqptr) + break; + + case (ulong)VERIFY_SECTIONS: +- if (STREQ(bfd_get_section_name(bfd, section), ".text") || +- STREQ(bfd_get_section_name(bfd, section), ".data")) { +- if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD)) ++ if (STREQ(bfd_section_name(section), ".text") || ++ STREQ(bfd_section_name(section), ".data")) { ++ if (!(bfd_section_flags(section) & SEC_LOAD)) + st->flags |= NO_SEC_LOAD; +- if (!(bfd_get_section_flags(bfd, section) & ++ if (!(bfd_section_flags(section) & + SEC_HAS_CONTENTS)) + st->flags |= NO_SEC_CONTENTS; + } +- if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) { ++ if (STREQ(bfd_section_name(section), ".eh_frame")) { + st->dwarf_eh_frame_file_offset = (off_t)section->filepos; +- st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section); ++ st->dwarf_eh_frame_size = (ulong)bfd_section_size(section); + } +- if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame")) { ++ if (STREQ(bfd_section_name(section), ".debug_frame")) { + st->dwarf_debug_frame_file_offset = (off_t)section->filepos; +- st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section); ++ st->dwarf_debug_frame_size = (ulong)bfd_section_size(section); + } + break; + +@@ -11290,7 +11279,7 @@ store_section_data(struct load_module *lm, bfd *bfd, asection *section) + char *name; + + prio = 0; +- name = (char *)bfd_get_section_name(bfd, section); ++ name = (char *)bfd_section_name(section); + + if (name[0] != '.' || strlen(name) != 10 || strcmp(name + 5, ".init")) + prio |= 32; +@@ -11312,10 +11301,10 @@ store_section_data(struct load_module *lm, bfd *bfd, asection *section) + */ + if (lm->mod_percpu && + (STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) { +- lm->mod_percpu_size = bfd_section_size(bfd, section); ++ lm->mod_percpu_size = bfd_section_size(section); + lm->mod_section_data[i].flags |= SEC_FOUND; + } +- lm->mod_section_data[i].size = bfd_section_size(bfd, section); ++ lm->mod_section_data[i].size = bfd_section_size(section); + lm->mod_section_data[i].offset = 0; + if (strlen(name) < MAX_MOD_SEC_NAME) + strcpy(lm->mod_section_data[i].name, name); +@@ -11393,7 +11382,7 @@ calculate_load_order_v1(struct load_module *lm, bfd *bfd) + for (i = (lm->mod_sections-1); i >= 0; i--) { + section = lm->mod_section_data[i].section; + +- alignment = power(2, bfd_get_section_alignment(bfd, section)); ++ alignment = power(2, bfd_section_alignment(section)); + + if (alignment && (offset & (alignment - 1))) + offset = (offset | (alignment - 1)) + 1; +@@ -11422,9 +11411,9 @@ calculate_load_order_v1(struct load_module *lm, bfd *bfd) + if (STREQ(lm->mod_section_data[i].name, ".rodata")) + lm->mod_rodata_start = lm->mod_base + offset; + +- offset += bfd_section_size(bfd, section); ++ offset += bfd_section_size(section); + +- if (STREQ(bfd_get_section_name(bfd, section), ".kstrtab")) ++ if (STREQ(bfd_section_name(section), ".kstrtab")) + offset += strlen(lm->mod_name)+1; + } + } +@@ -11501,7 +11490,7 @@ calculate_load_order_v2(struct load_module *lm, bfd *bfd, int dynamic, + (long) syminfo.value); + } + if (strcmp(syminfo.name, s1->name) == 0) { +- secname = (char *)bfd_get_section_name(bfd, sym->section); ++ secname = (char *)bfd_section_name(sym->section); + break; + } + +@@ -12249,7 +12238,7 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms, + + bfd_get_symbol_info(bfd, sym, &syminfo); + +- secname = (char *)bfd_get_section_name(bfd, sym->section); ++ secname = (char *)bfd_section_name(sym->section); + found = 0; + + if (kt->flags & KMOD_V1) { +@@ -12806,8 +12795,8 @@ numeric_forward(const void *P_x, const void *P_y) + st->saved_command_line_vmlinux = valueof(y); + } + +- xs = bfd_get_section(x); +- ys = bfd_get_section(y); ++ xs = bfd_asymbol_section(x); ++ ys = bfd_asymbol_section(y); + + if (bfd_is_und_section(xs)) { + if (!bfd_is_und_section(ys)) +diff --git a/tools.c b/tools.c +index 6fa3c70bac2b..39306c18c98f 100644 +--- a/tools.c ++++ b/tools.c +@@ -6239,7 +6239,7 @@ drop_core(char *s) + * The first time it's called, the device will be opened. + */ + int +-console(char *fmt, ...) ++console(const char *fmt, ...) + { + char output[BUFSIZE*2]; + va_list ap; +diff --git a/x86_64.c b/x86_64.c +index 87cbeaeb4f06..21756f6cf7ab 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -7104,7 +7104,8 @@ x86_64_virt_phys_base(void) + ulong phys, linux_banner_phys; + + if (!(sp = symbol_search("linux_banner")) || +- !((sp->type == 'R') || (sp->type == 'r'))) ++ !((sp->type == 'R') || (sp->type == 'r') || ++ (sp->type == 'D'))) + return FALSE; + + linux_banner_phys = sp->value - __START_KERNEL_map; +-- +2.30.2 + diff --git a/0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch b/0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch new file mode 100644 index 0000000..28702a5 --- /dev/null +++ b/0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch @@ -0,0 +1,120 @@ +From 163abcbbabdf8207c11ee93b1c909d85ecbcbf1f Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:26 -0700 +Subject: [PATCH 13/27] crash_get_nr_cpus: get nr_cpus from the dumps + +Most of the dumps have information about real number of CPUS. +Use that to instantiate GDB's target inferior threads. + +Signed-off-by: Alexey Makhalov +--- + diskdump.c | 13 +++++++++++-- + gdb_interface.c | 9 +++++++++ + netdump.c | 11 ++++++++--- + sadump.c | 2 +- + 4 files changed, 29 insertions(+), 6 deletions(-) + +diff --git a/diskdump.c b/diskdump.c +index 112f769f8949..3e1cfd548c96 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -2593,13 +2593,22 @@ diskdump_kaslr_check() + return FALSE; + } + +-#ifdef X86_64 + int + diskdump_get_nr_cpus(void) + { +- return dd->num_qemu_notes; ++ if (dd->num_prstatus_notes) ++ return dd->num_prstatus_notes; ++ else if (dd->num_qemu_notes) ++ return dd->num_qemu_notes; ++ else if (dd->num_vmcoredd_notes) ++ return dd->num_vmcoredd_notes; ++ else if (dd->header->nr_cpus) ++ return dd->header->nr_cpus; ++ ++ return 1; + } + ++#ifdef X86_64 + QEMUCPUState * + diskdump_get_qemucpustate(int cpu) + { +diff --git a/gdb_interface.c b/gdb_interface.c +index 93fc8baef2c6..bcca080eb8b4 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -1070,6 +1070,15 @@ int crash_get_nr_cpus(void); + + int crash_get_nr_cpus(void) + { ++ if (SADUMP_DUMPFILE()) ++ return sadump_get_nr_cpus(); ++ else if (DISKDUMP_DUMPFILE()) ++ return diskdump_get_nr_cpus(); ++ else if (KDUMP_DUMPFILE()) ++ return kdump_get_nr_cpus(); ++ else if (VMSS_DUMPFILE()) ++ return vmware_vmss_get_nr_cpus(); ++ + /* Just CPU #0 */ + return 1; + } +diff --git a/netdump.c b/netdump.c +index e8721d89f1a3..ff273b4fdfab 100644 +--- a/netdump.c ++++ b/netdump.c +@@ -5206,11 +5206,17 @@ kdump_kaslr_check(void) + return FALSE; + } + +-#ifdef X86_64 + int + kdump_get_nr_cpus(void) + { +- return nd->num_qemu_notes; ++ if (nd->num_prstatus_notes) ++ return nd->num_prstatus_notes; ++ else if (nd->num_qemu_notes) ++ return nd->num_qemu_notes; ++ else if (nd->num_vmcoredd_notes) ++ return nd->num_vmcoredd_notes; ++ ++ return 1; + } + + QEMUCPUState * +@@ -5232,7 +5238,6 @@ kdump_get_qemucpustate(int cpu) + + return (QEMUCPUState *)nd->nt_qemu_percpu[cpu]; + } +-#endif + + static void * + get_kdump_device_dump_offset(void) +diff --git a/sadump.c b/sadump.c +index d75c66b74be9..cb43fdb8ecab 100644 +--- a/sadump.c ++++ b/sadump.c +@@ -1670,7 +1670,6 @@ get_sadump_data(void) + return sd; + } + +-#ifdef X86_64 + int + sadump_get_nr_cpus(void) + { +@@ -1678,6 +1677,7 @@ sadump_get_nr_cpus(void) + return sd->dump_header->nr_cpus; + } + ++#ifdef X86_64 + int + sadump_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr) + { +-- +2.30.2 + diff --git a/0014-whatis-m-fix-duplications-in-the-output.patch b/0014-whatis-m-fix-duplications-in-the-output.patch new file mode 100644 index 0000000..6b453f4 --- /dev/null +++ b/0014-whatis-m-fix-duplications-in-the-output.patch @@ -0,0 +1,45 @@ +From 36e9d8673e9205f4ea4daad61c199597920c93df Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:27 -0700 +Subject: [PATCH 14/27] "whatis -m": fix duplications in the output + +"whatis -m" output started to generate duplicated results after GDB update: + +crash> whatis -m mm_struct +SIZE TYPE + 16 tlb_state +... + 256 linux_binprm + 2752 rq + 2752 rq <<-- duplicated + 2752 rq + 2752 rq + 2752 rq + 4048 task_struct + +It was caused by incorrect string comparisons. +Use strcmp for full string comparison instead of just string pointers +comparison. + +Signed-off-by: Alexey Makhalov +Reported-by: Kazuhito Hagio +--- + symbols.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/symbols.c b/symbols.c +index 7ffac2ee8b49..338af2ce5038 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -7000,7 +7000,7 @@ append_struct_symbol (struct gnu_request *req, void *data) + struct type_request *treq = (struct type_request *)data; + + for (i = 0; i < treq->idx; i++) +- if (treq->types[i].name == req->name) ++ if (!strcmp(treq->types[i].name, req->name)) + break; + + if (i < treq->idx) // We've already collected this type +-- +2.30.2 + diff --git a/0015-Fix-reduced-output-of-bt-command.patch b/0015-Fix-reduced-output-of-bt-command.patch new file mode 100644 index 0000000..1e76c34 --- /dev/null +++ b/0015-Fix-reduced-output-of-bt-command.patch @@ -0,0 +1,80 @@ +From 0b85218983ffcf939a638f1133871079c5615a46 Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:30 -0700 +Subject: [PATCH 15/27] Fix reduced output of `bt` command + +gdb-10 produces reduced output of `bt` command. + +Changed disassembler output is the reason of missing frames +in backtrace. Call instruction mnemonic for x86_64 was changed +from "callq" to "call" in gdb-10. + +Fixing the issue by adding a search for "call" word in disassembler +parser. + +Signed-off-by: Alexey Makhalov +Reported-by: Kazuhito Hagio +--- + x86_64.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/x86_64.c b/x86_64.c +index 21756f6cf7ab..4f34afac06f9 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -4415,7 +4415,7 @@ x86_64_function_called_by(ulong rip) + if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) { + rewind(pc->tmpfile2); + while (fgets(buf, BUFSIZE, pc->tmpfile2)) { +- if ((p1 = strstr(buf, "callq")) && ++ if ((p1 = strstr(buf, "call")) && + whitespace(*(p1-1))) { + if (extract_hex(p1, &value, NULLCHAR, TRUE)) + break; +@@ -6381,11 +6381,13 @@ search_for_switch_to(ulong start, ulong end) + char search_string1[BUFSIZE]; + char search_string2[BUFSIZE]; + char search_string3[BUFSIZE]; ++ char search_string4[BUFSIZE]; + int found; + + max_instructions = end - start; + found = FALSE; +- search_string1[0] = search_string2[0] = search_string3[0] = NULLCHAR; ++ search_string1[0] = search_string2[0] = NULLCHAR; ++ search_string3[0] = search_string4[0] = NULLCHAR; + sprintf(buf1, "x/%ldi 0x%lx", max_instructions, start); + + if (symbol_exists("__switch_to")) { +@@ -6396,7 +6398,9 @@ search_for_switch_to(ulong start, ulong end) + } + if (symbol_exists("__switch_to_asm")) { + sprintf(search_string3, +- "callq 0x%lx", symbol_value("__switch_to_asm")); ++ "callq 0x%lx", symbol_value("__switch_to_asm")); ++ sprintf(search_string4, ++ "call 0x%lx", symbol_value("__switch_to_asm")); + } + + open_tmpfile(); +@@ -6416,6 +6420,8 @@ search_for_switch_to(ulong start, ulong end) + found = TRUE; + if (strlen(search_string3) && strstr(buf1, search_string3)) + found = TRUE; ++ if (strlen(search_string4) && strstr(buf1, search_string4)) ++ found = TRUE; + } + close_tmpfile(); + +@@ -8230,7 +8236,7 @@ x86_64_do_not_cache_framesize(struct syment *sp, ulong textaddr) + return TRUE; + } + +- if (STREQ(arglist[instr], "callq")) ++ if (STREQ(arglist[instr], "callq") || STREQ(arglist[instr], "call")) + break; + } + close_tmpfile2(); +-- +2.30.2 + diff --git a/0016-crash_taget-fetch_registers-support.patch b/0016-crash_taget-fetch_registers-support.patch new file mode 100644 index 0000000..1040fc7 --- /dev/null +++ b/0016-crash_taget-fetch_registers-support.patch @@ -0,0 +1,335 @@ +From 2f967fb5ebd737ce5eadba462df35935122e8865 Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:33 -0700 +Subject: [PATCH 16/27] crash_taget: fetch_registers support + +Provides API for crash_target to fetch registers of given +CPU. It will allow gdb to perform such commands as "bt", +"frame", "info locals". + +Highlevel API is crash_get_cpu_reg (). It calls machine +(architecture) specific function: machdep->get_cpu_reg(). +Input arguments such as register number and register size +come from gdb arch information. So, get_cpu_regs() +implementations in crash must understand it. + +Signed-off-by: Alexey Makhalov +--- + crash_target.c | 33 +++++++++++++++++++++++++++++++- + defs.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ + gdb_interface.c | 19 +++++++++++++----- + vmware_vmss.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- + x86_64.c | 16 ++++++++++++++++ + 5 files changed, 163 insertions(+), 7 deletions(-) + +diff --git a/crash_target.c b/crash_target.c +index a123329019f5..455480679741 100644 +--- a/crash_target.c ++++ b/crash_target.c +@@ -27,6 +27,8 @@ void crash_target_init (void); + + extern "C" int gdb_readmem_callback(unsigned long, void *, int, int); + extern "C" int crash_get_nr_cpus(void); ++extern "C" int crash_get_cpu_reg (int cpu, int regno, const char *regname, ++ int regsize, void *val); + + + /* The crash target. */ +@@ -44,6 +46,7 @@ public: + const target_info &info () const override + { return crash_target_info; } + ++ void fetch_registers (struct regcache *, int) override; + enum target_xfer_status xfer_partial (enum target_object object, + const char *annex, + gdb_byte *readbuf, +@@ -54,13 +57,35 @@ public: + bool has_all_memory () override { return true; } + bool has_memory () override { return true; } + bool has_stack () override { return true; } +- bool has_registers () override { return false; } ++ bool has_registers () override { return true; } + bool thread_alive (ptid_t ptid) override { return true; } + std::string pid_to_str (ptid_t ptid) override + { return string_printf ("CPU %ld", ptid.tid ()); } + + }; + ++/* We just get all the registers, so we don't use regno. */ ++void ++crash_target::fetch_registers (struct regcache *regcache, int regno) ++{ ++ gdb_byte regval[16]; ++ int cpu = inferior_ptid.tid(); ++ struct gdbarch *arch = regcache->arch (); ++ ++ for (int r = 0; r < gdbarch_num_regs (arch); r++) ++ { ++ const char *regname = gdbarch_register_name(arch, r); ++ int regsize = register_size (arch, r); ++ if (regsize > sizeof (regval)) ++ error (_("fatal error: buffer size is not enough to fit register value")); ++ ++ if (crash_get_cpu_reg (cpu, r, regname, regsize, (void *)®val)) ++ regcache->raw_supply (r, regval); ++ else ++ regcache->raw_supply (r, NULL); ++ } ++} ++ + + enum target_xfer_status + crash_target::xfer_partial (enum target_object object, const char *annex, +@@ -101,4 +126,10 @@ crash_target_init (void) + if (!i) + switch_to_thread (thread); + } ++ ++ /* Fetch all registers from core file. */ ++ target_fetch_registers (get_current_regcache (), -1); ++ ++ /* Now, set up the frame cache. */ ++ reinit_frame_cache (); + } +diff --git a/defs.h b/defs.h +index db0bd9ca9fe8..b34c60e9a795 100644 +--- a/defs.h ++++ b/defs.h +@@ -1013,6 +1013,7 @@ struct machdep_table { + ulong (*processor_speed)(void); + int (*uvtop)(struct task_context *, ulong, physaddr_t *, int); + int (*kvtop)(struct task_context *, ulong, physaddr_t *, int); ++ int (*get_cpu_reg)(int, int, const char *, int, void *); + ulong (*get_task_pgd)(ulong); + void (*dump_irq)(int); + void (*get_stack_frame)(struct bt_info *, ulong *, ulong *); +@@ -6858,6 +6859,7 @@ int vmware_vmss_get_nr_cpus(void); + int vmware_vmss_get_cr3_cr4_idtr(int, ulong *, ulong *, ulong *); + int vmware_vmss_phys_base(ulong *phys_base); + int vmware_vmss_set_phys_base(ulong); ++int vmware_vmss_get_cpu_reg(int, int, const char *, int, void *); + + /* + * vmware_guestdump.c +@@ -7282,4 +7284,53 @@ extern int have_full_symbols(void); + #define XEN_HYPERVISOR_ARCH + #endif + ++/* ++ * Register numbers must be in sync with gdb/features/i386/64bit-core.c ++ * to make crash_target->fetch_registers() ---> machdep->get_cpu_reg() ++ * working properly. ++ */ ++enum x86_64_regnum { ++ RAX_REGNUM, ++ RBX_REGNUM, ++ RCX_REGNUM, ++ RDX_REGNUM, ++ RSI_REGNUM, ++ RDI_REGNUM, ++ RBP_REGNUM, ++ RSP_REGNUM, ++ R8_REGNUM, ++ R9_REGNUM, ++ R10_REGNUM, ++ R11_REGNUM, ++ R12_REGNUM, ++ R13_REGNUM, ++ R14_REGNUM, ++ R15_REGNUM, ++ RIP_REGNUM, ++ EFLAGS_REGNUM, ++ CS_REGNUM, ++ SS_REGNUM, ++ DS_REGNUM, ++ ES_REGNUM, ++ FS_REGNUM, ++ GS_REGNUM, ++ ST0_REGNUM, ++ ST1_REGNUM, ++ ST2_REGNUM, ++ ST3_REGNUM, ++ ST4_REGNUM, ++ ST5_REGNUM, ++ ST6_REGNUM, ++ ST7_REGNUM, ++ FCTRL_REGNUM, ++ FSTAT_REGNUM, ++ FTAG_REGNUM, ++ FISEG_REGNUM, ++ FIOFF_REGNUM, ++ FOSEG_REGNUM, ++ FOOFF_REGNUM, ++ FOP_REGNUM, ++ LAST_REGNUM ++}; ++ + #endif /* !GDB_COMMON */ +diff --git a/gdb_interface.c b/gdb_interface.c +index bcca080eb8b4..ce88d5a7c338 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -698,11 +698,10 @@ static char *prohibited_list[] = { + "run", "r", "break", "b", "tbreak", "hbreak", "thbreak", "rbreak", + "watch", "rwatch", "awatch", "attach", "continue", "c", "fg", "detach", + "finish", "handle", "interrupt", "jump", "kill", "next", "nexti", +- "signal", "step", "s", "stepi", "target", "thread", "until", "delete", +- "clear", "disable", "enable", "condition", "ignore", "frame", +- "select-frame", "f", "up", "down", "catch", "tcatch", "return", +- "file", "exec-file", "core-file", "symbol-file", "load", "si", "ni", +- "shell", "sy", ++ "signal", "step", "s", "stepi", "target", "until", "delete", ++ "clear", "disable", "enable", "condition", "ignore", "frame", "catch", ++ "tcatch", "return", "file", "exec-file", "core-file", "symbol-file", ++ "load", "si", "ni", "shell", "sy", + NULL /* must be last */ + }; + +@@ -1067,6 +1066,8 @@ unsigned long crash_get_kaslr_offset(void) + + /* Callbacks for crash_target */ + int crash_get_nr_cpus(void); ++int crash_get_cpu_reg (int cpu, int regno, const char *regname, ++ int regsize, void *val); + + int crash_get_nr_cpus(void) + { +@@ -1083,3 +1084,11 @@ int crash_get_nr_cpus(void) + return 1; + } + ++int crash_get_cpu_reg (int cpu, int regno, const char *regname, ++ int regsize, void *value) ++{ ++ if (!machdep->get_cpu_reg) ++ return FALSE; ++ return machdep->get_cpu_reg(cpu, regno, regname, regsize, value); ++} ++ +diff --git a/vmware_vmss.c b/vmware_vmss.c +index 52d58e87d1c5..948a83817847 100644 +--- a/vmware_vmss.c ++++ b/vmware_vmss.c +@@ -1,7 +1,7 @@ + /* + * vmware_vmss.c + * +- * Copyright (c) 2015 VMware, Inc. ++ * Copyright (c) 2015, 2020 VMware, Inc. + * Copyright (c) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify +@@ -16,6 +16,7 @@ + * + * Authors: Dyno Hongjun Fu + * Sergio Lopez ++ * Alexey Makhalov + */ + + #include "defs.h" +@@ -891,6 +892,54 @@ vmware_vmss_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr) + return TRUE; + } + ++int ++vmware_vmss_get_cpu_reg(int cpu, int regno, const char *name, int size, ++ void *value) ++{ ++ if (cpu >= vmss.num_vcpus) ++ return FALSE; ++ ++ /* All supported registers are 8 bytes long. */ ++ if (size != 8) ++ return FALSE; ++ ++#define CASE(R,r) \ ++ case R##_REGNUM: \ ++ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \ ++ return FALSE; \ ++ memcpy(value, &vmss.regs64[cpu]->r, size); \ ++ break ++ ++ ++ switch (regno) { ++ CASE (RAX, rax); ++ CASE (RBX, rbx); ++ CASE (RCX, rcx); ++ CASE (RDX, rdx); ++ CASE (RSI, rsi); ++ CASE (RDI, rdi); ++ CASE (RBP, rbp); ++ CASE (RSP, rsp); ++ CASE (R8, r8); ++ CASE (R9, r9); ++ CASE (R10, r10); ++ CASE (R11, r11); ++ CASE (R12, r12); ++ CASE (R13, r13); ++ CASE (R14, r14); ++ CASE (R15, r15); ++ CASE (RIP, rip); ++ case EFLAGS_REGNUM: ++ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_RFLAGS)) ++ return FALSE; ++ memcpy(value, &vmss.regs64[cpu]->rflags, size); ++ break; ++ default: ++ return FALSE; ++ } ++ return TRUE; ++} ++ + int + vmware_vmss_phys_base(ulong *phys_base) + { +diff --git a/x86_64.c b/x86_64.c +index 4f34afac06f9..d0565ba26a0c 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -126,6 +126,7 @@ static int x86_64_get_framesize(struct bt_info *, ulong, ulong); + static void x86_64_framesize_debug(struct bt_info *); + static void x86_64_get_active_set(void); + static int x86_64_get_kvaddr_ranges(struct vaddr_range *); ++static int x86_64_get_cpu_reg(int, int, const char *, int, void *); + static int x86_64_verify_paddr(uint64_t); + static void GART_init(void); + static void x86_64_exception_stacks_init(void); +@@ -194,6 +195,7 @@ x86_64_init(int when) + machdep->machspec->irq_eframe_link = UNINITIALIZED; + machdep->machspec->irq_stack_gap = UNINITIALIZED; + machdep->get_kvaddr_ranges = x86_64_get_kvaddr_ranges; ++ machdep->get_cpu_reg = x86_64_get_cpu_reg; + if (machdep->cmdline_args[0]) + parse_cmdline_args(); + if ((string = pc->read_vmcoreinfo("relocate"))) { +@@ -884,6 +886,7 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, " is_page_ptr: x86_64_is_page_ptr()\n"); + fprintf(fp, " verify_paddr: x86_64_verify_paddr()\n"); + fprintf(fp, " get_kvaddr_ranges: x86_64_get_kvaddr_ranges()\n"); ++ fprintf(fp, " get_cpu_reg: x86_64_get_cpu_reg()\n"); + fprintf(fp, " init_kernel_pgd: x86_64_init_kernel_pgd()\n"); + fprintf(fp, "clear_machdep_cache: x86_64_clear_machdep_cache()\n"); + fprintf(fp, " xendump_p2m_create: %s\n", PVOPS_XEN() ? +@@ -8934,6 +8937,19 @@ x86_64_get_kvaddr_ranges(struct vaddr_range *vrp) + return cnt; + } + ++static int ++x86_64_get_cpu_reg(int cpu, int regno, const char *name, ++ int size, void *value) ++{ ++ if (regno >= LAST_REGNUM) ++ return FALSE; ++ ++ if (VMSS_DUMPFILE()) ++ return vmware_vmss_get_cpu_reg(cpu, regno, name, size, value); ++ ++ return FALSE; ++} ++ + /* + * Determine the physical memory range reserved for GART. + */ +-- +2.30.2 + diff --git a/0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch b/0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch new file mode 100644 index 0000000..7a3a8bf --- /dev/null +++ b/0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch @@ -0,0 +1,33 @@ +From e832e0eb5bd8d97dfa9f4bd0e22fbfad849c11df Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:34 -0700 +Subject: [PATCH 17/27] Allow 'gdb disassemble' command for relocated kernel + +As new gdb is able to handle it properly. + +Signed-off-by: Alexey Makhalov +--- + gdb_interface.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/gdb_interface.c b/gdb_interface.c +index ce88d5a7c338..d3e1484f8dd9 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -741,13 +741,6 @@ is_restricted_command(char *cmd, ulong flags) + } + } + +- if (kt->relocate && +- STRNEQ("disassemble", cmd) && STRNEQ(cmd, "disas")) +- error(FATAL, +- "the gdb \"disassemble\" command is prohibited because the kernel text\n" +- "%swas relocated%s; use the crash \"dis\" command instead.\n", +- space(strlen(pc->curcmd)+2), kt->flags2 & KASLR ? " by KASLR" : ""); +- + return FALSE; + } + +-- +2.30.2 + diff --git a/0018-vmware-backend-honor-silence-flag.patch b/0018-vmware-backend-honor-silence-flag.patch new file mode 100644 index 0000000..fec2abb --- /dev/null +++ b/0018-vmware-backend-honor-silence-flag.patch @@ -0,0 +1,45 @@ +From 96716862765f73676bfdb2d19fc5872364d21b73 Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:35 -0700 +Subject: [PATCH 18/27] vmware backend: honor silence flag + +Do not print any boot messages in silence (-s) mode. + +Signed-off-by: Alexey Makhalov +--- + vmware_vmss.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/vmware_vmss.c b/vmware_vmss.c +index 948a83817847..f6c5f32ea4c0 100644 +--- a/vmware_vmss.c ++++ b/vmware_vmss.c +@@ -444,11 +444,13 @@ vmware_vmss_init(char *filename, FILE *ofp) + if (vmss.memsize == 0) { + char *vmem_filename, *p; + +- fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n"); ++ if (!(pc->flags & SILENT)) ++ fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n"); + fclose(fp); + fp = NULL; + +- fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n"); ++ if (!(pc->flags & SILENT)) ++ fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n"); + /* check the companion vmem file */ + vmem_filename = strdup(filename); + p = vmem_filename + strlen(vmem_filename) - 4; +@@ -471,7 +473,8 @@ vmware_vmss_init(char *filename, FILE *ofp) + vmss.separate_vmem = TRUE; + vmss.filename = filename; + +- fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename); ++ if (!(pc->flags & SILENT)) ++ fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename); + free(vmem_filename); + } + +-- +2.30.2 + diff --git a/0019-vmware_guestdump-add-debugging-of-the-init-function.patch b/0019-vmware_guestdump-add-debugging-of-the-init-function.patch new file mode 100644 index 0000000..7fb0bbc --- /dev/null +++ b/0019-vmware_guestdump-add-debugging-of-the-init-function.patch @@ -0,0 +1,31 @@ +From 6c5f0c6ff5d158f2ef4fa997a052b0643d0c25ee Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Fri, 19 Mar 2021 21:07:36 -0700 +Subject: [PATCH 19/27] vmware_guestdump: add debugging of the init function + +Dump memory and registers state after parsing. + +Signed-off-by: Alexey Makhalov +--- + vmware_guestdump.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vmware_guestdump.c b/vmware_guestdump.c +index 62da0a77a227..cf818e588a60 100644 +--- a/vmware_guestdump.c ++++ b/vmware_guestdump.c +@@ -267,6 +267,11 @@ vmware_guestdump_init(char *filename, FILE *ofp) + fseek(vmss.dfp, 0L, SEEK_SET); + fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename); + ++ if (CRASHDEBUG(1)) { ++ vmware_guestdump_memory_dump(ofp); ++ dump_registers_for_vmss_dump(); ++ } ++ + exit: + if (fp) + fclose(fp); +-- +2.30.2 + diff --git a/0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch b/0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch new file mode 100644 index 0000000..1b27628 --- /dev/null +++ b/0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch @@ -0,0 +1,65 @@ +From 8d6f677e54a2474b3da19402e29278b62603d71d Mon Sep 17 00:00:00 2001 +From: Alexey Makhalov +Date: Thu, 8 Jul 2021 16:14:02 -0700 +Subject: [PATCH 20/27] Do not adjust addr by relocate offset(KASLR) + +GBD symbol resolution already considers relocation (KASLR) offset. +So, there is no needs to adjust the function address before calling +GDB. + +It fixes file name and line number output for 'dis -l' and 'sys -c' +commands. + +Signed-off-by: Alexey Makhalov +Signed-off-by: Tao Liu +--- + gdb_interface.c | 3 +-- + kernel.c | 3 +-- + symbols.c | 3 +-- + 3 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/gdb_interface.c b/gdb_interface.c +index d3e1484f8dd9..b098ed823d55 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -1013,8 +1013,7 @@ gdb_set_crash_scope(ulong vaddr, char *arg) + return FALSE; + } + } +- } else if (kt->flags2 & KASLR) +- vaddr -= (kt->relocate * -1); ++ } + } + + req->command = GNU_SET_CRASH_BLOCK; +diff --git a/kernel.c b/kernel.c +index 6b586dbb05c1..6a812ac7b1bc 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -1484,8 +1484,7 @@ list_source_code(struct gnu_request *req, int count_entered) + if (!(lm->mod_flags & MOD_LOAD_SYMS)) + error(FATAL, "%s: module source code is not available\n", lm->mod_name); + get_line_number(req->addr, buf1, FALSE); +- } else if (kt->flags2 & KASLR) +- req->addr -= (kt->relocate * -1); ++ } + + sprintf(buf1, "list *0x%lx", req->addr); + open_tmpfile(); +diff --git a/symbols.c b/symbols.c +index 338af2ce5038..5d3c53a30abc 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -4296,8 +4296,7 @@ get_line_number(ulong addr, char *buf, int reserved) + if (module_symbol(addr, NULL, &lm, NULL, 0)) { + if (!(lm->mod_flags & MOD_LOAD_SYMS)) + return(buf); +- } else if (kt->flags2 & KASLR) +- addr -= (kt->relocate * -1); ++ } + + if ((lnh = machdep->line_number_hooks)) { + name = closest_symbol(addr); +-- +2.30.2 + diff --git a/0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch b/0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch new file mode 100644 index 0000000..5b37028 --- /dev/null +++ b/0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch @@ -0,0 +1,44 @@ +From fce91bec5bef534e52f3261cc289a21a2cdb5fe3 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Sun, 11 Jul 2021 22:30:22 +0800 +Subject: [PATCH 21/27] Fix the failure of reporting vmcore and vmlinux do not + match for kernels(<2.6.11) + +There is a regression issue for kernels(<2.6.11) as below: + + $ crash 2.6.9-68.9/vmcore 2.6.9-68.9/vmlinux.gz + ... + GNU gdb (GDB) 10.2 + ... + crash: /var/tmp/vmlinux.gz_GLsAvX and 2.6.9-68.9/vmcore do not match! + +The reason is that it needs to read out the address of linux banner with +readmem() first, and then the read_string() will be able to read the data +from linux banner. So, for the kernels(<2.6.11) case, lets still invoke +get_symbol_data() to accomplish this. See the changes: +[1] https://elixir.bootlin.com/linux/v2.6.10/source/init/version.c#L38 +[2] https://elixir.bootlin.com/linux/v2.6.11/source/init/version.c#L38 + +Signed-off-by: Tao Liu +Signed-off-by: Lianbo Jiang +--- + kernel.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel.c b/kernel.c +index 6a812ac7b1bc..a559f937980e 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -1052,7 +1052,8 @@ verify_version(void) + + if (!(sp = symbol_search("linux_banner"))) + error(FATAL, "linux_banner symbol does not exist?\n"); +- else if ((sp->type == 'R') || (sp->type == 'r') || (sp->type == 'D') || ++ else if ((sp->type == 'R') || (sp->type == 'r') || ++ (THIS_KERNEL_VERSION >= LINUX(2,6,11) && sp->type == 'D') || + (machine_type("ARM") && sp->type == 'T') || + (machine_type("ARM64"))) + linux_banner = symbol_value("linux_banner"); +-- +2.30.2 + diff --git a/0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch b/0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch new file mode 100644 index 0000000..c557cca --- /dev/null +++ b/0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch @@ -0,0 +1,90 @@ +From 51f21b0d1c91a4ae02ebf0d8c81460ec8b6c1283 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Thu, 15 Jul 2021 17:34:29 +0800 +Subject: [PATCH 22/27] x86_64_irq_eframe_link_init: Fix wrong instruction + searching range calculation + +In function x86_64_irq_eframe_link_init, instruction "push xxx" is searched in +addresses range from "common_interrupt" to the next nearby symbol, in order to +calculate the value of irq_eframe_link. The searching distance is given by +max_instructions, which is calculated by end ranging address minus start ranging +address. Then crash asks gdb to disassemble max_instructions quantity of instructions. + +Taking max_instructions as the quantity of disassemble instructions is inappropriate, +because most x86_64 instructions have a length longer than 1, as a consequence, much +more than the actual needed instructions get disassembled. + +In gdb-7.6 crash, the extra instructions are skipped by "if (!strstr(buf, sp->name))", +which breaks if one instruction doesn't belongs to a symbol: + + 0xffffffff8005d5b4 : cld + 0xffffffff8005d5b5 : sub $0x48,%rsp + ... + 0xffffffff8005d61e : leaveq + 0xffffffff8005d61f : mov %gs:0x10,%rcx <--- searching stops here + ... + +In gdb-10.2 crash, "exit_intr" doesn't show, however it really exist. As a result, +searching for "push xxx" will go to a wrong place. + + 0xffffffff8005d5b4 : cld + 0xffffffff8005d5b5 : sub $0x48,%rsp + ... + 0xffffffff8005d61e : leave + 0xffffffff8005d61f : mov %gs:0x10,%rcx <--- searching continues + ... + + (gdb) p exit_intr + $1 = {} 0xffffffff8005d61f + (gdb) info symbol exit_intr + common_interrupt + 107 in section .text + +The previous way to determine start and end searching range is not stable, otherwise we may +encounter regression that cmd "bt" prints wrong IRQ stack. This patch fix the bug by removing +max_instructions calculation, and directly ask gdb to disassemble addresses range from +"common_interrupt" to the next nearby symbol. + +Signed-off-by: Tao Liu +--- + x86_64.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/x86_64.c b/x86_64.c +index d0565ba26a0c..552d6194930b 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -6472,7 +6472,6 @@ x86_64_irq_eframe_link_init(void) + char buf[BUFSIZE]; + char link_register[BUFSIZE]; + char *arglist[MAXARGS]; +- ulong max_instructions; + + if (machdep->machspec->irq_eframe_link == UNINITIALIZED) + machdep->machspec->irq_eframe_link = 0; +@@ -6487,12 +6486,10 @@ x86_64_irq_eframe_link_init(void) + return; + } + +- max_instructions = spn->value - sp->value; +- + open_tmpfile(); + +- sprintf(buf, "x/%ldi 0x%lx", +- max_instructions, sp->value); ++ sprintf(buf, "disassemble 0x%lx, 0x%lx", ++ sp->value, spn->value); + + if (!gdb_pass_through(buf, pc->tmpfile, GNU_RETURN_ON_ERROR)) + return; +@@ -6501,6 +6498,8 @@ x86_64_irq_eframe_link_init(void) + + rewind(pc->tmpfile); + while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (STRNEQ(buf, "Dump of assembler code")) ++ continue; + if (!strstr(buf, sp->name)) + break; + if ((c = parse_line(buf, arglist)) < 4) +-- +2.30.2 + diff --git a/0023-Add-kernel-version-dependent-check-for-getting-lengt.patch b/0023-Add-kernel-version-dependent-check-for-getting-lengt.patch new file mode 100644 index 0000000..550faef --- /dev/null +++ b/0023-Add-kernel-version-dependent-check-for-getting-lengt.patch @@ -0,0 +1,49 @@ +From b8e1f2735b8dd1303aeb2affa309a2a409a82d38 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Mon, 26 Jul 2021 09:58:54 +0800 +Subject: [PATCH 23/27] Add kernel version dependent check for getting length + of log_end + +For kernels(>=2.4.9.11 [1] && <3.5 [2]), log_end was involved in the kernel sources. +For kernels(>=2.6.25 [3]), log_end was defined as: + static unsigned log_end; +For kernels(<2.6.25), log_end was defined as: + static unsigned long log_end; + +Previously, the length of log_end is determined by get_symbol_length, but it can +be a regression when the returned length is 0 for some cases and value unchecked: + + crash> help -t + ... + help: invalid size request: 0 type: "log_end" + +To solve the above issue, let's add a kernel version dependent check to get its +value appropriately when the length of the 'log_end' returns a value of zero. + +[1]: https://elixir.bootlin.com/linux/2.4.9.11/source/kernel/printk.c#L74 +[2]: https://elixir.bootlin.com/linux/v3.5/source/kernel/printk.c +[3]: https://elixir.bootlin.com/linux/v2.6.25/source/kernel/printk.c#L104 + +Signed-off-by: Tao Liu +--- + kernel.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/kernel.c b/kernel.c +index a559f937980e..a8be7bb1947f 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -5106,6 +5106,10 @@ dump_log(int msg_flags) + if ((len = get_symbol_length("log_end")) == sizeof(int)) { + get_symbol_data("log_end", len, &tmp); + log_end = (ulong)tmp; ++ } else if (len == 0) { ++ THIS_KERNEL_VERSION >= LINUX(2,6,25) ? ++ get_symbol_data("log_end", sizeof(unsigned), &log_end) : ++ get_symbol_data("log_end", sizeof(unsigned long), &log_end); + } else + get_symbol_data("log_end", len, &log_end); + +-- +2.30.2 + diff --git a/0024-Set-gdb-max-value-size-to-be-unlimited.patch b/0024-Set-gdb-max-value-size-to-be-unlimited.patch new file mode 100644 index 0000000..c612c70 --- /dev/null +++ b/0024-Set-gdb-max-value-size-to-be-unlimited.patch @@ -0,0 +1,39 @@ +From 5c2d8d2d9da6423eec076fd51049d7b4677b61c6 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Tue, 17 Aug 2021 16:21:43 +0800 +Subject: [PATCH 24/27] Set gdb max-value-size to be unlimited + +gdb-10.2 uses max-value-size as the maximum size in bytes that the contents +of a object may allocate. The default value of max-value-size is 64K. However, +it could be not enough for allocating an object which requires larger space, and +failed at the startup of crash. + +In gdb-7.6, there is no max-value-size check and works fine. So in this patch, +let's just set max-value-size to be unlimited. + +Signed-off-by: Tao Liu +--- + gdb_interface.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/gdb_interface.c b/gdb_interface.c +index b098ed823d55..2fe9ccde83a1 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -300,6 +300,13 @@ retry: + sprintf(req->buf, "set width 0"); + gdb_interface(req); + ++#ifdef GDB_10_2 ++ req->command = GNU_PASS_THROUGH; ++ req->name = NULL, req->flags = 0; ++ sprintf(req->buf, "set max-value-size unlimited"); ++ gdb_interface(req); ++#endif ++ + #if 0 + /* + * Patch gdb's symbol values with the correct values from either +-- +2.30.2 + diff --git a/0025-Fix-tab-completion-issues.patch b/0025-Fix-tab-completion-issues.patch new file mode 100644 index 0000000..66c598a --- /dev/null +++ b/0025-Fix-tab-completion-issues.patch @@ -0,0 +1,55 @@ +From c1e256249426dd59ceea99038451a39e98a26790 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Thu, 19 Aug 2021 10:52:58 +0900 +Subject: [PATCH 25/27] Fix tab completion issues + +1. The maximum number of tab completion candidates is limited to 200 +by default. Set it unlimited. + +2. The output of tab completion is not wrapped with the screen width. +Get and use it when tab completion is invoked. + +Signed-off-by: Kazuhito Hagio +--- + gdb-10.2.patch | 11 +++++++++++ + gdb_interface.c | 5 +++++ + 2 files changed, 16 insertions(+) + +diff --git a/gdb-10.2.patch b/gdb-10.2.patch +index 4f8d418b17ed..1332b6638028 100644 +--- a/gdb-10.2.patch ++++ b/gdb-10.2.patch +@@ -1580,3 +1580,14 @@ + _rl_tracefp = 0; + return r; + } ++--- gdb-10.2/gdb/completer.c.orig +++++ gdb-10.2/gdb/completer.c ++@@ -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 --git a/gdb_interface.c b/gdb_interface.c +index 2fe9ccde83a1..ff45cdcd39ae 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -305,6 +305,11 @@ retry: + req->name = NULL, req->flags = 0; + sprintf(req->buf, "set max-value-size unlimited"); + gdb_interface(req); ++ ++ req->command = GNU_PASS_THROUGH; ++ req->name = NULL, req->flags = 0; ++ sprintf(req->buf, "set max-completions unlimited"); ++ gdb_interface(req); + #endif + + #if 0 +-- +2.30.2 + diff --git a/0026-Remove-text-value-cache-code.patch b/0026-Remove-text-value-cache-code.patch new file mode 100644 index 0000000..7b5889b --- /dev/null +++ b/0026-Remove-text-value-cache-code.patch @@ -0,0 +1,402 @@ +From 05a3a328fcd8920e49926b6d1c9c81ce0b6acbca Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Thu, 9 Sep 2021 15:23:27 +0900 +Subject: [PATCH 26/27] Remove text value cache code + +The text value cache was implemented for analysis of remote dumpfiles +using the deprecated "crash daemon" running on the remote host. On +updating GDB to 10.2, a regression occurred when we tried to fix a +"help -x" command problem, and there was no performance degradation +even without the text cache, so let's drop this functionality. + +Signed-off-by: Kazuhito Hagio +--- + alpha.c | 8 +- + cmdline.c | 1 - + defs.h | 4 - + gdb_interface.c | 14 ---- + help.c | 8 +- + kernel.c | 1 - + symbols.c | 196 ------------------------------------------------ + x86.c | 7 -- + 8 files changed, 3 insertions(+), 236 deletions(-) + +diff --git a/alpha.c b/alpha.c +index fa2d5f5935c9..73497120b4bf 100644 +--- a/alpha.c ++++ b/alpha.c +@@ -776,12 +776,8 @@ alpha_frame_offset(struct gnu_request *req, ulong alt_pc) + * 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); +- } ++ readmem((ulong)ip, KVADDR, &ival, sizeof(uint), ++ "text value", FAULT_ON_ERROR); + + if ((ival & 0xffe01fff) == 0x43c0153e) { + value = (ival & 0x1fe000) >> 13; +diff --git a/cmdline.c b/cmdline.c +index 796f7c58f243..ded6551c2597 100644 +--- a/cmdline.c ++++ b/cmdline.c +@@ -1235,7 +1235,6 @@ restore_sanity(void) + if (CRASHDEBUG(5)) { + dump_filesys_table(0); + dump_vma_cache(0); +- dump_text_value_cache(0); + } + + if (REMOTE()) +diff --git a/defs.h b/defs.h +index b34c60e9a795..cbd45e52f9da 100644 +--- a/defs.h ++++ b/defs.h +@@ -5327,10 +5327,6 @@ char *load_module_filter(char *, int); + long datatype_info(char *, char *, struct datatype_member *); + int get_symbol_type(char *, char *, struct gnu_request *); + int get_symbol_length(char *); +-int text_value_cache(ulong, uint32_t, uint32_t *); +-int text_value_cache_byte(ulong, unsigned char *); +-void dump_text_value_cache(int); +-void clear_text_value_cache(void); + void dump_numargs_cache(void); + int patch_kernel_symbol(struct gnu_request *); + struct syment *generic_machdep_value_to_symbol(ulong, ulong *); +diff --git a/gdb_interface.c b/gdb_interface.c +index ff45cdcd39ae..3a7fcc9e3ade 100644 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -828,7 +828,6 @@ int + gdb_readmem_callback(ulong addr, void *buf, int len, int write) + { + char locbuf[SIZEOF_32BIT], *p1; +- uint32_t *p2; + int memtype; + ulong readflags; + +@@ -885,19 +884,12 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write) + } + + p1 = (char *)buf; +- if ((memtype == KVADDR) && +- text_value_cache_byte(addr, (unsigned char *)p1)) +- return TRUE; + + if (!readmem(addr, memtype, locbuf, SIZEOF_32BIT, + "gdb_readmem_callback", readflags)) + return FALSE; + + *p1 = locbuf[0]; +- if (memtype == KVADDR) { +- p2 = (uint32_t *)locbuf; +- text_value_cache(addr, *p2, 0); +- } + return TRUE; + + case SIZEOF_32BIT: +@@ -907,16 +899,10 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write) + return TRUE; + } + +- if ((memtype == KVADDR) && text_value_cache(addr, 0, buf)) +- return TRUE; +- + if (!readmem(addr, memtype, buf, SIZEOF_32BIT, + "gdb_readmem callback", readflags)) + return FALSE; + +- if (memtype == KVADDR) +- text_value_cache(addr, +- (uint32_t)*((uint32_t *)buf), NULL); + return TRUE; + } + +diff --git a/help.c b/help.c +index e67fde0018ab..c19b69b8b20c 100644 +--- a/help.c ++++ b/help.c +@@ -535,7 +535,7 @@ cmd_help(void) + oflag = 0; + + while ((c = getopt(argcnt, args, +- "efNDdmM:ngcaBbHhkKsvVoptTzLxOr")) != EOF) { ++ "efNDdmM:ngcaBbHhkKsvVoptTzLOr")) != EOF) { + switch(c) + { + case 'e': +@@ -551,10 +551,6 @@ cmd_help(void) + dumpfile_memory(DUMPFILE_MEM_DUMP); + return; + +- case 'x': +- dump_text_value_cache(VERBOSE); +- return; +- + case 'd': + dump_dev_table(); + return; +@@ -666,7 +662,6 @@ cmd_help(void) + fprintf(fp, " -T - task_table plus context_array\n"); + fprintf(fp, " -v - vm_table\n"); + fprintf(fp, " -V - vm_table (verbose)\n"); +- fprintf(fp, " -x - text cache\n"); + fprintf(fp, " -z - help options\n"); + return; + +@@ -1026,7 +1021,6 @@ char *help_help[] = { + " -T - task_table plus context_array", + " -v - vm_table", + " -V - vm_table (verbose)", +-" -x - text cache", + " -z - help options", + NULL + }; +diff --git a/kernel.c b/kernel.c +index a8be7bb1947f..3ead4bbb172e 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -4661,7 +4661,6 @@ reinit_modules(void) + st->ext_module_symtable = NULL; + st->load_modules = NULL; + kt->mods_installed = 0; +- clear_text_value_cache(); + + module_init(); + } +diff --git a/symbols.c b/symbols.c +index 5d3c53a30abc..69dccdb09d5f 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -12824,202 +12824,6 @@ gnu_qsort(bfd *bfd, + qsort(minisyms, symcount, size, numeric_forward); + } + +-/* +- * Keep a stash of commonly-accessed text locations checked by the +- * back_trace code. The saved values unsigned 32-bit values. +- * The same routine is used to store and query, based upon whether +- * the passed-in value and valptr args are non-zero. +- */ +-#define TEXT_CACHE (50) +-#define MAX_TEXT_CACHE (TEXT_CACHE*4) +- +-struct text_cache_entry { +- ulong vaddr; +- uint32_t value; +-}; +- +-static struct text_cache { +- int index; +- int entries; +- ulong hits; +- ulong refs; +- struct text_cache_entry *cache; +-} text_cache = { 0 }; +- +-/* +- * Cache the contents of 32-bit text addresses. If "value" is set, the purpose +- * is to cache it. If "valptr" is set, a query is being made for the text +- * address. +- */ +-int +-text_value_cache(ulong vaddr, uint32_t value, uint32_t *valptr) +-{ +- int i; +- struct text_cache *tc; +- +- if (!is_kernel_text(vaddr)) +- return FALSE; +- +- tc = &text_cache; +- +- if (!tc->cache) { +- if (!(tc->cache = (struct text_cache_entry *) +- malloc(sizeof(struct text_cache_entry) * TEXT_CACHE))) +- return FALSE; +- BZERO(tc->cache, sizeof(struct text_cache_entry) * TEXT_CACHE); +- tc->index = 0; +- tc->entries = TEXT_CACHE; +- } +- +- if (value) { +- for (i = 0; i < tc->entries; i++) { +- if (tc->cache[i].vaddr == vaddr) +- return TRUE; +- } +- +- i = tc->index; +- tc->cache[i].vaddr = vaddr; +- tc->cache[i].value = value; +- tc->index++; +- if (tc->index == MAX_TEXT_CACHE) { +- tc->index = 0; +- } else if (tc->index == tc->entries) { +- struct text_cache_entry *old_cache; +- +- old_cache = tc->cache; +- if ((tc->cache = (struct text_cache_entry *) +- realloc(old_cache, sizeof(struct text_cache_entry) * +- (TEXT_CACHE+tc->entries)))) { +- BZERO(&tc->cache[tc->index], +- sizeof(struct text_cache_entry) * +- TEXT_CACHE); +- tc->entries += TEXT_CACHE; +- } else { +- tc->cache = old_cache; +- tc->index = 0; +- } +- } +- return TRUE; +- } +- +- if (valptr) { +- tc->refs++; +- +- for (i = 0; i < tc->entries; i++) { +- if (!tc->cache[i].vaddr) +- return FALSE; +- +- if (tc->cache[i].vaddr == vaddr) { +- *valptr = tc->cache[i].value; +- tc->hits++; +- return TRUE; +- } +- } +- } +- +- return FALSE; +-} +- +-/* +- * The gdb disassembler reads text memory byte-by-byte, so this routine +- * acts as a front-end to the 32-bit (4-byte) text storage. +- */ +- +-int +-text_value_cache_byte(ulong vaddr, unsigned char *valptr) +-{ +- int i; +- int shift; +- struct text_cache *tc; +- ulong valtmp; +- +- if (!is_kernel_text(vaddr)) +- return FALSE; +- +- tc = &text_cache; +- +- tc->refs++; +- +- for (i = 0; i < tc->entries; i++) { +- if (!tc->cache[i].vaddr) +- return FALSE; +- +- if ((vaddr >= tc->cache[i].vaddr) && +- (vaddr < (tc->cache[i].vaddr+SIZEOF_32BIT))) { +- valtmp = tc->cache[i].value; +- shift = (vaddr - tc->cache[i].vaddr) * 8; +- valtmp >>= shift; +- *valptr = valtmp & 0xff; +- tc->hits++; +- return TRUE; +- } +- } +- return FALSE; +-} +- +-void +-dump_text_value_cache(int verbose) +-{ +- int i; +- struct syment *sp; +- ulong offset; +- struct text_cache *tc; +- +- tc = &text_cache; +- +- if (!verbose) { +- if (!tc->refs || !tc->cache) +- return; +- +- fprintf(stderr, " text hit rate: %2ld%% (%ld of %ld)\n", +- (tc->hits * 100)/tc->refs, +- (ulong)tc->hits, (ulong)tc->refs); +- return; +- } +- +- for (i = 0; tc->cache && (i < tc->entries); i++) { +- if (!tc->cache[i].vaddr) +- break; +- fprintf(fp, "[%2d]: %lx %08x ", i, tc->cache[i].vaddr, +- tc->cache[i].value); +- if ((sp = value_search(tc->cache[i].vaddr, &offset))) { +- fprintf(fp, "(%s+", sp->name); +- switch (pc->output_radix) +- { +- case 10: +- fprintf(fp, "%ld)", offset); +- break; +- case 16: +- fprintf(fp, "%lx)", offset); +- break; +- } +- } +- fprintf(fp, "\n"); +- } +- +- fprintf(fp, +- "text_cache entries: %d index: %d hit rate: %ld%% (%ld of %ld)\n", +- tc->entries, tc->index, +- (tc->hits * 100)/(tc->refs ? tc->refs : 1), +- tc->hits, tc->refs); +- +-} +- +-void +-clear_text_value_cache(void) +-{ +- int i; +- struct text_cache *tc; +- +- tc = &text_cache; +- tc->index = 0; +- +- for (i = 0; tc->cache && (i < tc->entries); i++) { +- tc->cache[i].vaddr = 0; +- tc->cache[i].value = 0; +- } +-} +- + /* + * If a System.map file or a debug kernel was specified, the name hash + * has been filled -- so sync up gdb's notion of symbol values with +diff --git a/x86.c b/x86.c +index a174bbc7737c..b36f44c54819 100644 +--- a/x86.c ++++ b/x86.c +@@ -474,17 +474,10 @@ db_get_value(addr, size, is_signed, bt) + else + GET_STACK_DATA(addr, data, size); + } else { +- if ((size == sizeof(int)) && +- text_value_cache(addr, 0, (uint32_t *)&value)) +- return value; +- + if (!readmem(addr, KVADDR, &value, size, "db_get_value", + RETURN_ON_ERROR)) + error(FATAL, "db_get_value: read error: address: %lx\n", + addr); +- +- if (size == sizeof(int)) +- text_value_cache(addr, value, NULL); + } + #endif + +-- +2.30.2 + diff --git a/0027-.gitignore-add-gdb-10.2-directory.patch b/0027-.gitignore-add-gdb-10.2-directory.patch new file mode 100644 index 0000000..c7537e8 --- /dev/null +++ b/0027-.gitignore-add-gdb-10.2-directory.patch @@ -0,0 +1,25 @@ +From f7e3b2d9b753793e230a5242974a111cdf139e49 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Thu, 30 Sep 2021 11:04:31 +0900 +Subject: [PATCH 27/27] .gitignore: add gdb-10.2 directory + +Signed-off-by: Kazuhito Hagio +--- + .gitignore | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.gitignore b/.gitignore +index b39832fa71df..f391c5d340f9 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -11,6 +11,7 @@ crash.spec + *.rpm + gdb.files + gdb-7.6/ ++gdb-10.2/ + extensions/defs.h + extensions/*.so + extensions/eppic +-- +2.30.2 + diff --git a/crash.spec b/crash.spec index 75f8cee..f8348d7 100644 --- a/crash.spec +++ b/crash.spec @@ -4,19 +4,19 @@ Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash Version: 7.3.0 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3 Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz -Source1: http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz +Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz URL: https://crash-utility.github.io ExclusiveOS: Linux ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le -BuildRequires: ncurses-devel zlib-devel lzo-devel snappy-devel bison wget patch +BuildRequires: ncurses-devel zlib-devel lzo-devel snappy-devel bison wget patch texinfo libzstd-devel BuildRequires: gcc gcc-c++ BuildRequires: make Requires: binutils Provides: bundled(libiberty) -Provides: bundled(gdb) = 7.6 +Provides: bundled(gdb) = 10.2 Patch0: lzo_snappy.patch Patch1: 0001-arm64-Add-lowercase-tcr_el1_t1sz.patch Patch2: 0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch @@ -34,6 +34,33 @@ Patch13: 0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch Patch14: 0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch Patch15: 0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch Patch16: 0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch +Patch17: 0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch +Patch18: 0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch +Patch19: 0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch +Patch20: 0004-diskdump-Print-total-number-of-dumpable-pages.patch +Patch21: 0005-diskdump-Introduce-read_pd.patch +Patch22: 0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch +Patch23: 0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch +Patch24: 0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch +Patch25: 0009-ppc64-Add-MMU-type-info-in-machdep-command.patch +Patch26: 0010-mod-fix-module-object-file-lookup.patch +Patch27: 0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch +Patch28: 0012-Update-to-gdb-10.2.patch +Patch29: 0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch +Patch30: 0014-whatis-m-fix-duplications-in-the-output.patch +Patch31: 0015-Fix-reduced-output-of-bt-command.patch +Patch32: 0016-crash_taget-fetch_registers-support.patch +Patch33: 0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch +Patch34: 0018-vmware-backend-honor-silence-flag.patch +Patch35: 0019-vmware_guestdump-add-debugging-of-the-init-function.patch +Patch36: 0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch +Patch37: 0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch +Patch38: 0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch +Patch39: 0023-Add-kernel-version-dependent-check-for-getting-lengt.patch +Patch40: 0024-Set-gdb-max-value-size-to-be-unlimited.patch +Patch41: 0025-Fix-tab-completion-issues.patch +Patch42: 0026-Remove-text-value-cache-code.patch +Patch43: 0027-.gitignore-add-gdb-10.2-directory.patch %description The core analysis suite is a self-contained tool that can be used to @@ -70,6 +97,33 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch14 -p1 %patch15 -p1 %patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 %build # This package has an internal copy of GDB which has broken configure code for @@ -78,6 +132,8 @@ offered by Mission Critical Linux, or the LKCD kernel patch. # maintainer. # Disable LTO %define _lto_cflags %{nil} +# Disable hardened package +%undefine _hardened_build cp %{SOURCE1} . make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}" @@ -101,6 +157,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash %{_includedir}/* %changelog +* Tue Oct 12 2021 Lianbo Jiang - 7.3.0-4 +- Update to gdb-10.2 + * Wed Jul 21 2021 Fedora Release Engineering - 7.3.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index f169968..e8fb89c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (crash-7.3.0.tar.gz) = bc288821892c3d7ecbf192d9fe6ea9e73216f8074a24d12a00fbcaf967a1faa38ee69c4a5a97aa93bf75426293f5b275f5ab496c154b4e7be265ba0e263b2bc8 -SHA512 (gdb-7.6.tar.gz) = 02d9c62fa73bcb79138d14c7fc182443f0ca82d4545b4d260b67d3f0074ed75f899a657814a56727e601032a668b0ddd7b48aabd49215fc012eeea6077bca368 +SHA512 (gdb-10.2.tar.gz) = aa89caf47c1c84366020377d47e7c51ddbc48e5b7686f244e38797c8eb88411cf57fcdc37eb669961efb41ceeac4181747f429625fd1acce7712cb9a1fea9c41