├── README.md ├── TUTORIAL.md ├── gdb └── bin │ └── x86_64 │ ├── .gdbinit │ ├── amd-gdb │ ├── data-directory │ ├── Makefile │ ├── python │ │ └── gdb │ │ │ ├── FrameDecorator.py │ │ │ ├── FrameIterator.py │ │ │ ├── __init__.py │ │ │ ├── command │ │ │ ├── __init__.py │ │ │ ├── explore.py │ │ │ ├── frame_filters.py │ │ │ ├── pretty_printers.py │ │ │ ├── prompt.py │ │ │ ├── type_printers.py │ │ │ ├── unwinders.py │ │ │ └── xmethods.py │ │ │ ├── frames.py │ │ │ ├── function │ │ │ ├── __init__.py │ │ │ ├── caller_is.py │ │ │ └── strfns.py │ │ │ ├── printer │ │ │ ├── __init__.py │ │ │ └── bound_registers.py │ │ │ ├── printing.py │ │ │ ├── prompt.py │ │ │ ├── types.py │ │ │ ├── unwinder.py │ │ │ └── xmethod.py │ ├── stamp-guile │ ├── stamp-python │ ├── stamp-syscalls │ ├── stamp-system-gdbinit │ ├── syscalls │ │ ├── aarch64-linux.xml │ │ ├── amd64-linux.xml │ │ ├── arm-linux.xml │ │ ├── gdb-syscalls.dtd │ │ ├── i386-linux.xml │ │ ├── mips-n32-linux.xml │ │ ├── mips-n64-linux.xml │ │ ├── mips-o32-linux.xml │ │ ├── ppc-linux.xml │ │ ├── ppc64-linux.xml │ │ ├── s390-linux.xml │ │ ├── s390x-linux.xml │ │ ├── sparc-linux.xml │ │ └── sparc64-linux.xml │ └── system-gdbinit │ │ ├── elinos.py │ │ └── wrs-linux.py │ └── rocm-gdb └── gpudebugsdk ├── include ├── AMDGPUDebug.h ├── common │ ├── elfdefinitions.h │ └── linux │ │ └── sys │ │ └── elf_common.h └── libelf.h ├── lib └── x86_64 │ ├── libAMDGPUDebugHSA-x64.so │ ├── libAMDHSADebugAgent-x64.so │ ├── libAMDHwDbgFacilities-x64.so │ └── libelf.a └── samples ├── Common ├── HSAExtensionFinalizer.cpp ├── HSAExtensionFinalizer.h ├── HSAResourceManager.cpp └── HSAResourceManager.h └── MatrixMultiplication ├── Makefile ├── MatrixMul.cpp ├── matrixMul_kernel.brig └── matrixMul_kernel.hsail /README.md: -------------------------------------------------------------------------------- 1 | # ROCm Debugger - Deprecated Project 2 | ## This ROCm Debugger is a Deprecated project. 3 | As of 2018, this is a deprecated software project. The ROCm software team is working on a new GDB-based debugger that works with the ROCr Debug Agent to support debugging GPU kernels. 4 | 5 | ## Overview 6 | The ROCm Debugger provides a gdb-based debugging environment for debugging host application and GPU kernels running on Radeon Open Compute platforms (ROCm). 7 | It can support all language runtimes (such as HIP and HCC) built on top of ROCm. Initially, the debugging support within the GPU kernels starts with the 8 | HSAIL 1.0 programming language. This support requires a kernel compilation path that goes through HSAIL kernel (such as through HCC-HSAIL or [libHSAIL/HSAILAsm](https://github.com/HSAFoundation/HSAIL-Tools)). 9 | 10 | There are two packages included in this release: 11 | * ROCm gdb package that contains the rocm-gdb tool 12 | * based on GDB 7.11, the GNU source-level debugger 13 | * ROCm GPU Debug SDK package that contains the necessary header, library and sample files to run the rocm-gdb tool 14 | 15 | The ROCm Debugger extends the existing [HSA Debugger](https://github.com/HSAFoundation/HSA-Debugger-AMD) with new features for ROCm . 16 | 17 | ## Table of Contents 18 | * [Major Features](#major-features) 19 | * [What's New](#whats-new) 20 | * [System Requirements](#system-requirements) 21 | * [Package Contents](#package-contents) 22 | * [Installation](#installation) 23 | * [Usage Examples](TUTORIAL.md) 24 | * [Known Issues](#known-issues) 25 | * [ROCm GDB LICENSE](gdb/LICENSE.txt) and [SDK LICENSE](gpudebugsdk/LICENSE.txt) 26 | 27 | ## Major Features 28 | * Seamless host application and GPU kernel source debugging using a familiar gdb-based debugging environment on ROCm 29 | * Set GPU kernel breakpoints, single stepping and inspect registers within HSAIL kernel source 30 | * View active GPU states (active work-groups, work-items and wavefronts information) 31 | * Disassemble GPU kernel at GPU kernel function and source breakpoint 32 | * Trace GPU kernel launches into an output file 33 | 34 | ## What's New in May 2017 Release (version 1.5) 35 | * Compatible with [ROCm 1.5 release](https://github.com/RadeonOpenCompute/ROCm) 36 | * Added the *info rocm devices* command to show the available devices in the system 37 | 38 | 39 | ## What's New in Dec 2016 Release (version 1.4) 40 | * Compatible with [ROCm 1.4 release](https://github.com/RadeonOpenCompute/ROCm) 41 | * Support for demangling kernel names of HIP and HCC kernels (requires *clang_tot_upgrade* branch of HCC). Also requires c++filt to be intalled on the system. c++filt can be installed using *sudo apt-get install binutils* 42 | 43 | ## What's New in Nov 2016 Release (version 1.3) 44 | * Compatible with [ROCm 1.3 release](https://github.com/RadeonOpenCompute/ROCm) 45 | * Support for AMD code object loader extension 46 | * Initial support for Polaris GPUs 47 | * Detect and gracefully fail on unsupported devices 48 | 49 | ## What's New in Aug 2016 Release (version 1.2) 50 | * Compatible with [ROCm 1.2 release](https://github.com/RadeonOpenCompute/ROCm) 51 | * Update gdb base to gdb v7.11. 52 | * Initial support for provided GPU debug information via the GDB machine interface 53 | * Support for debugging applications that use SIGUSR2. (Provided by [Pull Request#1](https://github.com/RadeonOpenCompute/ROCm-GDB/pull/1) from Didier Nadeaud) 54 | * Add support to report HSAIL source text along with line number when single stepping. 55 | 56 | ## What's New in April 2016 Release (version 1.0) 57 | * Compatible with [ROCm 1.0 release](https://github.com/RadeonOpenCompute/ROCm) 58 | * Support 6th Generation AMD A-series APU processors (codenamed “Carrizo”) 59 | * Support AMD Radeon™ R9 Fury, Fury X and Fury Nano GPUs (codenamed “Fiji”) 60 | * Support [CodeXL 2.0](https://github.com/GPUOpen-Tools/CodeXL/tree/v2.0) 61 | * Add support to gdb *disassemble* command to disassemble and show the GPU isa disassembly text 62 | * Add ability to trace GPU kernel launches 63 | * Add gdb *help rocm* command to show the list of rocm debugging related commands 64 | * Add support to report the hardware slot scheduling information for wavefronts 65 | 66 | ## System Requirements 67 | * Boltzmann system 68 | * CPU: CPUs with PCIe Gen3 Atomics: Haswell-class Intel(c) Core CPUs v3 or newer and Intel Xeon E5 v3 or newer. 69 | * GPU: AMD Radeon™ R9 Fury, Fury X and Fury Nano GPUs (codenamed “Fiji”) 70 | * Refer to the [ROCm platform requirements](https://radeonopencompute.github.io/hardware.html) for additional information 71 | * or 6th Generation AMD A-series APU processors (codenamed “Carrizo”). 72 | * OS: 64-bit Ubuntu 14.04 and Fedora 23 73 | * [ROCm 1.2 platform](https://github.com/RadeonOpenCompute/ROCm) 74 | 75 | To debug within a GPU kernel, the GPU kernel must be assembled using the latest [LibHSAIL/HSAILAsm](https://github.com/HSAFoundation/HSAIL-Tools) (from April 4th 2016 or newer) built with *BUILD_WITH_LIBBRIGDWARF=1*. 76 | 77 | ## Package Contents 78 | The directory structure of the ROCm Debugger packages: 79 | * *gpudebugsdk* 80 | * *include* 81 | * *AMDGPUDebug.h*, *FacilitiesInterface.h* 82 | * *bin/x86_64* 83 | * *amd-debug-lock*, *rocm-gdb-debug-flags.sh* 84 | * *lib/x86_64* 85 | * *libAMDGPUDebugHSA-x64.so*, *libAMDHSADebugAgent-x64.so*, *libAMDHwDbgFacilities-x64.so* 86 | * *samples* 87 | * *Common* 88 | * *HSAResourceManager.h*, *HSAResourceManager.cpp*, *HSAExtensionFinalizer.h*, *HSAExtensionFinalizer.cpp* 89 | * *MatrixMultiplication* 90 | * *Makefile*, *MatrixMul.cpp*, *matrixMul_kernel.brig*, *matrixMul_kernel.hsail* 91 | * *LICENSE.txt* 92 | * *gdb* 93 | * *bin/x86_64* 94 | * *rocm-gdb*, *amd-gdb*, *.gdbinit*, *data-directory* 95 | * *LICENSE.txt* 96 | * *ubuntu* 97 | * *rocm-gpudebugsdk_\_amd64.deb* 98 | * *rocm-gdb_\_amd64.deb* 99 | 100 | If you download the ROCm Debugger packages or files separately, you must create the same directory structure as shown above in order to run rocm-gdb successfully. 101 | 102 | ## Installation 103 | First, make sure that the ROCm platform is setup correctly. 104 | * [Install ROCm](https://github.com/RadeonOpenCompute/ROCm#installing-from-amd-rocm-repositories) 105 | * [Verify the setup by running HSAIL *vector_copy* sample successfully](https://github.com/RadeonOpenCompute/ROCm#verify-installation) 106 | * Note that with the default *vector_copy* sample, you can't single step within the GPU kernel as the GPU kernel is not compiled with debugging support. 107 | * As part of the ROCm debugger package, there is a sample *MatrixMultiplication* that can be used with rocm-gdb. 108 | * Install c++filt using *sudo apt-get install binutils* 109 | 110 | ###ROCm Debugger Installation 111 | 1. If you did not install ROCm Debugger as part of the ROCm installation, you can download the ROCm Debugger debian packages (*rocm-gpudebugsdk_\_amd64.deb* and *rocm-gdb_\_amd64.deb*) independently and install them as follows. 112 | * `sudo dpkg -i rocm-gpudebugsdk__amd64.deb` 113 | * `sudo dpkg -i rocm-gdb__amd64.deb` 114 | * The installed files will be placed in */opt/rocm/gpudebugsdk* and */opt/rocm/gdb* folders. 115 | * Note that both *rocm-gpudebugsdk* and *rocm-gdb* debian packages are included as part of the [ROCm](https://github.com/RadeonOpenCompute/ROCm#installing-from-amd-rocm-repositories) repo install. 116 | 2. Verify the setup 117 | * Run the *MatrixMultiplication* sample provided in the GPU Debug SDK package 118 | * `cd /opt/rocm/gpudebugsdk/samples/MatrixMultiplication` 119 | * `make` 120 | * The *Makefile* assumes that the hsa header files are located at */opt/rocm/hsa/include*. If you encounter a compilation failure, please update the *HSADIR* within the *Makefile* to the directory of the hsa header files in the system. 121 | * Note that *matrixMul_kernel.hsail* is included for reference only. This sample will load the pre-built brig binary (*matrixMul_kernel.brig*) to run the kernel. 122 | * `/opt/rocm/bin/rocm-gdb MatrixMul` 123 | * Tips: include the */opt/rocm/bin* in your *PATH* environment variable 124 | 125 | ## Usage Examples 126 | Check out the [tutorial](TUTORIAL.md) for some usage examples. 127 | 128 | ## Known Issues 129 | * Debugging hsa code objects that contain more than one BRIG module are not supported 130 | * Debugging HSAIL kernels that contain global (or read only) variables are not supported 131 | * Debugging HSAIL kernels that contain HSAIL function calls are not supported 132 | * Using rocm-gdb objects in python scripts is not yet supported 133 | * Single stepping branch instructions could require multiple step commands 134 | 135 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/.gdbinit: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved. 2 | 3 | # Enable this when debugging a gdb 4 | 5 | add-auto-load-safe-path / 6 | 7 | 8 | define ROCmConfigure 9 | # Enable logging, the file will be deleted by the high level script 10 | # if logging isnt desired as per the env variable 11 | set logging on 12 | 13 | #give a warning of the evil that has been done 14 | echo ROCm Configure Steps Done\n 15 | echo ....Certain GDB signals have been changed\n 16 | 17 | set pagination off 18 | handle SIGUSR1 nostop pass noprint 19 | set mi-async on 20 | end 21 | 22 | document ROCmConfigure 23 | This command configures GDB internals for debugging ROCm kernels 24 | end 25 | 26 | define ROCmReset 27 | 28 | echo Undoing ROCm configuration steps\n 29 | echo ROCm applications will not work anymore\n 30 | 31 | handle SIGCHLD nostop pass noprint 32 | handle SIGUSR1 stop pass print 33 | set pagination on 34 | set mi-async off 35 | end 36 | 37 | ROCmConfigure 38 | 39 | # Enable this to save the last gdb session's commands into ./gdb_history. 40 | #shell rm ./gdb_history 41 | #set history filename ./gdb_history 42 | #set history save 43 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/amd-gdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gdb/bin/x86_64/amd-gdb -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 2 | 3 | # Makefile for building a staged copy of the data-directory. 4 | # This file is part of GDB. 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | srcdir = ../../../gdb/data-directory 20 | SYSCALLS_SRCDIR = $(srcdir)/../syscalls 21 | PYTHON_SRCDIR = $(srcdir)/../python/lib 22 | GUILE_SRCDIR = $(srcdir)/../guile/lib 23 | SYSTEM_GDBINIT_SRCDIR = $(srcdir)/../system-gdbinit 24 | VPATH = $(srcdir):$(SYSCALLS_SRCDIR):$(PYTHON_SRCDIR):$(GUILE_SRCDIR):$(SYSTEM_GDBINIT_SRCDIR) 25 | 26 | top_srcdir = ../../../gdb 27 | top_builddir = .. 28 | 29 | prefix = /usr/local 30 | exec_prefix = ${prefix} 31 | 32 | datarootdir = ${prefix}/share 33 | datadir = ${datarootdir} 34 | 35 | SHELL = /bin/bash 36 | 37 | LN_S = ln -s 38 | 39 | INSTALL = /usr/bin/install -c 40 | INSTALL_DATA = /usr/bin/install -c -m 644 41 | INSTALL_DIR = $(SHELL) $(srcdir)/../../mkinstalldirs 42 | 43 | GDB_DATADIR = ${datarootdir}/gdb 44 | 45 | SYSCALLS_DIR = syscalls 46 | SYSCALLS_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(SYSCALLS_DIR) 47 | SYSCALLS_FILES = \ 48 | gdb-syscalls.dtd \ 49 | arm-linux.xml aarch64-linux.xml \ 50 | ppc-linux.xml ppc64-linux.xml \ 51 | i386-linux.xml amd64-linux.xml \ 52 | sparc-linux.xml sparc64-linux.xml \ 53 | mips-o32-linux.xml mips-n32-linux.xml mips-n64-linux.xml \ 54 | s390-linux.xml s390x-linux.xml 55 | 56 | PYTHON_DIR = python 57 | PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR) 58 | PYTHON_FILE_LIST = \ 59 | gdb/__init__.py \ 60 | gdb/frames.py \ 61 | gdb/FrameIterator.py \ 62 | gdb/FrameDecorator.py \ 63 | gdb/types.py \ 64 | gdb/printing.py \ 65 | gdb/unwinder.py \ 66 | gdb/prompt.py \ 67 | gdb/xmethod.py \ 68 | gdb/command/__init__.py \ 69 | gdb/command/xmethods.py \ 70 | gdb/command/frame_filters.py \ 71 | gdb/command/unwinders.py \ 72 | gdb/command/type_printers.py \ 73 | gdb/command/pretty_printers.py \ 74 | gdb/command/prompt.py \ 75 | gdb/command/explore.py \ 76 | gdb/function/__init__.py \ 77 | gdb/function/caller_is.py \ 78 | gdb/function/strfns.py \ 79 | gdb/printer/__init__.py \ 80 | gdb/printer/bound_registers.py 81 | 82 | PYTHON_FILES = $(PYTHON_FILE_LIST) 83 | #PYTHON_FILES = 84 | 85 | GUILE_DIR = guile 86 | GUILE_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(GUILE_DIR) 87 | 88 | GUILE_SOURCE_FILES = \ 89 | ./gdb.scm \ 90 | gdb/boot.scm \ 91 | gdb/experimental.scm \ 92 | gdb/init.scm \ 93 | gdb/iterator.scm \ 94 | gdb/printing.scm \ 95 | gdb/support.scm \ 96 | gdb/types.scm 97 | 98 | GUILE_COMPILED_FILES = \ 99 | ./gdb.go \ 100 | gdb/experimental.go \ 101 | gdb/iterator.go \ 102 | gdb/printing.go \ 103 | gdb/support.go \ 104 | gdb/types.go 105 | 106 | #GUILE_FILES = $(GUILE_SOURCE_FILES) $(GUILE_COMPILED_FILES) 107 | GUILE_FILES = 108 | 109 | GUILD = 110 | GUILD_TARGET_FLAG = 111 | 112 | # Flags passed to 'guild compile'. 113 | # Note: We can't use -Wunbound-variable because all the variables 114 | # defined in C aren't visible when we compile. 115 | # Note: To work around a guile 2.0.5 issue (it can't find gdb/init.scm even if 116 | # we pass -L ) we have to compile in the directory containing gdb.scm. 117 | # We still need to pass "-L ." so that other modules are found. 118 | GUILD_COMPILE_FLAGS = \ 119 | $(GUILD_TARGET_FLAG) \ 120 | -Warity-mismatch -Wformat -Wunused-toplevel \ 121 | -L . 122 | 123 | SYSTEM_GDBINIT_DIR = system-gdbinit 124 | SYSTEM_GDBINIT_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(SYSTEM_GDBINIT_DIR) 125 | SYSTEM_GDBINIT_FILES = \ 126 | elinos.py \ 127 | wrs-linux.py 128 | 129 | FLAGS_TO_PASS = \ 130 | "prefix=$(prefix)" \ 131 | "exec_prefix=$(exec_prefix)" \ 132 | "infodir=$(infodir)" \ 133 | "datarootdir=$(datarootdir)" \ 134 | "docdir=$(docdir)" \ 135 | "htmldir=$(htmldir)" \ 136 | "pdfdir=$(pdfdir)" \ 137 | "libdir=$(libdir)" \ 138 | "mandir=$(mandir)" \ 139 | "datadir=$(datadir)" \ 140 | "includedir=$(includedir)" \ 141 | "against=$(against)" \ 142 | "DESTDIR=$(DESTDIR)" \ 143 | "AR=$(AR)" \ 144 | "AR_FLAGS=$(AR_FLAGS)" \ 145 | "CC=$(CC)" \ 146 | "CFLAGS=$(CFLAGS)" \ 147 | "CXX=$(CXX)" \ 148 | "CXXFLAGS=$(CXXFLAGS)" \ 149 | "DLLTOOL=$(DLLTOOL)" \ 150 | "LDFLAGS=$(LDFLAGS)" \ 151 | "RANLIB=$(RANLIB)" \ 152 | "MAKEINFO=$(MAKEINFO)" \ 153 | "MAKEHTML=$(MAKEHTML)" \ 154 | "MAKEHTMLFLAGS=$(MAKEHTMLFLAGS)" \ 155 | "INSTALL=$(INSTALL)" \ 156 | "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ 157 | "INSTALL_DATA=$(INSTALL_DATA)" \ 158 | "RUNTEST=$(RUNTEST)" \ 159 | "RUNTESTFLAGS=$(RUNTESTFLAGS)" 160 | 161 | .PHONY: all 162 | all: stamp-syscalls stamp-python stamp-guile stamp-system-gdbinit 163 | 164 | # For portability's sake, we need to handle systems that don't have 165 | # symbolic links. 166 | stamp-syscalls: Makefile $(SYSCALLS_FILES) 167 | rm -rf ./$(SYSCALLS_DIR) 168 | mkdir ./$(SYSCALLS_DIR) 169 | files='$(SYSCALLS_FILES)' ; \ 170 | for file in $$files ; do \ 171 | f=$(SYSCALLS_SRCDIR)/$$file ; \ 172 | if test -f $$f ; then \ 173 | $(INSTALL_DATA) $$f ./$(SYSCALLS_DIR) ; \ 174 | fi ; \ 175 | done 176 | touch $@ 177 | 178 | .PHONY: clean-syscalls 179 | clean-syscalls: 180 | rm -rf $(SYSCALLS_DIR) 181 | rm -f stamp-syscalls 182 | 183 | # This target is responsible for properly installing the syscalls' 184 | # XML files in the system. 185 | .PHONY: install-syscalls 186 | install-syscalls: 187 | $(INSTALL_DIR) $(SYSCALLS_INSTALL_DIR) 188 | files='$(SYSCALLS_FILES)' ; \ 189 | for file in $$files; do \ 190 | f=$(SYSCALLS_SRCDIR)/$$file ; \ 191 | if test -f $$f ; then \ 192 | $(INSTALL_DATA) $$f $(SYSCALLS_INSTALL_DIR) ; \ 193 | fi ; \ 194 | done 195 | 196 | .PHONY: uninstall-syscalls 197 | uninstall-syscalls: 198 | files='$(SYSCALLS_FILES)' ; \ 199 | for file in $$files ; do \ 200 | slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'` ; \ 201 | rm -f $(SYSCALLS_INSTALL_DIR)/$$file ; \ 202 | while test "x$$file" != "x$$slashdir" ; do \ 203 | rmdir 2>/dev/null "$(SYSCALLS_INSTALL_DIR)$$slashdir" ; \ 204 | file="$$slashdir" ; \ 205 | slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 206 | done \ 207 | done 208 | 209 | stamp-python: Makefile $(PYTHON_FILES) 210 | rm -rf ./$(PYTHON_DIR) 211 | files='$(PYTHON_FILES)' ; \ 212 | if test "x$$files" != x ; then \ 213 | for file in $$files ; do \ 214 | dir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 215 | $(INSTALL_DIR) ./$(PYTHON_DIR)/$$dir ; \ 216 | $(INSTALL_DATA) $(PYTHON_SRCDIR)/$$file ./$(PYTHON_DIR)/$$dir ; \ 217 | done ; \ 218 | fi 219 | touch $@ 220 | 221 | .PHONY: clean-python 222 | clean-python: 223 | rm -rf $(PYTHON_DIR) 224 | rm -f stamp-python 225 | 226 | .PHONY: install-python 227 | install-python: 228 | files='$(PYTHON_FILES)' ; \ 229 | if test "x$$files" != x ; then \ 230 | for file in $$files ; do \ 231 | dir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 232 | $(INSTALL_DIR) $(PYTHON_INSTALL_DIR)/$$dir ; \ 233 | $(INSTALL_DATA) ./$(PYTHON_DIR)/$$file $(PYTHON_INSTALL_DIR)/$$dir ; \ 234 | done ; \ 235 | fi 236 | 237 | .PHONY: uninstall-python 238 | uninstall-python: 239 | files='$(PYTHON_FILES)' ; \ 240 | if test "x$$files" != x ; then \ 241 | for file in $$files ; do \ 242 | slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'` ; \ 243 | rm -f $(PYTHON_INSTALL_DIR)/$$file ; \ 244 | while test "x$$file" != "x$$slashdir" ; do \ 245 | rmdir 2>/dev/null "$(PYTHON_INSTALL_DIR)$$slashdir" ; \ 246 | file="$$slashdir" ; \ 247 | slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 248 | done \ 249 | done ; \ 250 | fi 251 | 252 | stamp-guile: Makefile $(GUILE_SOURCE_FILES) 253 | rm -rf ./$(GUILE_DIR) 254 | if test "x$(GUILE_FILES)" != x ; then \ 255 | files='$(GUILE_SOURCE_FILES)' ; \ 256 | for file in $$files ; do \ 257 | dir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 258 | $(INSTALL_DIR) ./$(GUILE_DIR)/$$dir ; \ 259 | $(INSTALL_DATA) $(GUILE_SRCDIR)/$$file ./$(GUILE_DIR)/$$dir ; \ 260 | done ; \ 261 | files='$(GUILE_COMPILED_FILES)' ; \ 262 | cd ./$(GUILE_DIR) ; \ 263 | for go in $$files ; do \ 264 | source="`echo $$go | sed 's/\.go$$/.scm/'`" ; \ 265 | echo $(GUILD) compile $(GUILD_COMPILE_FLAGS) -o "$$go" "$$source" ; \ 266 | $(GUILD) compile $(GUILD_COMPILE_FLAGS) -o "$$go" "$$source" || exit 1 ; \ 267 | done ; \ 268 | fi 269 | touch $@ 270 | 271 | .PHONY: clean-guile 272 | clean-guile: 273 | rm -rf $(GUILE_DIR) 274 | rm -f stamp-guile 275 | 276 | .PHONY: install-guile 277 | install-guile: 278 | files='$(GUILE_FILES)' ; \ 279 | if test "x$$files" != x ; then \ 280 | for file in $$files ; do \ 281 | dir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 282 | $(INSTALL_DIR) $(GUILE_INSTALL_DIR)/$$dir ; \ 283 | $(INSTALL_DATA) ./$(GUILE_DIR)/$$file $(GUILE_INSTALL_DIR)/$$dir ; \ 284 | done ; \ 285 | fi 286 | 287 | .PHONY: uninstall-guile 288 | uninstall-guile: 289 | files='$(GUILE_FILES)' ; \ 290 | if test "x$$files" != x ; then \ 291 | for file in $$files ; do \ 292 | slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'` ; \ 293 | rm -f $(GUILE_INSTALL_DIR)/$$file ; \ 294 | while test "x$$file" != "x$$slashdir" ; do \ 295 | rmdir 2>/dev/null "$(GUILE_INSTALL_DIR)$$slashdir" ; \ 296 | file="$$slashdir" ; \ 297 | slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 298 | done \ 299 | done ; \ 300 | fi 301 | 302 | stamp-system-gdbinit: Makefile $(SYSTEM_GDBINIT_FILES) 303 | rm -rf ./$(SYSTEM_GDBINIT_DIR) 304 | mkdir ./$(SYSTEM_GDBINIT_DIR) 305 | files='$(SYSTEM_GDBINIT_FILES)' ; \ 306 | for file in $$files ; do \ 307 | f=$(SYSTEM_GDBINIT_SRCDIR)/$$file ; \ 308 | if test -f $$f ; then \ 309 | $(INSTALL_DATA) $$f ./$(SYSTEM_GDBINIT_DIR) ; \ 310 | fi ; \ 311 | done 312 | touch $@ 313 | 314 | .PHONY: clean-system-gdbinit 315 | clean-system-gdbinit: 316 | rm -rf $(SYSTEM_GDBINIT_DIR) 317 | rm -f stamp-system-gdbinit 318 | 319 | .PHONY: install-system-gdbinit 320 | install-system-gdbinit: 321 | $(INSTALL_DIR) $(SYSTEM_GDBINIT_INSTALL_DIR) 322 | files='$(SYSTEM_GDBINIT_FILES)' ; \ 323 | for file in $$files; do \ 324 | f=$(SYSTEM_GDBINIT_SRCDIR)/$$file ; \ 325 | if test -f $$f ; then \ 326 | $(INSTALL_DATA) $$f $(SYSTEM_GDBINIT_INSTALL_DIR) ; \ 327 | fi ; \ 328 | done 329 | 330 | .PHONY: uninstall-system-gdbinit 331 | uninstall-system-gdbinit: 332 | files='$(SYSTEM_GDBINIT_FILES)' ; \ 333 | for file in $$files ; do \ 334 | slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'` ; \ 335 | rm -f $(SYSTEM_GDBINIT_INSTALL_DIR)/$$file ; \ 336 | while test "x$$file" != "x$$slashdir" ; do \ 337 | rmdir 2>/dev/null "$(SYSTEM_GDBINIT_INSTALL_DIR)$$slashdir" ; \ 338 | file="$$slashdir" ; \ 339 | slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'` ; \ 340 | done \ 341 | done 342 | 343 | # Traditionally "install" depends on "all". But it may be useful 344 | # not to; for example, if the user has made some trivial change to a 345 | # source file and doesn't care about rebuilding or just wants to save the 346 | # time it takes for make to check that all is up to date. 347 | # install-only is intended to address that need. 348 | .PHONY: install 349 | install: all 350 | @$(MAKE) $(FLAGS_TO_PASS) install-only 351 | 352 | .PHONY: install-only 353 | install-only: install-syscalls install-python install-guile \ 354 | install-system-gdbinit 355 | 356 | .PHONY: uninstall 357 | uninstall: uninstall-syscalls uninstall-python uninstall-guile \ 358 | uninstall-system-gdbinit 359 | 360 | .PHONY: clean 361 | clean: clean-syscalls clean-python clean-guile clean-system-gdbinit 362 | 363 | .PHONY: maintainer-clean realclean distclean 364 | maintainer-clean realclean distclean: clean 365 | rm -f Makefile 366 | 367 | .PHONY: check installcheck info dvi pdf html 368 | .PHONY: install-info install-pdf install-html clean-info 369 | check installcheck: 370 | info dvi pdf html: 371 | install-info install-pdf install-html: 372 | clean-info: 373 | 374 | # GNU Make has an annoying habit of putting *all* the Makefile variables 375 | # into the environment, unless you include this target as a circumvention. 376 | # Rumor is that this will be fixed (and this target can be removed) 377 | # in GNU Make 4.0. 378 | .NOEXPORT: 379 | 380 | # GNU Make 3.63 has a different problem: it keeps tacking command line 381 | # overrides onto the definition of $(MAKE). This variable setting 382 | # will remove them. 383 | MAKEOVERRIDES= 384 | 385 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 386 | cd $(top_builddir) && $(MAKE) data-directory/Makefile 387 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/FrameDecorator.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | import gdb 17 | 18 | # This small code snippet deals with problem of strings in Python 2.x 19 | # and Python 3.x. Python 2.x has str and unicode classes which are 20 | # sub-classes of basestring. In Python 3.x all strings are encoded 21 | # and basestring has been removed. 22 | try: 23 | basestring 24 | except NameError: 25 | basestring = str 26 | 27 | class FrameDecorator(object): 28 | """Basic implementation of a Frame Decorator""" 29 | 30 | """ This base frame decorator decorates a frame or another frame 31 | decorator, and provides convenience methods. If this object is 32 | wrapping a frame decorator, defer to that wrapped object's method 33 | if it has one. This allows for frame decorators that have 34 | sub-classed FrameDecorator object, but also wrap other frame 35 | decorators on the same frame to correctly execute. 36 | 37 | E.g 38 | 39 | If the result of frame filters running means we have one gdb.Frame 40 | wrapped by multiple frame decorators, all sub-classed from 41 | FrameDecorator, the resulting hierarchy will be: 42 | 43 | Decorator1 44 | -- (wraps) Decorator2 45 | -- (wraps) FrameDecorator 46 | -- (wraps) gdb.Frame 47 | 48 | In this case we have two frame decorators, both of which are 49 | sub-classed from FrameDecorator. If Decorator1 just overrides the 50 | 'function' method, then all of the other methods are carried out 51 | by the super-class FrameDecorator. But Decorator2 may have 52 | overriden other methods, so FrameDecorator will look at the 53 | 'base' parameter and defer to that class's methods. And so on, 54 | down the chain.""" 55 | 56 | # 'base' can refer to a gdb.Frame or another frame decorator. In 57 | # the latter case, the child class will have called the super 58 | # method and _base will be an object conforming to the Frame Filter 59 | # class. 60 | def __init__(self, base): 61 | self._base = base 62 | 63 | @staticmethod 64 | def _is_limited_frame(frame): 65 | """Internal utility to determine if the frame is special or 66 | limited.""" 67 | sal = frame.find_sal() 68 | 69 | if (not sal.symtab or not sal.symtab.filename 70 | or frame.type() == gdb.DUMMY_FRAME 71 | or frame.type() == gdb.SIGTRAMP_FRAME): 72 | 73 | return True 74 | 75 | return False 76 | 77 | def elided(self): 78 | """Return any elided frames that this class might be 79 | wrapping, or None.""" 80 | if hasattr(self._base, "elided"): 81 | return self._base.elided() 82 | 83 | return None 84 | 85 | def function(self): 86 | """ Return the name of the frame's function or an address of 87 | the function of the frame. First determine if this is a 88 | special frame. If not, try to determine filename from GDB's 89 | frame internal function API. Finally, if a name cannot be 90 | determined return the address. If this function returns an 91 | address, GDB will attempt to determine the function name from 92 | its internal minimal symbols store (for example, for inferiors 93 | without debug-info).""" 94 | 95 | # Both gdb.Frame, and FrameDecorator have a method called 96 | # "function", so determine which object this is. 97 | if not isinstance(self._base, gdb.Frame): 98 | if hasattr(self._base, "function"): 99 | # If it is not a gdb.Frame, and there is already a 100 | # "function" method, use that. 101 | return self._base.function() 102 | 103 | frame = self.inferior_frame() 104 | 105 | if frame.type() == gdb.DUMMY_FRAME: 106 | return "" 107 | elif frame.type() == gdb.SIGTRAMP_FRAME: 108 | return "" 109 | 110 | func = frame.function() 111 | 112 | # If we cannot determine the function name, return the 113 | # address. If GDB detects an integer value from this function 114 | # it will attempt to find the function name from minimal 115 | # symbols via its own internal functions. 116 | if func == None: 117 | pc = frame.pc() 118 | return pc 119 | 120 | return str(func) 121 | 122 | def address(self): 123 | """ Return the address of the frame's pc""" 124 | 125 | if hasattr(self._base, "address"): 126 | return self._base.address() 127 | 128 | frame = self.inferior_frame() 129 | return frame.pc() 130 | 131 | def filename(self): 132 | """ Return the filename associated with this frame, detecting 133 | and returning the appropriate library name is this is a shared 134 | library.""" 135 | 136 | if hasattr(self._base, "filename"): 137 | return self._base.filename() 138 | 139 | frame = self.inferior_frame() 140 | sal = frame.find_sal() 141 | if not sal.symtab or not sal.symtab.filename: 142 | pc = frame.pc() 143 | return gdb.solib_name(pc) 144 | else: 145 | return sal.symtab.filename 146 | 147 | def frame_args(self): 148 | """ Return an iterable of frame arguments for this frame, if 149 | any. The iterable object contains objects conforming with the 150 | Symbol/Value interface. If there are no frame arguments, or 151 | if this frame is deemed to be a special case, return None.""" 152 | 153 | if hasattr(self._base, "frame_args"): 154 | return self._base.frame_args() 155 | 156 | frame = self.inferior_frame() 157 | if self._is_limited_frame(frame): 158 | return None 159 | 160 | args = FrameVars(frame) 161 | return args.fetch_frame_args() 162 | 163 | def frame_locals(self): 164 | """ Return an iterable of local variables for this frame, if 165 | any. The iterable object contains objects conforming with the 166 | Symbol/Value interface. If there are no frame locals, or if 167 | this frame is deemed to be a special case, return None.""" 168 | 169 | if hasattr(self._base, "frame_locals"): 170 | return self._base.frame_locals() 171 | 172 | frame = self.inferior_frame() 173 | if self._is_limited_frame(frame): 174 | return None 175 | 176 | args = FrameVars(frame) 177 | return args.fetch_frame_locals() 178 | 179 | def line(self): 180 | """ Return line number information associated with the frame's 181 | pc. If symbol table/line information does not exist, or if 182 | this frame is deemed to be a special case, return None""" 183 | 184 | if hasattr(self._base, "line"): 185 | return self._base.line() 186 | 187 | frame = self.inferior_frame() 188 | if self._is_limited_frame(frame): 189 | return None 190 | 191 | sal = frame.find_sal() 192 | if (sal): 193 | return sal.line 194 | else: 195 | return None 196 | 197 | def inferior_frame(self): 198 | """ Return the gdb.Frame underpinning this frame decorator.""" 199 | 200 | # If 'base' is a frame decorator, we want to call its inferior 201 | # frame method. If '_base' is a gdb.Frame, just return that. 202 | if hasattr(self._base, "inferior_frame"): 203 | return self._base.inferior_frame() 204 | return self._base 205 | 206 | class SymValueWrapper(object): 207 | """A container class conforming to the Symbol/Value interface 208 | which holds frame locals or frame arguments.""" 209 | def __init__(self, symbol, value): 210 | self.sym = symbol 211 | self.val = value 212 | 213 | def value(self): 214 | """ Return the value associated with this symbol, or None""" 215 | return self.val 216 | 217 | def symbol(self): 218 | """ Return the symbol, or Python text, associated with this 219 | symbol, or None""" 220 | return self.sym 221 | 222 | class FrameVars(object): 223 | 224 | """Utility class to fetch and store frame local variables, or 225 | frame arguments.""" 226 | 227 | def __init__(self, frame): 228 | self.frame = frame 229 | self.symbol_class = { 230 | gdb.SYMBOL_LOC_STATIC: True, 231 | gdb.SYMBOL_LOC_REGISTER: True, 232 | gdb.SYMBOL_LOC_ARG: True, 233 | gdb.SYMBOL_LOC_REF_ARG: True, 234 | gdb.SYMBOL_LOC_LOCAL: True, 235 | gdb.SYMBOL_LOC_REGPARM_ADDR: True, 236 | gdb.SYMBOL_LOC_COMPUTED: True 237 | } 238 | 239 | def fetch_b(self, sym): 240 | """ Local utility method to determine if according to Symbol 241 | type whether it should be included in the iterator. Not all 242 | symbols are fetched, and only symbols that return 243 | True from this method should be fetched.""" 244 | 245 | # SYM may be a string instead of a symbol in the case of 246 | # synthetic local arguments or locals. If that is the case, 247 | # always fetch. 248 | if isinstance(sym, basestring): 249 | return True 250 | 251 | sym_type = sym.addr_class 252 | 253 | return self.symbol_class.get(sym_type, False) 254 | 255 | def fetch_frame_locals(self): 256 | """Public utility method to fetch frame local variables for 257 | the stored frame. Frame arguments are not fetched. If there 258 | are no frame local variables, return an empty list.""" 259 | lvars = [] 260 | 261 | try: 262 | block = self.frame.block() 263 | except RuntimeError: 264 | block = None 265 | 266 | while block != None: 267 | if block.is_global or block.is_static: 268 | break 269 | for sym in block: 270 | if sym.is_argument: 271 | continue; 272 | if self.fetch_b(sym): 273 | lvars.append(SymValueWrapper(sym, None)) 274 | 275 | block = block.superblock 276 | 277 | return lvars 278 | 279 | def fetch_frame_args(self): 280 | """Public utility method to fetch frame arguments for the 281 | stored frame. Frame arguments are the only type fetched. If 282 | there are no frame argument variables, return an empty list.""" 283 | 284 | args = [] 285 | 286 | try: 287 | block = self.frame.block() 288 | except RuntimeError: 289 | block = None 290 | 291 | while block != None: 292 | if block.function != None: 293 | break 294 | block = block.superblock 295 | 296 | if block != None: 297 | for sym in block: 298 | if not sym.is_argument: 299 | continue; 300 | args.append(SymValueWrapper(sym, None)) 301 | 302 | return args 303 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/FrameIterator.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | import gdb 17 | import itertools 18 | 19 | class FrameIterator(object): 20 | """A gdb.Frame iterator. Iterates over gdb.Frames or objects that 21 | conform to that interface.""" 22 | 23 | def __init__(self, frame_obj): 24 | """Initialize a FrameIterator. 25 | 26 | Arguments: 27 | frame_obj the starting frame.""" 28 | 29 | super(FrameIterator, self).__init__() 30 | self.frame = frame_obj 31 | 32 | def __iter__(self): 33 | return self 34 | 35 | def next(self): 36 | """next implementation. 37 | 38 | Returns: 39 | The next oldest frame.""" 40 | 41 | result = self.frame 42 | if result is None: 43 | raise StopIteration 44 | self.frame = result.older() 45 | return result 46 | 47 | # Python 3.x requires __next__(self) while Python 2.x requires 48 | # next(self). Define next(self), and for Python 3.x create this 49 | # wrapper. 50 | def __next__(self): 51 | return self.next() 52 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | import traceback 17 | import os 18 | import sys 19 | import _gdb 20 | 21 | if sys.version_info[0] > 2: 22 | # Python 3 moved "reload" 23 | from imp import reload 24 | 25 | from _gdb import * 26 | 27 | class _GdbFile (object): 28 | # These two are needed in Python 3 29 | encoding = "UTF-8" 30 | errors = "strict" 31 | 32 | def close(self): 33 | # Do nothing. 34 | return None 35 | 36 | def isatty(self): 37 | return False 38 | 39 | def writelines(self, iterable): 40 | for line in iterable: 41 | self.write(line) 42 | 43 | def flush(self): 44 | flush() 45 | 46 | class GdbOutputFile (_GdbFile): 47 | def write(self, s): 48 | write(s, stream=STDOUT) 49 | 50 | sys.stdout = GdbOutputFile() 51 | 52 | class GdbOutputErrorFile (_GdbFile): 53 | def write(self, s): 54 | write(s, stream=STDERR) 55 | 56 | sys.stderr = GdbOutputErrorFile() 57 | 58 | # Default prompt hook does nothing. 59 | prompt_hook = None 60 | 61 | # Ensure that sys.argv is set to something. 62 | # We do not use PySys_SetArgvEx because it did not appear until 2.6.6. 63 | sys.argv = [''] 64 | 65 | # Initial pretty printers. 66 | pretty_printers = [] 67 | 68 | # Initial type printers. 69 | type_printers = [] 70 | # Initial xmethod matchers. 71 | xmethods = [] 72 | # Initial frame filters. 73 | frame_filters = {} 74 | # Initial frame unwinders. 75 | frame_unwinders = [] 76 | 77 | def execute_unwinders(pending_frame): 78 | """Internal function called from GDB to execute all unwinders. 79 | 80 | Runs each currently enabled unwinder until it finds the one that 81 | can unwind given frame. 82 | 83 | Arguments: 84 | pending_frame: gdb.PendingFrame instance. 85 | Returns: 86 | gdb.UnwindInfo instance or None. 87 | """ 88 | for objfile in _gdb.objfiles(): 89 | for unwinder in objfile.frame_unwinders: 90 | if unwinder.enabled: 91 | unwind_info = unwinder(pending_frame) 92 | if unwind_info is not None: 93 | return unwind_info 94 | 95 | current_progspace = _gdb.current_progspace() 96 | for unwinder in current_progspace.frame_unwinders: 97 | if unwinder.enabled: 98 | unwind_info = unwinder(pending_frame) 99 | if unwind_info is not None: 100 | return unwind_info 101 | 102 | for unwinder in frame_unwinders: 103 | if unwinder.enabled: 104 | unwind_info = unwinder(pending_frame) 105 | if unwind_info is not None: 106 | return unwind_info 107 | 108 | return None 109 | 110 | 111 | # Convenience variable to GDB's python directory 112 | PYTHONDIR = os.path.dirname(os.path.dirname(__file__)) 113 | 114 | # Auto-load all functions/commands. 115 | 116 | # Packages to auto-load. 117 | 118 | packages = [ 119 | 'function', 120 | 'command', 121 | 'printer' 122 | ] 123 | 124 | # pkgutil.iter_modules is not available prior to Python 2.6. Instead, 125 | # manually iterate the list, collating the Python files in each module 126 | # path. Construct the module name, and import. 127 | 128 | def auto_load_packages(): 129 | for package in packages: 130 | location = os.path.join(os.path.dirname(__file__), package) 131 | if os.path.exists(location): 132 | py_files = filter(lambda x: x.endswith('.py') 133 | and x != '__init__.py', 134 | os.listdir(location)) 135 | 136 | for py_file in py_files: 137 | # Construct from foo.py, gdb.module.foo 138 | modname = "%s.%s.%s" % ( __name__, package, py_file[:-3] ) 139 | try: 140 | if modname in sys.modules: 141 | # reload modules with duplicate names 142 | reload(__import__(modname)) 143 | else: 144 | __import__(modname) 145 | except: 146 | sys.stderr.write (traceback.format_exc() + "\n") 147 | 148 | auto_load_packages() 149 | 150 | def GdbSetPythonDirectory(dir): 151 | """Update sys.path, reload gdb and auto-load packages.""" 152 | global PYTHONDIR 153 | 154 | try: 155 | sys.path.remove(PYTHONDIR) 156 | except ValueError: 157 | pass 158 | sys.path.insert(0, dir) 159 | 160 | PYTHONDIR = dir 161 | 162 | # note that reload overwrites the gdb module without deleting existing 163 | # attributes 164 | reload(__import__(__name__)) 165 | auto_load_packages() 166 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/command/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | 17 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/command/prompt.py: -------------------------------------------------------------------------------- 1 | # Extended prompt. 2 | # Copyright (C) 2011-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """GDB command for working with extended prompts.""" 18 | 19 | import gdb 20 | import gdb.prompt 21 | 22 | class _ExtendedPrompt(gdb.Parameter): 23 | 24 | """Set the extended prompt. 25 | 26 | Usage: set extended-prompt VALUE 27 | 28 | Substitutions are applied to VALUE to compute the real prompt. 29 | 30 | The currently defined substitutions are: 31 | 32 | """ 33 | # Add the prompt library's dynamically generated help to the 34 | # __doc__ string. 35 | __doc__ = __doc__ + gdb.prompt.prompt_help() 36 | 37 | set_doc = "Set the extended prompt." 38 | show_doc = "Show the extended prompt." 39 | 40 | def __init__(self): 41 | super(_ExtendedPrompt, self).__init__("extended-prompt", 42 | gdb.COMMAND_SUPPORT, 43 | gdb.PARAM_STRING_NOESCAPE) 44 | self.value = '' 45 | self.hook_set = False 46 | 47 | def get_show_string (self, pvalue): 48 | if self.value is not '': 49 | return "The extended prompt is: " + self.value 50 | else: 51 | return "The extended prompt is not set." 52 | 53 | def get_set_string (self): 54 | if self.hook_set == False: 55 | gdb.prompt_hook = self.before_prompt_hook 56 | self.hook_set = True 57 | return "" 58 | 59 | def before_prompt_hook(self, current): 60 | if self.value is not '': 61 | return gdb.prompt.substitute_prompt(self.value) 62 | else: 63 | return None 64 | 65 | _ExtendedPrompt() 66 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/command/type_printers.py: -------------------------------------------------------------------------------- 1 | # Type printer commands. 2 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | import copy 18 | import gdb 19 | 20 | """GDB commands for working with type-printers.""" 21 | 22 | class InfoTypePrinter(gdb.Command): 23 | """GDB command to list all registered type-printers. 24 | 25 | Usage: info type-printers 26 | """ 27 | 28 | def __init__ (self): 29 | super(InfoTypePrinter, self).__init__("info type-printers", 30 | gdb.COMMAND_DATA) 31 | 32 | def list_type_printers(self, type_printers): 33 | """Print a list of type printers.""" 34 | # A potential enhancement is to provide an option to list printers in 35 | # "lookup order" (i.e. unsorted). 36 | sorted_type_printers = sorted (copy.copy(type_printers), 37 | key = lambda x: x.name) 38 | for printer in sorted_type_printers: 39 | if printer.enabled: 40 | enabled = '' 41 | else: 42 | enabled = " [disabled]" 43 | print (" %s%s" % (printer.name, enabled)) 44 | 45 | def invoke(self, arg, from_tty): 46 | """GDB calls this to perform the command.""" 47 | sep = '' 48 | for objfile in gdb.objfiles(): 49 | if objfile.type_printers: 50 | print ("%sType printers for %s:" % (sep, objfile.filename)) 51 | self.list_type_printers(objfile.type_printers) 52 | sep = '\n' 53 | if gdb.current_progspace().type_printers: 54 | print ("%sType printers for program space:" % sep) 55 | self.list_type_printers(gdb.current_progspace().type_printers) 56 | sep = '\n' 57 | if gdb.type_printers: 58 | print ("%sGlobal type printers:" % sep) 59 | self.list_type_printers(gdb.type_printers) 60 | 61 | class _EnableOrDisableCommand(gdb.Command): 62 | def __init__(self, setting, name): 63 | super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA) 64 | self.setting = setting 65 | 66 | def set_some(self, name, printers): 67 | result = False 68 | for p in printers: 69 | if name == p.name: 70 | p.enabled = self.setting 71 | result = True 72 | return result 73 | 74 | def invoke(self, arg, from_tty): 75 | """GDB calls this to perform the command.""" 76 | for name in arg.split(): 77 | ok = False 78 | for objfile in gdb.objfiles(): 79 | if self.set_some(name, objfile.type_printers): 80 | ok = True 81 | if self.set_some(name, gdb.current_progspace().type_printers): 82 | ok = True 83 | if self.set_some(name, gdb.type_printers): 84 | ok = True 85 | if not ok: 86 | print ("No type printer named '%s'" % name) 87 | 88 | def add_some(self, result, word, printers): 89 | for p in printers: 90 | if p.name.startswith(word): 91 | result.append(p.name) 92 | 93 | def complete(self, text, word): 94 | result = [] 95 | for objfile in gdb.objfiles(): 96 | self.add_some(result, word, objfile.type_printers) 97 | self.add_some(result, word, gdb.current_progspace().type_printers) 98 | self.add_some(result, word, gdb.type_printers) 99 | return result 100 | 101 | class EnableTypePrinter(_EnableOrDisableCommand): 102 | """GDB command to enable the specified type printer. 103 | 104 | Usage: enable type-printer NAME 105 | 106 | NAME is the name of the type-printer. 107 | """ 108 | 109 | def __init__(self): 110 | super(EnableTypePrinter, self).__init__(True, "enable type-printer") 111 | 112 | class DisableTypePrinter(_EnableOrDisableCommand): 113 | """GDB command to disable the specified type-printer. 114 | 115 | Usage: disable type-printer NAME 116 | 117 | NAME is the name of the type-printer. 118 | """ 119 | 120 | def __init__(self): 121 | super(DisableTypePrinter, self).__init__(False, "disable type-printer") 122 | 123 | InfoTypePrinter() 124 | EnableTypePrinter() 125 | DisableTypePrinter() 126 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/command/unwinders.py: -------------------------------------------------------------------------------- 1 | # Unwinder commands. 2 | # Copyright 2015-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | import gdb 18 | import re 19 | 20 | 21 | def validate_regexp(exp, idstring): 22 | try: 23 | return re.compile(exp) 24 | except SyntaxError: 25 | raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp)) 26 | 27 | 28 | def parse_unwinder_command_args(arg): 29 | """Internal utility to parse unwinder command argv. 30 | 31 | Arguments: 32 | arg: The arguments to the command. The format is: 33 | [locus-regexp [name-regexp]] 34 | 35 | Returns: 36 | A 2-tuple of compiled regular expressions. 37 | 38 | Raises: 39 | SyntaxError: an error processing ARG 40 | """ 41 | 42 | argv = gdb.string_to_argv(arg) 43 | argc = len(argv) 44 | if argc > 2: 45 | raise SyntaxError("Too many arguments.") 46 | locus_regexp = "" 47 | name_regexp = "" 48 | if argc >= 1: 49 | locus_regexp = argv[0] 50 | if argc >= 2: 51 | name_regexp = argv[1] 52 | return (validate_regexp(locus_regexp, "locus"), 53 | validate_regexp(name_regexp, "unwinder")) 54 | 55 | 56 | class InfoUnwinder(gdb.Command): 57 | """GDB command to list unwinders. 58 | 59 | Usage: info unwinder [locus-regexp [name-regexp]] 60 | 61 | LOCUS-REGEXP is a regular expression matching the location of the 62 | unwinder. If it is omitted, all registered unwinders from all 63 | loci are listed. A locus can be 'global', 'progspace' to list 64 | the unwinders from the current progspace, or a regular expression 65 | matching filenames of objfiles. 66 | 67 | NAME-REGEXP is a regular expression to filter unwinder names. If 68 | this omitted for a specified locus, then all registered unwinders 69 | in the locus are listed. 70 | """ 71 | 72 | def __init__(self): 73 | super(InfoUnwinder, self).__init__("info unwinder", 74 | gdb.COMMAND_STACK) 75 | 76 | def list_unwinders(self, title, unwinders, name_re): 77 | """Lists the unwinders whose name matches regexp. 78 | 79 | Arguments: 80 | title: The line to print before the list. 81 | unwinders: The list of the unwinders. 82 | name_re: unwinder name filter. 83 | """ 84 | if not unwinders: 85 | return 86 | print(title) 87 | for unwinder in unwinders: 88 | if name_re.match(unwinder.name): 89 | print(" %s%s" % (unwinder.name, 90 | "" if unwinder.enabled else " [disabled]")) 91 | 92 | def invoke(self, arg, from_tty): 93 | locus_re, name_re = parse_unwinder_command_args(arg) 94 | if locus_re.match("global"): 95 | self.list_unwinders("Global:", gdb.frame_unwinders, 96 | name_re) 97 | if locus_re.match("progspace"): 98 | cp = gdb.current_progspace() 99 | self.list_unwinders("Progspace %s:" % cp.filename, 100 | cp.frame_unwinders, name_re) 101 | for objfile in gdb.objfiles(): 102 | if locus_re.match(objfile.filename): 103 | self.list_unwinders("Objfile %s:" % objfile.filename, 104 | objfile.frame_unwinders, name_re) 105 | 106 | 107 | def do_enable_unwinder1(unwinders, name_re, flag): 108 | """Enable/disable unwinders whose names match given regex. 109 | 110 | Arguments: 111 | unwinders: The list of unwinders. 112 | name_re: Unwinder name filter. 113 | flag: Enable/disable. 114 | 115 | Returns: 116 | The number of unwinders affected. 117 | """ 118 | total = 0 119 | for unwinder in unwinders: 120 | if name_re.match(unwinder.name): 121 | unwinder.enabled = flag 122 | total += 1 123 | return total 124 | 125 | 126 | def do_enable_unwinder(arg, flag): 127 | """Enable/disable unwinder(s).""" 128 | (locus_re, name_re) = parse_unwinder_command_args(arg) 129 | total = 0 130 | if locus_re.match("global"): 131 | total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag) 132 | if locus_re.match("progspace"): 133 | total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders, 134 | name_re, flag) 135 | for objfile in gdb.objfiles(): 136 | if locus_re.match(objfile.filename): 137 | total += do_enable_unwinder1(objfile.frame_unwinders, name_re, 138 | flag) 139 | print("%d unwinder%s %s" % (total, "" if total == 1 else "s", 140 | "enabled" if flag else "disabled")) 141 | 142 | 143 | class EnableUnwinder(gdb.Command): 144 | """GDB command to enable unwinders. 145 | 146 | Usage: enable unwinder [locus-regexp [name-regexp]] 147 | 148 | LOCUS-REGEXP is a regular expression specifying the unwinders to 149 | enable. It can 'global', 'progspace', or the name of an objfile 150 | within that progspace. 151 | 152 | NAME_REGEXP is a regular expression to filter unwinder names. If 153 | this omitted for a specified locus, then all registered unwinders 154 | in the locus are affected. 155 | 156 | """ 157 | 158 | def __init__(self): 159 | super(EnableUnwinder, self).__init__("enable unwinder", 160 | gdb.COMMAND_STACK) 161 | 162 | def invoke(self, arg, from_tty): 163 | """GDB calls this to perform the command.""" 164 | do_enable_unwinder(arg, True) 165 | 166 | 167 | class DisableUnwinder(gdb.Command): 168 | """GDB command to disable the specified unwinder. 169 | 170 | Usage: disable unwinder [locus-regexp [name-regexp]] 171 | 172 | LOCUS-REGEXP is a regular expression specifying the unwinders to 173 | disable. It can 'global', 'progspace', or the name of an objfile 174 | within that progspace. 175 | 176 | NAME_REGEXP is a regular expression to filter unwinder names. If 177 | this omitted for a specified locus, then all registered unwinders 178 | in the locus are affected. 179 | 180 | """ 181 | 182 | def __init__(self): 183 | super(DisableUnwinder, self).__init__("disable unwinder", 184 | gdb.COMMAND_STACK) 185 | 186 | def invoke(self, arg, from_tty): 187 | """GDB calls this to perform the command.""" 188 | do_enable_unwinder(arg, False) 189 | 190 | 191 | def register_unwinder_commands(): 192 | """Installs the unwinder commands.""" 193 | InfoUnwinder() 194 | EnableUnwinder() 195 | DisableUnwinder() 196 | 197 | 198 | register_unwinder_commands() 199 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/command/xmethods.py: -------------------------------------------------------------------------------- 1 | # Xmethod commands. 2 | # Copyright 2013-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | import gdb 18 | import re 19 | 20 | """GDB commands for working with xmethods.""" 21 | 22 | 23 | def validate_xm_regexp(part_name, regexp): 24 | try: 25 | return re.compile(regexp) 26 | except SyntaxError: 27 | raise SyntaxError("Invalid %s regexp: %s", part_name, regexp) 28 | 29 | 30 | def parse_xm_command_args(arg): 31 | """Parses the arguments passed to a xmethod command. 32 | 33 | Arguments: 34 | arg: The argument string passed to a xmethod command. 35 | 36 | Returns: 37 | A 3-tuple: (, 38 | , 39 | ) 40 | """ 41 | argv = gdb.string_to_argv(arg) 42 | argc = len(argv) 43 | if argc > 2: 44 | raise SyntaxError("Too many arguments to command.") 45 | locus_regexp = "" 46 | matcher_name_regexp = "" 47 | xm_name_regexp = None 48 | if argc >= 1: 49 | locus_regexp = argv[0] 50 | if argc == 2: 51 | parts = argv[1].split(";", 1) 52 | matcher_name_regexp = parts[0] 53 | if len(parts) > 1: 54 | xm_name_regexp = parts[1] 55 | if xm_name_regexp: 56 | name_re = validate_xm_regexp("xmethod name", xm_name_regexp) 57 | else: 58 | name_re = None 59 | return (validate_xm_regexp("locus", locus_regexp), 60 | validate_xm_regexp("matcher name", matcher_name_regexp), 61 | name_re) 62 | 63 | 64 | def get_global_method_matchers(locus_re, matcher_re): 65 | """Returns a dict of matching globally registered xmethods. 66 | 67 | Arguments: 68 | locus_re: Even though only globally registered xmethods are 69 | looked up, they will be looked up only if 'global' matches 70 | LOCUS_RE. 71 | matcher_re: The regular expression matching the names of xmethods. 72 | 73 | Returns: 74 | A dict of matching globally registered xmethod matchers. The only 75 | key in the dict will be 'global'. 76 | """ 77 | locus_str = "global" 78 | xm_dict = { locus_str: [] } 79 | if locus_re.match("global"): 80 | xm_dict[locus_str].extend( 81 | [m for m in gdb.xmethods if matcher_re.match(m.name)]) 82 | return xm_dict 83 | 84 | 85 | def get_method_matchers_in_loci(loci, locus_re, matcher_re): 86 | """Returns a dict of matching registered xmethods in the LOCI. 87 | 88 | Arguments: 89 | loci: The list of loci to lookup matching xmethods in. 90 | locus_re: If a locus is an objfile, then xmethod matchers will be 91 | looked up in it only if its filename matches the regular 92 | expression LOCUS_RE. If a locus is the current progspace, 93 | then xmethod matchers will be looked up in it only if the 94 | string "progspace" matches LOCUS_RE. 95 | matcher_re: The regular expression to match the xmethod matcher 96 | names. 97 | 98 | Returns: 99 | A dict of matching xmethod matchers. The keys of the dict are the 100 | filenames of the loci the xmethod matchers belong to. 101 | """ 102 | xm_dict = {} 103 | for locus in loci: 104 | if isinstance(locus, gdb.Progspace): 105 | if not locus_re.match('progspace'): 106 | continue 107 | locus_type = "progspace" 108 | else: 109 | if not locus_re.match(locus.filename): 110 | continue 111 | locus_type = "objfile" 112 | locus_str = "%s %s" % (locus_type, locus.filename) 113 | xm_dict[locus_str] = [ 114 | m for m in locus.xmethods if matcher_re.match(m.name)] 115 | return xm_dict 116 | 117 | 118 | def print_xm_info(xm_dict, name_re): 119 | """Print a dictionary of xmethods.""" 120 | def get_status_string(m): 121 | if not m.enabled: 122 | return " [disabled]" 123 | else: 124 | return "" 125 | 126 | if not xm_dict: 127 | return 128 | for locus_str in xm_dict: 129 | if not xm_dict[locus_str]: 130 | continue 131 | print ("Xmethods in %s:" % locus_str) 132 | for matcher in xm_dict[locus_str]: 133 | print (" %s%s" % (matcher.name, get_status_string(matcher))) 134 | if not matcher.methods: 135 | continue 136 | for m in matcher.methods: 137 | if name_re is None or name_re.match(m.name): 138 | print (" %s%s" % (m.name, get_status_string(m))) 139 | 140 | 141 | def set_xm_status1(xm_dict, name_re, status): 142 | """Set the status (enabled/disabled) of a dictionary of xmethods.""" 143 | for locus_str, matchers in xm_dict.items(): 144 | for matcher in matchers: 145 | if not name_re: 146 | # If the name regex is missing, then set the status of the 147 | # matcher and move on. 148 | matcher.enabled = status 149 | continue 150 | if not matcher.methods: 151 | # The methods attribute could be None. Move on. 152 | continue 153 | for m in matcher.methods: 154 | if name_re.match(m.name): 155 | m.enabled = status 156 | 157 | 158 | def set_xm_status(arg, status): 159 | """Set the status (enabled/disabled) of xmethods matching ARG. 160 | This is a helper function for enable/disable commands. ARG is the 161 | argument string passed to the commands. 162 | """ 163 | locus_re, matcher_re, name_re = parse_xm_command_args(arg) 164 | set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re, 165 | status) 166 | set_xm_status1( 167 | get_method_matchers_in_loci( 168 | [gdb.current_progspace()], locus_re, matcher_re), 169 | name_re, 170 | status) 171 | set_xm_status1( 172 | get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), 173 | name_re, 174 | status) 175 | 176 | 177 | class InfoXMethod(gdb.Command): 178 | """GDB command to list registered xmethod matchers. 179 | 180 | Usage: info xmethod [locus-regexp [name-regexp]] 181 | 182 | LOCUS-REGEXP is a regular expression matching the location of the 183 | xmethod matchers. If it is omitted, all registered xmethod matchers 184 | from all loci are listed. A locus could be 'global', a regular expression 185 | matching the current program space's filename, or a regular expression 186 | matching filenames of objfiles. Locus could be 'progspace' to specify that 187 | only xmethods from the current progspace should be listed. 188 | 189 | NAME-REGEXP is a regular expression matching the names of xmethod 190 | matchers. If this omitted for a specified locus, then all registered 191 | xmethods in the locus are listed. To list only a certain xmethods 192 | managed by a single matcher, the name regexp can be specified as 193 | matcher-name-regexp;xmethod-name-regexp. 194 | """ 195 | 196 | def __init__(self): 197 | super(InfoXMethod, self).__init__("info xmethod", 198 | gdb.COMMAND_DATA) 199 | 200 | def invoke(self, arg, from_tty): 201 | locus_re, matcher_re, name_re = parse_xm_command_args(arg) 202 | print_xm_info(get_global_method_matchers(locus_re, matcher_re), 203 | name_re) 204 | print_xm_info( 205 | get_method_matchers_in_loci( 206 | [gdb.current_progspace()], locus_re, matcher_re), 207 | name_re) 208 | print_xm_info( 209 | get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), 210 | name_re) 211 | 212 | 213 | class EnableXMethod(gdb.Command): 214 | """GDB command to enable a specified (group of) xmethod(s). 215 | 216 | Usage: enable xmethod [locus-regexp [name-regexp]] 217 | 218 | LOCUS-REGEXP is a regular expression matching the location of the 219 | xmethod matchers. If it is omitted, all registered xmethods matchers 220 | from all loci are enabled. A locus could be 'global', a regular expression 221 | matching the current program space's filename, or a regular expression 222 | matching filenames of objfiles. Locus could be 'progspace' to specify that 223 | only xmethods from the current progspace should be enabled. 224 | 225 | NAME-REGEXP is a regular expression matching the names of xmethods 226 | within a given locus. If this omitted for a specified locus, then all 227 | registered xmethod matchers in the locus are enabled. To enable only 228 | a certain xmethods managed by a single matcher, the name regexp can be 229 | specified as matcher-name-regexp;xmethod-name-regexp. 230 | """ 231 | 232 | def __init__(self): 233 | super(EnableXMethod, self).__init__("enable xmethod", 234 | gdb.COMMAND_DATA) 235 | 236 | def invoke(self, arg, from_tty): 237 | set_xm_status(arg, True) 238 | 239 | 240 | class DisableXMethod(gdb.Command): 241 | """GDB command to disable a specified (group of) xmethod(s). 242 | 243 | Usage: disable xmethod [locus-regexp [name-regexp]] 244 | 245 | LOCUS-REGEXP is a regular expression matching the location of the 246 | xmethod matchers. If it is omitted, all registered xmethod matchers 247 | from all loci are disabled. A locus could be 'global', a regular 248 | expression matching the current program space's filename, or a regular 249 | expression filenames of objfiles. Locus could be 'progspace' to specify 250 | that only xmethods from the current progspace should be disabled. 251 | 252 | NAME-REGEXP is a regular expression matching the names of xmethods 253 | within a given locus. If this omitted for a specified locus, then all 254 | registered xmethod matchers in the locus are disabled. To disable 255 | only a certain xmethods managed by a single matcher, the name regexp 256 | can be specified as matcher-name-regexp;xmethod-name-regexp. 257 | """ 258 | 259 | def __init__(self): 260 | super(DisableXMethod, self).__init__("disable xmethod", 261 | gdb.COMMAND_DATA) 262 | 263 | def invoke(self, arg, from_tty): 264 | set_xm_status(arg, False) 265 | 266 | 267 | def register_xmethod_commands(): 268 | """Installs the xmethod commands.""" 269 | InfoXMethod() 270 | EnableXMethod() 271 | DisableXMethod() 272 | 273 | 274 | register_xmethod_commands() 275 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/frames.py: -------------------------------------------------------------------------------- 1 | # Frame-filter commands. 2 | # Copyright (C) 2013-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """Internal functions for working with frame-filters.""" 18 | 19 | import gdb 20 | from gdb.FrameIterator import FrameIterator 21 | from gdb.FrameDecorator import FrameDecorator 22 | import itertools 23 | import collections 24 | 25 | def get_priority(filter_item): 26 | """ Internal worker function to return the frame-filter's priority 27 | from a frame filter object. This is a fail free function as it is 28 | used in sorting and filtering. If a badly implemented frame 29 | filter does not implement the priority attribute, return zero 30 | (otherwise sorting/filtering will fail and prevent other frame 31 | filters from executing). 32 | 33 | Arguments: 34 | filter_item: An object conforming to the frame filter 35 | interface. 36 | 37 | Returns: 38 | The priority of the frame filter from the "priority" 39 | attribute, or zero. 40 | """ 41 | # Do not fail here, as the sort will fail. If a filter has not 42 | # (incorrectly) set a priority, set it to zero. 43 | return getattr(filter_item, "priority", 0) 44 | 45 | def set_priority(filter_item, priority): 46 | """ Internal worker function to set the frame-filter's priority. 47 | 48 | Arguments: 49 | filter_item: An object conforming to the frame filter 50 | interface. 51 | priority: The priority to assign as an integer. 52 | """ 53 | 54 | filter_item.priority = priority 55 | 56 | def get_enabled(filter_item): 57 | """ Internal worker function to return a filter's enabled state 58 | from a frame filter object. This is a fail free function as it is 59 | used in sorting and filtering. If a badly implemented frame 60 | filter does not implement the enabled attribute, return False 61 | (otherwise sorting/filtering will fail and prevent other frame 62 | filters from executing). 63 | 64 | Arguments: 65 | filter_item: An object conforming to the frame filter 66 | interface. 67 | 68 | Returns: 69 | The enabled state of the frame filter from the "enabled" 70 | attribute, or False. 71 | """ 72 | 73 | # If the filter class is badly implemented when called from the 74 | # Python filter command, do not cease filter operations, just set 75 | # enabled to False. 76 | return getattr(filter_item, "enabled", False) 77 | 78 | def set_enabled(filter_item, state): 79 | """ Internal Worker function to set the frame-filter's enabled 80 | state. 81 | 82 | Arguments: 83 | filter_item: An object conforming to the frame filter 84 | interface. 85 | state: True or False, depending on desired state. 86 | """ 87 | 88 | filter_item.enabled = state 89 | 90 | def return_list(name): 91 | """ Internal Worker function to return the frame filter 92 | dictionary, depending on the name supplied as an argument. If the 93 | name is not "all", "global" or "progspace", it is assumed to name 94 | an object-file. 95 | 96 | Arguments: 97 | name: The name of the list, as specified by GDB user commands. 98 | 99 | Returns: 100 | A dictionary object for a single specified dictionary, or a 101 | list containing all the items for "all" 102 | 103 | Raises: 104 | gdb.GdbError: A dictionary of that name cannot be found. 105 | """ 106 | 107 | # If all dictionaries are wanted in the case of "all" we 108 | # cannot return a combined dictionary as keys() may clash in 109 | # between different dictionaries. As we just want all the frame 110 | # filters to enable/disable them all, just return the combined 111 | # items() as a chained iterator of dictionary values. 112 | if name == "all": 113 | glob = gdb.frame_filters.values() 114 | prog = gdb.current_progspace().frame_filters.values() 115 | return_iter = itertools.chain(glob, prog) 116 | for objfile in gdb.objfiles(): 117 | return_iter = itertools.chain(return_iter, objfile.frame_filters.values()) 118 | 119 | return return_iter 120 | 121 | if name == "global": 122 | return gdb.frame_filters 123 | else: 124 | if name == "progspace": 125 | cp = gdb.current_progspace() 126 | return cp.frame_filters 127 | else: 128 | for objfile in gdb.objfiles(): 129 | if name == objfile.filename: 130 | return objfile.frame_filters 131 | 132 | msg = "Cannot find frame-filter dictionary for '" + name + "'" 133 | raise gdb.GdbError(msg) 134 | 135 | def _sort_list(): 136 | """ Internal Worker function to merge all known frame-filter 137 | lists, prune any filters with the state set to "disabled", and 138 | sort the list on the frame-filter's "priority" attribute. 139 | 140 | Returns: 141 | sorted_list: A sorted, pruned list of frame filters to 142 | execute. 143 | """ 144 | 145 | all_filters = return_list("all") 146 | sorted_frame_filters = sorted(all_filters, key = get_priority, 147 | reverse = True) 148 | 149 | sorted_frame_filters = filter(get_enabled, 150 | sorted_frame_filters) 151 | 152 | return sorted_frame_filters 153 | 154 | def execute_frame_filters(frame, frame_low, frame_high): 155 | """ Internal function called from GDB that will execute the chain 156 | of frame filters. Each filter is executed in priority order. 157 | After the execution completes, slice the iterator to frame_low - 158 | frame_high range. 159 | 160 | Arguments: 161 | frame: The initial frame. 162 | 163 | frame_low: The low range of the slice. If this is a negative 164 | integer then it indicates a backward slice (ie bt -4) which 165 | counts backward from the last frame in the backtrace. 166 | 167 | frame_high: The high range of the slice. If this is -1 then 168 | it indicates all frames until the end of the stack from 169 | frame_low. 170 | 171 | Returns: 172 | frame_iterator: The sliced iterator after all frame 173 | filters have had a change to execute, or None if no frame 174 | filters are registered. 175 | """ 176 | 177 | # Get a sorted list of frame filters. 178 | sorted_list = list(_sort_list()) 179 | 180 | # Check to see if there are any frame-filters. If not, just 181 | # return None and let default backtrace printing occur. 182 | if len(sorted_list) == 0: 183 | return None 184 | 185 | frame_iterator = FrameIterator(frame) 186 | 187 | # Apply a basic frame decorator to all gdb.Frames. This unifies 188 | # the interface. Python 3.x moved the itertools.imap 189 | # functionality to map(), so check if it is available. 190 | if hasattr(itertools,"imap"): 191 | frame_iterator = itertools.imap(FrameDecorator, frame_iterator) 192 | else: 193 | frame_iterator = map(FrameDecorator, frame_iterator) 194 | 195 | for ff in sorted_list: 196 | frame_iterator = ff.filter(frame_iterator) 197 | 198 | # Slicing 199 | 200 | # Is this a slice from the end of the backtrace, ie bt -2? 201 | if frame_low < 0: 202 | count = 0 203 | slice_length = abs(frame_low) 204 | # We cannot use MAXLEN argument for deque as it is 2.6 onwards 205 | # and some GDB versions might be < 2.6. 206 | sliced = collections.deque() 207 | 208 | for frame_item in frame_iterator: 209 | if count >= slice_length: 210 | sliced.popleft(); 211 | count = count + 1 212 | sliced.append(frame_item) 213 | 214 | return iter(sliced) 215 | 216 | # -1 for frame_high means until the end of the backtrace. Set to 217 | # None if that is the case, to indicate to itertools.islice to 218 | # slice to the end of the iterator. 219 | if frame_high == -1: 220 | frame_high = None 221 | else: 222 | # As frames start from 0, add one to frame_high so islice 223 | # correctly finds the end 224 | frame_high = frame_high + 1; 225 | 226 | sliced = itertools.islice(frame_iterator, frame_low, frame_high) 227 | 228 | return sliced 229 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/function/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2012-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/function/caller_is.py: -------------------------------------------------------------------------------- 1 | # Caller-is functions. 2 | # Copyright (C) 2008-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | import gdb 18 | import re 19 | 20 | class CallerIs(gdb.Function): 21 | """Check the calling function's name. 22 | 23 | Usage: 24 | $_caller_is(name [, number_of_frames]) 25 | 26 | Arguments: 27 | 28 | name: The name of the function to search for. 29 | 30 | number_of_frames: How many stack frames to traverse back from the currently 31 | selected frame to compare with. If the value is greater than the depth of 32 | the stack from that point then the result is False. 33 | The default is 1. 34 | 35 | Returns: 36 | True if the function's name at the specified frame is equal to name. 37 | """ 38 | 39 | def __init__(self): 40 | super(CallerIs, self).__init__("_caller_is") 41 | 42 | def invoke(self, name, nframes = 1): 43 | if nframes < 0: 44 | raise ValueError("nframes must be >= 0") 45 | frame = gdb.selected_frame() 46 | while nframes > 0: 47 | frame = frame.older() 48 | if frame is None: 49 | return False 50 | nframes = nframes - 1 51 | return frame.name() == name.string() 52 | 53 | class CallerMatches(gdb.Function): 54 | """Compare the calling function's name with a regexp. 55 | 56 | Usage: 57 | $_caller_matches(regex [, number_of_frames]) 58 | 59 | Arguments: 60 | 61 | regex: The regular expression to compare the function's name with. 62 | 63 | number_of_frames: How many stack frames to traverse back from the currently 64 | selected frame to compare with. If the value is greater than the depth of 65 | the stack from that point then the result is False. 66 | The default is 1. 67 | 68 | Returns: 69 | True if the function's name at the specified frame matches regex. 70 | """ 71 | 72 | def __init__(self): 73 | super(CallerMatches, self).__init__("_caller_matches") 74 | 75 | def invoke(self, name, nframes = 1): 76 | if nframes < 0: 77 | raise ValueError("nframes must be >= 0") 78 | frame = gdb.selected_frame() 79 | while nframes > 0: 80 | frame = frame.older() 81 | if frame is None: 82 | return False 83 | nframes = nframes - 1 84 | return re.match(name.string(), frame.name()) is not None 85 | 86 | class AnyCallerIs(gdb.Function): 87 | """Check all calling function's names. 88 | 89 | Usage: 90 | $_any_caller_is(name [, number_of_frames]) 91 | 92 | Arguments: 93 | 94 | name: The name of the function to search for. 95 | 96 | number_of_frames: How many stack frames to traverse back from the currently 97 | selected frame to compare with. If the value is greater than the depth of 98 | the stack from that point then the result is False. 99 | The default is 1. 100 | 101 | Returns: 102 | True if any function's name is equal to name. 103 | """ 104 | 105 | def __init__(self): 106 | super(AnyCallerIs, self).__init__("_any_caller_is") 107 | 108 | def invoke(self, name, nframes = 1): 109 | if nframes < 0: 110 | raise ValueError("nframes must be >= 0") 111 | frame = gdb.selected_frame() 112 | while nframes >= 0: 113 | if frame.name() == name.string(): 114 | return True 115 | frame = frame.older() 116 | if frame is None: 117 | return False 118 | nframes = nframes - 1 119 | return False 120 | 121 | class AnyCallerMatches(gdb.Function): 122 | """Compare all calling function's names with a regexp. 123 | 124 | Usage: 125 | $_any_caller_matches(regex [, number_of_frames]) 126 | 127 | Arguments: 128 | 129 | regex: The regular expression to compare the function's name with. 130 | 131 | number_of_frames: How many stack frames to traverse back from the currently 132 | selected frame to compare with. If the value is greater than the depth of 133 | the stack from that point then the result is False. 134 | The default is 1. 135 | 136 | Returns: 137 | True if any function's name matches regex. 138 | """ 139 | 140 | def __init__(self): 141 | super(AnyCallerMatches, self).__init__("_any_caller_matches") 142 | 143 | def invoke(self, name, nframes = 1): 144 | if nframes < 0: 145 | raise ValueError("nframes must be >= 0") 146 | frame = gdb.selected_frame() 147 | name_re = re.compile(name.string()) 148 | while nframes >= 0: 149 | if name_re.match(frame.name()) is not None: 150 | return True 151 | frame = frame.older() 152 | if frame is None: 153 | return False 154 | nframes = nframes - 1 155 | return False 156 | 157 | CallerIs() 158 | CallerMatches() 159 | AnyCallerIs() 160 | AnyCallerMatches() 161 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/function/strfns.py: -------------------------------------------------------------------------------- 1 | # Useful gdb string convenience functions. 2 | # Copyright (C) 2012-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """$_memeq, $_strlen, $_streq, $_regex""" 18 | 19 | import gdb 20 | import re 21 | 22 | 23 | class _MemEq(gdb.Function): 24 | """$_memeq - compare bytes of memory 25 | 26 | Usage: 27 | $_memeq(a, b, len) 28 | 29 | Returns: 30 | True if len bytes at a and b compare equally. 31 | """ 32 | def __init__(self): 33 | super(_MemEq, self).__init__("_memeq") 34 | 35 | def invoke(self, a, b, length): 36 | if length < 0: 37 | raise ValueError("length must be non-negative") 38 | if length == 0: 39 | return True 40 | # The argument(s) to vector are [low_bound,]high_bound. 41 | byte_vector = gdb.lookup_type("char").vector(length - 1) 42 | ptr_byte_vector = byte_vector.pointer() 43 | a_ptr = a.reinterpret_cast(ptr_byte_vector) 44 | b_ptr = b.reinterpret_cast(ptr_byte_vector) 45 | return a_ptr.dereference() == b_ptr.dereference() 46 | 47 | 48 | class _StrLen(gdb.Function): 49 | """$_strlen - compute string length 50 | 51 | Usage: 52 | $_strlen(a) 53 | 54 | Returns: 55 | Length of string a, assumed to be a string in the current language. 56 | """ 57 | def __init__(self): 58 | super(_StrLen, self).__init__("_strlen") 59 | 60 | def invoke(self, a): 61 | s = a.string() 62 | return len(s) 63 | 64 | 65 | class _StrEq(gdb.Function): 66 | """$_streq - check string equality 67 | 68 | Usage: 69 | $_streq(a, b) 70 | 71 | Returns: 72 | True if a and b are identical strings in the current language. 73 | 74 | Example (amd64-linux): 75 | catch syscall open 76 | cond $bpnum $_streq((char*) $rdi, "foo") 77 | """ 78 | def __init__(self): 79 | super(_StrEq, self).__init__("_streq") 80 | 81 | def invoke(self, a, b): 82 | return a.string() == b.string() 83 | 84 | 85 | class _RegEx(gdb.Function): 86 | """$_regex - check if a string matches a regular expression 87 | 88 | Usage: 89 | $_regex(string, regex) 90 | 91 | Returns: 92 | True if string str (in the current language) matches the 93 | regular expression regex. 94 | """ 95 | def __init__(self): 96 | super(_RegEx, self).__init__("_regex") 97 | 98 | def invoke(self, string, regex): 99 | s = string.string() 100 | r = re.compile(regex.string()) 101 | return bool(r.match(s)) 102 | 103 | 104 | # GDB will import us automagically via gdb/__init__.py. 105 | _MemEq() 106 | _StrLen() 107 | _StrEq() 108 | _RegEx() 109 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/printer/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/printer/bound_registers.py: -------------------------------------------------------------------------------- 1 | # Pretty-printers for bounds registers. 2 | # Copyright (C) 2013-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | import gdb.printing 18 | 19 | class MpxBound128Printer: 20 | """Adds size field to a mpx __gdb_builtin_type_bound128 type.""" 21 | 22 | def __init__ (self, val): 23 | self.val = val 24 | 25 | def to_string (self): 26 | upper = self.val["ubound"] 27 | lower = self.val["lbound"] 28 | size = (long) ((upper) - (lower)) 29 | if size > -1: 30 | size = size + 1 31 | result = '{lbound = %s, ubound = %s} : size %s' % (lower, upper, size) 32 | return result 33 | 34 | gdb.printing.add_builtin_pretty_printer ('mpx_bound128', 35 | '^__gdb_builtin_type_bound128', 36 | MpxBound128Printer) 37 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/printing.py: -------------------------------------------------------------------------------- 1 | # Pretty-printer utilities. 2 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """Utilities for working with pretty-printers.""" 18 | 19 | import gdb 20 | import gdb.types 21 | import re 22 | import sys 23 | 24 | if sys.version_info[0] > 2: 25 | # Python 3 removed basestring and long 26 | basestring = str 27 | long = int 28 | 29 | class PrettyPrinter(object): 30 | """A basic pretty-printer. 31 | 32 | Attributes: 33 | name: A unique string among all printers for the context in which 34 | it is defined (objfile, progspace, or global(gdb)), and should 35 | meaningfully describe what can be pretty-printed. 36 | E.g., "StringPiece" or "protobufs". 37 | subprinters: An iterable object with each element having a `name' 38 | attribute, and, potentially, "enabled" attribute. 39 | Or this is None if there are no subprinters. 40 | enabled: A boolean indicating if the printer is enabled. 41 | 42 | Subprinters are for situations where "one" pretty-printer is actually a 43 | collection of several printers. E.g., The libstdc++ pretty-printer has 44 | a pretty-printer for each of several different types, based on regexps. 45 | """ 46 | 47 | # While one might want to push subprinters into the subclass, it's 48 | # present here to formalize such support to simplify 49 | # commands/pretty_printers.py. 50 | 51 | def __init__(self, name, subprinters=None): 52 | self.name = name 53 | self.subprinters = subprinters 54 | self.enabled = True 55 | 56 | def __call__(self, val): 57 | # The subclass must define this. 58 | raise NotImplementedError("PrettyPrinter __call__") 59 | 60 | 61 | class SubPrettyPrinter(object): 62 | """Baseclass for sub-pretty-printers. 63 | 64 | Sub-pretty-printers needn't use this, but it formalizes what's needed. 65 | 66 | Attributes: 67 | name: The name of the subprinter. 68 | enabled: A boolean indicating if the subprinter is enabled. 69 | """ 70 | 71 | def __init__(self, name): 72 | self.name = name 73 | self.enabled = True 74 | 75 | 76 | def register_pretty_printer(obj, printer, replace=False): 77 | """Register pretty-printer PRINTER with OBJ. 78 | 79 | The printer is added to the front of the search list, thus one can override 80 | an existing printer if one needs to. Use a different name when overriding 81 | an existing printer, otherwise an exception will be raised; multiple 82 | printers with the same name are disallowed. 83 | 84 | Arguments: 85 | obj: Either an objfile, progspace, or None (in which case the printer 86 | is registered globally). 87 | printer: Either a function of one argument (old way) or any object 88 | which has attributes: name, enabled, __call__. 89 | replace: If True replace any existing copy of the printer. 90 | Otherwise if the printer already exists raise an exception. 91 | 92 | Returns: 93 | Nothing. 94 | 95 | Raises: 96 | TypeError: A problem with the type of the printer. 97 | ValueError: The printer's name contains a semicolon ";". 98 | RuntimeError: A printer with the same name is already registered. 99 | 100 | If the caller wants the printer to be listable and disableable, it must 101 | follow the PrettyPrinter API. This applies to the old way (functions) too. 102 | If printer is an object, __call__ is a method of two arguments: 103 | self, and the value to be pretty-printed. See PrettyPrinter. 104 | """ 105 | 106 | # Watch for both __name__ and name. 107 | # Functions get the former for free, but we don't want to use an 108 | # attribute named __foo__ for pretty-printers-as-objects. 109 | # If printer has both, we use `name'. 110 | if not hasattr(printer, "__name__") and not hasattr(printer, "name"): 111 | raise TypeError("printer missing attribute: name") 112 | if hasattr(printer, "name") and not hasattr(printer, "enabled"): 113 | raise TypeError("printer missing attribute: enabled") 114 | if not hasattr(printer, "__call__"): 115 | raise TypeError("printer missing attribute: __call__") 116 | 117 | if hasattr(printer, "name"): 118 | name = printer.name 119 | else: 120 | name = printer.__name__ 121 | if obj is None or obj is gdb: 122 | if gdb.parameter("verbose"): 123 | gdb.write("Registering global %s pretty-printer ...\n" % name) 124 | obj = gdb 125 | else: 126 | if gdb.parameter("verbose"): 127 | gdb.write("Registering %s pretty-printer for %s ...\n" % ( 128 | name, obj.filename)) 129 | 130 | # Printers implemented as functions are old-style. In order to not risk 131 | # breaking anything we do not check __name__ here. 132 | if hasattr(printer, "name"): 133 | if not isinstance(printer.name, basestring): 134 | raise TypeError("printer name is not a string") 135 | # If printer provides a name, make sure it doesn't contain ";". 136 | # Semicolon is used by the info/enable/disable pretty-printer commands 137 | # to delimit subprinters. 138 | if printer.name.find(";") >= 0: 139 | raise ValueError("semicolon ';' in printer name") 140 | # Also make sure the name is unique. 141 | # Alas, we can't do the same for functions and __name__, they could 142 | # all have a canonical name like "lookup_function". 143 | # PERF: gdb records printers in a list, making this inefficient. 144 | i = 0 145 | for p in obj.pretty_printers: 146 | if hasattr(p, "name") and p.name == printer.name: 147 | if replace: 148 | del obj.pretty_printers[i] 149 | break 150 | else: 151 | raise RuntimeError("pretty-printer already registered: %s" % 152 | printer.name) 153 | i = i + 1 154 | 155 | obj.pretty_printers.insert(0, printer) 156 | 157 | 158 | class RegexpCollectionPrettyPrinter(PrettyPrinter): 159 | """Class for implementing a collection of regular-expression based pretty-printers. 160 | 161 | Intended usage: 162 | 163 | pretty_printer = RegexpCollectionPrettyPrinter("my_library") 164 | pretty_printer.add_printer("myclass1", "^myclass1$", MyClass1Printer) 165 | ... 166 | pretty_printer.add_printer("myclassN", "^myclassN$", MyClassNPrinter) 167 | register_pretty_printer(obj, pretty_printer) 168 | """ 169 | 170 | class RegexpSubprinter(SubPrettyPrinter): 171 | def __init__(self, name, regexp, gen_printer): 172 | super(RegexpCollectionPrettyPrinter.RegexpSubprinter, self).__init__(name) 173 | self.regexp = regexp 174 | self.gen_printer = gen_printer 175 | self.compiled_re = re.compile(regexp) 176 | 177 | def __init__(self, name): 178 | super(RegexpCollectionPrettyPrinter, self).__init__(name, []) 179 | 180 | def add_printer(self, name, regexp, gen_printer): 181 | """Add a printer to the list. 182 | 183 | The printer is added to the end of the list. 184 | 185 | Arguments: 186 | name: The name of the subprinter. 187 | regexp: The regular expression, as a string. 188 | gen_printer: A function/method that given a value returns an 189 | object to pretty-print it. 190 | 191 | Returns: 192 | Nothing. 193 | """ 194 | 195 | # NOTE: A previous version made the name of each printer the regexp. 196 | # That makes it awkward to pass to the enable/disable commands (it's 197 | # cumbersome to make a regexp of a regexp). So now the name is a 198 | # separate parameter. 199 | 200 | self.subprinters.append(self.RegexpSubprinter(name, regexp, 201 | gen_printer)) 202 | 203 | def __call__(self, val): 204 | """Lookup the pretty-printer for the provided value.""" 205 | 206 | # Get the type name. 207 | typename = gdb.types.get_basic_type(val.type).tag 208 | if not typename: 209 | typename = val.type.name 210 | if not typename: 211 | return None 212 | 213 | # Iterate over table of type regexps to determine 214 | # if a printer is registered for that type. 215 | # Return an instantiation of the printer if found. 216 | for printer in self.subprinters: 217 | if printer.enabled and printer.compiled_re.search(typename): 218 | return printer.gen_printer(val) 219 | 220 | # Cannot find a pretty printer. Return None. 221 | return None 222 | 223 | # A helper class for printing enum types. This class is instantiated 224 | # with a list of enumerators to print a particular Value. 225 | class _EnumInstance: 226 | def __init__(self, enumerators, val): 227 | self.enumerators = enumerators 228 | self.val = val 229 | 230 | def to_string(self): 231 | flag_list = [] 232 | v = long(self.val) 233 | any_found = False 234 | for (e_name, e_value) in self.enumerators: 235 | if v & e_value != 0: 236 | flag_list.append(e_name) 237 | v = v & ~e_value 238 | any_found = True 239 | if not any_found or v != 0: 240 | # Leftover value. 241 | flag_list.append('' % v) 242 | return "0x%x [%s]" % (int(self.val), " | ".join(flag_list)) 243 | 244 | class FlagEnumerationPrinter(PrettyPrinter): 245 | """A pretty-printer which can be used to print a flag-style enumeration. 246 | A flag-style enumeration is one where the enumerators are or'd 247 | together to create values. The new printer will print these 248 | symbolically using '|' notation. The printer must be registered 249 | manually. This printer is most useful when an enum is flag-like, 250 | but has some overlap. GDB's built-in printing will not handle 251 | this case, but this printer will attempt to.""" 252 | 253 | def __init__(self, enum_type): 254 | super(FlagEnumerationPrinter, self).__init__(enum_type) 255 | self.initialized = False 256 | 257 | def __call__(self, val): 258 | if not self.initialized: 259 | self.initialized = True 260 | flags = gdb.lookup_type(self.name) 261 | self.enumerators = [] 262 | for field in flags.fields(): 263 | self.enumerators.append((field.name, field.enumval)) 264 | # Sorting the enumerators by value usually does the right 265 | # thing. 266 | self.enumerators.sort(key = lambda x: x[1]) 267 | 268 | if self.enabled: 269 | return _EnumInstance(self.enumerators, val) 270 | else: 271 | return None 272 | 273 | 274 | # Builtin pretty-printers. 275 | # The set is defined as empty, and files in printing/*.py add their printers 276 | # to this with add_builtin_pretty_printer. 277 | 278 | _builtin_pretty_printers = RegexpCollectionPrettyPrinter("builtin") 279 | 280 | register_pretty_printer(None, _builtin_pretty_printers) 281 | 282 | # Add a builtin pretty-printer. 283 | 284 | def add_builtin_pretty_printer(name, regexp, printer): 285 | _builtin_pretty_printers.add_printer(name, regexp, printer) 286 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/prompt.py: -------------------------------------------------------------------------------- 1 | # Extended prompt utilities. 2 | # Copyright (C) 2011-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """ Extended prompt library functions.""" 18 | 19 | import gdb 20 | import os 21 | 22 | def _prompt_pwd(ignore): 23 | "The current working directory." 24 | return os.getcwd() 25 | 26 | def _prompt_object_attr(func, what, attr, nattr): 27 | """Internal worker for fetching GDB attributes.""" 28 | if attr is None: 29 | attr = nattr 30 | try: 31 | obj = func() 32 | except gdb.error: 33 | return '' % what 34 | if hasattr(obj, attr): 35 | result = getattr(obj, attr) 36 | if callable(result): 37 | result = result() 38 | return result 39 | else: 40 | return '' % (attr, what) 41 | 42 | def _prompt_frame(attr): 43 | "The selected frame; an argument names a frame parameter." 44 | return _prompt_object_attr(gdb.selected_frame, 'frame', attr, 'name') 45 | 46 | def _prompt_thread(attr): 47 | "The selected thread; an argument names a thread parameter." 48 | return _prompt_object_attr(gdb.selected_thread, 'thread', attr, 'num') 49 | 50 | def _prompt_version(attr): 51 | "The version of GDB." 52 | return gdb.VERSION 53 | 54 | def _prompt_esc(attr): 55 | "The ESC character." 56 | return '\033' 57 | 58 | def _prompt_bs(attr): 59 | "A backslash." 60 | return '\\' 61 | 62 | def _prompt_n(attr): 63 | "A newline." 64 | return '\n' 65 | 66 | def _prompt_r(attr): 67 | "A carriage return." 68 | return '\r' 69 | 70 | def _prompt_param(attr): 71 | "A parameter's value; the argument names the parameter." 72 | return gdb.parameter(attr) 73 | 74 | def _prompt_noprint_begin(attr): 75 | "Begins a sequence of non-printing characters." 76 | return '\001' 77 | 78 | def _prompt_noprint_end(attr): 79 | "Ends a sequence of non-printing characters." 80 | return '\002' 81 | 82 | prompt_substitutions = { 83 | 'e': _prompt_esc, 84 | '\\': _prompt_bs, 85 | 'n': _prompt_n, 86 | 'r': _prompt_r, 87 | 'v': _prompt_version, 88 | 'w': _prompt_pwd, 89 | 'f': _prompt_frame, 90 | 't': _prompt_thread, 91 | 'p': _prompt_param, 92 | '[': _prompt_noprint_begin, 93 | ']': _prompt_noprint_end 94 | } 95 | 96 | def prompt_help(): 97 | """Generate help dynamically from the __doc__ strings of attribute 98 | functions.""" 99 | 100 | result = '' 101 | keys = sorted (prompt_substitutions.keys()) 102 | for key in keys: 103 | result += ' \\%s\t%s\n' % (key, prompt_substitutions[key].__doc__) 104 | result += """ 105 | A substitution can be used in a simple form, like "\\f". 106 | An argument can also be passed to it, like "\\f{name}". 107 | The meaning of the argument depends on the particular substitution.""" 108 | return result 109 | 110 | def substitute_prompt(prompt): 111 | "Perform substitutions on PROMPT." 112 | 113 | result = '' 114 | plen = len(prompt) 115 | i = 0 116 | while i < plen: 117 | if prompt[i] == '\\': 118 | i = i + 1 119 | if i >= plen: 120 | break 121 | cmdch = prompt[i] 122 | 123 | if cmdch in prompt_substitutions: 124 | cmd = prompt_substitutions[cmdch] 125 | 126 | if i + 1 < plen and prompt[i + 1] == '{': 127 | j = i + 1 128 | while j < plen and prompt[j] != '}': 129 | j = j + 1 130 | # Just ignore formatting errors. 131 | if j >= plen or prompt[j] != '}': 132 | arg = None 133 | else: 134 | arg = prompt[i + 2 : j] 135 | i = j 136 | else: 137 | arg = None 138 | result += str(cmd(arg)) 139 | else: 140 | # Unrecognized escapes are turned into the escaped 141 | # character itself. 142 | result += prompt[i] 143 | else: 144 | result += prompt[i] 145 | 146 | i = i + 1 147 | 148 | return result 149 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/types.py: -------------------------------------------------------------------------------- 1 | # Type utilities. 2 | # Copyright (C) 2010-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """Utilities for working with gdb.Types.""" 18 | 19 | import gdb 20 | 21 | 22 | def get_basic_type(type_): 23 | """Return the "basic" type of a type. 24 | 25 | Arguments: 26 | type_: The type to reduce to its basic type. 27 | 28 | Returns: 29 | type_ with const/volatile is stripped away, 30 | and typedefs/references converted to the underlying type. 31 | """ 32 | 33 | while (type_.code == gdb.TYPE_CODE_REF or 34 | type_.code == gdb.TYPE_CODE_TYPEDEF): 35 | if type_.code == gdb.TYPE_CODE_REF: 36 | type_ = type_.target() 37 | else: 38 | type_ = type_.strip_typedefs() 39 | return type_.unqualified() 40 | 41 | 42 | def has_field(type_, field): 43 | """Return True if a type has the specified field. 44 | 45 | Arguments: 46 | type_: The type to examine. 47 | It must be one of gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION. 48 | field: The name of the field to look up. 49 | 50 | Returns: 51 | True if the field is present either in type_ or any baseclass. 52 | 53 | Raises: 54 | TypeError: The type is not a struct or union. 55 | """ 56 | 57 | type_ = get_basic_type(type_) 58 | if (type_.code != gdb.TYPE_CODE_STRUCT and 59 | type_.code != gdb.TYPE_CODE_UNION): 60 | raise TypeError("not a struct or union") 61 | for f in type_.fields(): 62 | if f.is_base_class: 63 | if has_field(f.type, field): 64 | return True 65 | else: 66 | # NOTE: f.name could be None 67 | if f.name == field: 68 | return True 69 | return False 70 | 71 | 72 | def make_enum_dict(enum_type): 73 | """Return a dictionary from a program's enum type. 74 | 75 | Arguments: 76 | enum_type: The enum to compute the dictionary for. 77 | 78 | Returns: 79 | The dictionary of the enum. 80 | 81 | Raises: 82 | TypeError: The type is not an enum. 83 | """ 84 | 85 | if enum_type.code != gdb.TYPE_CODE_ENUM: 86 | raise TypeError("not an enum type") 87 | enum_dict = {} 88 | for field in enum_type.fields(): 89 | # The enum's value is stored in "enumval". 90 | enum_dict[field.name] = field.enumval 91 | return enum_dict 92 | 93 | 94 | def deep_items (type_): 95 | """Return an iterator that recursively traverses anonymous fields. 96 | 97 | Arguments: 98 | type_: The type to traverse. It should be one of 99 | gdb.TYPE_CODE_STRUCT or gdb.TYPE_CODE_UNION. 100 | 101 | Returns: 102 | an iterator similar to gdb.Type.iteritems(), i.e., it returns 103 | pairs of key, value, but for any anonymous struct or union 104 | field that field is traversed recursively, depth-first. 105 | """ 106 | for k, v in type_.iteritems (): 107 | if k: 108 | yield k, v 109 | else: 110 | for i in deep_items (v.type): 111 | yield i 112 | 113 | class TypePrinter(object): 114 | """The base class for type printers. 115 | 116 | Instances of this type can be used to substitute type names during 117 | 'ptype'. 118 | 119 | A type printer must have at least 'name' and 'enabled' attributes, 120 | and supply an 'instantiate' method. 121 | 122 | The 'instantiate' method must either return None, or return an 123 | object which has a 'recognize' method. This method must accept a 124 | gdb.Type argument and either return None, meaning that the type 125 | was not recognized, or a string naming the type. 126 | """ 127 | 128 | def __init__(self, name): 129 | self.name = name 130 | self.enabled = True 131 | 132 | def instantiate(self): 133 | return None 134 | 135 | # Helper function for computing the list of type recognizers. 136 | def _get_some_type_recognizers(result, plist): 137 | for printer in plist: 138 | if printer.enabled: 139 | inst = printer.instantiate() 140 | if inst is not None: 141 | result.append(inst) 142 | return None 143 | 144 | def get_type_recognizers(): 145 | "Return a list of the enabled type recognizers for the current context." 146 | result = [] 147 | 148 | # First try the objfiles. 149 | for objfile in gdb.objfiles(): 150 | _get_some_type_recognizers(result, objfile.type_printers) 151 | # Now try the program space. 152 | _get_some_type_recognizers(result, gdb.current_progspace().type_printers) 153 | # Finally, globals. 154 | _get_some_type_recognizers(result, gdb.type_printers) 155 | 156 | return result 157 | 158 | def apply_type_recognizers(recognizers, type_obj): 159 | """Apply the given list of type recognizers to the type TYPE_OBJ. 160 | If any recognizer in the list recognizes TYPE_OBJ, returns the name 161 | given by the recognizer. Otherwise, this returns None.""" 162 | for r in recognizers: 163 | result = r.recognize(type_obj) 164 | if result is not None: 165 | return result 166 | return None 167 | 168 | def register_type_printer(locus, printer): 169 | """Register a type printer. 170 | PRINTER is the type printer instance. 171 | LOCUS is either an objfile, a program space, or None, indicating 172 | global registration.""" 173 | 174 | if locus is None: 175 | locus = gdb 176 | locus.type_printers.insert(0, printer) 177 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/unwinder.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | """Unwinder class and register_unwinder function.""" 17 | 18 | import gdb 19 | 20 | 21 | class Unwinder(object): 22 | """Base class (or a template) for frame unwinders written in Python. 23 | 24 | An unwinder has a single method __call__ and the attributes 25 | described below. 26 | 27 | Attributes: 28 | name: The name of the unwinder. 29 | enabled: A boolean indicating whether the unwinder is enabled. 30 | """ 31 | 32 | def __init__(self, name): 33 | """Constructor. 34 | 35 | Args: 36 | name: An identifying name for the unwinder. 37 | """ 38 | self.name = name 39 | self.enabled = True 40 | 41 | def __call__(self, pending_frame): 42 | """GDB calls this method to unwind a frame. 43 | 44 | Arguments: 45 | pending_frame: gdb.PendingFrame instance. 46 | 47 | Returns: 48 | gdb.UnwindInfo instance. 49 | """ 50 | raise NotImplementedError("Unwinder __call__.") 51 | 52 | 53 | def register_unwinder(locus, unwinder, replace=False): 54 | """Register unwinder in given locus. 55 | 56 | The unwinder is prepended to the locus's unwinders list. Unwinder 57 | name should be unique. 58 | 59 | Arguments: 60 | locus: Either an objfile, progspace, or None (in which case 61 | the unwinder is registered globally). 62 | unwinder: An object of a gdb.Unwinder subclass 63 | replace: If True, replaces existing unwinder with the same name. 64 | Otherwise, raises exception if unwinder with the same 65 | name already exists. 66 | 67 | Returns: 68 | Nothing. 69 | 70 | Raises: 71 | RuntimeError: Unwinder name is not unique 72 | TypeError: Bad locus type 73 | """ 74 | if locus is None: 75 | if gdb.parameter("verbose"): 76 | gdb.write("Registering global %s unwinder ...\n" % unwinder.name) 77 | locus = gdb 78 | elif isinstance(locus, gdb.Objfile) or isinstance(locus, gdb.Progspace): 79 | if gdb.parameter("verbose"): 80 | gdb.write("Registering %s unwinder for %s ...\n" % 81 | (unwinder.name, locus.filename)) 82 | else: 83 | raise TypeError("locus should be gdb.Objfile or gdb.Progspace or None") 84 | 85 | i = 0 86 | for needle in locus.frame_unwinders: 87 | if needle.name == unwinder.name: 88 | if replace: 89 | del locus.frame_unwinders[i] 90 | else: 91 | raise RuntimeError("Unwinder %s already exists." % 92 | unwinder.name) 93 | i += 1 94 | locus.frame_unwinders.insert(0, unwinder) 95 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/python/gdb/xmethod.py: -------------------------------------------------------------------------------- 1 | # Python side of the support for xmethods. 2 | # Copyright (C) 2013-2016 Free Software Foundation, Inc. 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | """Utilities for defining xmethods""" 18 | 19 | import gdb 20 | import re 21 | import sys 22 | 23 | 24 | if sys.version_info[0] > 2: 25 | # Python 3 removed basestring and long 26 | basestring = str 27 | long = int 28 | 29 | 30 | class XMethod(object): 31 | """Base class (or a template) for an xmethod description. 32 | 33 | Currently, the description requires only the 'name' and 'enabled' 34 | attributes. Description objects are managed by 'XMethodMatcher' 35 | objects (see below). Note that this is only a template for the 36 | interface of the XMethodMatcher.methods objects. One could use 37 | this class or choose to use an object which supports this exact same 38 | interface. Also, an XMethodMatcher can choose not use it 'methods' 39 | attribute. In such cases this class (or an equivalent) is not used. 40 | 41 | Attributes: 42 | name: The name of the xmethod. 43 | enabled: A boolean indicating if the xmethod is enabled. 44 | """ 45 | 46 | def __init__(self, name): 47 | self.name = name 48 | self.enabled = True 49 | 50 | 51 | class XMethodMatcher(object): 52 | """Abstract base class for matching an xmethod. 53 | 54 | When looking for xmethods, GDB invokes the `match' method of a 55 | registered xmethod matcher to match the object type and method name. 56 | The `match' method in concrete classes derived from this class should 57 | return an `XMethodWorker' object, or a list of `XMethodWorker' 58 | objects if there is a match (see below for 'XMethodWorker' class). 59 | 60 | Attributes: 61 | name: The name of the matcher. 62 | enabled: A boolean indicating if the matcher is enabled. 63 | methods: A sequence of objects of type 'XMethod', or objects 64 | which have at least the attributes of an 'XMethod' object. 65 | This list is used by the 'enable'/'disable'/'info' commands to 66 | enable/disable/list the xmethods registered with GDB. See 67 | the 'match' method below to know how this sequence is used. 68 | This attribute is None if the matcher chooses not have any 69 | xmethods managed by it. 70 | """ 71 | 72 | def __init__(self, name): 73 | """ 74 | Args: 75 | name: An identifying name for the xmethod or the group of 76 | xmethods returned by the `match' method. 77 | """ 78 | self.name = name 79 | self.enabled = True 80 | self.methods = None 81 | 82 | def match(self, class_type, method_name): 83 | """Match class type and method name. 84 | 85 | In derived classes, it should return an XMethodWorker object, or a 86 | sequence of 'XMethodWorker' objects. Only those xmethod workers 87 | whose corresponding 'XMethod' descriptor object is enabled should be 88 | returned. 89 | 90 | Args: 91 | class_type: The class type (gdb.Type object) to match. 92 | method_name: The name (string) of the method to match. 93 | """ 94 | raise NotImplementedError("XMethodMatcher match") 95 | 96 | 97 | class XMethodWorker(object): 98 | """Base class for all xmethod workers defined in Python. 99 | 100 | An xmethod worker is an object which matches the method arguments, and 101 | invokes the method when GDB wants it to. Internally, GDB first invokes the 102 | 'get_arg_types' method to perform overload resolution. If GDB selects to 103 | invoke this Python xmethod, then it invokes it via the overridden 104 | '__call__' method. The 'get_result_type' method is used to implement 105 | 'ptype' on the xmethod. 106 | 107 | Derived classes should override the 'get_arg_types', 'get_result_type' 108 | and '__call__' methods. 109 | """ 110 | 111 | def get_arg_types(self): 112 | """Return arguments types of an xmethod. 113 | 114 | A sequence of gdb.Type objects corresponding to the arguments of the 115 | xmethod are returned. If the xmethod takes no arguments, then 'None' 116 | or an empty sequence is returned. If the xmethod takes only a single 117 | argument, then a gdb.Type object or a sequence with a single gdb.Type 118 | element is returned. 119 | """ 120 | raise NotImplementedError("XMethodWorker get_arg_types") 121 | 122 | def get_result_type(self, *args): 123 | """Return the type of the result of the xmethod. 124 | 125 | Args: 126 | args: Arguments to the method. Each element of the tuple is a 127 | gdb.Value object. The first element is the 'this' pointer 128 | value. These are the same arguments passed to '__call__'. 129 | 130 | Returns: 131 | A gdb.Type object representing the type of the result of the 132 | xmethod. 133 | """ 134 | raise NotImplementedError("XMethodWorker get_result_type") 135 | 136 | def __call__(self, *args): 137 | """Invoke the xmethod. 138 | 139 | Args: 140 | args: Arguments to the method. Each element of the tuple is a 141 | gdb.Value object. The first element is the 'this' pointer 142 | value. 143 | 144 | Returns: 145 | A gdb.Value corresponding to the value returned by the xmethod. 146 | Returns 'None' if the method does not return anything. 147 | """ 148 | raise NotImplementedError("XMethodWorker __call__") 149 | 150 | 151 | class SimpleXMethodMatcher(XMethodMatcher): 152 | """A utility class to implement simple xmethod mathers and workers. 153 | 154 | See the __init__ method below for information on how instances of this 155 | class can be used. 156 | 157 | For simple classes and methods, one can choose to use this class. For 158 | complex xmethods, which need to replace/implement template methods on 159 | possibly template classes, one should implement their own xmethod 160 | matchers and workers. See py-xmethods.py in testsuite/gdb.python 161 | directory of the GDB source tree for examples. 162 | """ 163 | 164 | class SimpleXMethodWorker(XMethodWorker): 165 | def __init__(self, method_function, arg_types): 166 | self._arg_types = arg_types 167 | self._method_function = method_function 168 | 169 | def get_arg_types(self): 170 | return self._arg_types 171 | 172 | def __call__(self, *args): 173 | return self._method_function(*args) 174 | 175 | 176 | def __init__(self, name, class_matcher, method_matcher, method_function, 177 | *arg_types): 178 | """ 179 | Args: 180 | name: Name of the xmethod matcher. 181 | class_matcher: A regular expression used to match the name of the 182 | class whose method this xmethod is implementing/replacing. 183 | method_matcher: A regular expression used to match the name of the 184 | method this xmethod is implementing/replacing. 185 | method_function: A Python callable which would be called via the 186 | 'invoke' method of the worker returned by the objects of this 187 | class. This callable should accept the object (*this) as the 188 | first argument followed by the rest of the arguments to the 189 | method. All arguments to this function should be gdb.Value 190 | objects. 191 | arg_types: The gdb.Type objects corresponding to the arguments that 192 | this xmethod takes. It can be None, or an empty sequence, 193 | or a single gdb.Type object, or a sequence of gdb.Type objects. 194 | """ 195 | XMethodMatcher.__init__(self, name) 196 | assert callable(method_function), ( 197 | "The 'method_function' argument to 'SimpleXMethodMatcher' " 198 | "__init__ method should be a callable.") 199 | self._method_function = method_function 200 | self._class_matcher = class_matcher 201 | self._method_matcher = method_matcher 202 | self._arg_types = arg_types 203 | 204 | def match(self, class_type, method_name): 205 | cm = re.match(self._class_matcher, str(class_type.unqualified().tag)) 206 | mm = re.match(self._method_matcher, method_name) 207 | if cm and mm: 208 | return SimpleXMethodMatcher.SimpleXMethodWorker( 209 | self._method_function, self._arg_types) 210 | 211 | 212 | # A helper function for register_xmethod_matcher which returns an error 213 | # object if MATCHER is not having the requisite attributes in the proper 214 | # format. 215 | 216 | def _validate_xmethod_matcher(matcher): 217 | if not hasattr(matcher, "match"): 218 | return TypeError("Xmethod matcher is missing method: match") 219 | if not hasattr(matcher, "name"): 220 | return TypeError("Xmethod matcher is missing attribute: name") 221 | if not hasattr(matcher, "enabled"): 222 | return TypeError("Xmethod matcher is missing attribute: enabled") 223 | if not isinstance(matcher.name, basestring): 224 | return TypeError("Attribute 'name' of xmethod matcher is not a " 225 | "string") 226 | if matcher.name.find(";") >= 0: 227 | return ValueError("Xmethod matcher name cannot contain ';' in it") 228 | 229 | 230 | # A helper function for register_xmethod_matcher which looks up an 231 | # xmethod matcher with NAME in LOCUS. Returns the index of the xmethod 232 | # matcher in 'xmethods' sequence attribute of the LOCUS. If NAME is not 233 | # found in LOCUS, then -1 is returned. 234 | 235 | def _lookup_xmethod_matcher(locus, name): 236 | for i in range(0, len(locus.xmethods)): 237 | if locus.xmethods[i].name == name: 238 | return i 239 | return -1 240 | 241 | 242 | def register_xmethod_matcher(locus, matcher, replace=False): 243 | """Registers a xmethod matcher MATCHER with a LOCUS. 244 | 245 | Arguments: 246 | locus: The locus in which the xmethods should be registered. 247 | It can be 'None' to indicate that the xmethods should be 248 | registered globally. Or, it could be a gdb.Objfile or a 249 | gdb.Progspace object in which the xmethods should be 250 | registered. 251 | matcher: The xmethod matcher to register with the LOCUS. It 252 | should be an instance of 'XMethodMatcher' class. 253 | replace: If True, replace any existing xmethod matcher with the 254 | same name in the locus. Otherwise, if a matcher with the same name 255 | exists in the locus, raise an exception. 256 | """ 257 | err = _validate_xmethod_matcher(matcher) 258 | if err: 259 | raise err 260 | if not locus: 261 | locus = gdb 262 | if locus == gdb: 263 | locus_name = "global" 264 | else: 265 | locus_name = locus.filename 266 | index = _lookup_xmethod_matcher(locus, matcher.name) 267 | if index >= 0: 268 | if replace: 269 | del locus.xmethods[index] 270 | else: 271 | raise RuntimeError("Xmethod matcher already registered with " 272 | "%s: %s" % (locus_name, matcher.name)) 273 | if gdb.parameter("verbose"): 274 | gdb.write("Registering xmethod matcher '%s' with %s' ...\n") 275 | locus.xmethods.insert(0, matcher) 276 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/stamp-guile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gdb/bin/x86_64/data-directory/stamp-guile -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/stamp-python: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gdb/bin/x86_64/data-directory/stamp-python -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/stamp-syscalls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gdb/bin/x86_64/data-directory/stamp-syscalls -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/stamp-system-gdbinit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gdb/bin/x86_64/data-directory/stamp-system-gdbinit -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/syscalls/aarch64-linux.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/syscalls/gdb-syscalls.dtd: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/syscalls/ppc-linux.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/syscalls/ppc64-linux.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/system-gdbinit/elinos.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | """Configure GDB using the ELinOS environment.""" 17 | 18 | import os 19 | import glob 20 | import gdb 21 | 22 | 23 | def warn(msg): 24 | print "warning: %s" % msg 25 | 26 | 27 | def get_elinos_environment(): 28 | """Return the ELinOS environment. 29 | 30 | If the ELinOS environment is properly set up, return a dictionary 31 | which contains: 32 | * The path to the ELinOS project at key 'project'; 33 | * The path to the ELinOS CDK at key 'cdk'; 34 | * The ELinOS target name at key 'target' (Eg. 'i486-linux'); 35 | * A list of Xenomai install prefixes (which could be empty, if 36 | the ELinOS project does not include Xenomai) at key 'xenomai'. 37 | 38 | If one of these cannot be found, print a warning; the corresponding 39 | value in the returned dictionary will be None. 40 | """ 41 | result = {} 42 | for key in ("project", "cdk", "target"): 43 | var = "ELINOS_" + key.upper() 44 | if var in os.environ: 45 | result[key] = os.environ[var] 46 | else: 47 | warn("%s not set" % var) 48 | result[key] = None 49 | 50 | if result["project"] is not None: 51 | result["xenomai"] = glob.glob(result["project"] + "/xenomai-[0-9.]*") 52 | else: 53 | result["xenomai"] = [] 54 | 55 | return result 56 | 57 | 58 | def elinos_init(): 59 | """Initialize debugger environment for ELinOS. 60 | 61 | Let the debugger know where to find the ELinOS libraries on host. This 62 | assumes that an ELinOS environment is properly set up. If some environment 63 | variables are missing, warn about which library may be missing. 64 | """ 65 | elinos_env = get_elinos_environment() 66 | 67 | solib_dirs = [] 68 | 69 | # System libraries 70 | if None in (elinos_env[key] for key in ("cdk", "target")): 71 | warn("ELinOS system libraries will not be loaded") 72 | else: 73 | solib_prefix = "%s/%s" % (elinos_env["cdk"], elinos_env["target"]) 74 | solib_dirs += ["%s/%s" % (solib_prefix, "lib")] 75 | gdb.execute("set solib-absolute-prefix %s" % solib_prefix) 76 | 77 | # Xenomai libraries. Those are optional, so have a lighter warning 78 | # if they cannot be located. 79 | if elinos_env["project"] is None: 80 | warn("Xenomai libraries may not be loaded") 81 | else: 82 | for dir in elinos_env['xenomai']: 83 | solib_dirs += ["%s/%s" 84 | % (dir, "xenomai-build/usr/realtime/lib")] 85 | 86 | if len(solib_dirs) != 0: 87 | gdb.execute("set solib-search-path %s" % ":".join(solib_dirs)) 88 | 89 | 90 | if __name__ == "__main__": 91 | elinos_init() 92 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/data-directory/system-gdbinit/wrs-linux.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011-2016 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | """Configure GDB using the WRS/Linux environment.""" 17 | 18 | import os 19 | 20 | if 'ENV_PREFIX' in os.environ: 21 | gdb.execute('set sysroot %s' % os.environ['ENV_PREFIX']) 22 | 23 | else: 24 | print "warning: ENV_PREFIX environment variable missing." 25 | print "The debugger will probably be unable to find the correct system libraries" 26 | -------------------------------------------------------------------------------- /gdb/bin/x86_64/rocm-gdb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # **************************************************************************************************/ 4 | # ROCM-GDB Driver script 5 | # 6 | # Copyright (c) 2015-2016 ADVANCED MICRO DEVICES, INC. All rights reserved. 7 | # This file includes code originally published under 8 | # 9 | # Copyright (C) 1986-2014 Free Software Foundation, Inc. 10 | # 11 | # This file is part of GDB. 12 | # 13 | # This program is free software; you can redistribute it and/or modify 14 | # it under the terms of the GNU General Public License as published by 15 | # the Free Software Foundation; either version 3 of the License, or 16 | # (at your option) any later version. 17 | # 18 | # This program is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU General Public License 24 | # along with this program. If not, see . */ 25 | # **************************************************************************************************** 26 | 27 | # A wrapper script to check for the environment and call amd-gdb. 28 | 29 | # Concatenate all arguments in a single variable 30 | GDB_ARGS="$*" 31 | 32 | # Get the full path to the script 33 | SOURCE="${BASH_SOURCE[0]}" 34 | ROOTDIR="$( dirname "$SOURCE" )" 35 | # If any part of the path is a symbolic link 36 | # replace it with the full path 37 | while [ -h "$SOURCE" ]; do 38 | TARGET="$( readlink "$SOURCE" )" 39 | if [[ $SOURCE == /* ]]; then 40 | SOURCE="$TARGET" 41 | else 42 | DIR="$( dirname "$SOURCE" )" 43 | SOURCE="$DIR/$TARGET" 44 | fi 45 | if [[ $SOURCE == \.* ]]; then 46 | SOURCE="$ROOTDIR/$SOURCE" 47 | fi 48 | done 49 | REALPATH="$( dirname "$SOURCE" )" 50 | 51 | IPCResourceCleanup() 52 | { 53 | # Done in case GDB didnt exit cleanly 54 | ipcrm -M 4567 2> /dev/null 55 | ipcrm -M 1234 2> /dev/null 56 | ipcrm -M 2222 2> /dev/null 57 | ipcrm -M 1111 2> /dev/null 58 | ipcrm -M 7890 2> /dev/null 59 | 60 | # The FIFO will be created in the same directory that the script is in 61 | rm -f fifo-agent-w-gdb-r 2> /dev/null 62 | rm -f fifo-gdb-w-agent-r 2> /dev/null 63 | 64 | # remove temp_source file and any other left-over files 65 | # Needs to be kept in sync with temp files used by the HSADebugAgent 66 | rm -f temp_source 2> /dev/null 67 | rm -f .temp_source* 2> /dev/null 68 | rm -f temp_isa 2> /dev/null 69 | rm -f .temp_isa* 2> /dev/null 70 | rm -f /tmp/debugger_isa_dump 2> /dev/null 71 | rm -f /tmp/mangled_kernel 2> /dev/null 72 | rm -f /tmp/demangled_kernel 2> /dev/null 73 | } 74 | 75 | IPCResourceCleanup 76 | 77 | # Enable SoftCP mode in the HSA runtime 78 | export HSA_EMULATE_AQL=1 79 | export HSA_TOOLS_LIB="libhsa-runtime-tools64.so.1 libAMDHSADebugAgent-x64.so" 80 | 81 | # Enable Finalizer's workaround to use code segment offsets for the isa line table 82 | export HSA_USE_OFFSETS_FOR_DWARF_CODE_ADDRESSES=1 83 | 84 | 85 | if [ ! -f $REALPATH/amd-gdb ]; then 86 | echo amd-gdb executable not found in folder $REALPATH 87 | exit -1 88 | fi 89 | 90 | # Add a possible path to amdhsacod 91 | export PATH=$PATH:'/opt/rocm/bin' 92 | 93 | # These flags will be used by libhsail 94 | export LIBHSAIL_OPTIONS_APPEND="-g -include-source" 95 | # This flag will be used by runtime to process the debug info when the brig module is added to create a program 96 | export PROGRAM_CREATE_OPTIONS_APPEND="-g" 97 | export PROGRAM_FINALIZE_OPTIONS_APPEND="-g -O0 -amd-reserved-num-vgprs=4 " 98 | 99 | # Set and export the LD_LIBRARY_PATH for gpudebugsdk 100 | # This assumes a specific directory structure with ROCm-gdb and gpudebugsdk folders are in the same directory 101 | SDK="gpudebugsdk" 102 | # If the user has specified the SDK path already, use that 103 | # otherwise look for the SDK folder relative to the rocm-gdb folder 104 | if [[ ! "$LD_LIBRARY_PATH" == *$SDK* ]]; then 105 | for fileName in $( ls $REALPATH/../../.. ); do 106 | if [[ "$fileName" == *$SDK* ]]; then 107 | if [[ ! "$fileName" == *tar* ]]; then 108 | export LD_LIBRARY_PATH=$REALPATH/../../../$fileName/lib/x86_64:${LD_LIBRARY_PATH} 109 | fi 110 | fi 111 | done 112 | if [[ ! "$LD_LIBRARY_PATH" == *$SDK* ]]; then 113 | echo The $SDK folder cannot be found. Please use the directory structure shown in the README and make sure the $SDK folder is specified in the LD_LIBRARY_PATH environment variable. 114 | exit -1 115 | fi 116 | fi 117 | 118 | # Remove any stale FIFO files 119 | if [ -p fifo-agent-w-gdb-r ]; then 120 | rm -f fifo-agent-w-gdb-r 121 | fi 122 | if [ -p fifo-gdb-w-agent-r ]; then 123 | rm -f fifo-gdb-w-agent-r 124 | fi 125 | 126 | # Define a session ID, if logging is enabled by the user 127 | if [ -z "$ROCM_GDB_ENABLE_LOG" ]; then 128 | export ROCM_GDB_DEBUG_SESSION_ID="" 129 | else 130 | export ROCM_GDB_DEBUG_SESSION_ID=$$ 131 | fi 132 | 133 | export GDB_RETURN_CODE=1 134 | 135 | # We can now call gdb 136 | export ROCM_ENABLE_GDB=1 137 | 138 | # The ROCM_GDB_ENABLE_SELF_DEBUG will launch rocm-gdb within the system's gdb. 139 | # Used only for GDB development and testing. 140 | if [ -z "$ROCM_GDB_ENABLE_SELF_DEBUG" ]; then 141 | $REALPATH/amd-gdb -data-directory $REALPATH/data-directory -iex "add-auto-load-safe-path $REALPATH" -ix $REALPATH/.gdbinit $GDB_ARGS 142 | # Capture GDB's return code to send to the terminal, 143 | # we are not interested in the subsequent IPC cleanup and logging return codes 144 | GDB_RETURN_CODE=$? 145 | else 146 | cp $REALPATH/amd-gdb $REALPATH/gdb 147 | gdb --args $REALPATH/gdb -data-directory $REALPATH/data-directory $GDB_ARGS 148 | GDB_RETURN_CODE=$? 149 | fi 150 | 151 | 152 | 153 | 154 | #valgrind --tool=memcheck --log-file=valgrind_log $REALPATH/amd-gdb -data-directory $REALPATH/data-directory -iex "add-auto-load-safe-path $REALPATH" -ix $REALPATH/.gdbinit $GDB_ARGS 155 | 156 | 157 | # Steps to run after amd-gdb exits 158 | unset ROCM_ENABLE_GDB 159 | 160 | # If the ROCM loggging variable was not defined, remove the gdb log 161 | # else save it with the session id 162 | if [ -z "$ROCM_GDB_ENABLE_LOG" ]; then 163 | rm -f gdb.txt 164 | else 165 | GDBLOGFILENAME=$ROCM_GDB_ENABLE_LOG"_rocm_gdb_log_"$ROCM_GDB_DEBUG_SESSION_ID 166 | 167 | echo "GDB Log saved to " $GDBLOGFILENAME 168 | mv gdb.txt $GDBLOGFILENAME 2> /dev/null 169 | fi 170 | 171 | # There is an issue with how we terminate gdb when we call quit 172 | # 173 | # Some internal ncurses state is getting messed up when we call the quit functionality twice in gdb 174 | # As a temporary workaround we use the below command 175 | # http://unix.stackexchange.com/questions/79684/fix-terminal-after-displaying-a-binary-file 176 | # This does not seem to clear the full terminal like the "reset" command and seems to have no other side effect 177 | # 178 | # If we want to clear the terminal of all previous OP, we should add "tput rs1" 179 | # tput and stty together seem to have the same functionality as reset 180 | stty sane 2> /dev/null 181 | 182 | IPCResourceCleanup 183 | 184 | # Return with GDB's return code 185 | exit $GDB_RETURN_CODE 186 | -------------------------------------------------------------------------------- /gpudebugsdk/include/common/linux/sys/elf_common.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* ELFCLASS defs - used by e_ident[EI_CLASS]. */ 4 | #define ELFCLASSNONE 0 /* Unknown class. */ 5 | #define ELFCLASS32 1 /* 32-bit architecture. */ 6 | #define ELFCLASS64 2 /* 64-bit architecture. */ 7 | -------------------------------------------------------------------------------- /gpudebugsdk/include/libelf.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2006,2008-2010 Joseph Koshy 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | * 26 | * $Id: libelf.h 2366 2011-12-29 06:12:14Z jkoshy $ 27 | */ 28 | 29 | #ifndef _LIBELF_H_ 30 | #define _LIBELF_H_ 31 | 32 | #ifdef WIN32 33 | #include "compat.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #else 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #endif 45 | 46 | 47 | /* Library private data structures */ 48 | typedef struct _Elf Elf; 49 | typedef struct _Elf_Scn Elf_Scn; 50 | 51 | /* File types */ 52 | typedef enum { 53 | ELF_K_NONE = 0, 54 | ELF_K_AR, /* `ar' archives */ 55 | ELF_K_COFF, /* COFF files (unsupported) */ 56 | ELF_K_ELF, /* ELF files */ 57 | ELF_K_NUM 58 | } Elf_Kind; 59 | 60 | #define ELF_K_FIRST ELF_K_NONE 61 | #define ELF_K_LAST ELF_K_NUM 62 | 63 | /* Data types */ 64 | typedef enum { 65 | ELF_T_ADDR, 66 | ELF_T_BYTE, 67 | ELF_T_CAP, 68 | ELF_T_DYN, 69 | ELF_T_EHDR, 70 | ELF_T_HALF, 71 | ELF_T_LWORD, 72 | ELF_T_MOVE, 73 | ELF_T_MOVEP, 74 | ELF_T_NOTE, 75 | ELF_T_OFF, 76 | ELF_T_PHDR, 77 | ELF_T_REL, 78 | ELF_T_RELA, 79 | ELF_T_SHDR, 80 | ELF_T_SWORD, 81 | ELF_T_SXWORD, 82 | ELF_T_SYMINFO, 83 | ELF_T_SYM, 84 | ELF_T_VDEF, 85 | ELF_T_VNEED, 86 | ELF_T_WORD, 87 | ELF_T_XWORD, 88 | ELF_T_GNUHASH, /* GNU style hash tables. */ 89 | ELF_T_NUM 90 | } Elf_Type; 91 | 92 | #define ELF_T_FIRST ELF_T_ADDR 93 | #define ELF_T_LAST ELF_T_GNUHASH 94 | 95 | /* Commands */ 96 | typedef enum { 97 | ELF_C_NULL = 0, 98 | ELF_C_CLR, 99 | ELF_C_FDDONE, 100 | ELF_C_FDREAD, 101 | ELF_C_RDWR, 102 | ELF_C_READ, 103 | ELF_C_SET, 104 | ELF_C_WRITE, 105 | ELF_C_NUM 106 | } Elf_Cmd; 107 | 108 | #define ELF_C_FIRST ELF_C_NULL 109 | #define ELF_C_LAST ELF_C_NUM 110 | 111 | /* 112 | * An `Elf_Data' structure describes data in an 113 | * ELF section. 114 | */ 115 | typedef struct _Elf_Data { 116 | /* 117 | * `Public' members that are part of the ELF(3) API. 118 | */ 119 | uint64_t d_align; 120 | void *d_buf; 121 | uint64_t d_off; 122 | uint64_t d_size; 123 | Elf_Type d_type; 124 | unsigned int d_version; 125 | } Elf_Data; 126 | 127 | /* 128 | * An `Elf_Arhdr' structure describes an archive 129 | * header. 130 | */ 131 | typedef struct { 132 | time_t ar_date; 133 | char *ar_name; /* archive member name */ 134 | gid_t ar_gid; 135 | mode_t ar_mode; 136 | char *ar_rawname; /* 'raw' member name */ 137 | size_t ar_size; 138 | uid_t ar_uid; 139 | 140 | /* 141 | * Members that are not part of the public API. 142 | */ 143 | int ar_flags; 144 | } Elf_Arhdr; 145 | 146 | /* 147 | * An `Elf_Arsym' describes an entry in the archive 148 | * symbol table. 149 | */ 150 | typedef struct { 151 | off_t as_off; /* byte offset to member's header */ 152 | unsigned long as_hash; /* elf_hash() value for name */ 153 | char *as_name; /* null terminated symbol name */ 154 | } Elf_Arsym; 155 | 156 | /* 157 | * Error numbers. 158 | */ 159 | 160 | enum Elf_Error { 161 | ELF_E_NONE, /* No error */ 162 | ELF_E_ARCHIVE, /* Malformed ar(1) archive */ 163 | ELF_E_ARGUMENT, /* Invalid argument */ 164 | ELF_E_CLASS, /* Mismatched ELF class */ 165 | ELF_E_DATA, /* Invalid data descriptor */ 166 | ELF_E_HEADER, /* Missing or malformed ELF header */ 167 | ELF_E_IO, /* I/O error */ 168 | ELF_E_LAYOUT, /* Layout constraint violation */ 169 | ELF_E_MODE, /* Wrong mode for ELF descriptor */ 170 | ELF_E_RANGE, /* Value out of range */ 171 | ELF_E_RESOURCE, /* Resource exhaustion */ 172 | ELF_E_SECTION, /* Invalid section descriptor */ 173 | ELF_E_SEQUENCE, /* API calls out of sequence */ 174 | ELF_E_UNIMPL, /* Feature is unimplemented */ 175 | ELF_E_VERSION, /* Unknown API version */ 176 | ELF_E_NUM /* Max error number */ 177 | }; 178 | 179 | /* 180 | * Flags defined by the API. 181 | */ 182 | 183 | #define ELF_F_LAYOUT 0x001U /* application will layout the file */ 184 | #define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ 185 | 186 | /* ELF(3) API extensions. */ 187 | #define ELF_F_ARCHIVE 0x100U /* archive creation */ 188 | #define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */ 189 | 190 | __BEGIN_DECLS 191 | Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); 192 | int elf_cntl(Elf *_elf, Elf_Cmd _cmd); 193 | int elf_end(Elf *_elf); 194 | const char *elf_errmsg(int _error); 195 | int elf_errno(void); 196 | void elf_fill(int _fill); 197 | unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd, 198 | unsigned int _flags); 199 | unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, 200 | unsigned int _flags); 201 | unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); 202 | unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); 203 | unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); 204 | unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); 205 | unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); 206 | Elf_Arhdr *elf_getarhdr(Elf *_elf); 207 | Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); 208 | off_t elf_getbase(Elf *_elf); 209 | Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); 210 | char *elf_getident(Elf *_elf, size_t *_ptr); 211 | int elf_getphdrnum(Elf *_elf, size_t *_dst); 212 | int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ 213 | Elf_Scn *elf_getscn(Elf *_elf, size_t _index); 214 | int elf_getshdrnum(Elf *_elf, size_t *_dst); 215 | int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ 216 | int elf_getshdrstrndx(Elf *_elf, size_t *_dst); 217 | int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ 218 | unsigned long elf_hash(const char *_name); 219 | Elf_Kind elf_kind(Elf *_elf); 220 | Elf *elf_memory(char *_image, size_t _size); 221 | size_t elf_ndxscn(Elf_Scn *_scn); 222 | Elf_Data *elf_newdata(Elf_Scn *_scn); 223 | Elf_Scn *elf_newscn(Elf *_elf); 224 | Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); 225 | Elf_Cmd elf_next(Elf *_elf); 226 | Elf *elf_open(int _fd); 227 | Elf *elf_openmemory(char *_image, size_t _size); 228 | off_t elf_rand(Elf *_elf, off_t _off); 229 | Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); 230 | char *elf_rawfile(Elf *_elf, size_t *_size); 231 | int elf_setshstrndx(Elf *_elf, size_t _shnum); 232 | char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); 233 | off_t elf_update(Elf *_elf, Elf_Cmd _cmd); 234 | unsigned int elf_version(unsigned int _version); 235 | 236 | long elf32_checksum(Elf *_elf); 237 | size_t elf32_fsize(Elf_Type _type, size_t _count, 238 | unsigned int _version); 239 | Elf32_Ehdr *elf32_getehdr(Elf *_elf); 240 | Elf32_Phdr *elf32_getphdr(Elf *_elf); 241 | Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); 242 | Elf32_Ehdr *elf32_newehdr(Elf *_elf); 243 | Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); 244 | Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, 245 | unsigned int _enc); 246 | Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, 247 | unsigned int _enc); 248 | 249 | long elf64_checksum(Elf *_elf); 250 | size_t elf64_fsize(Elf_Type _type, size_t _count, 251 | unsigned int _version); 252 | Elf64_Ehdr *elf64_getehdr(Elf *_elf); 253 | Elf64_Phdr *elf64_getphdr(Elf *_elf); 254 | Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); 255 | Elf64_Ehdr *elf64_newehdr(Elf *_elf); 256 | Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); 257 | Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, 258 | unsigned int _enc); 259 | Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, 260 | unsigned int _enc); 261 | 262 | #if defined(LIBELF_TEST_HOOKS) 263 | int _libelf_get_elf_class(Elf *_elf); 264 | int _libelf_get_max_error(void); 265 | const char *_libelf_get_no_error_message(void); 266 | const char *_libelf_get_unknown_error_message(void); 267 | void _libelf_set_elf_class(Elf *_elf, int _class); 268 | void _libelf_set_error(int _error); 269 | #endif /* LIBELF_TEST_HOOKS */ 270 | __END_DECLS 271 | 272 | #endif /* _LIBELF_H_ */ 273 | -------------------------------------------------------------------------------- /gpudebugsdk/lib/x86_64/libAMDGPUDebugHSA-x64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gpudebugsdk/lib/x86_64/libAMDGPUDebugHSA-x64.so -------------------------------------------------------------------------------- /gpudebugsdk/lib/x86_64/libAMDHSADebugAgent-x64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gpudebugsdk/lib/x86_64/libAMDHSADebugAgent-x64.so -------------------------------------------------------------------------------- /gpudebugsdk/lib/x86_64/libAMDHwDbgFacilities-x64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gpudebugsdk/lib/x86_64/libAMDHwDbgFacilities-x64.so -------------------------------------------------------------------------------- /gpudebugsdk/lib/x86_64/libelf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gpudebugsdk/lib/x86_64/libelf.a -------------------------------------------------------------------------------- /gpudebugsdk/samples/Common/HSAExtensionFinalizer.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. 3 | // 4 | /// \author AMD Developer Tools 5 | /// \file 6 | /// \brief Data structure to keep HSA extension function pointer table, and call hsa_ext_* through it. 7 | //============================================================================== 8 | 9 | #include // memset 10 | #include 11 | 12 | #include "HSAExtensionFinalizer.h" 13 | 14 | namespace AMDT 15 | { 16 | static bool GetExtensionTable(const uint16_t& extension, const uint16_t& major, const uint16_t minor, void* pTable) 17 | { 18 | bool isSupported = false; 19 | hsa_status_t status = hsa_system_extension_supported(extension, major, minor, &isSupported); 20 | 21 | if (HSA_STATUS_SUCCESS != status || true != isSupported) 22 | { 23 | if (HSA_STATUS_ERROR_NOT_INITIALIZED == status) 24 | { 25 | std::cerr << "HSA haven't initialized yet.\n"; 26 | return false; 27 | } 28 | 29 | if (HSA_STATUS_ERROR_INVALID_ARGUMENT == status) 30 | { 31 | std::cerr << "Extension 0x" << std::hex << extension << " is not a valid extension.\n"; 32 | std::cerr << std::dec; 33 | return false; 34 | } 35 | 36 | std::cerr << "HSA Runtime " << major << "." << minor << " doesn't support this extension: " << extension << ".\n"; 37 | return false; 38 | } 39 | 40 | status = hsa_system_get_extension_table(extension, major, minor, pTable); 41 | 42 | if (HSA_STATUS_SUCCESS != status) 43 | { 44 | std::cerr << "Get extension functions table failed. Extension: " << extension << "\n"; 45 | return false; 46 | } 47 | 48 | return true; 49 | } 50 | 51 | HSAFinalizer::HSAFinalizer() : m_pTable(nullptr) 52 | { 53 | } 54 | 55 | HSAFinalizer::~HSAFinalizer() 56 | { 57 | if (nullptr != m_pTable) 58 | { 59 | delete m_pTable; 60 | m_pTable = nullptr; 61 | } 62 | } 63 | 64 | bool HSAFinalizer::GetExtensionTable(const uint16_t& major, const uint16_t& minor) 65 | { 66 | if (nullptr == m_pTable) 67 | { 68 | m_pTable = new HSAFinalizerTable; 69 | 70 | if (nullptr == m_pTable) 71 | { 72 | std::cerr << "Cannot allocate Finalizer functions table.\n"; 73 | return false; 74 | } 75 | 76 | memset(m_pTable, 0, sizeof(*m_pTable)); 77 | } 78 | 79 | bool ret = AMDT::GetExtensionTable(HSA_EXTENSION_FINALIZER, major, minor, m_pTable); 80 | 81 | if (!ret) 82 | { 83 | std::cerr << "Fail to get finalizer extension table.\n"; 84 | return false; 85 | } 86 | 87 | return true; 88 | } 89 | }// namespace AMDT 90 | -------------------------------------------------------------------------------- /gpudebugsdk/samples/Common/HSAExtensionFinalizer.h: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. 3 | // 4 | /// \author AMD Developer Tools 5 | /// \file 6 | /// \brief Data structure to keep HSA extension function pointer table, and call hsa_ext_* through it. 7 | //============================================================================== 8 | 9 | #ifndef HSA_EXTENSION_FINALIZER_H_ 10 | #define HSA_EXTENSION_FINALIZER_H_ 11 | 12 | #include 13 | 14 | #ifdef USE_EXISTING_FINALIZER_EXTENSION 15 | #include 16 | #else 17 | // \todo: Add these struct definitions here. 18 | struct hsa_ext_program_t; 19 | 20 | struct hsa_ext_program_info_t; 21 | 22 | struct hsa_ext_control_directives_t; 23 | 24 | struct BrigModuleHeader; 25 | typedef struct BrigModuleHeader* BrigModule_t; 26 | 27 | typedef BrigModule_t hsa_ext_module_t; 28 | #endif 29 | 30 | namespace AMDT 31 | { 32 | class HSAFinalizer 33 | { 34 | private: 35 | typedef struct HSAFinalizerTable 36 | { 37 | hsa_status_t(*hsa_ext_program_create)( 38 | hsa_machine_model_t machine_model, 39 | hsa_profile_t profile, 40 | hsa_default_float_rounding_mode_t default_float_rounding_mode, 41 | const char* options, 42 | hsa_ext_program_t* program); 43 | 44 | hsa_status_t(*hsa_ext_program_destroy)(hsa_ext_program_t program); 45 | 46 | hsa_status_t(*hsa_ext_program_add_module)(hsa_ext_program_t program, 47 | hsa_ext_module_t module); 48 | 49 | hsa_status_t(*hsa_ext_program_iterate_modules)( 50 | hsa_ext_program_t program, 51 | hsa_status_t(*callback)(hsa_ext_program_t program, 52 | hsa_ext_module_t module, void* data), 53 | void* data); 54 | 55 | hsa_status_t(*hsa_ext_program_get_info)( 56 | hsa_ext_program_t program, hsa_ext_program_info_t attribute, 57 | void* value); 58 | 59 | hsa_status_t(*hsa_ext_program_finalize)( 60 | hsa_ext_program_t program, hsa_isa_t isa, int32_t call_convention, 61 | hsa_ext_control_directives_t control_directives, const char* options, 62 | hsa_code_object_type_t code_object_type, hsa_code_object_t* code_object); 63 | } HSAFinalizerTable; 64 | 65 | public: 66 | HSAFinalizer(); 67 | ~HSAFinalizer(); 68 | 69 | bool GetExtensionTable(const uint16_t& major, const uint16_t& minor); 70 | 71 | HSAFinalizerTable* m_pTable; 72 | }; 73 | 74 | }// namespace AMDT 75 | #endif // HSA_EXTENSION_FINALIZER_H_ 76 | -------------------------------------------------------------------------------- /gpudebugsdk/samples/MatrixMultiplication/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved. 2 | 3 | makefile: all 4 | all: MatrixMul 5 | 6 | SDKINC=../../include/ 7 | 8 | HSADIR=/opt/rocm/hsa/ 9 | HSAINC=$(HSADIR)include/hsa 10 | HSALIB=$(HSADIR)lib/ 11 | 12 | LIBLINE=-L$(HSALIB) -l:libhsa-runtime64.so.1 13 | 14 | CC=g++ 15 | 16 | TESTCOMMON=../Common 17 | CFLAGS= -g -D_DEBUG -std=c++11 -m64 -Werror -I$(HSAINC) -I$(TESTCOMMON) -I$(SDKINC) 18 | LDFLAGS= -g -m64 -Werror -Wl,--unresolved-symbols=ignore-in-shared-libs 19 | 20 | OBJFLAGS = -c $(CFLAGS) 21 | 22 | SOURCES=\ 23 | $(TESTCOMMON)/HSAResourceManager.cpp\ 24 | $(TESTCOMMON)/HSAExtensionFinalizer.cpp\ 25 | MatrixMul.cpp 26 | 27 | OBJECTS=$(SOURCES:.cpp=.o) 28 | 29 | DEPS := $(OBJECTS:.o=.d) 30 | 31 | MatrixMul : $(OBJECTS) 32 | $(CC) $(LDFLAGS) $(OBJECTS) $(LIBLINE) -o MatrixMul 33 | 34 | .cpp.o: 35 | $(CC) -c -MMD $(CFLAGS) $< -o $@ 36 | 37 | clean: 38 | rm -f $(TESTCOMMON)/*.o $(TESTCOMMON)/*.d 39 | rm -f *.o *.d 40 | rm -f MatrixMul 41 | 42 | -include $(DEPS) 43 | -------------------------------------------------------------------------------- /gpudebugsdk/samples/MatrixMultiplication/MatrixMul.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved. 3 | // 4 | /// \author AMD Developer Tools 5 | /// \file 6 | /// \brief A matrix multiplication sample implemented using the HSA runtime and 7 | /// HSAIL kernel 1.0F. This sample is provided to demonstrate 8 | /// rocm-gdb functionality. It loads brig file directly (that was 9 | /// generated with debugging support). 10 | //============================================================================== 11 | #include 12 | #include 13 | #include 14 | #if !defined(_WIN32) && !defined(_WIN64) 15 | #include 16 | #include 17 | #endif 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include "HSAResourceManager.h" 26 | 27 | static const std::string gs_MATRIX_MUL_KERNEL_SYMBOL = "&__OpenCL_matrixMul_kernel"; 28 | static const std::string gs_MATRIX_MUL_KERNEL_BRIG_FILE = "matrixMul_kernel.brig"; 29 | 30 | static const std::string gs_OUTPUT_MATRIX_DIR = "./outputMatrix/"; 31 | 32 | // ================================= Functions declaration ============================================ 33 | 34 | void RunTest(bool doVerify); 35 | 36 | // Helper function to load binary file into data. 37 | bool LoadFile(const std::string& fileName, std::vector& data); 38 | 39 | // Helper function to output matrix result to file. 40 | void OutputMatrix(const std::string& fileName, const float* pMatrix, const size_t numElements, const size_t width); 41 | 42 | // ===================================================================================================== 43 | 44 | int main(int argc, char** argv) 45 | { 46 | bool doVerify = false; 47 | 48 | if (argc > 1) 49 | { 50 | std::string ipOption(argv[1]); 51 | 52 | if (ipOption == "--verify") 53 | { 54 | doVerify = true; 55 | } 56 | else 57 | { 58 | std::cout << "Matrixmul dispatches an HSAIL matrix multiplication kernel\n"; 59 | std::cout << "Possible options"; 60 | std::cout << " \t--verify\t verify correctness by comparing against a serial implementation\n"; 61 | } 62 | 63 | } 64 | 65 | RunTest(doVerify); 66 | return 0; 67 | } 68 | 69 | void RunTest(bool doVerify) 70 | { 71 | using namespace AMDT; 72 | 73 | // Initialize HSA runtime 74 | std::cout << "Initializing HSA runtime...\n"; 75 | 76 | if (true != HSAResourceManager::InitRuntime()) 77 | { 78 | std::cerr << "RunTest(): HSA runtime initialization fail, exiting...\n"; 79 | return; 80 | } 81 | 82 | HSAResourceManager myHsa; 83 | 84 | // Create default queue 85 | if (!myHsa.CreateDefaultQueue(true)) 86 | { 87 | std::cerr << "RunTest(): Error on creating default queue.\n"; 88 | return; 89 | } 90 | 91 | // Load the kernel brig 92 | std::vector brigData; 93 | if (!LoadFile(gs_MATRIX_MUL_KERNEL_BRIG_FILE, brigData)) 94 | { 95 | std::cerr << "Error in RunTest(): LoadFile() failed.\n"; 96 | return; 97 | } 98 | 99 | if (0 == brigData.size()) 100 | { 101 | std::cerr << "RuntTest(): Error in loading brig.\n"; 102 | return; 103 | } 104 | 105 | // Create AQL packet 106 | hsa_kernel_dispatch_packet_t aql; 107 | 108 | if (!myHsa.CreateAQLPacketFromBrig( 109 | &brigData[0], 110 | gs_MATRIX_MUL_KERNEL_SYMBOL, 111 | true, 112 | aql)) 113 | { 114 | std::cerr << "RuntTest(): Error in finalizing and creating AQL packet.\n"; 115 | return; 116 | } 117 | 118 | // Setup matrices dimensions 119 | const size_t WORK_GROUP_SIZE = 16; 120 | const size_t HA = 5 * WORK_GROUP_SIZE; 121 | const size_t WA = 3 * WORK_GROUP_SIZE; 122 | const size_t HB = WA; 123 | const size_t WB = 8 * WORK_GROUP_SIZE; 124 | const size_t HC = HA; 125 | const size_t WC = WB; 126 | 127 | // Setup AQL packet 128 | aql.setup |= 2 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS; 129 | aql.workgroup_size_x = WORK_GROUP_SIZE; 130 | aql.workgroup_size_y = WORK_GROUP_SIZE; 131 | aql.grid_size_x = WC; 132 | aql.grid_size_y = HC; 133 | 134 | // Allocate memory for computation 135 | size_t sizeA = HA * WA; 136 | size_t sizeB = HB * WB; 137 | size_t sizeC = HC * WC; 138 | float* pBufferA = (float*) HSAResourceManager::AllocateSysMemory(sizeA * sizeof(float)); 139 | float* pBufferB = (float*) HSAResourceManager::AllocateSysMemory(sizeB * sizeof(float)); 140 | float* pBufferC = (float*) HSAResourceManager::AllocateSysMemory(sizeC * sizeof(float)); 141 | // Initialize buffers, generate random matrices data. 142 | srand(static_cast(time(nullptr))); 143 | 144 | for (size_t i = 0; i < sizeA; ++i) 145 | { 146 | pBufferA[i] = static_cast(rand()) / static_cast(RAND_MAX); 147 | } 148 | 149 | for (size_t i = 0; i < sizeB; ++i) 150 | { 151 | pBufferB[i] = static_cast(rand()) / static_cast(RAND_MAX); 152 | } 153 | 154 | for (size_t i = 0; i < sizeC; ++i) 155 | { 156 | pBufferC[i] = 0.0f; 157 | } 158 | 159 | #ifdef _DEBUG 160 | // Output matrices data to files 161 | OutputMatrix("matrixA.mat", pBufferA, sizeA, WA); 162 | OutputMatrix("matrixB.mat", pBufferB, sizeB, WB); 163 | #endif 164 | 165 | // Setup aql kernel arguments. 166 | // Pass kernel arguments 167 | 168 | // We have extra 6 64-bits kernel arguments before matrix C, A and B in kernel 169 | // arguments, so we need to set them up in offset size. 170 | if (!myHsa.AppendKernelArgs(&pBufferC, sizeof(float*), aql)) 171 | { 172 | std::cerr << "RunTest(): Error on pBufferC AppendKernelArgs()\n"; 173 | } 174 | 175 | if (!myHsa.AppendKernelArgs(&pBufferA, sizeof(float*), aql)) 176 | { 177 | std::cerr << "RunTest(): Error on pBufferA AppendKernelArgs()\n"; 178 | } 179 | 180 | if (!myHsa.AppendKernelArgs(&pBufferB, sizeof(float*), aql)) 181 | { 182 | std::cerr << "RunTest(): Error on pBufferB AppendKernelArgs()\n";; 183 | } 184 | 185 | if (!myHsa.AppendKernelArgs(&WA, sizeof(uint32_t), aql)) 186 | { 187 | std::cerr << "RunTest(): Error on WA AppendKernelArgs()\n"; 188 | } 189 | 190 | if (!myHsa.AppendKernelArgs(&WB, sizeof(uint32_t), aql)) 191 | { 192 | std::cerr << "RunTest(): Error on WB AppendKernelArgs()\n"; 193 | } 194 | 195 | myHsa.RegisterKernelArgsBuffer(aql); 196 | 197 | if (!myHsa.Dispatch(aql)) 198 | { 199 | std::cerr << "RunTest(): Error on Dispatch()\n"; 200 | return; 201 | } 202 | 203 | // Wait for completion 204 | std::cout << "Waiting for completion...\n"; 205 | 206 | if (!myHsa.WaitForCompletion(aql.completion_signal, UINT64_MAX, true)) 207 | { 208 | std::cerr << "Error in RunTest(): Signal return error.\n"; 209 | return; 210 | } 211 | 212 | std::cout << "Complete.\n"; 213 | 214 | #ifdef _DEBUG 215 | // Output matrices data to files 216 | OutputMatrix("matrixC.mat", pBufferC, sizeC, WC); 217 | #endif 218 | 219 | if (doVerify) 220 | { 221 | std::cout << "Calculating reference data...\n"; 222 | std::vector referenceData(sizeC, 0.0f); 223 | 224 | for (uint32_t i = 0; i < HA; ++i) 225 | { 226 | for (uint32_t j = 0; j < WB; ++j) 227 | { 228 | float sum = 0; 229 | 230 | for (uint32_t k = 0; k < HB; ++k) 231 | { 232 | // c_ij = sum_k^HB(a_ik * b_kj); 233 | sum += pBufferA[i * WA + k] * pBufferB[k * WB + j]; 234 | } 235 | 236 | referenceData[i * WC + j] = sum; 237 | } 238 | } 239 | 240 | // Validate 241 | std::cout << "Validating...\n"; 242 | bool valid = true; 243 | uint32_t failIndex = 0; 244 | 245 | for (size_t i = 0; i < referenceData.size(); ++i) 246 | { 247 | if (fabs(pBufferC[i] - referenceData[i]) > 1e-3f) 248 | { 249 | failIndex = static_cast(i); 250 | valid = false; 251 | break; 252 | } 253 | } 254 | 255 | if (!valid) 256 | { 257 | uint32_t fi = failIndex / WC; 258 | uint32_t fj = failIndex % WC; 259 | std::cerr << "Result not correct!\n"; 260 | std::cerr << "Fail index: " << failIndex << "(" << fi << ", " << fj << ")\n"; 261 | std::cerr << "pBufferC[" << failIndex << "] = " << pBufferC[failIndex] << "\n"; 262 | std::cerr << "Expected: " << referenceData[failIndex] << "\n"; 263 | } 264 | else 265 | { 266 | std::cout << "Pass.\n"; 267 | } 268 | 269 | #ifdef _DEBUG 270 | // Output matrices data to files 271 | OutputMatrix("referenceResult.mat", &referenceData[0], referenceData.size(), WC); 272 | #endif 273 | } 274 | 275 | // Cleanup. 276 | if (nullptr != pBufferA) 277 | { 278 | HSAResourceManager::FreeHSAMemory(pBufferA); 279 | pBufferA = nullptr; 280 | } 281 | if (nullptr != pBufferB) 282 | { 283 | HSAResourceManager::FreeHSAMemory(pBufferB); 284 | pBufferB = nullptr; 285 | } 286 | if (nullptr != pBufferC) 287 | { 288 | HSAResourceManager::FreeHSAMemory(pBufferC); 289 | pBufferC = nullptr; 290 | } 291 | 292 | myHsa.CleanUp(); 293 | myHsa.DestroyQueue(); 294 | 295 | // Explicit call ShutDown() function, though it will 296 | // be called automatically when the program exit. 297 | HSAResourceManager::ShutDown(); 298 | } 299 | 300 | bool LoadFile(const std::string& fileName, std::vector& data) 301 | { 302 | bool ret = false; 303 | std::ifstream inFile(fileName, std::ios::binary); 304 | 305 | if (inFile.good()) 306 | { 307 | // get the size of the file; 308 | inFile.seekg(0, std::ios::end); 309 | std::size_t length = inFile.tellg(); 310 | inFile.seekg(0, std::ios::beg); 311 | 312 | data.clear(); 313 | data.resize(length, 0); 314 | inFile.read(&data[0], length); 315 | ret = true; 316 | } 317 | else 318 | { 319 | std::cerr << "Error in LoadFile(): Error when open file \"" << fileName << "\"\n"; 320 | ret = false; 321 | } 322 | 323 | inFile.close(); 324 | return ret; 325 | } 326 | 327 | void OutputMatrix(const std::string& fileName, const float* pMatrix, const size_t numElements, const size_t width) 328 | { 329 | static std::string realMatrixOutDir = gs_OUTPUT_MATRIX_DIR; 330 | static bool isFirst = true; 331 | 332 | // First time run to check the output matrix directory 333 | if (isFirst) 334 | { 335 | #if defined(_WIN32) || defined(_WIN64) 336 | /// \todo: windows version directory creation 337 | #else 338 | // Check if gs_OUTPUT_MATRIX_DIR is exist. 339 | DIR* pDir = opendir(gs_OUTPUT_MATRIX_DIR.c_str()); 340 | 341 | if (nullptr == pDir) 342 | { 343 | // Create it. 344 | int err = mkdir(gs_OUTPUT_MATRIX_DIR.c_str(), S_IRWXU | S_IRWXG); 345 | 346 | if (0 != err) 347 | { 348 | std::cout << "Warning in RunTest(): Cannot create output matrix directory \"" << gs_OUTPUT_MATRIX_DIR << "\"\n"; 349 | realMatrixOutDir = ""; 350 | } 351 | } 352 | else 353 | { 354 | // Nothing need to be done if gs_OUTPUT_MATRIX_DIR already exist. 355 | closedir(pDir); 356 | } 357 | 358 | #endif 359 | isFirst = false; 360 | } 361 | 362 | std::string realPath = realMatrixOutDir + fileName; 363 | std::ofstream outFile(realPath); 364 | 365 | if (outFile.is_open()) 366 | { 367 | size_t height = numElements / width; 368 | 369 | for (size_t i = 0; i < height; ++i) 370 | { 371 | size_t rowOffset = i * width; 372 | outFile << pMatrix[rowOffset]; 373 | 374 | for (size_t j = 1; j < width; ++j) 375 | { 376 | outFile << "\t" << pMatrix[rowOffset + j]; 377 | } 378 | 379 | outFile << "\n"; 380 | } 381 | } 382 | else 383 | { 384 | std::cerr << "Cannot open file " << realPath << "\n"; 385 | } 386 | 387 | outFile.close(); 388 | } 389 | -------------------------------------------------------------------------------- /gpudebugsdk/samples/MatrixMultiplication/matrixMul_kernel.brig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocmarchive/ROCm-Debugger/f3bf3b202b6d8285c4c6ed661d9957e3e709ff5f/gpudebugsdk/samples/MatrixMultiplication/matrixMul_kernel.brig -------------------------------------------------------------------------------- /gpudebugsdk/samples/MatrixMultiplication/matrixMul_kernel.hsail: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved. 3 | // 4 | /// \author AMD Developer Tools 5 | /// \file 6 | //============================================================================== 7 | module &m:1:0:$full:$large:$default; 8 | extension "amd:gcn"; 9 | extension "IMAGE"; 10 | 11 | decl prog function &abort()(); 12 | 13 | prog kernel &__OpenCL_matrixMul_kernel( 14 | kernarg_u64 %__global_offset_0, 15 | kernarg_u64 %__global_offset_1, 16 | kernarg_u64 %__global_offset_2, 17 | kernarg_u64 %__printf_buffer, 18 | kernarg_u64 %__vqueue_pointer, 19 | kernarg_u64 %__aqlwrap_pointer, 20 | kernarg_u64 %C, 21 | kernarg_u64 %A, 22 | kernarg_u64 %B, 23 | kernarg_u32 %wA, 24 | kernarg_u32 %wB) 25 | { 26 | pragma "AMD RTI", "ARGSTART:__OpenCL_matrixMul_kernel"; 27 | pragma "AMD RTI", "version:3:1:104"; 28 | pragma "AMD RTI", "device:generic"; 29 | pragma "AMD RTI", "uniqueid:1024"; 30 | pragma "AMD RTI", "memory:private:0"; 31 | pragma "AMD RTI", "memory:region:0"; 32 | pragma "AMD RTI", "memory:local:0"; 33 | pragma "AMD RTI", "value:__global_offset_0:u64:1:1:0"; 34 | pragma "AMD RTI", "value:__global_offset_1:u64:1:1:16"; 35 | pragma "AMD RTI", "value:__global_offset_2:u64:1:1:32"; 36 | pragma "AMD RTI", "pointer:__printf_buffer:u8:1:1:48:uav:7:1:RW:0:0:0"; 37 | pragma "AMD RTI", "value:__vqueue_pointer:u64:1:1:64"; 38 | pragma "AMD RTI", "value:__aqlwrap_pointer:u64:1:1:80"; 39 | pragma "AMD RTI", "pointer:C:float:1:1:96:uav:7:4:RW:0:0:0"; 40 | pragma "AMD RTI", "pointer:A:float:1:1:112:uav:7:4:RW:0:0:0"; 41 | pragma "AMD RTI", "pointer:B:float:1:1:128:uav:7:4:RW:0:0:0"; 42 | pragma "AMD RTI", "value:wA:u32:1:1:144"; 43 | pragma "AMD RTI", "value:wB:u32:1:1:160"; 44 | pragma "AMD RTI", "function:1:0"; 45 | pragma "AMD RTI", "memory:64bitABI"; 46 | pragma "AMD RTI", "privateid:8"; 47 | pragma "AMD RTI", "enqueue_kernel:0"; 48 | pragma "AMD RTI", "kernel_index:0"; 49 | pragma "AMD RTI", "reflection:0:size_t"; 50 | pragma "AMD RTI", "reflection:1:size_t"; 51 | pragma "AMD RTI", "reflection:2:size_t"; 52 | pragma "AMD RTI", "reflection:3:size_t"; 53 | pragma "AMD RTI", "reflection:4:size_t"; 54 | pragma "AMD RTI", "reflection:5:size_t"; 55 | pragma "AMD RTI", "reflection:6:float*"; 56 | pragma "AMD RTI", "reflection:7:float*"; 57 | pragma "AMD RTI", "reflection:8:float*"; 58 | pragma "AMD RTI", "reflection:9:int"; 59 | pragma "AMD RTI", "reflection:10:int"; 60 | pragma "AMD RTI", "ARGEND:__OpenCL_matrixMul_kernel"; 61 | 62 | @__OpenCL_matrixMul_kernel_entry: 63 | // BB#0: // %entry 64 | workitemabsid_u32 $s0, 0; 65 | cvt_u64_u32 $d5, $s0; // $d5 = work_item_id_x (tx) 66 | workitemabsid_u32 $s0, 1; 67 | ld_kernarg_align(8)_width(all)_u64 $d6, [%__global_offset_0]; // $d6 = 0 68 | add_u64 $d0, $d5, $d6; // $d0 = tx 69 | cvt_u64_u32 $d7, $s0; // $d7 = work_item_id_y (ty) 70 | ld_kernarg_align(8)_width(all)_u64 $d8, [%__global_offset_1]; // $d8 = 0 71 | add_u64 $d2, $d7, $d8; // $d2 = ty 72 | ld_kernarg_align(4)_width(all)_u32 $s0, [%wB]; // $s0 = wB 73 | ld_kernarg_align(4)_width(all)_u32 $s1, [%wA]; // $s1 = wA 74 | ld_kernarg_align(8)_width(all)_u64 $d1, [%C]; // $d1 = C 75 | cmp_lt_b1_s32 $c0, $s1, 1; // if (wA < 1) 76 | cbr_b1 $c0, @BB0_1; 77 | // BB#2: // %for.body.lr.ph 78 | ld_kernarg_align(8)_width(all)_u64 $d3, [%B]; // $d3 = B 79 | ld_kernarg_align(8)_width(all)_u64 $d4, [%A]; // $d4 = A 80 | add_u64 $d7, $d8, $d7; // $d7 = ty 81 | cvt_u32_u64 $s2, $d7; 82 | mul_u32 $s3, $s1, $s2; // $s3 = ty * wA 83 | add_u64 $d5, $d6, $d5; // $d5 = tx 84 | cvt_u32_u64 $s4, $d5; // $s4 = tx 85 | mov_b32 $s2, 0; // value = 0 86 | 87 | @BB0_3: 88 | // %for.body 89 | cvt_s64_s32 $d5, $s4; // $d5 = $s4 90 | shl_u64 $d5, $d5, 2; // $d5 *= 4 91 | add_u64 $d5, $d3, $d5; // $d5 = &B + (k*wB + tx)*4 92 | ld_global_align(4)_f32 $s5, [$d5]; // $s5 = B[k*wB + tx] 93 | cvt_s64_s32 $d5, $s3; // $d5 = ty * wA + k 94 | shl_u64 $d5, $d5, 2; 95 | add_u64 $d5, $d4, $d5; // $d5 = &A + (ty*wA+k)*4 96 | ld_global_align(4)_f32 $s6, [$d5]; // $s6 = A[ty*wA + k] 97 | mul_ftz_f32 $s5, $s6, $s5; // $s5 = A[ty*wA + k] * B[k*wB + tx] 98 | add_ftz_f32 $s2, $s2, $s5; // value += $s5 99 | add_u32 $s4, $s4, $s0; // $s4 += wB, (++k)*wB 100 | add_u32 $s3, $s3, 1; // $s3 += 1, ++k 101 | add_u32 $s1, $s1, 4294967295; // $s1 += 0xFFFFFFFF 102 | cmp_ne_b1_s32 $c0, $s1, 0; // $c0 = ($s1 != 0) , loop wA times 103 | cbr_b1 $c0, @BB0_3; 104 | br @BB0_4; 105 | 106 | @BB0_1: 107 | mov_b32 $s2, 0; 108 | 109 | @BB0_4: 110 | // %for.end 111 | cvt_u32_u64 $s1, $d2; 112 | cvt_u32_u64 $s3, $d0; 113 | mad_u32 $s0, $s1, $s0, $s3; 114 | cvt_s64_s32 $d0, $s0; 115 | shl_u64 $d0, $d0, 2; 116 | add_u64 $d0, $d1, $d0; 117 | st_global_align(4)_f32 $s2, [$d0]; // C[ty*wB + tx] = value 118 | ret; 119 | }; 120 | --------------------------------------------------------------------------------