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

📄 readme-interworking

📁 linux下的gcc编译器
💻
📖 第 1 页 / 共 2 页
字号:
==============================================When -mcallee-super-interworking is specified on the command line theThumb compiler behaves as if every externally visible function that itcompiles has had the (interfacearm) attribute specified for it.  Whatthis attribute does is to put a special, ARM mode header onto thefunction which forces a switch into Thumb mode:  without __attribute__((interfacearm)):		.code 16		.thumb_func	function:		... start of function ...  with __attribute__((interfacearm)):		.code 32	function:		orr	r12, pc, #1		bx	r12		.code 16                .thumb_func        .real_start_of_function:		... start of function ...Note that since the function now expects to be entered in ARM mode, itno longer has the .thumb_func pseudo op specified for its name.Instead the pseudo op is attached to a new label .real_start_of_<name>(where <name> is the name of the function) which indicates the startof the Thumb code.  This does have the interesting side effect in thatif this function is now called from a Thumb mode piece of codeoutsside of the current file, the linker will generate a calling stubto switch from Thumb mode into ARM mode, and then this is immediatelyoverridden by the function's header which switches back into Thumbmode. In addition the (interfacearm) attribute also forces the function toreturn by using the BX instruction, even if has not been compiled withthe -mthumb-interwork command line flag, so that the correct mode willbe restored upon exit from the function.8. Some examples================   Given these two test files:             int arm (void) { return 1 + thumb (); }             int thumb (void) { return 2 + arm (); }   The following pieces of assembler are produced by the ARM and Thumbversion of GCC depending upon the command line options used:   `-O2':             .code 32                               .code 16             .global _arm                           .global _thumb                                                    .thumb_func     _arm:                                    _thumb:             mov     ip, sp             stmfd   sp!, {fp, ip, lr, pc}          push    {lr}             sub     fp, ip, #4             bl      _thumb                          bl      _arm             add     r0, r0, #1                      add     r0, r0, #2             ldmea   fp, {fp, sp, pc}                pop     {pc}   Note how the functions return without using the BX instruction.  Ifthese files were assembled and linked together they would fail to workbecause they do not change mode when returning to their caller.   `-O2 -mthumb-interwork':             .code 32                               .code 16             .global _arm                           .global _thumb                                                    .thumb_func     _arm:                                    _thumb:             mov     ip, sp             stmfd   sp!, {fp, ip, lr, pc}          push    {lr}             sub     fp, ip, #4             bl      _thumb                         bl       _arm             add     r0, r0, #1                     add      r0, r0, #2             ldmea   fp, {fp, sp, lr}               pop      {r1}             bx      lr                             bx       r1   Now the functions use BX to return their caller.  They have grown by4 and 2 bytes respectively, but they can now successfully be linkedtogether and be expect to work.  The linker will replace thedestinations of the two BL instructions with the addresses of callingstubs which convert to the correct mode before jumping to the calledfunction.   `-O2 -mcallee-super-interworking':             .code 32                               .code 32             .global _arm                           .global _thumb     _arm:                                    _thumb:                                                    orr      r12, pc, #1                                                    bx       r12             mov     ip, sp                         .code 16             stmfd   sp!, {fp, ip, lr, pc}          push     {lr}             sub     fp, ip, #4             bl      _thumb                         bl       _arm             add     r0, r0, #1                     add      r0, r0, #2             ldmea   fp, {fp, sp, lr}               pop      {r1}             bx      lr                             bx       r1   The thumb function now has an ARM encoded prologue, and it no longerhas the `.thumb-func' pseudo op attached to it.  The linker will notgenerate a calling stub for the call from arm() to thumb(), but it willstill have to generate a stub for the call from thumb() to arm().  Alsonote how specifying `--mcallee-super-interworking' automaticallyimplies `-mthumb-interworking'.9. Some Function Pointer Examples=================================   Given this test file:     	int func (void) { return 1; }          	int call (int (* ptr)(void)) { return ptr (); }   The following varying pieces of assembler are produced by the Thumbversion of GCC depending upon the command line options used:   `-O2':     		.code	16     		.globl	_func     		.thumb_func     	_func:     		mov	r0, #1     		bx	lr          		.globl	_call     		.thumb_func     	_call:     		push	{lr}     		bl	__call_via_r0     		pop	{pc}   Note how the two functions have different exit sequences.  Inparticular call() uses pop {pc} to return, which would not work if thecaller was in ARM mode.  func() however, uses the BX instruction, eventhough `-mthumb-interwork' has not been specified, as this is the mostefficient way to exit a function when the return address is held in thelink register.   `-O2 -mthumb-interwork':     		.code	16     		.globl	_func     		.thumb_func     	_func:     		mov	r0, #1     		bx	lr          		.globl	_call     		.thumb_func     	_call:     		push	{lr}     		bl	__call_via_r0     		pop	{r1}     		bx	r1   This time both functions return by using the BX instruction.  Thismeans that call() is now two bytes longer and several cycles slowerthan the previous version.   `-O2 -mcaller-super-interworking':     		.code	16     		.globl	_func     		.thumb_func     	_func:     		mov	r0, #1     		bx	lr          		.globl	_call     		.thumb_func     	_call:     		push	{lr}     		bl	__interwork_call_via_r0     		pop	{pc}   Very similar to the first (non-interworking) version, except that adifferent stub is used to call via the function pointer.  This new stubwill work even if the called function is not interworking aware, andtries to return to call() in ARM mode.  Note that the assembly code forcall() is still not interworking aware itself, and so should not becalled from ARM code.   `-O2 -mcallee-super-interworking':     		.code	32     		.globl	_func     	_func:     		orr	r12, pc, #1     		bx	r12          		.code	16     		.globl .real_start_of_func     		.thumb_func     	.real_start_of_func:     		mov	r0, #1     		bx	lr          		.code	32     		.globl	_call     	_call:     		orr	r12, pc, #1     		bx	r12          		.code	16     		.globl .real_start_of_call     		.thumb_func     	.real_start_of_call:     		push	{lr}     		bl	__call_via_r0     		pop	{r1}     		bx	r1   Now both functions have an ARM coded prologue, and both functionsreturn by using the BX instruction.  These functions are interworkingaware therefore and can safely be called from ARM code.  The code forthe call() function is now 10 bytes longer than the original, noninterworking aware version, an increase of over 200%.   If a prototype for call() is added to the source code, and thisprototype includes the `interfacearm' attribute:     	int __attribute__((interfacearm)) call (int (* ptr)(void));   then this code is produced (with only -O2 specified on the commandline):     		.code	16     		.globl	_func     		.thumb_func     	_func:     		mov	r0, #1     		bx	lr          		.globl	_call     		.code	32     	_call:     		orr	r12, pc, #1     		bx	r12          		.code	16     		.globl .real_start_of_call     		.thumb_func     	.real_start_of_call:     		push	{lr}     		bl	__call_via_r0     		pop	{r1}     		bx	r1   So now both call() and func() can be safely called vianon-interworking aware ARM code.  If, when such a file is assembled,the assembler detects the fact that call() is being called by anotherfunction in the same file, it will automatically adjust the target ofthe BL instruction to point to .real_start_of_call.  In this way thereis no need for the linker to generate a Thumb-to-ARM calling stub sothat call can be entered in ARM mode.10. How to use dlltool to build ARM/Thumb DLLs==============================================   Given a program (`prog.c') like this:             extern int func_in_dll (void);                  int main (void) { return func_in_dll(); }   And a DLL source file (`dll.c') like this:             int func_in_dll (void) { return 1; }   Here is how to build the DLL and the program for a purely ARM basedenvironment:*Step One     Build a `.def' file describing the DLL:             ; example.def             ; This file describes the contents of the DLL             LIBRARY     example             HEAPSIZE    0x40000, 0x2000             EXPORTS                          func_in_dll  1*Step Two     Compile the DLL source code:            arm-pe-gcc -O2 -c dll.c*Step Three     Use `dlltool' to create an exports file and a library file:            dlltool --def example.def --output-exp example.o --output-lib example.a*Step Four     Link together the complete DLL:            arm-pe-ld dll.o example.o -o example.dll*Step Five     Compile the program's source code:            arm-pe-gcc -O2 -c prog.c*Step Six     Link together the program and the DLL's library file:            arm-pe-gcc prog.o example.a -o prog   If instead this was a Thumb DLL being called from an ARM program, thesteps would look like this.  (To save space only those steps that aredifferent from the previous version are shown):*Step Two     Compile the DLL source code (using the Thumb compiler):            thumb-pe-gcc -O2 -c dll.c -mthumb-interwork*Step Three     Build the exports and library files (and support interworking):            dlltool -d example.def -z example.o -l example.a --interwork -m thumb*Step Five     Compile the program's source code (and support interworking):            arm-pe-gcc -O2 -c prog.c -mthumb-interwork   If instead, the DLL was an old, ARM DLL which does not supportinterworking, and which cannot be rebuilt, then these steps would beused.*Step One     Skip.  If you do not have access to the sources of a DLL, there is     no point in building a `.def' file for it.*Step Two     Skip.  With no DLL sources there is nothing to compile.*Step Three     Skip.  Without a `.def' file you cannot use dlltool to build an     exports file or a library file.*Step Four     Skip.  Without a set of DLL object files you cannot build the DLL.     Besides it has already been built for you by somebody else.*Step Five     Compile the program's source code, this is the same as before:            arm-pe-gcc -O2 -c prog.c*Step Six     Link together the program and the DLL's library file, passing the     `--support-old-code' option to the linker:            arm-pe-gcc prog.o example.a -Wl,--support-old-code -o prog     Ignore the warning message about the input file not supporting     interworking as the --support-old-code switch has taken care if this.

⌨️ 快捷键说明

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