diff options
| author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2019-07-25 09:23:39 +0200 | 
|---|---|---|
| committer | Vasily Gorbik <gor@linux.ibm.com> | 2019-08-21 12:41:43 +0200 | 
| commit | f62f7dcbf023160ca47eb4bc7228ece8207f8a8e (patch) | |
| tree | 2d661e3a7fc877bedcd4d17588721fbf79e30f26 /Documentation/s390 | |
| parent | 8c72e0c85212df4e7c77fca55556e423fe17e801 (diff) | |
| download | linux-f62f7dcbf023160ca47eb4bc7228ece8207f8a8e.tar.bz2 | |
Documentation/s390: remove outdated debugging390 documentation
This file would need a lot of work to make sense again. Thomas Huth
started working on that four years ago, but that wasn't finished.
Therefore remove this.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'Documentation/s390')
| -rw-r--r-- | Documentation/s390/debugging390.rst | 2613 | ||||
| -rw-r--r-- | Documentation/s390/index.rst | 1 | 
2 files changed, 0 insertions, 2614 deletions
| diff --git a/Documentation/s390/debugging390.rst b/Documentation/s390/debugging390.rst deleted file mode 100644 index 73ad0b06c666..000000000000 --- a/Documentation/s390/debugging390.rst +++ /dev/null @@ -1,2613 +0,0 @@ -============================================= -Debugging on Linux for s/390 & z/Architecture -============================================= - -Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - -Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation - -.. Best viewed with fixed width fonts - -Overview of Document: -===================== -This document is intended to give a good overview of how to debug Linux for -s/390 and z/Architecture. It is not intended as a complete reference and not a -tutorial on the fundamentals of C & assembly. It doesn't go into -390 IO in any detail. It is intended to complement the documents in the -reference section below & any other worthwhile references you get. - -It is intended like the Enterprise Systems Architecture/390 Reference Summary -to be printed out & used as a quick cheat sheet self help style reference when -problems occur. - -.. Contents -   ======== -   Register Set -   Address Spaces on Intel Linux -   Address Spaces on Linux for s/390 & z/Architecture -   The Linux for s/390 & z/Architecture Kernel Task Structure -   Register Usage & Stackframes on Linux for s/390 & z/Architecture -   A sample program with comments -   Compiling programs for debugging on Linux for s/390 & z/Architecture -   Debugging under VM -   s/390 & z/Architecture IO Overview -   Debugging IO on s/390 & z/Architecture under VM -   GDB on s/390 & z/Architecture -   Stack chaining in gdb by hand -   Examining core dumps -   ldd -   Debugging modules -   The proc file system -   SysRq -   References -   Special Thanks - -Register Set -============ -The current architectures have the following registers. - -16 General propose registers, 32 bit on s/390 and 64 bit on z/Architecture, -r0-r15 (or gpr0-gpr15), used for arithmetic and addressing. - -16 Control registers, 32 bit on s/390 and 64 bit on z/Architecture, cr0-cr15, -kernel usage only, used for memory management, interrupt control, debugging -control etc. - -16 Access registers (ar0-ar15), 32 bit on both s/390 and z/Architecture, -normally not used by normal programs but potentially could be used as -temporary storage. These registers have a 1:1 association with general -purpose registers and are designed to be used in the so-called access -register mode to select different address spaces. -Access register 0 (and access register 1 on z/Architecture, which needs a -64 bit pointer) is currently used by the pthread library as a pointer to -the current running threads private area. - -16 64-bit floating point registers (fp0-fp15 ) IEEE & HFP floating -point format compliant on G5 upwards & a Floating point control reg (FPC) - -4  64-bit registers (fp0,fp2,fp4 & fp6) HFP only on older machines. - -Note: -   Linux (currently) always uses IEEE & emulates G5 IEEE format on older -   machines, ( provided the kernel is configured for this ). - - -The PSW is the most important register on the machine it -is 64 bit on s/390 & 128 bit on z/Architecture & serves the roles of -a program counter (pc), condition code register,memory space designator. -In IBM standard notation I am counting bit 0 as the MSB. -It has several advantages over a normal program counter -in that you can change address translation & program counter -in a single instruction. To change address translation, -e.g. switching address translation off requires that you -have a logical=physical mapping for the address you are -currently running at. - -+-------------------------+-------------------------------------------------+ -|          Bit            |                                                 | -+--------+----------------+                     Value                       | -| s/390  | z/Architecture |                                                 | -+========+================+=================================================+ -| 0      |     0          | Reserved (must be 0) otherwise specification    | -|        |                | exception occurs.                               | -+--------+----------------+-------------------------------------------------+ -| 1      |     1          | Program Event Recording 1 PER enabled,          | -|        |                | PER is used to facilitate debugging e.g.        | -|        |                | single stepping.                                | -+--------+----------------+-------------------------------------------------+ -| 2-4    |    2-4         | Reserved (must be 0).                           | -+--------+----------------+-------------------------------------------------+ -| 5      |     5          | Dynamic address translation 1=DAT on.           | -+--------+----------------+-------------------------------------------------+ -| 6      |     6          | Input/Output interrupt Mask                     | -+--------+----------------+-------------------------------------------------+ -| 7      |     7          | External interrupt Mask used primarily for      | -|        |                | interprocessor signalling and clock interrupts. | -+--------+----------------+-------------------------------------------------+ -| 8-11   |   8-11         | PSW Key used for complex memory protection      | -|        |                | mechanism (not used under linux)                | -+--------+----------------+-------------------------------------------------+ -| 12     |     12         | 1 on s/390 0 on z/Architecture                  | -+--------+----------------+-------------------------------------------------+ -| 13     |     13         | Machine Check Mask 1=enable machine check       | -|        |                | interrupts                                      | -+--------+----------------+-------------------------------------------------+ -| 14     |     14         | Wait State. Set this to 1 to stop the processor | -|        |                | except for interrupts and give  time to other   | -|        |                | LPARS. Used in CPU idle in the kernel to        | -|        |                | increase overall usage of processor resources.  | -+--------+----------------+-------------------------------------------------+ -| 15     |     15         | Problem state (if set to 1 certain instructions | -|        |                | are disabled). All linux user programs run with | -|        |                | this bit 1 (useful info for debugging under VM).| -+--------+----------------+-------------------------------------------------+ -| 16-17  |    16-17       | Address Space Control                           | -|        |                |                                                 | -|        |                | 00 Primary Space Mode:                          | -|        |                |                                                 | -|        |                | The register CR1 contains the primary           | -|        |                | address-space control element (PASCE), which    | -|        |                | points to the primary space region/segment      | -|        |                | table origin.                                   | -|        |                |                                                 | -|        |                | 01 Access register mode                         | -|        |                |                                                 | -|        |                | 10 Secondary Space Mode:                        | -|        |                |                                                 | -|        |                | The register CR7 contains the secondary         | -|        |                | address-space control element (SASCE), which    | -|        |                | points to the secondary space region or         | -|        |                | segment table origin.                           | -|        |                |                                                 | -|        |                | 11 Home Space Mode:                             | -|        |                |                                                 | -|        |                | The register CR13 contains the home space       | -|        |                | address-space control element (HASCE), which    | -|        |                | points to the home space region/segment         | -|        |                | table origin.                                   | -|        |                |                                                 | -|        |                | See "Address Spaces on Linux for s/390 &        | -|        |                | z/Architecture" below for more information      | -|        |                | about address space usage in Linux.             | -+--------+----------------+-------------------------------------------------+ -| 18-19  |    18-19       | Condition codes (CC)                            | -+--------+----------------+-------------------------------------------------+ -| 20     |    20          | Fixed point overflow mask if 1=FPU exceptions   | -|        |                | for this event occur (normally 0)               | -+--------+----------------+-------------------------------------------------+ -| 21     |    21          | Decimal overflow mask if 1=FPU exceptions for   | -|        |                | this event occur (normally 0)                   | -+--------+----------------+-------------------------------------------------+ -| 22     |    22          | Exponent underflow mask if 1=FPU exceptions     | -|        |                | for this event occur (normally 0)               | -+--------+----------------+-------------------------------------------------+ -| 23     |    23          | Significance Mask if 1=FPU exceptions for this  | -|        |                | event occur (normally 0)                        | -+--------+----------------+-------------------------------------------------+ -| 24-31  |    24-30       | Reserved Must be 0.                             | -|        +----------------+-------------------------------------------------+ -|        |    31          | Extended Addressing Mode                        | -|        +----------------+-------------------------------------------------+ -|        |    32          | Basic Addressing Mode                           | -|        |                |                                                 | -|        |                | Used to set addressing mode::                   | -|        |                |                                                 | -|        |                |    +---------+----------+----------+            | -|        |                |    | PSW 31  | PSW 32   |          |            | -|        |                |    +---------+----------+----------+            | -|        |                |    |   0     |    0     |  24 bit  |            | -|        |                |    +---------+----------+----------+            | -|        |                |    |   0     |    1     |  31 bit  |            | -|        |                |    +---------+----------+----------+            | -|        |                |    |   1     |    1     |  64 bit  |            | -|        |                |    +---------+----------+----------+            | -+--------+----------------+-------------------------------------------------+ -| 32     |                | 1=31 bit addressing mode 0=24 bit addressing    | -|        |                | mode (for backward compatibility), linux        | -|        |                | always runs with this bit set to 1              | -+--------+----------------+-------------------------------------------------+ -| 33-64  |                | Instruction address.                            | -|        +----------------+-------------------------------------------------+ -|        |    33-63       | Reserved must be 0                              | -|        +----------------+-------------------------------------------------+ -|        |    64-127      | Address                                         | -|        |                |                                                 | -|        |                |   - In 24 bits mode bits 64-103=0 bits 104-127  | -|        |                |     Address                                     | -|        |                |   - In 31 bits mode bits 64-96=0 bits 97-127    | -|        |                |     Address                                     | -|        |                |                                                 | -|        |                | Note:                                           | -|        |                |     unlike 31 bit mode on s/390 bit 96 must be  | -|        |                |     zero when loading the address with LPSWE    | -|        |                |     otherwise a specification exception occurs, | -|        |                |     LPSW is fully backward compatible.          | -+--------+----------------+-------------------------------------------------+ - -Prefix Page(s) --------------- -This per cpu memory area is too intimately tied to the processor not to mention. -It exists between the real addresses 0-4096 on s/390 and between 0-8192 on -z/Architecture and is exchanged with one page on s/390 or two pages on -z/Architecture in absolute storage by the set prefix instruction during Linux -startup. - -This page is mapped to a different prefix for each processor in an SMP -configuration (assuming the OS designer is sane of course). - -Bytes 0-512 (200 hex) on s/390 and 0-512, 4096-4544, 4604-5119 currently on -z/Architecture are used by the processor itself for holding such information -as exception indications and entry points for exceptions. - -Bytes after 0xc00 hex are used by linux for per processor globals on s/390 and -z/Architecture (there is a gap on z/Architecture currently between 0xc00 and -0x1000, too, which is used by Linux). - -The closest thing to this on traditional architectures is the interrupt -vector table. This is a good thing & does simplify some of the kernel coding -however it means that we now cannot catch stray NULL pointers in the -kernel without hard coded checks. - - - -Address Spaces on Intel Linux -============================= - -The traditional Intel Linux is approximately mapped as follows forgive -the ascii art:: - -  0xFFFFFFFF 4GB Himem          ***************** -				*               * -				* Kernel Space  * -				*               * -				*****************         **************** -  User Space Himem              *  User Stack   *         *              * -  (typically 0xC0000000 3GB )   *****************         *              * -				*  Shared Libs  *         * Next Process * -				*****************         *     to       * -				*               *   <==   *     Run      *  <== -				*  User Program *         *              * -				*   Data BSS    *         *              * -				*    Text       *         *              * -				*   Sections    *         *              * -  0x00000000                    *****************         **************** - -Now it is easy to see that on Intel it is quite easy to recognise a kernel -address as being one greater than user space himem (in this case 0xC0000000), -and addresses of less than this are the ones in the current running program on -this processor (if an smp box). - -If using the virtual machine ( VM ) as a debugger it is quite difficult to -know which user process is running as the address space you are looking at -could be from any process in the run queue. - -The limitation of Intels addressing technique is that the linux -kernel uses a very simple real address to virtual addressing technique -of Real Address=Virtual Address-User Space Himem. -This means that on Intel the kernel linux can typically only address -Himem=0xFFFFFFFF-0xC0000000=1GB & this is all the RAM these machines -can typically use. - -They can lower User Himem to 2GB or lower & thus be -able to use 2GB of RAM however this shrinks the maximum size -of User Space from 3GB to 2GB they have a no win limit of 4GB unless -they go to 64 Bit. - - -On 390 our limitations & strengths make us slightly different. -For backward compatibility we are only allowed use 31 bits (2GB) -of our 32 bit addresses, however, we use entirely separate address -spaces for the user & kernel. - -This means we can support 2GB of non Extended RAM on s/390, & more -with the Extended memory management swap device & -currently 4TB of physical memory currently on z/Architecture. - - -Address Spaces on Linux for s/390 & z/Architecture -================================================== - -Our addressing scheme is basically as follows:: - -				   Primary Space               Home Space -  Himem 0x7fffffff 2GB on s/390    *****************          **************** -  currently 0x3ffffffffff (2^42)-1 *  User Stack   *          *              * -  on z/Architecture.               *****************          *              * -				   *  Shared Libs  *          *              * -				   *****************          *              * -				   *               *          *    Kernel    * -				   *  User Program *          *              * -				   *   Data BSS    *          *              * -				   *    Text       *          *              * -				   *   Sections    *          *              * -  0x00000000                       *****************          **************** - -This also means that we need to look at the PSW problem state bit and the -addressing mode to decide whether we are looking at user or kernel space. - -User space runs in primary address mode (or access register mode within -the vdso code). - -The kernel usually also runs in home space mode, however when accessing -user space the kernel switches to primary or secondary address mode if -the mvcos instruction is not available or if a compare-and-swap (futex) -instruction on a user space address is performed. - -When also looking at the ASCE control registers, this means: - -User space: - -- runs in primary or access register mode -- cr1 contains the user asce -- cr7 contains the user asce -- cr13 contains the kernel asce - -Kernel space: - -- runs in home space mode -- cr1 contains the user or kernel asce - -  - the kernel asce is loaded when a uaccess requires primary or -    secondary address mode - -- cr7 contains the user or kernel asce, (changed with set_fs()) -- cr13 contains the kernel asce - -In case of uaccess the kernel changes to: - -- primary space mode in case of a uaccess (copy_to_user) and uses -  e.g. the mvcp instruction to access user space. However the kernel -  will stay in home space mode if the mvcos instruction is available -- secondary space mode in case of futex atomic operations, so that the -  instructions come from primary address space and data from secondary -  space - -In case of KVM, the kernel runs in home space mode, but cr1 gets switched -to contain the gmap asce before the SIE instruction gets executed. When -the SIE instruction is finished, cr1 will be switched back to contain the -user asce. - - -Virtual Addresses on s/390 & z/Architecture -=========================================== - -A virtual address on s/390 is made up of 3 parts -The SX (segment index, roughly corresponding to the PGD & PMD in Linux -terminology) being bits 1-11. - -The PX (page index, corresponding to the page table entry (pte) in Linux -terminology) being bits 12-19. - -The remaining bits BX (the byte index are the offset in the page ) -i.e. bits 20 to 31. - -On z/Architecture in linux we currently make up an address from 4 parts. - -- The region index bits (RX) 0-32 we currently use bits 22-32 -- The segment index (SX) being bits 33-43 -- The page index (PX) being bits  44-51 -- The byte index (BX) being bits  52-63 - -Notes: -  1) s/390 has no PMD so the PMD is really the PGD also. -     A lot of this stuff is defined in pgtable.h. - -  2) Also seeing as s/390's page indexes are only 1k  in size -     (bits 12-19 x 4 bytes per pte ) we use 1 ( page 4k ) -     to make the best use of memory by updating 4 segment indices -     entries each time we mess with a PMD & use offsets -     0,1024,2048 & 3072 in this page as for our segment indexes. -     On z/Architecture our page indexes are now 2k in size -     ( bits 12-19 x 8 bytes per pte ) we do a similar trick -     but only mess with 2 segment indices each time we mess with -     a PMD. - -  3) As z/Architecture supports up to a massive 5-level page table lookup we -     can only use 3 currently on Linux ( as this is all the generic kernel -     currently supports ) however this may change in future -     this allows us to access ( according to my sums ) -     4TB of virtual storage per process i.e. -     4096*512(PTES)*1024(PMDS)*2048(PGD) = 4398046511104 bytes, -     enough for another 2 or 3 of years I think :-). -     to do this we use a region-third-table designation type in -     our address space control registers. - - -The Linux for s/390 & z/Architecture Kernel Task Structure -========================================================== -Each process/thread under Linux for S390 has its own kernel task_struct -defined in linux/include/linux/sched.h -The S390 on initialisation & resuming of a process on a cpu sets -the __LC_KERNEL_STACK variable in the spare prefix area for this cpu -(which we use for per-processor globals). - -The kernel stack pointer is intimately tied with the task structure for -each processor as follows:: - -			s/390 -	      ************************ -	      *  1 page kernel stack * -	      *        ( 4K )        * -	      ************************ -	      *   1 page task_struct * -	      *        ( 4K )        * -  8K aligned  ************************ - -		   z/Architecture -	      ************************ -	      *  2 page kernel stack * -	      *        ( 8K )        * -	      ************************ -	      *  2 page task_struct  * -	      *        ( 8K )        * -  16K aligned ************************ - -What this means is that we don't need to dedicate any register or global -variable to point to the current running process & can retrieve it with the -following very simple construct for s/390 & one very similar for -z/Architecture:: - -  static inline struct task_struct * get_current(void) -  { -	struct task_struct *current; -	__asm__("lhi   %0,-8192\n\t" -		"nr    %0,15" -		: "=r" (current) ); -	return current; -  } - -i.e. just anding the current kernel stack pointer with the mask -8192. -Thankfully because Linux doesn't have support for nested IO interrupts -& our devices have large buffers can survive interrupts being shut for -short amounts of time we don't need a separate stack for interrupts. - - - - -Register Usage & Stackframes on Linux for s/390 & z/Architecture -================================================================= -Overview: ---------- -This is the code that gcc produces at the top & the bottom of -each function. It usually is fairly consistent & similar from -function to function & if you know its layout you can probably -make some headway in finding the ultimate cause of a problem -after a crash without a source level debugger. - -Note: To follow stackframes requires a knowledge of C or Pascal & -limited knowledge of one assembly language. - -It should be noted that there are some differences between the -s/390 and z/Architecture stack layouts as the z/Architecture stack layout -didn't have to maintain compatibility with older linkage formats. - -Glossary: ---------- -alloca: -  This is a built in compiler function for runtime allocation -  of extra space on the callers stack which is obviously freed -  up on function exit ( e.g. the caller may choose to allocate nothing -  of a buffer of 4k if required for temporary purposes ), it generates -  very efficient code ( a few cycles  ) when compared to alternatives -  like malloc. - -automatics: -  These are local variables on the stack, i.e they aren't in registers & -  they aren't static. - -back-chain: -  This is a pointer to the stack pointer before entering a -  framed functions ( see frameless function ) prologue got by -  dereferencing the address of the current stack pointer, -  i.e. got by accessing the 32 bit value at the stack pointers -  current location. - -base-pointer: -  This is a pointer to the back of the literal pool which -  is an area just behind each procedure used to store constants -  in each function. - -call-clobbered: -  The caller probably needs to save these registers if there -  is something of value in them, on the stack or elsewhere before making a -  call to another procedure so that it can restore it later. - -epilogue: -  The code generated by the compiler to return to the caller. - -frameless-function: -  A frameless function in Linux for s390 & z/Architecture is one which doesn't -  need more than the register save area (96 bytes on s/390, 160 on z/Architecture) -  given to it by the caller. - -  A frameless function never: - -  1) Sets up a back chain. -  2) Calls alloca. -  3) Calls other normal functions -  4) Has automatics. - -GOT-pointer: -  This is a pointer to the global-offset-table in ELF -  ( Executable Linkable Format, Linux'es most common executable format ), -  all globals & shared library objects are found using this pointer. - -lazy-binding -  ELF shared libraries are typically only loaded when routines in the shared -  library are actually first called at runtime. This is lazy binding. - -procedure-linkage-table -  This is a table found from the GOT which contains pointers to routines -  in other shared libraries which can't be called to by easier means. - -prologue: -  The code generated by the compiler to set up the stack frame. - -outgoing-args: -  This is extra area allocated on the stack of the calling function if the -  parameters for the callee's cannot all be put in registers, the same -  area can be reused by each function the caller calls. - -routine-descriptor: -  A COFF  executable format based concept of a procedure reference -  actually being 8 bytes or more as opposed to a simple pointer to the routine. -  This is typically defined as follows: - -  - Routine Descriptor offset 0=Pointer to Function -  - Routine Descriptor offset 4=Pointer to Table of Contents - -  The table of contents/TOC is roughly equivalent to a GOT pointer. -  & it means that shared libraries etc. can be shared between several -  environments each with their own TOC. - -static-chain: -  This is used in nested functions a concept adopted from pascal -  by gcc not used in ansi C or C++ ( although quite useful ), basically it -  is a pointer used to reference local variables of enclosing functions. -  You might come across this stuff once or twice in your lifetime. - -  e.g. - -  The function below should return 11 though gcc may get upset & toss warnings -  about unused variables:: - -    int FunctionA(int a) -    { -	int b; -	FunctionC(int c) -	{ -		b=c+1; -	} -	FunctionC(10); -	return(b); -    } - - -s/390 & z/Architecture Register usage -===================================== - -======== ========================================== =============== -r0       used by syscalls/assembly                  call-clobbered -r1       used by syscalls/assembly                  call-clobbered -r2       argument 0 / return value 0                call-clobbered -r3       argument 1 / return value 1 (if long long) call-clobbered -r4       argument 2                                 call-clobbered -r5       argument 3                                 call-clobbered -r6       argument 4                                 saved -r7       pointer-to arguments 5 to ...              saved -r8       this & that                                saved -r9       this & that                                saved -r10      static-chain ( if nested function )        saved -r11      frame-pointer ( if function used alloca )  saved -r12      got-pointer                                saved -r13      base-pointer                               saved -r14      return-address                             saved -r15      stack-pointer                              saved - -f0       argument 0 / return value ( float/double ) call-clobbered -f2       argument 1                                 call-clobbered -f4       z/Architecture argument 2                  saved -f6       z/Architecture argument 3                  saved -======== ========================================== =============== - -The remaining floating points -f1,f3,f5 f7-f15 are call-clobbered. - -Notes: ------- -1) The only requirement is that registers which are used -   by the callee are saved, e.g. the compiler is perfectly -   capable of using r11 for purposes other than a frame a -   frame pointer if a frame pointer is not needed. -2) In functions with variable arguments e.g. printf the calling procedure -   is identical to one without variable arguments & the same number of -   parameters. However, the prologue of this function is somewhat more -   hairy owing to it having to move these parameters to the stack to -   get va_start, va_arg & va_end to work. -3) Access registers are currently unused by gcc but are used in -   the kernel. Possibilities exist to use them at the moment for -   temporary storage but it isn't recommended. -4) Only 4 of the floating point registers are used for -   parameter passing as older machines such as G3 only have only 4 -   & it keeps the stack frame compatible with other compilers. -   However with IEEE floating point emulation under linux on the -   older machines you are free to use the other 12. -5) A long long or double parameter cannot be have the -   first 4 bytes in a register & the second four bytes in the -   outgoing args area. It must be purely in the outgoing args -   area if crossing this boundary. -6) Floating point parameters are mixed with outgoing args -   on the outgoing args area in the order the are passed in as parameters. -7) Floating point arguments 2 & 3 are saved in the outgoing args area for -   z/Architecture - - -Stack Frame Layout ------------------- - -========= ============== ====================================================== -s/390     z/Architecture -========= ============== ====================================================== -0         0              back chain ( a 0 here signifies end of back chain ) -4         8              eos ( end of stack, not used on Linux for S390 used -			 in other linkage formats ) -8         16             glue used in other s/390 linkage formats for saved -			 routine descriptors etc. -12        24             glue used in other s/390 linkage formats for saved -			 routine descriptors etc. -16        32             scratch area -20        40             scratch area -24        48             saved r6 of caller function -28        56             saved r7 of caller function -32        64             saved r8 of caller function -36        72             saved r9 of caller function -40        80             saved r10 of caller function -44        88             saved r11 of caller function -48        96             saved r12 of caller function -52        104            saved r13 of caller function -56        112            saved r14 of caller function -60        120            saved r15 of caller function -64        128            saved f4 of caller function -72        132            saved f6 of caller function -80                       undefined -96        160            outgoing args passed from caller to callee -96+x      160+x          possible stack alignment ( 8 bytes desirable ) -96+x+y    160+x+y        alloca space of caller ( if used ) -96+x+y+z  160+x+y+z      automatics of caller ( if used ) -0                        back-chain -========= ============== ====================================================== - -A sample program with comments. -=============================== - -Comments on the function test ------------------------------ -1) It didn't need to set up a pointer to the constant pool gpr13 as it is not -   used ( :-( ). -2) This is a frameless function & no stack is bought. -3) The compiler was clever enough to recognise that it could return the -   value in r2 as well as use it for the passed in parameter ( :-) ). -4) The basr ( branch relative & save ) trick works as follows the instruction -   has a special case with r0,r0 with some instruction operands is understood as -   the literal value 0, some risc architectures also do this ). So now -   we are branching to the next address & the address new program counter is -   in r13,so now we subtract the size of the function prologue we have executed -   the size of the literal pool to get to the top of the literal pool:: - - -     0040037c int test(int b) -     {                                                     # Function prologue below -       40037c:  90 de f0 34     stm     %r13,%r14,52(%r15) # Save registers r13 & r14 -       400380:  0d d0           basr    %r13,%r0           # Set up pointer to constant pool using -       400382:  a7 da ff fa     ahi     %r13,-6            # basr trick -	return(5+b); -							   # Huge main program -       400386:  a7 2a 00 05     ahi     %r2,5              # add 5 to r2 - -							   # Function epilogue below -       40038a:  98 de f0 34     lm      %r13,%r14,52(%r15) # restore registers r13 & 14 -       40038e:  07 fe           br      %r14               # return -     } - -Comments on the function main ------------------------------ -1) The compiler did this function optimally ( 8-) ):: - -     Literal pool for main. -     400390:    ff ff ff ec     .long 0xffffffec -     main(int argc,char *argv[]) -     {                                                     # Function prologue below -       400394:  90 bf f0 2c     stm     %r11,%r15,44(%r15) # Save necessary registers -       400398:  18 0f           lr      %r0,%r15           # copy stack pointer to r0 -       40039a:  a7 fa ff a0     ahi     %r15,-96           # Make area for callee saving -       40039e:  0d d0           basr    %r13,%r0           # Set up r13 to point to -       4003a0:  a7 da ff f0     ahi     %r13,-16           # literal pool -       4003a4:  50 00 f0 00     st      %r0,0(%r15)        # Save backchain - -	return(test(5));                                   # Main Program Below -       4003a8:  58 e0 d0 00     l       %r14,0(%r13)       # load relative address of test from -							   # literal pool -       4003ac:  a7 28 00 05     lhi     %r2,5              # Set first parameter to 5 -       4003b0:  4d ee d0 00     bas     %r14,0(%r14,%r13)  # jump to test setting r14 as return -							   # address using branch & save instruction. - -							   # Function Epilogue below -       4003b4:  98 bf f0 8c     lm      %r11,%r15,140(%r15)# Restore necessary registers. -       4003b8:  07 fe           br      %r14               # return to do program exit -     } - - -Compiler updates ----------------- - -:: - -  main(int argc,char *argv[]) -  { -    4004fc:     90 7f f0 1c             stm     %r7,%r15,28(%r15) -    400500:     a7 d5 00 04             bras    %r13,400508 <main+0xc> -    400504:     00 40 04 f4             .long   0x004004f4 -    # compiler now puts constant pool in code to so it saves an instruction -    400508:     18 0f                   lr      %r0,%r15 -    40050a:     a7 fa ff a0             ahi     %r15,-96 -    40050e:     50 00 f0 00             st      %r0,0(%r15) -	return(test(5)); -    400512:     58 10 d0 00             l       %r1,0(%r13) -    400516:     a7 28 00 05             lhi     %r2,5 -    40051a:     0d e1                   basr    %r14,%r1 -    # compiler adds 1 extra instruction to epilogue this is done to -    # avoid processor pipeline stalls owing to data dependencies on g5 & -    # above as register 14 in the old code was needed directly after being loaded -    # by the lm %r11,%r15,140(%r15) for the br %14. -    40051c:     58 40 f0 98             l       %r4,152(%r15) -    400520:     98 7f f0 7c             lm      %r7,%r15,124(%r15) -    400524:     07 f4                   br      %r4 -  } - - -Hartmut ( our compiler developer ) also has been threatening to take out the -stack backchain in optimised code as this also causes pipeline stalls, you -have been warned. - -64 bit z/Architecture code disassembly --------------------------------------- - -If you understand the stuff above you'll understand the stuff -below too so I'll avoid repeating myself & just say that -some of the instructions have g's on the end of them to indicate -they are 64 bit & the stack offsets are a bigger, -the only other difference you'll find between 32 & 64 bit is that -we now use f4 & f6 for floating point arguments on 64 bit:: - -  00000000800005b0 <test>: -  int test(int b) -  { -	return(5+b); -      800005b0: a7 2a 00 05             ahi     %r2,5 -      800005b4: b9 14 00 22             lgfr    %r2,%r2 # downcast to integer -      800005b8: 07 fe                   br      %r14 -      800005ba: 07 07                   bcr     0,%r7 - - -  } - -  00000000800005bc <main>: -  main(int argc,char *argv[]) -  { -      800005bc: eb bf f0 58 00 24       stmg    %r11,%r15,88(%r15) -      800005c2: b9 04 00 1f             lgr     %r1,%r15 -      800005c6: a7 fb ff 60             aghi    %r15,-160 -      800005ca: e3 10 f0 00 00 24       stg     %r1,0(%r15) -	return(test(5)); -      800005d0: a7 29 00 05             lghi    %r2,5 -      # brasl allows jumps > 64k & is overkill here bras would do fune -      800005d4: c0 e5 ff ff ff ee       brasl   %r14,800005b0 <test> -      800005da: e3 40 f1 10 00 04       lg      %r4,272(%r15) -      800005e0: eb bf f0 f8 00 04       lmg     %r11,%r15,248(%r15) -      800005e6: 07 f4                   br      %r4 -  } - - - -Compiling programs for debugging on Linux for s/390 & z/Architecture -==================================================================== --gdwarf-2 now works it should be considered the default debugging -format for s/390 & z/Architecture as it is more reliable for debugging -shared libraries,  normal -g debugging works much better now -Thanks to the IBM java compiler developers bug reports. - -This is typically done adding/appending the flags -g or -gdwarf-2 to the -CFLAGS & LDFLAGS variables Makefile of the program concerned. - -If using gdb & you would like accurate displays of registers & -stack traces compile without optimisation i.e make sure -that there is no -O2 or similar on the CFLAGS line of the Makefile & -the emitted gcc commands, obviously this will produce worse code -( not advisable for shipment ) but it is an  aid to the debugging process. - -This aids debugging because the compiler will copy parameters passed in -in registers onto the stack so backtracing & looking at passed in -parameters will work, however some larger programs which use inline functions -will not compile without optimisation. - -Debugging with optimisation has since much improved after fixing -some bugs, please make sure you are using gdb-5.0 or later developed -after Nov'2000. - - - -Debugging under VM -================== - -Notes ------ -Addresses & values in the VM debugger are always hex never decimal -Address ranges are of the format <HexValue1>-<HexValue2> or -<HexValue1>.<HexValue2> -For example, the address range  0x2000 to 0x3000 can be described as 2000-3000 -or 2000.1000 - -The VM Debugger is case insensitive. - -VM's strengths are usually other debuggers weaknesses you can get at any -resource no matter how sensitive e.g. memory management resources, change -address translation in the PSW. For kernel hacking you will reap dividends if -you get good at it. - -The VM Debugger displays operators but not operands, and also the debugger -displays useful information on the same line as the author of the code probably -felt that it was a good idea not to go over the 80 columns on the screen. -This isn't as unintuitive as it may seem as the s/390 instructions are easy to -decode mentally and you can make a good guess at a lot of them as all the -operands are nibble (half byte aligned). -So if you have an objdump listing by hand, it is quite easy to follow, and if -you don't have an objdump listing keep a copy of the s/390 Reference Summary -or alternatively the s/390 principles of operation next to you. -e.g. even I can guess that -0001AFF8' LR    180F        CC 0 -is a ( load register ) lr r0,r15 - -Also it is very easy to tell the length of a 390 instruction from the 2 most -significant bits in the instruction (not that this info is really useful except -if you are trying to make sense of a hexdump of code). -Here is a table - -======================= ================== -Bits                    Instruction Length -======================= ================== -00                          2 Bytes -01                          4 Bytes -10                          4 Bytes -11                          6 Bytes -======================= ================== - -The debugger also displays other useful info on the same line such as the -addresses being operated on destination addresses of branches & condition codes. -e.g.:: - -  00019736' AHI   A7DAFF0E    CC 1 -  000198BA' BRC   A7840004 -> 000198C2'   CC 0 -  000198CE' STM   900EF068 >> 0FA95E78    CC 2 - - - -Useful VM debugger commands ---------------------------- - -I suppose I'd better mention this before I start -to list the current active traces do:: - -	Q TR - -there can be a maximum of 255 of these per set -( more about trace sets later ). - -To stop traces issue a:: - -	TR END. - -To delete a particular breakpoint issue:: - -	TR DEL <breakpoint number> - -The PA1 key drops to CP mode so you can issue debugger commands, -Doing alt c (on my 3270 console at least ) clears the screen. - -hitting b <enter> comes back to the running operating system -from cp mode ( in our case linux ). - -It is typically useful to add shortcuts to your profile.exec file -if you have one ( this is roughly equivalent to autoexec.bat in DOS ). -file here are a few from mine:: - -  /* this gives me command history on issuing f12 */ -  set pf12 retrieve -  /* this continues */ -  set pf8 imm b -  /* goes to trace set a */ -  set pf1 imm tr goto a -  /* goes to trace set b */ -  set pf2 imm tr goto b -  /* goes to trace set c */ -  set pf3 imm tr goto c - - - -Instruction Tracing -------------------- -Setting a simple breakpoint:: - -	TR I PSWA <address> - -To debug a particular function try:: - -  TR I R <function address range> -  TR I on its own will single step. -  TR I DATA <MNEMONIC> <OPTIONAL RANGE> will trace for particular mnemonics - -e.g.:: - -  TR I DATA 4D R 0197BC.4000 - -will trace for BAS'es ( opcode 4D ) in the range 0197BC.4000 - -if you were inclined you could add traces for all branch instructions & -suffix them with the run prefix so you would have a backtrace on screen -when a program crashes:: - -	TR BR <INTO OR FROM> will trace branches into or out of an address. - -e.g.:: - -	TR BR INTO 0 - -is often quite useful if a program is getting awkward & deciding -to branch to 0 & crashing as this will stop at the address before in jumps to 0. - -:: - -	TR I R <address range> RUN cmd d g - -single steps a range of addresses but stays running & -displays the gprs on each step. - - - -Displaying & modifying Registers --------------------------------- -D G -	will display all the gprs - -Adding a extra G to all the commands is necessary to access the full 64 bit -content in VM on z/Architecture. Obviously this isn't required for access -registers as these are still 32 bit. - -e.g. - -DGG -	instead of DG - -D X -	will display all the control registers -D AR -	will display all the access registers -D AR4-7 -	will display access registers 4 to 7 -CPU ALL D G -	will display the GRPS of all CPUS in the configuration -D PSW -	will display the current PSW -st PSW 2000 -	will put the value 2000 into the PSW & cause crash your machine. -D PREFIX -	displays the prefix offset - - -Displaying Memory ------------------ -To display memory mapped using the current PSW's mapping try:: - -   D <range> - -To make VM display a message each time it hits a particular address and -continue try: - -D I<range> -	will disassemble/display a range of instructions. - -ST addr 32 bit word -	will store a 32 bit aligned address -D T<range> -	will display the EBCDIC in an address (if you are that way inclined) -D R<range> -	will display real addresses ( without DAT ) but with prefixing. - -There are other complex options to display if you need to get at say home space -but are in primary space the easiest thing to do is to temporarily -modify the PSW to the other addressing mode, display the stuff & then -restore it. - - - -Hints ------ -If you want to issue a debugger command without halting your virtual machine -with the PA1 key try prefixing the command with #CP e.g.:: - -	#cp tr i pswa 2000 - -also suffixing most debugger commands with RUN will cause them not -to stop just display the mnemonic at the current instruction on the console. - -If you have several breakpoints you want to put into your program & -you get fed up of cross referencing with System.map -you can do the following trick for several symbols. - -:: - -	grep do_signal System.map - -which emits the following among other things:: - -	0001f4e0 T do_signal - -now you can do:: - -	TR I PSWA 0001f4e0 cmd msg * do_signal - -This sends a message to your own console each time do_signal is entered. -( As an aside I wrote a perl script once which automatically generated a REXX -script with breakpoints on every kernel procedure, this isn't a good idea -because there are thousands of these routines & VM can only set 255 breakpoints -at a time so you nearly had to spend as long pruning the file down as you would -entering the msgs by hand), however, the trick might be useful for a single -object file. In the 3270 terminal emulator x3270 there is a very useful option -in the file menu called "Save Screen In File" - this is very good for keeping a -copy of traces. - -From CMS help <command name> will give you online help on a particular command. -e.g.:: - -	HELP DISPLAY - -Also CP has a file called profile.exec which automatically gets called -on startup of CMS ( like autoexec.bat ), keeping on a DOS analogy session -CP has a feature similar to doskey, it may be useful for you to -use profile.exec to define some keystrokes. - -SET PF9 IMM B -	This does a single step in VM on pressing F8. - -SET PF10  ^ -	This sets up the ^ key. -	which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed -	directly into some 3270 consoles. - -SET PF11 ^- -	This types the starting keystrokes for a sysrq see SysRq below. -SET PF12 RETRIEVE -	This retrieves command history on pressing F12. - - -Sometimes in VM the display is set up to scroll automatically this -can be very annoying if there are messages you wish to look at -to stop this do - -TERM MORE 255 255 -  This will nearly stop automatic screen updates, however it will -  cause a denial of service if lots of messages go to the 3270 console, -  so it would be foolish to use this as the default on a production machine. - - -Tracing particular processes ----------------------------- -The kernel's text segment is intentionally at an address in memory that it will -very seldom collide with text segments of user programs ( thanks Martin ), -this simplifies debugging the kernel. -However it is quite common for user processes to have addresses which collide -this can make debugging a particular process under VM painful under normal -circumstances as the process may change when doing a:: - -	TR I R <address range>. - -Thankfully after reading VM's online help I figured out how to debug -I particular process. - -Your first problem is to find the STD ( segment table designation ) -of the program you wish to debug. -There are several ways you can do this here are a few - -Run:: - -	objdump --syms <program to be debugged> | grep main - -To get the address of main in the program. Then:: - -	tr i pswa <address of main> - -Start the program, if VM drops to CP on what looks like the entry -point of the main function this is most likely the process you wish to debug. -Now do a D X13 or D XG13 on z/Architecture. - -On 31 bit the STD is bits 1-19 ( the STO segment table origin ) -& 25-31 ( the STL segment table length ) of CR13. - -now type:: - -	TR I R STD <CR13's value> 0.7fffffff - -e.g.:: - -	TR I R STD 8F32E1FF 0.7fffffff - -Another very useful variation is:: - -	TR STORE INTO STD <CR13's value> <address range> - -for finding out when a particular variable changes. - -An alternative way of finding the STD of a currently running process -is to do the following, ( this method is more complex but -could be quite convenient if you aren't updating the kernel much & -so your kernel structures will stay constant for a reasonable period of -time ). - -:: - -	grep task /proc/<pid>/status - -from this you should see something like:: - -	task: 0f160000 ksp: 0f161de8 pt_regs: 0f161f68 - -This now gives you a pointer to the task structure. - -Now make:: - -	CC:="s390-gcc -g" kernel/sched.s - -To get the task_struct stabinfo. - -( task_struct is defined in include/linux/sched.h ). - -Now we want to look at -task->active_mm->pgd - -on my machine the active_mm in the task structure stab is -active_mm:(4,12),672,32 - -its offset is 672/8=84=0x54 - -the pgd member in the mm_struct stab is -pgd:(4,6)=*(29,5),96,32 -so its offset is 96/8=12=0xc - -so we'll:: - -	hexdump -s 0xf160054 /dev/mem | more - -i.e. task_struct+active_mm offset -to look at the active_mm member:: - -	f160054 0fee cc60 0019 e334 0000 0000 0000 0011 - -:: - -	hexdump -s 0x0feecc6c /dev/mem | more - -i.e. active_mm+pgd offset:: - -	feecc6c 0f2c 0000 0000 0001 0000 0001 0000 0010 - -we get something like -now do:: - -	TR I R STD <pgd|0x7f> 0.7fffffff - -i.e. the 0x7f is added because the pgd only -gives the page table origin & we need to set the low bits -to the maximum possible segment table length. - -:: - -	TR I R STD 0f2c007f 0.7fffffff - -on z/Architecture you'll probably need to do:: - -	TR I R STD <pgd|0x7> 0.ffffffffffffffff - -to set the TableType to 0x1 & the Table length to 3. - - - -Tracing Program Exceptions --------------------------- -If you get a crash which says something like -illegal operation or specification exception followed by a register dump -You can restart linux & trace these using the tr prog <range or value> trace -option. - - -The most common ones you will normally be tracing for is: - -- 1=operation exception -- 2=privileged operation exception -- 4=protection exception -- 5=addressing exception -- 6=specification exception -- 10=segment translation exception -- 11=page translation exception - -The full list of these is on page 22 of the current s/390 Reference Summary. -e.g. - -tr prog 10 will trace segment translation exceptions. - -tr prog on its own will trace all program interruption codes. - -Trace Sets ----------- -On starting VM you are initially in the INITIAL trace set. -You can do a Q TR to verify this. -If you have a complex tracing situation where you wish to wait for instance -till a driver is open before you start tracing IO, but know in your -heart that you are going to have to make several runs through the code till you -have a clue whats going on. - -What you can do is:: - -	TR I PSWA <Driver open address> - -hit b to continue till breakpoint - -reach the breakpoint - -now do your:: - -	TR GOTO B -	TR IO 7c08-7c09 inst int run - -or whatever the IO channels you wish to trace are & hit b - -To got back to the initial trace set do:: - -	TR GOTO INITIAL - -& the TR I PSWA <Driver open address> will be the only active breakpoint again. - - -Tracing linux syscalls under VM -------------------------------- -Syscalls are implemented on Linux for S390 by the Supervisor call instruction -(SVC). There 256 possibilities of these as the instruction is made up of a 0xA -opcode and the second byte being the syscall number. They are traced using the -simple command:: - -	TR SVC  <Optional value or range> - -the syscalls are defined in linux/arch/s390/include/asm/unistd.h -e.g. to trace all file opens just do:: - -	TR SVC 5 ( as this is the syscall number of open ) - - -SMP Specific commands ---------------------- -To find out how many cpus you have -Q CPUS displays all the CPU's available to your virtual machine -To find the cpu that the current cpu VM debugger commands are being directed at -do Q CPU to change the current cpu VM debugger commands are being directed at -do:: - -	CPU <desired cpu no> - -On a SMP guest issue a command to all CPUs try prefixing the command with cpu -all. To issue a command to a particular cpu try cpu <cpu number> e.g.:: - -	CPU 01 TR I R 2000.3000 - -If you are running on a guest with several cpus & you have a IO related problem -& cannot follow the flow of code but you know it isn't smp related. - -from the bash prompt issue:: - -	shutdown -h now or halt. - -do a:: - -	Q CPUS - -to find out how many cpus you have detach each one of them from cp except -cpu 0 by issuing a:: - -	DETACH CPU 01-(number of cpus in configuration) - -& boot linux again. - -TR SIGP -	will trace inter processor signal processor instructions. - -DEFINE CPU 01-(number in configuration) -	will get your guests cpus back. - - -Help for displaying ascii textstrings -------------------------------------- -On the very latest VM Nucleus'es VM can now display ascii -( thanks Neale for the hint ) by doing:: - -	D TX<lowaddr>.<len> - -e.g.:: - -	D TX0.100 - -Alternatively -============= -Under older VM debuggers (I love EBDIC too) you can use following little -program which converts a command line of hex digits to ascii text. It can be -compiled under linux and you can copy the hex digits from your x3270 terminal -to your xterm if you are debugging from a linuxbox. - -This is quite useful when looking at a parameter passed in as a text string -under VM ( unless you are good at decoding ASCII in your head ). - -e.g. consider tracing an open syscall:: - -	TR SVC 5 - -We have stopped at a breakpoint:: - -	000151B0' SVC   0A05     -> 0001909A'   CC 0 - -D 20.8 to check the SVC old psw in the prefix area and see was it from userspace -(for the layout of the prefix area consult the "Fixed Storage Locations" -chapter of the s/390 Reference Summary if you have it available). - -:: - -  V00000020  070C2000 800151B2 - -The problem state bit wasn't set &  it's also too early in the boot sequence -for it to be a userspace SVC if it was we would have to temporarily switch the -psw to user space addressing so we could get at the first parameter of the open -in gpr2. - -Next do a:: - -	D G2 -	GPR  2 =  00014CB4 - -Now display what gpr2 is pointing to:: - -	D 00014CB4.20 -	V00014CB4  2F646576 2F636F6E 736F6C65 00001BF5 -	V00014CC4  FC00014C B4001001 E0001000 B8070707 - -Now copy the text till the first 00 hex ( which is the end of the string -to an xterm & do hex2ascii on it:: - -	hex2ascii 2F646576 2F636F6E 736F6C65 00 - -outputs:: - -	Decoded Hex:=/ d e v / c o n s o l e 0x00 - -We were opening the console device, - -You can compile the code below yourself for practice :-), - -:: - -  /* -   *    hex2ascii.c -   *    a useful little tool for converting a hexadecimal command line to ascii -   * -   *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) -   *    (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation. -   */ -  #include <stdio.h> - -  int main(int argc,char *argv[]) -  { -    int cnt1,cnt2,len,toggle=0; -    int startcnt=1; -    unsigned char c,hex; - -    if(argc>1&&(strcmp(argv[1],"-a")==0)) -       startcnt=2; -    printf("Decoded Hex:="); -    for(cnt1=startcnt;cnt1<argc;cnt1++) -    { -      len=strlen(argv[cnt1]); -      for(cnt2=0;cnt2<len;cnt2++) -      { -	 c=argv[cnt1][cnt2]; -	 if(c>='0'&&c<='9') -	  c=c-'0'; -	 if(c>='A'&&c<='F') -	  c=c-'A'+10; -	 if(c>='a'&&c<='f') -	  c=c-'a'+10; -	 switch(toggle) -	 { -	  case 0: -	     hex=c<<4; -	     toggle=1; -	  break; -	  case 1: -	     hex+=c; -	     if(hex<32||hex>127) -	     { -		if(startcnt==1) -		   printf("0x%02X ",(int)hex); -		else -		   printf("."); -	     } -	     else -	     { -	       printf("%c",hex); -	       if(startcnt==1) -		  printf(" "); -	     } -	     toggle=0; -	  break; -	 } -      } -    } -    printf("\n"); -  } - - - - -Stack tracing under VM ----------------------- -A basic backtrace ------------------ - -Here are the tricks I use 9 out of 10 times it works pretty well, - -When your backchain reaches a dead end --------------------------------------- -This can happen when an exception happens in the kernel and the kernel is -entered twice. If you reach the NULL pointer at the end of the back chain you -should be able to sniff further back if you follow the following tricks. -1) A kernel address should be easy to recognise since it is in -primary space & the problem state bit isn't set & also -The Hi bit of the address is set. -2) Another backchain should also be easy to recognise since it is an -address pointing to another address approximately 100 bytes or 0x70 hex -behind the current stackpointer. - - -Here is some practice. - -boot the kernel & hit PA1 at some random time - -d g to display the gprs, this should display something like:: - -  GPR  0 =  00000001  00156018  0014359C  00000000 -  GPR  4 =  00000001  001B8888  000003E0  00000000 -  GPR  8 =  00100080  00100084  00000000  000FE000 -  GPR 12 =  00010400  8001B2DC  8001B36A  000FFED8 - -Note that GPR14 is a return address but as we are real men we are going to -trace the stack. -display 0x40 bytes after the stack pointer:: - -  V000FFED8  000FFF38 8001B838 80014C8E 000FFF38 -  V000FFEE8  00000000 00000000 000003E0 00000000 -  V000FFEF8  00100080 00100084 00000000 000FE000 -  V000FFF08  00010400 8001B2DC 8001B36A 000FFED8 - - -Ah now look at whats in sp+56 (sp+0x38) this is 8001B36A our saved r14 if -you look above at our stackframe & also agrees with GPR14. - -now backchain:: - -	d 000FFF38.40 - -we now are taking the contents of SP to get our first backchain:: - -  V000FFF38  000FFFA0 00000000 00014995 00147094 -  V000FFF48  00147090 001470A0 000003E0 00000000 -  V000FFF58  00100080 00100084 00000000 001BF1D0 -  V000FFF68  00010400 800149BA 80014CA6 000FFF38 - -This displays a 2nd return address of 80014CA6 - -now do:: - -	d 000FFFA0.40 - -for our 3rd backchain:: - -  V000FFFA0  04B52002 0001107F 00000000 00000000 -  V000FFFB0  00000000 00000000 FF000000 0001107F -  V000FFFC0  00000000 00000000 00000000 00000000 -  V000FFFD0  00010400 80010802 8001085A 000FFFA0 - - -our 3rd return address is 8001085A - -as the 04B52002 looks suspiciously like rubbish it is fair to assume that the -kernel entry routines for the sake of optimisation don't set up a backchain. - -now look at System.map to see if the addresses make any sense:: - -	grep -i 0001b3 System.map - -outputs among other things:: - -	0001b304 T cpu_idle - -so 8001B36A -is cpu_idle+0x66 ( quiet the cpu is asleep, don't wake it ) - -:: - -	grep -i 00014 System.map - -produces among other things:: - -	00014a78 T start_kernel - -so 0014CA6 is start_kernel+some hex number I can't add in my head. - -:: - -	grep -i 00108 System.map - -this produces:: - -	00010800 T _stext - -so   8001085A is _stext+0x5a - -Congrats you've done your first backchain. - - - -s/390 & z/Architecture IO Overview -================================== - -I am not going to give a course in 390 IO architecture as this would take me -quite a while and I'm no expert. Instead I'll give a 390 IO architecture -summary for Dummies. If you have the s/390 principles of operation available -read this instead. If nothing else you may find a few useful keywords in here -and be able to use them on a web search engine to find more useful information. - -Unlike other bus architectures modern 390 systems do their IO using mostly -fibre optics and devices such as tapes and disks can be shared between several -mainframes. Also S390 can support up to 65536 devices while a high end PC based -system might be choking with around 64. - -Here is some of the common IO terminology: - -Subchannel: -  This is the logical number most IO commands use to talk to an IO device. There -  can be up to 0x10000 (65536) of these in a configuration, typically there are a -  few hundred. Under VM for simplicity they are allocated contiguously, however -  on the native hardware they are not. They typically stay consistent between -  boots provided no new hardware is inserted or removed. - -  Under Linux for s390 we use these as IRQ's and also when issuing an IO command -  (CLEAR SUBCHANNEL, HALT SUBCHANNEL, MODIFY SUBCHANNEL, RESUME SUBCHANNEL, -  START SUBCHANNEL, STORE SUBCHANNEL and TEST SUBCHANNEL). We use this as the ID -  of the device we wish to talk to. The most important of these instructions are -  START SUBCHANNEL (to start IO), TEST SUBCHANNEL (to check whether the IO -  completed successfully) and HALT SUBCHANNEL (to kill IO). A subchannel can have -  up to 8 channel paths to a device, this offers redundancy if one is not -  available. - -Device Number: -  This number remains static and is closely tied to the hardware. There are 65536 -  of these, made up of a CHPID (Channel Path ID, the most significant 8 bits) and -  another lsb 8 bits. These remain static even if more devices are inserted or -  removed from the hardware. There is a 1 to 1 mapping between subchannels and -  device numbers, provided devices aren't inserted or removed. - -Channel Control Words: -  CCWs are linked lists of instructions initially pointed to by an operation -  request block (ORB), which is initially given to Start Subchannel (SSCH) -  command along with the subchannel number for the IO subsystem to process -  while the CPU continues executing normal code. -  CCWs come in two flavours, Format 0 (24 bit for backward compatibility) and -  Format 1 (31 bit). These are typically used to issue read and write (and many -  other) instructions. They consist of a length field and an absolute address -  field. - -  Each IO typically gets 1 or 2 interrupts, one for channel end (primary status) -  when the channel is idle, and the second for device end (secondary status). -  Sometimes you get both concurrently. You check how the IO went on by issuing a -  TEST SUBCHANNEL at each interrupt, from which you receive an Interruption -  response block (IRB). If you get channel and device end status in the IRB -  without channel checks etc. your IO probably went okay. If you didn't you -  probably need to examine the IRB, extended status word etc. -  If an error occurs, more sophisticated control units have a facility known as -  concurrent sense. This means that if an error occurs Extended sense information -  will be presented in the Extended status word in the IRB. If not you have to -  issue a subsequent SENSE CCW command after the test subchannel. - - -TPI (Test pending interrupt) can also be used for polled IO, but in -multitasking multiprocessor systems it isn't recommended except for -checking special cases (i.e. non looping checks for pending IO etc.). - -Store Subchannel and Modify Subchannel can be used to examine and modify -operating characteristics of a subchannel (e.g. channel paths). - -Other IO related Terms: - -Sysplex: -  S390's Clustering Technology -QDIO: -  S390's new high speed IO architecture to support devices such as gigabit -  ethernet, this architecture is also designed to be forward compatible with -  upcoming 64 bit machines. - - -General Concepts ----------------- - -Input Output Processors (IOP's) are responsible for communicating between -the mainframe CPU's & the channel & relieve the mainframe CPU's from the -burden of communicating with IO devices directly, this allows the CPU's to -concentrate on data processing. - -IOP's can use one or more links ( known as channel paths ) to talk to each -IO device. It first checks for path availability & chooses an available one, -then starts ( & sometimes terminates IO ). -There are two types of channel path: ESCON & the Parallel IO interface. - -IO devices are attached to control units, control units provide the -logic to interface the channel paths & channel path IO protocols to -the IO devices, they can be integrated with the devices or housed separately -& often talk to several similar devices ( typical examples would be raid -controllers or a control unit which connects to 1000 3270 terminals ):: - - -      +---------------------------------------------------------------+ -      | +-----+ +-----+ +-----+ +-----+  +----------+  +----------+   | -      | | CPU | | CPU | | CPU | | CPU |  |  Main    |  | Expanded |   | -      | |     | |     | |     | |     |  |  Memory  |  |  Storage |   | -      | +-----+ +-----+ +-----+ +-----+  +----------+  +----------+   | -      |---------------------------------------------------------------+ -      |   IOP        |      IOP      |       IOP                      | -      |--------------------------------------------------------------- -      | C | C | C | C | C | C | C | C | C | C | C | C | C | C | C | C | -      ---------------------------------------------------------------- -	   ||                                              || -	   ||  Bus & Tag Channel Path                      || ESCON -	   ||  ======================                      || Channel -	   ||  ||                  ||                      || Path -      +----------+               +----------+         +----------+ -      |          |               |          |         |          | -      |    CU    |               |    CU    |         |    CU    | -      |          |               |          |         |          | -      +----------+               +----------+         +----------+ -	 |      |                     |                |       | -  +----------+ +----------+      +----------+   +----------+ +----------+ -  |I/O Device| |I/O Device|      |I/O Device|   |I/O Device| |I/O Device| -  +----------+ +----------+      +----------+   +----------+ +----------+ -    CPU = Central Processing Unit -    C = Channel -    IOP = IP Processor -    CU = Control Unit - -The 390 IO systems come in 2 flavours the current 390 machines support both - -The Older 360 & 370 Interface,sometimes called the Parallel I/O interface, -sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers -Interface (OEMI). - -This byte wide Parallel channel path/bus has parity & data on the "Bus" cable -and control lines on the "Tag" cable. These can operate in byte multiplex mode -for sharing between several slow devices or burst mode and monopolize the -channel for the whole burst. Up to 256 devices can be addressed on one of these -cables. These cables are about one inch in diameter. The maximum unextended -length supported by these cables is 125 Meters but this can be extended up to -2km with a fibre optic channel extended such as a 3044. The maximum burst speed -supported is 4.5 megabytes per second. However, some really old processors -support only transfer rates of 3.0, 2.0 & 1.0 MB/sec. -One of these paths can be daisy chained to up to 8 control units. - - -ESCON if fibre optic it is also called FICON -Was introduced by IBM in 1990. Has 2 fibre optic cables and uses either leds or -lasers for communication at a signaling rate of up to 200 megabits/sec. As -10bits are transferred for every 8 bits info this drops to 160 megabits/sec -and to 18.6 Megabytes/sec once control info and CRC are added. ESCON only -operates in burst mode. - -ESCONs typical max cable length is 3km for the led version and 20km for the -laser version known as XDF (extended distance facility). This can be further -extended by using an ESCON director which triples the above mentioned ranges. -Unlike Bus & Tag as ESCON is serial it uses a packet switching architecture, -the standard Bus & Tag control protocol is however present within the packets. -Up to 256 devices can be attached to each control unit that uses one of these -interfaces. - -Common 390 Devices include: -Network adapters typically OSA2,3172's,2116's & OSA-E gigabit ethernet adapters, -Consoles 3270 & 3215 (a teletype emulated under linux for a line mode console). -DASD's direct access storage devices ( otherwise known as hard disks ). -Tape Drives. -CTC ( Channel to Channel Adapters ), -ESCON or Parallel Cables used as a very high speed serial link -between 2 machines. - - -Debugging IO on s/390 & z/Architecture under VM -=============================================== - -Now we are ready to go on with IO tracing commands under VM - -A few self explanatory queries:: - -	Q OSA -	Q CTC -	Q DISK ( This command is CMS specific ) -	Q DASD - -Q OSA on my machine returns:: - -	OSA  7C08 ON OSA   7C08 SUBCHANNEL = 0000 -	OSA  7C09 ON OSA   7C09 SUBCHANNEL = 0001 -	OSA  7C14 ON OSA   7C14 SUBCHANNEL = 0002 -	OSA  7C15 ON OSA   7C15 SUBCHANNEL = 0003 - -If you have a guest with certain privileges you may be able to see devices -which don't belong to you. To avoid this, add the option V. -e.g.:: - -	Q V OSA - -Now using the device numbers returned by this command we will -Trace the io starting up on the first device 7c08 & 7c09 -In our simplest case we can trace the -start subchannels -like TR SSCH 7C08-7C09 -or the halt subchannels -or TR HSCH 7C08-7C09 -MSCH's ,STSCH's I think you can guess the rest - -A good trick is tracing all the IO's and CCWS and spooling them into the reader -of another VM guest so he can ftp the logfile back to his own machine. I'll do -a small bit of this and give you a look at the output. - -1) Spool stdout to VM reader:: - -	SP PRT TO (another vm guest ) or * for the local vm guest - -2) Fill the reader with the trace:: - -	TR IO 7c08-7c09 INST INT CCW PRT RUN - -3) Start up linux:: - -	i 00c -4) Finish the trace:: - -	TR END - -5) close the reader:: - -	C PRT - -6) list reader contents:: - -	RDRLIST - -7) copy it to linux4's minidisk:: - -	RECEIVE / LOG TXT A1 ( replace - -8) -filel & press F11 to look at it -You should see something like:: - -  00020942' SSCH  B2334000    0048813C    CC 0    SCH 0000    DEV 7C08 -	    CPA 000FFDF0   PARM 00E2C9C4    KEY 0  FPI C0  LPM 80 -	    CCW    000FFDF0  E4200100 00487FE8   0000  E4240100 ........ -	    IDAL                                      43D8AFE8 -	    IDAL                                      0FB76000 -  00020B0A'   I/O DEV 7C08 -> 000197BC'   SCH 0000   PARM 00E2C9C4 -  00021628' TSCH  B2354000 >> 00488164    CC 0    SCH 0000    DEV 7C08 -	    CCWA 000FFDF8   DEV STS 0C  SCH STS 00  CNT 00EC -	     KEY 0   FPI C0  CC 0   CTLS 4007 -  00022238' STSCH B2344000 >> 00488108    CC 0    SCH 0000    DEV 7C08 - -If you don't like messing up your readed ( because you possibly booted from it ) -you can alternatively spool it to another readers guest. - - -Other common VM device related commands ---------------------------------------------- -These commands are listed only because they have -been of use to me in the past & may be of use to -you too. For more complete info on each of the commands -use type HELP <command> from CMS. - -detaching devices:: - -	DET <devno range> -	ATT <devno range> <guest> - -attach a device to guest * for your own guest - -READY <devno> -	cause VM to issue a fake interrupt. - -The VARY command is normally only available to VM administrators:: - -	VARY ON PATH <path> TO <devno range> -	VARY OFF PATH <PATH> FROM <devno range> - -This is used to switch on or off channel paths to devices. - -Q CHPID <channel path ID> -   This displays state of devices using this channel path - -D SCHIB <subchannel> -   This displays the subchannel information SCHIB block for the device. -   this I believe is also only available to administrators. - -DEFINE CTC <devno> -  defines a virtual CTC channel to channel connection -  2 need to be defined on each guest for the CTC driver to use. - -COUPLE  devno userid remote devno -  Joins a local virtual device to a remote virtual device -  ( commonly used for the CTC driver ). - -Building a VM ramdisk under CMS which linux can use:: - -	def vfb-<blocksize> <subchannel> <number blocks> - -blocksize is commonly 4096 for linux. - -Formatting it:: - -	format <subchannel> <driver letter e.g. x> (blksize <blocksize> - -Sharing a disk between multiple guests:: - -	LINK userid devno1 devno2 mode password - - - -GDB on S390 -=========== -N.B. if compiling for debugging gdb works better without optimisation -( see Compiling programs for debugging ) - -invocation ----------- -gdb <victim program> <optional corefile> - -Online help ------------ -help: gives help on commands - -e.g.:: - -	help -	help display - -Note gdb's online help is very good use it. - - -Assembly --------- -info registers: -  displays registers other than floating point. - -info all-registers: -  displays floating points as well. - -disassemble: -  disassembles - -e.g.:: - -	disassemble without parameters will disassemble the current function -	disassemble $pc $pc+10 - -Viewing & modifying variables ------------------------------ -print or p: -  displays variable or register - -e.g. p/x $sp will display the stack pointer - -display: -  prints variable or register each time program stops - -e.g.:: - -	display/x $pc will display the program counter -	display argc - -undisplay: -  undo's display's - -info breakpoints: -  shows all current breakpoints - -info stack: -  shows stack back trace (if this doesn't work too well, I'll show -  you the stacktrace by hand below). - -info locals: -  displays local variables. - -info args: -  display current procedure arguments. - -set args: -  will set argc & argv each time the victim program is invoked - -e.g.:: - -	set <variable>=value -	set argc=100 -	set $pc=0 - - - -Modifying execution -------------------- -step: -  steps n lines of sourcecode - -step -  steps 1 line. - -step 100 -  steps 100 lines of code. - -next: -	like step except this will not step into subroutines - -stepi: -	steps a single machine code instruction. - -e.g.:: - -	stepi 100 - -nexti: -	steps a single machine code instruction but will not step into -	subroutines. - -finish: -	will run until exit of the current routine - -run: -	(re)starts a program - -cont: -	continues a program - -quit: -	exits gdb. - - -breakpoints ------------- - -break -  sets a breakpoint - -e.g.:: - -	break main -	break *$pc -	break *0x400618 - -Here's a really useful one for large programs - -rbr -	Set a breakpoint for all functions matching REGEXP - -e.g.:: - -	rbr 390 - -will set a breakpoint with all functions with 390 in their name. - -info breakpoints -	lists all breakpoints - -delete: -	delete breakpoint by number or delete them all - -e.g. - -delete 1 -	will delete the first breakpoint - - -delete -	will delete them all - -watch: -	This will set a watchpoint ( usually hardware assisted ), - -This will watch a variable till it changes - -e.g. - -watch cnt -	will watch the variable cnt till it changes. - -As an aside unfortunately gdb's, architecture independent watchpoint code -is inconsistent & not very good, watchpoints usually work but not always. - -info watchpoints: -	Display currently active watchpoints - -condition: ( another useful one ) -	Specify breakpoint number N to break only if COND is true. - -Usage is `condition N COND`, where N is an integer and COND is an -expression to be evaluated whenever breakpoint N is reached. - - - -User defined functions/macros ------------------------------ -define: ( Note this is very very useful,simple & powerful ) - -usage define <name> <list of commands> end - -examples which you should consider putting into .gdbinit in your home -directory:: - -	define d -	stepi -	disassemble $pc $pc+10 -	end -	define e -	nexti -	disassemble $pc $pc+10 -	end - - -Other hard to classify stuff ----------------------------- -signal n: -   sends the victim program a signal. - -e.g. `signal 3` will send a SIGQUIT. - -info signals: -	what gdb does when the victim receives certain signals. - -list: - -e.g.: - -list -	lists current function source -list 1,10 -	list first 10 lines of current file. - -list test.c:1,10 - - -directory: -  Adds directories to be searched for source if gdb cannot find the source. -  (note it is a bit sensitive about slashes) - -e.g. To add the root of the filesystem to the searchpath do:: - -	directory // - - -call <function> -This calls a function in the victim program, this is pretty powerful -e.g. -(gdb) call printf("hello world") -outputs: -$1 = 11 - -You might now be thinking that the line above didn't work, something extra had -to be done. -(gdb) call fflush(stdout) -hello world$2 = 0 -As an aside the debugger also calls malloc & free under the hood -to make space for the "hello world" string. - - - -hints ------ -1) command completion works just like bash -   ( if you are a bad typist like me this really helps ) - -e.g. hit br <TAB> & cursor up & down :-). - -2) if you have a debugging problem that takes a few steps to recreate -put the steps into a file called .gdbinit in your current working directory -if you have defined a few extra useful user defined commands put these in -your home directory & they will be read each time gdb is launched. - -A typical .gdbinit file might be.:: - -	break main -	run -	break runtime_exception -	cont - - -stack chaining in gdb by hand ------------------------------ -This is done using a the same trick described for VM:: - -	p/x (*($sp+56))&0x7fffffff - -get the first backchain. - -For z/Architecture -Replace 56 with 112 & ignore the &0x7fffffff -in the macros below & do nasty casts to longs like the following -as gdb unfortunately deals with printed arguments as ints which -messes up everything. - -i.e. here is a 3rd backchain dereference:: - -	p/x *(long *)(***(long ***)$sp+112) - - -this outputs:: - -	$5 = 0x528f18 - -on my machine. - -Now you can use:: - -	info symbol (*($sp+56))&0x7fffffff - -you might see something like:: - -	rl_getc + 36 in section .text - -telling you what is located at address 0x528f18 -Now do:: - -	p/x (*(*$sp+56))&0x7fffffff - -This outputs:: - -	$6 = 0x528ed0 - -Now do:: - -	info symbol (*(*$sp+56))&0x7fffffff -	rl_read_key + 180 in section .text - -now do:: - -	p/x (*(**$sp+56))&0x7fffffff - -& so on. - -Disassembling instructions without debug info ---------------------------------------------- -gdb typically complains if there is a lack of debugging -symbols in the disassemble command with -"No function contains specified address." To get around -this do:: - -	x/<number lines to disassemble>xi <address> - -e.g.:: - -	x/20xi 0x400730 - - - -Note: -  Remember gdb has history just like bash you don't need to retype the -  whole line just use the up & down arrows. - - - -For more info -------------- -From your linuxbox do:: - -	man gdb - -or:: - -	info gdb. - -core dumps ----------- - -What a core dump ? -^^^^^^^^^^^^^^^^^^ - -A core dump is a file generated by the kernel (if allowed) which contains the -registers and all active pages of the program which has crashed. - -From this file gdb will allow you to look at the registers, stack trace and -memory of the program as if it just crashed on your system. It is usually -called core and created in the current working directory. - -This is very useful in that a customer can mail a core dump to a technical -support department and the technical support department can reconstruct what -happened. Provided they have an identical copy of this program with debugging -symbols compiled in and the source base of this build is available. - -In short it is far more useful than something like a crash log could ever hope -to be. - -Why have I never seen one ? -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Probably because you haven't used the command:: - -	ulimit -c unlimited in bash - -to allow core dumps, now do:: - -	ulimit -a - -to verify that the limit was accepted. - -A sample core dump -   To create this I'm going to do:: - -	ulimit -c unlimited -	gdb - -to launch gdb (my victim app. ) now be bad & do the following from another -telnet/xterm session to the same machine:: - -	ps -aux | grep gdb -	kill -SIGSEGV <gdb's pid> - -or alternatively use `killall -SIGSEGV gdb` if you have the killall command. - -Now look at the core dump:: - -	./gdb core - -Displays the following:: - -  GNU gdb 4.18 -  Copyright 1998 Free Software Foundation, Inc. -  GDB is free software, covered by the GNU General Public License, and you are -  welcome to change it and/or distribute copies of it under certain conditions. -  Type "show copying" to see the conditions. -  There is absolutely no warranty for GDB.  Type "show warranty" for details. -  This GDB was configured as "s390-ibm-linux"... -  Core was generated by `./gdb'. -  Program terminated with signal 11, Segmentation fault. -  Reading symbols from /usr/lib/libncurses.so.4...done. -  Reading symbols from /lib/libm.so.6...done. -  Reading symbols from /lib/libc.so.6...done. -  Reading symbols from /lib/ld-linux.so.2...done. -  #0  0x40126d1a in read () from /lib/libc.so.6 -  Setting up the environment for debugging gdb. -  Breakpoint 1 at 0x4dc6f8: file utils.c, line 471. -  Breakpoint 2 at 0x4d87a4: file top.c, line 2609. -  (top-gdb) info stack -  #0  0x40126d1a in read () from /lib/libc.so.6 -  #1  0x528f26 in rl_getc (stream=0x7ffffde8) at input.c:402 -  #2  0x528ed0 in rl_read_key () at input.c:381 -  #3  0x5167e6 in readline_internal_char () at readline.c:454 -  #4  0x5168ee in readline_internal_charloop () at readline.c:507 -  #5  0x51692c in readline_internal () at readline.c:521 -  #6  0x5164fe in readline (prompt=0x7ffff810) -      at readline.c:349 -  #7  0x4d7a8a in command_line_input (prompt=0x564420 "(gdb) ", repeat=1, -      annotation_suffix=0x4d6b44 "prompt") at top.c:2091 -  #8  0x4d6cf0 in command_loop () at top.c:1345 -  #9  0x4e25bc in main (argc=1, argv=0x7ffffdf4) at main.c:635 - - -LDD -=== -This is a program which lists the shared libraries which a library needs, -Note you also get the relocations of the shared library text segments which -help when using objdump --source. - -e.g.:: - -	ldd ./gdb - -outputs:: - -  libncurses.so.4 => /usr/lib/libncurses.so.4 (0x40018000) -  libm.so.6 => /lib/libm.so.6 (0x4005e000) -  libc.so.6 => /lib/libc.so.6 (0x40084000) -  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) - - -Debugging shared libraries -========================== -Most programs use shared libraries, however it can be very painful -when you single step instruction into a function like printf for the -first time & you end up in functions like _dl_runtime_resolve this is -the ld.so doing lazy binding, lazy binding is a concept in ELF where -shared library functions are not loaded into memory unless they are -actually used, great for saving memory but a pain to debug. - -To get around this either relink the program -static or exit gdb type -export LD_BIND_NOW=true this will stop lazy binding & restart the gdb'ing -the program in question. - - - -Debugging modules -================= -As modules are dynamically loaded into the kernel their address can be -anywhere to get around this use the -m option with insmod to emit a load -map which can be piped into a file if required. - -The proc file system -==================== -What is it ?. -It is a filesystem created by the kernel with files which are created on demand -by the kernel if read, or can be used to modify kernel parameters, -it is a powerful concept. - -e.g.:: - -	cat /proc/sys/net/ipv4/ip_forward - -On my machine outputs:: - -	0 - -telling me ip_forwarding is not on to switch it on I can do:: - -	echo 1 >  /proc/sys/net/ipv4/ip_forward - -cat it again:: - -	cat /proc/sys/net/ipv4/ip_forward - -On my machine now outputs:: - -	1 - -IP forwarding is on. - -There is a lot of useful info in here best found by going in and having a look -around, so I'll take you through some entries I consider important. - -All the processes running on the machine have their own entry defined by -/proc/<pid> - -So lets have a look at the init process:: - -	cd /proc/1 -	cat cmdline - -emits:: - -	init [2] - -:: - -	cd /proc/1/fd - -This contains numerical entries of all the open files, -some of these you can cat e.g. stdout (2):: - -	cat /proc/29/maps - -on my machine emits:: - -  00400000-00478000 r-xp 00000000 5f:00 4103       /bin/bash -  00478000-0047e000 rw-p 00077000 5f:00 4103       /bin/bash -  0047e000-00492000 rwxp 00000000 00:00 0 -  40000000-40015000 r-xp 00000000 5f:00 14382      /lib/ld-2.1.2.so -  40015000-40016000 rw-p 00014000 5f:00 14382      /lib/ld-2.1.2.so -  40016000-40017000 rwxp 00000000 00:00 0 -  40017000-40018000 rw-p 00000000 00:00 0 -  40018000-4001b000 r-xp 00000000 5f:00 14435      /lib/libtermcap.so.2.0.8 -  4001b000-4001c000 rw-p 00002000 5f:00 14435      /lib/libtermcap.so.2.0.8 -  4001c000-4010d000 r-xp 00000000 5f:00 14387      /lib/libc-2.1.2.so -  4010d000-40111000 rw-p 000f0000 5f:00 14387      /lib/libc-2.1.2.so -  40111000-40114000 rw-p 00000000 00:00 0 -  40114000-4011e000 r-xp 00000000 5f:00 14408      /lib/libnss_files-2.1.2.so -  4011e000-4011f000 rw-p 00009000 5f:00 14408      /lib/libnss_files-2.1.2.so -  7fffd000-80000000 rwxp ffffe000 00:00 0 - - -Showing us the shared libraries init uses where they are in memory -& memory access permissions for each virtual memory area. - -/proc/1/cwd is a softlink to the current working directory. - -/proc/1/root is the root of the filesystem for this process. - -/proc/1/mem is the current running processes memory which you -can read & write to like a file. - -strace uses this sometimes as it is a bit faster than the -rather inefficient ptrace interface for peeking at DATA. - -:: - -  cat status - -  Name:   init -  State:  S (sleeping) -  Pid:    1 -  PPid:   0 -  Uid:    0       0       0       0 -  Gid:    0       0       0       0 -  Groups: -  VmSize:      408 kB -  VmLck:         0 kB -  VmRSS:       208 kB -  VmData:       24 kB -  VmStk:         8 kB -  VmExe:       368 kB -  VmLib:         0 kB -  SigPnd: 0000000000000000 -  SigBlk: 0000000000000000 -  SigIgn: 7fffffffd7f0d8fc -  SigCgt: 00000000280b2603 -  CapInh: 00000000fffffeff -  CapPrm: 00000000ffffffff -  CapEff: 00000000fffffeff - -  User PSW:    070de000 80414146 -  task: 004b6000 tss: 004b62d8 ksp: 004b7ca8 pt_regs: 004b7f68 -  User GPRS: -  00000400  00000000  0000000b  7ffffa90 -  00000000  00000000  00000000  0045d9f4 -  0045cafc  7ffffa90  7fffff18  0045cb08 -  00010400  804039e8  80403af8  7ffff8b0 -  User ACRS: -  00000000  00000000  00000000  00000000 -  00000001  00000000  00000000  00000000 -  00000000  00000000  00000000  00000000 -  00000000  00000000  00000000  00000000 -  Kernel BackChain  CallChain    BackChain  CallChain -	 004b7ca8   8002bd0c     004b7d18   8002b92c -	 004b7db8   8005cd50     004b7e38   8005d12a -	 004b7f08   80019114 - -Showing among other things memory usage & status of some signals & -the processes'es registers from the kernel task_structure -as well as a backchain which may be useful if a process crashes -in the kernel for some unknown reason. - -Some driver debugging techniques -================================ -debug feature -------------- -Some of our drivers now support a "debug feature" in -/proc/s390dbf see s390dbf.txt in the linux/Documentation directory -for more info. - -e.g. -to switch on the lcs "debug feature":: - -	echo 5 > /proc/s390dbf/lcs/level - -& then after the error occurred:: - -	cat /proc/s390dbf/lcs/sprintf >/logfile - -the logfile now contains some information which may help -tech support resolve a problem in the field. - - - -high level debugging network drivers ------------------------------------- -ifconfig is a quite useful command -it gives the current state of network drivers. - -If you suspect your network device driver is dead -one way to check is type:: - -	ifconfig <network device> - -e.g. tr0 - -You should see something like:: - -	ifconfig tr0 -	tr0      Link encap:16/4 Mbps Token Ring (New)  HWaddr 00:04:AC:20:8E:48 -		inet addr:9.164.185.132  Bcast:9.164.191.255  Mask:255.255.224.0 -		UP BROADCAST RUNNING MULTICAST  MTU:2000  Metric:1 -		RX packets:246134 errors:0 dropped:0 overruns:0 frame:0 -		TX packets:5 errors:0 dropped:0 overruns:0 carrier:0 -		collisions:0 txqueuelen:100 - -if the device doesn't say up -try:: - -	/etc/rc.d/init.d/network start - -( this starts the network stack & hopefully calls ifconfig tr0 up ). -ifconfig looks at the output of /proc/net/dev and presents it in a more -presentable form. - -Now ping the device from a machine in the same subnet. - -if the RX packets count & TX packets counts don't increment you probably -have problems. - -next:: - -	cat /proc/net/arp - -Do you see any hardware addresses in the cache if not you may have problems. -Next try:: - -	ping -c 5 <broadcast_addr> - -i.e. the Bcast field above in the output of -ifconfig. Do you see any replies from machines other than the local machine -if not you may have problems. also if the TX packets count in ifconfig -hasn't incremented either you have serious problems in your driver -(e.g. the txbusy field of the network device being stuck on ) -or you may have multiple network devices connected. - - -chandev -------- -There is a new device layer for channel devices, some -drivers e.g. lcs are registered with this layer. - -If the device uses the channel device layer you'll be -able to find what interrupts it uses & the current state -of the device. - -See the manpage chandev.8 &type cat /proc/chandev for more info. - - -SysRq -===== -This is now supported by linux for s/390 & z/Architecture. - -To enable it do compile the kernel with:: - -	Kernel Hacking -> Magic SysRq Key Enabled - -Then:: - -	echo "1" > /proc/sys/kernel/sysrq - -also type:: - -	echo "8" >/proc/sys/kernel/printk - -To make printk output go to console. - -On 390 all commands are prefixed with:: - -	^- - -e.g.:: - -	^-t will show tasks. -	^-? or some unknown command will display help. - -The sysrq key reading is very picky ( I have to type the keys in an -xterm session & paste them  into the x3270 console ) -& it may be wise to predefine the keys as described in the VM hints above - -This is particularly useful for syncing disks unmounting & rebooting -if the machine gets partially hung. - -Read Documentation/admin-guide/sysrq.rst for more info - -References: -=========== -- Enterprise Systems Architecture Reference Summary -- Enterprise Systems Architecture Principles of Operation -- Hartmut Penners s390 stack frame sheet. -- IBM Mainframe Channel Attachment a technology brief from a CISCO webpage -- Various bits of man & info pages of Linux. -- Linux & GDB source. -- Various info & man pages. -- CMS Help on tracing commands. -- Linux for s/390 Elf Application Binary Interface -- Linux for z/Series Elf Application Binary Interface ( Both Highly Recommended ) -- z/Architecture Principles of Operation SA22-7832-00 -- Enterprise Systems Architecture/390 Reference Summary SA22-7209-01 & the -- Enterprise Systems Architecture/390 Principles of Operation SA22-7201-05 - -Special Thanks -============== -Special thanks to Neale Ferguson who maintains a much -prettier HTML version of this page at -http://linuxvm.org/penguinvm/ -Bob Grainger Stefan Bader & others for reporting bugs diff --git a/Documentation/s390/index.rst b/Documentation/s390/index.rst index f8c01cb7fa37..f7af2061e406 100644 --- a/Documentation/s390/index.rst +++ b/Documentation/s390/index.rst @@ -7,7 +7,6 @@ s390 Architecture      cds      3270 -    debugging390      driver-model      monreader      qeth |