⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debugging390.txt

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 TXT
📖 第 1 页 / 共 5 页
字号:
            *        ( 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 variableto point to the current running process & can retrieve it with the followingvery 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 dosen'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 ofeach function, it usually is fairly consistent & similar from function to function & if you know its layout you can probalbymake some headway in finding the ultimate cause of a problemafter 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 thes/390 & z/Architecture stack layouts as the z/Architecture stack layout didn't haveto maintain compatibility with older linkage formats.Glossary:---------alloca:This is a built in compiler function for runtime allocationof extra space on the callers stack which is obviously freedup on function exit ( e.g. the caller may choose to allocate nothingof a buffer of 4k if required for temporary purposes ), it generates very efficent 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 aframed functions ( see frameless function ) prologue got by deferencing the address of the current stack pointer, i.e. got by accessing the 32 bit value at the stack pointerscurrent location.base-pointer:This is a pointer to the back of the literal pool whichis an area just behind each procedure used to store constantsin 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-functionA 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 functions4) 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-bindingELF shared libraries are typically only loaded when routines in the sharedlibrary are actually first called at runtime. This is lazy binding.procedure-linkage-tableThis is a table found from the GOT which contains pointers to routinesin 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 theparameters for the callee's cannot all be put in registers, the samearea 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 followsRoutine Descriptor offset 0=Pointer to FunctionRoutine Descriptor offset 4=Pointer to Table of ContentsThe table of contents/TOC is roughly equivalent to a GOT pointer.& it means that shared libraries etc. can be shared between severalenvironments 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 itis 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-clobberedr1	 used by syscalls/assembly                  call-clobberedr2       argument 0 / return value 0                call-clobberedr3       argument 1 / return value 1 (if long long) call-clobberedr4       argument 2                                 call-clobberedr5       argument 3                                 call-clobberedr6	 argument 5                                 savedr7       pointer-to arguments 5 to ...              saved      r8       this & that                                savedr9       this & that                                savedr10      static-chain ( if nested function )        savedr11      frame-pointer ( if function used alloca )  savedr12      got-pointer                                savedr13      base-pointer                               savedr14      return-address                             savedr15      stack-pointer                              savedf0       argument 0 / return value ( float/double ) call-clobberedf2       argument 1                                 call-clobberedf4       z/Architecture argument 2                  savedf6       z/Architecture argument 3                  savedThe remaining floating pointsf1,f3,f5 f7-f15 are call-clobbered.Notes:------1) The only requirement is that registers which are usedby the callee are saved, e.g. the compiler is perfectlycapible of using r11 for purposes other than a frame aframe 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 morehairy owing to it having to move these parameters to the stack toget va_start, va_arg & va_end to work.3) Access registers are currently unused by gcc but are used inthe kernel. Possibilities exist to use them at the moment fortemporary storage but it isn't recommended.4) Only 4 of the floating point registers are used forparameter 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 theolder 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 argsarea if crossing this boundary.6) Floating point parameters are mixed with outgoing argson 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/ArchitectureStack Frame Layout------------------s/390     z/Architecture0         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 area20        40            scratch area24        48            saved r6 of caller function28        56            saved r7 of caller function32        64            saved r8 of caller function36        72            saved r9 of caller function40        80            saved r10 of caller function44        88            saved r11 of caller function48        96            saved r12 of caller function52        104           saved r13 of caller function56        112           saved r14 of caller function60        120           saved r15 of caller function64        128           saved f4 of caller function72        132           saved f6 of caller function80                      undefined96        160           outgoing args passed from caller to callee96+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-chainA 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 isn't used( :-( ).2) This is a frameless function & no stack is bought.3) The compiler was clever enough to recognise that it could return thevalue 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 nowwe are branching to the next address & the address new program counter isin 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 pool0040037c 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 0xffffffecmain(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 thestack backchain in optimised code as this also causes pipeline stalls, youhave been warned.64 bit z/Architecture code disassembly--------------------------------------If you understand the stuff above you'll understand the stuffbelow too so I'll avoid repeating myself & just say that some of the instructions have g's on the end of them to indicatethey are 64 bit & the stack offsets are a bigger, the only other difference you'll find between 32 & 64 bit is thatwe 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -