NameDateSize

..16-Oct-2014100

aof.hH A D22-Nov-201213.1 KiB

aout.hH A D22-Nov-20129.8 KiB

arm.cH A D22-Nov-2012176.3 KiB

arm.hH A D22-Nov-201284.7 KiB

arm.mdH A D22-Nov-2012196 KiB

coff.hH A D22-Nov-20126.9 KiB

ecos-elf.hH A D22-Nov-2012981

elf.hH A D22-Nov-201212.3 KiB

lib1funcs.asmH A D22-Nov-201214.7 KiB

lib1thumb.asmH A D22-Nov-201215.6 KiB

linux-aout.hH A D22-Nov-20121.8 KiB

linux-elf.hH A D22-Nov-20129.3 KiB

linux-elf26.hH A D22-Nov-2012988

linux-gas.hH A D22-Nov-20122.7 KiB

linux-oldld.hH A D22-Nov-20121.2 KiB

netbsd.hH A D22-Nov-20125.5 KiB

README-interworkingH A D22-Nov-201226.4 KiB

riscix.hH A D22-Nov-20125.3 KiB

riscix1-1.hH A D22-Nov-20123.4 KiB

rix-gas.hH A D22-Nov-20121.7 KiB

semi.hH A D22-Nov-20121.3 KiB

semiaof.hH A D22-Nov-20121.5 KiB

t-arm-elfH A D22-Nov-20121.2 KiB

t-bareH A D22-Nov-2012974

t-linuxH A D22-Nov-2012692

t-netbsdH A D22-Nov-2012228

t-peH A D22-Nov-2012993

t-riscixH A D22-Nov-2012196

t-semiH A D22-Nov-20121.6 KiB

t-semiaofH A D22-Nov-20122 KiB

t-thumbH A D22-Nov-20121.2 KiB

tcoff.hH A D22-Nov-20126 KiB

thumb.cH A D22-Nov-201252.3 KiB

thumb.hH A D22-Nov-201238 KiB

thumb.mdH A D22-Nov-201233.3 KiB

unknown-elf-oabi.hH A D22-Nov-20121.3 KiB

unknown-elf.hH A D22-Nov-20125.6 KiB

vxarm.hH A D22-Nov-20122.1 KiB

x-riscixH A D22-Nov-2012375

xm-arm.hH A D22-Nov-20122.2 KiB

xm-linux.hH A D22-Nov-2012933

xm-netbsd.hH A D22-Nov-2012127

xm-thumb.hH A D22-Nov-201216

README-interworking

1		Arm / Thumb Interworking
2		========================
3
4The Cygnus GNU Pro Toolkit for the ARM7T processor supports function
5calls between code compiled for the ARM instruction set and code
6compiled for the Thumb instruction set and vice versa.  This document
7describes how that interworking support operates and explains the
8command line switches that should be used in order to produce working
9programs.
10
11Note:  The Cygnus GNU Pro Toolkit does not support switching between
12compiling for the ARM instruction set and the Thumb instruction set
13on anything other than a per file basis.  There are in fact two
14completely separate compilers, one that produces ARM assembler
15instructions and one that produces Thumb assembler instructions.  The
16two compilers share the same assembler, linker and so on.
17
18
191. Explicit interworking support for C and C++ files
20====================================================
21
22By default if a file is compiled without any special command line
23switches then the code produced will not support interworking.
24Provided that a program is made up entirely from object files and
25libraries produced in this way and which contain either exclusively
26ARM instructions or exclusively Thumb instructions then this will not
27matter and a working executable will be created.  If an attempt is
28made to link together mixed ARM and Thumb object files and libraries,
29then warning messages will be produced by the linker and a non-working
30executable will be created.
31
32In order to produce code which does support interworking it should be
33compiled with the
34
35	-mthumb-interwork
36
37command line option.  Provided that a program is made up entirely from
38object files and libraries built with this command line switch a
39working executable will be produced, even if both ARM and Thumb
40instructions are used by the various components of the program.  (No
41warning messages will be produced by the linker either).
42
43Note that specifying -mthumb-interwork does result in slightly larger,
44slower code being produced.  This is why interworking support must be
45specifically enabled by a switch.
46
47
482. Explicit interworking support for assembler files
49====================================================
50
51If assembler files are to be included into an interworking program
52then the following rules must be obeyed:
53
54	* Any externally visible functions must return by using the BX
55	instruction.
56
57	* Normal function calls can just use the BL instruction.  The
58	linker will automatically insert code to switch between ARM
59	and Thumb modes as necessary.
60
61	* Calls via function pointers should use the BX instruction if
62	the call is made in ARM mode:
63
64		.code 32
65		mov lr, pc
66		bx  rX
67
68	This code sequence will not work in Thumb mode however, since
69	the mov instruction will not set the bottom bit of the lr
70	register.  Instead a branch-and-link to the _call_via_rX
71	functions should be used instead:
72
73		.code 16
74		bl  _call_via_rX
75
76	where rX is replaced by the name of the register containing
77	the function address.
78
79	* All externally visible functions which should be entered in
80	Thumb mode must have the .thumb_func pseudo op specified just
81	before their entry point.  eg:
82
83			.code 16
84			.global function
85			.thumb_func
86		function:
87			...start of function....
88
89	* All assembler files must be assembled with the switch
90	-mthumb-interwork specified on the command line.  (If the file
91	is assembled by calling gcc it will automatically pass on the
92	-mthumb-interwork switch to the assembler, provided that it
93	was specified on the gcc command line in the first place.) 
94
95
963. Support for old, non-interworking aware code.
97================================================
98
99If it is necessary to link together code produced by an older,
100non-interworking aware compiler, or code produced by the new compiler
101but without the -mthumb-interwork command line switch specified, then
102there are two command line switches that can be used to support this.
103
104The switch
105
106	-mcaller-super-interworking
107
108will allow calls via function pointers in Thumb mode to work,
109regardless of whether the function pointer points to old,
110non-interworking aware code or not.  Specifying this switch does
111produce slightly slower code however.
112
113Note:  There is no switch to allow calls via function pointers in ARM
114mode to be handled specially.  Calls via function pointers from
115interworking aware ARM code to non-interworking aware ARM code work
116without any special considerations by the compiler.  Calls via
117function pointers from interworking aware ARM code to non-interworking
118aware Thumb code however will not work.  (Actually under some
119circumstances they may work, but there are no guarantees).  This is
120because only the new compiler is able to produce Thumb code, and this
121compiler already has a command line switch to produce interworking
122aware code.
123
124
125The switch
126
127	-mcallee-super-interworking
128
129will allow non-interworking aware ARM or Thumb code to call Thumb
130functions, either directly or via function pointers.  Specifying this
131switch does produce slightly larger, slower code however.
132
133Note:  There is no switch to allow non-interworking aware ARM or Thumb
134code to call ARM functions.  There is no need for any special handling
135of calls from non-interworking aware ARM code to interworking aware
136ARM functions, they just work normally.  Calls from non-interworking
137aware Thumb functions to ARM code however, will not work.  There is no
138option to support this, since it is always possible to recompile the
139Thumb code to be interworking aware.
140
141As an alternative to the command line switch
142-mcallee-super-interworking, which affects all externally visible
143functions in a file, it is possible to specify an attribute or
144declspec for individual functions, indicating that that particular
145function should support being called by non-interworking aware code.
146The function should be defined like this:
147
148	int __attribute__((interfacearm)) function 
149	{
150		... body of function ...
151	}
152
153or
154
155	int __declspec(interfacearm) function
156	{
157		... body of function ...
158	}
159
160
161
1624. Interworking support in dlltool
163==================================
164
165It is possible to create DLLs containing mixed ARM and Thumb code.  It
166is also possible to call Thumb code in a DLL from an ARM program and
167vice versa.  It is even possible to call ARM DLLs that have been compiled
168without interworking support (say by an older version of the compiler),
169from Thumb programs and still have things work properly.
170
171   A version of the `dlltool' program which supports the `--interwork'
172command line switch is needed, as well as the following special
173considerations when building programs and DLLs:
174
175*Use `-mthumb-interwork'*
176     When compiling files for a DLL or a program the `-mthumb-interwork'
177     command line switch should be specified if calling between ARM and
178     Thumb code can happen.  If a program is being compiled and the
179     mode of the DLLs that it uses is not known, then it should be
180     assumed that interworking might occur and the switch used.
181
182*Use `-m thumb'*
183     If the exported functions from a DLL are all Thumb encoded then the
184     `-m thumb' command line switch should be given to dlltool when
185     building the stubs.  This will make dlltool create Thumb encoded
186     stubs, rather than its default of ARM encoded stubs.
187
188     If the DLL consists of both exported Thumb functions and exported
189     ARM functions then the `-m thumb' switch should not be used.
190     Instead the Thumb functions in the DLL should be compiled with the
191     `-mcallee-super-interworking' switch, or with the `interfacearm'
192     attribute specified on their prototypes.  In this way they will be
193     given ARM encoded prologues, which will work with the ARM encoded
194     stubs produced by dlltool.
195
196*Use `-mcaller-super-interworking'*
197     If it is possible for Thumb functions in a DLL to call
198     non-interworking aware code via a function pointer, then the Thumb
199     code must be compiled with the `-mcaller-super-interworking'
200     command line switch.  This will force the function pointer calls
201     to use the _interwork_call_via_rX stub functions which will
202     correctly restore Thumb mode upon return from the called function.
203
204*Link with `libgcc.a'*
205     When the dll is built it may have to be linked with the GCC
206     library (`libgcc.a') in order to extract the _call_via_rX functions
207     or the _interwork_call_via_rX functions.  This represents a partial
208     redundancy since the same functions *may* be present in the
209     application itself, but since they only take up 372 bytes this
210     should not be too much of a consideration.
211
212*Use `--support-old-code'*
213     When linking a program with an old DLL which does not support
214     interworking, the `--support-old-code' command line switch to the
215     linker should be used.   This causes the linker to generate special
216     interworking stubs which can cope with old, non-interworking aware
217     ARM code, at the cost of generating bulkier code.  The linker will
218     still generate a warning message along the lines of:
219       "Warning: input file XXX does not support interworking, whereas YYY does."
220     but this can now be ignored because the --support-old-code switch
221     has been used.
222
223
224
2255. How interworking support works
226=================================
227
228Switching between the ARM and Thumb instruction sets is accomplished
229via the BX instruction which takes as an argument a register name.
230Control is transfered to the address held in this register (with the
231bottom bit masked out), and if the bottom bit is set, then Thumb
232instruction processing is enabled, otherwise ARM instruction
233processing is enabled.
234
235When the -mthumb-interwork command line switch is specified, gcc
236arranges for all functions to return to their caller by using the BX
237instruction.  Thus provided that the return address has the bottom bit
238correctly initialised to indicate the instruction set of the caller,
239correct operation will ensue.
240
241When a function is called explicitly (rather than via a function
242pointer), the compiler generates a BL instruction to do this.  The
243Thumb version of the BL instruction has the special property of
244setting the bottom bit of the LR register after it has stored the
245return address into it, so that a future BX instruction will correctly
246return the instruction after the BL instruction, in Thumb mode.
247
248The BL instruction does not change modes itself however, so if an ARM
249function is calling a Thumb function, or vice versa, it is necessary
250to generate some extra instructions to handle this.  This is done in
251the linker when it is storing the address of the referenced function
252into the BL instruction.  If the BL instruction is an ARM style BL
253instruction, but the referenced function is a Thumb function, then the
254linker automatically generates a calling stub that converts from ARM
255mode to Thumb mode, puts the address of this stub into the BL
256instruction, and puts the address of the referenced function into the
257stub.  Similarly if the BL instruction is a Thumb BL instruction, and
258the referenced function is an ARM function, the linker generates a
259stub which converts from Thumb to ARM mode, puts the address of this
260stub into the BL instruction, and the address of the referenced
261function into the stub.
262
263This is why it is necessary to mark Thumb functions with the
264.thumb_func pseudo op when creating assembler files.  This pseudo op
265allows the assembler to distinguish between ARM functions and Thumb
266functions.  (The Thumb version of GCC automatically generates these
267pseudo ops for any Thumb functions that it generates).
268
269Calls via function pointers work differently.  Whenever the address of
270a function is taken, the linker examines the type of the function
271being referenced.  If the function is a Thumb function, then it sets
272the bottom bit of the address.  Technically this makes the address
273incorrect, since it is now one byte into the start of the function,
274but this is never a problem because:
275
276	a. with interworking enabled all calls via function pointer
277	   are done using the BX instruction and this ignores the
278	   bottom bit when computing where to go to.
279
280	b. the linker will always set the bottom bit when the address
281	   of the function is taken, so it is never possible to take
282	   the address of the function in two different places and
283	   then compare them and find that they are not equal.
284
285As already mentioned any call via a function pointer will use the BX
286instruction (provided that interworking is enabled).  The only problem
287with this is computing the return address for the return from the
288called function.  For ARM code this can easily be done by the code
289sequence:
290
291	mov	lr, pc
292	bx	rX
293
294(where rX is the name of the register containing the function
295pointer).  This code does not work for the Thumb instruction set,
296since the MOV instruction will not set the bottom bit of the LR
297register, so that when the called function returns, it will return in
298ARM mode not Thumb mode.  Instead the compiler generates this
299sequence:
300
301	bl	_call_via_rX
302
303(again where rX is the name if the register containing the function
304pointer).  The special call_via_rX functions look like this:
305
306	.thumb_func
307_call_via_r0:
308	bx	r0
309	nop
310
311The BL instruction ensures that the correct return address is stored
312in the LR register and then the BX instruction jumps to the address
313stored in the function pointer, switch modes if necessary.
314
315
3166. How caller-super-interworking support works
317==============================================
318
319When the -mcaller-super-interworking command line switch is specified
320it changes the code produced by the Thumb compiler so that all calls
321via function pointers (including virtual function calls) now go via a
322different stub function.  The code to call via a function pointer now
323looks like this:
324
325	bl _interwork_call_via_r0
326
327Note: The compiler does not insist that r0 be used to hold the
328function address.  Any register will do, and there are a suite of stub
329functions, one for each possible register.  The stub functions look
330like this:
331
332	.code 16
333	.thumb_func
334_interwork_call_via_r0
335	bx 	pc
336	nop
337	
338	.code 32
339	tst	r0, #1
340	stmeqdb	r13!, {lr}
341	adreq	lr, _arm_return
342	bx	r0
343
344The stub first switches to ARM mode, since it is a lot easier to
345perform the necessary operations using ARM instructions.  It then
346tests the bottom bit of the register containing the address of the
347function to be called.  If this bottom bit is set then the function
348being called uses Thumb instructions and the BX instruction to come
349will switch back into Thumb mode before calling this function.  (Note
350that it does not matter how this called function chooses to return to
351its caller, since the both the caller and callee are Thumb functions,
352and mode switching is necessary).  If the function being called is an
353ARM mode function however, the stub pushes the return address (with
354its bottom bit set) onto the stack, replaces the return address with
355the address of the a piece of code called '_arm_return' and then
356performs a BX instruction to call the function.
357
358The '_arm_return' code looks like this:
359
360	.code 32
361_arm_return:		
362	ldmia 	r13!, {r12}
363	bx 	r12
364	.code 16
365
366
367It simply retrieves the return address from the stack, and then
368performs a BX operation to return to the caller and switch back into
369Thumb mode.
370
371
3727. How callee-super-interworking support works
373==============================================
374
375When -mcallee-super-interworking is specified on the command line the
376Thumb compiler behaves as if every externally visible function that it
377compiles has had the (interfacearm) attribute specified for it.  What
378this attribute does is to put a special, ARM mode header onto the
379function which forces a switch into Thumb mode:
380
381  without __attribute__((interfacearm)):
382
383		.code 16
384		.thumb_func
385	function:
386		... start of function ...
387
388  with __attribute__((interfacearm)):
389
390		.code 32
391	function:
392		orr	r12, pc, #1
393		bx	r12
394
395		.code 16
396                .thumb_func
397        .real_start_of_function:
398
399		... start of function ...
400
401Note that since the function now expects to be entered in ARM mode, it
402no longer has the .thumb_func pseudo op specified for its name.
403Instead the pseudo op is attached to a new label .real_start_of_<name>
404(where <name> is the name of the function) which indicates the start
405of the Thumb code.  This does have the interesting side effect in that
406if this function is now called from a Thumb mode piece of code
407outsside of the current file, the linker will generate a calling stub
408to switch from Thumb mode into ARM mode, and then this is immediately
409overridden by the function's header which switches back into Thumb
410mode. 
411
412In addition the (interfacearm) attribute also forces the function to
413return by using the BX instruction, even if has not been compiled with
414the -mthumb-interwork command line flag, so that the correct mode will
415be restored upon exit from the function.
416
417
4188. Some examples
419================
420
421   Given these two test files:
422
423             int arm (void) { return 1 + thumb (); }
424
425             int thumb (void) { return 2 + arm (); }
426
427   The following pieces of assembler are produced by the ARM and Thumb
428version of GCC depending upon the command line options used:
429
430   `-O2':
431             .code 32                               .code 16
432             .global _arm                           .global _thumb
433                                                    .thumb_func
434     _arm:                                    _thumb:
435             mov     ip, sp
436             stmfd   sp!, {fp, ip, lr, pc}          push    {lr}
437             sub     fp, ip, #4
438             bl      _thumb                          bl      _arm
439             add     r0, r0, #1                      add     r0, r0, #2
440             ldmea   fp, {fp, sp, pc}                pop     {pc}
441
442   Note how the functions return without using the BX instruction.  If
443these files were assembled and linked together they would fail to work
444because they do not change mode when returning to their caller.
445
446   `-O2 -mthumb-interwork':
447
448             .code 32                               .code 16
449             .global _arm                           .global _thumb
450                                                    .thumb_func
451     _arm:                                    _thumb:
452             mov     ip, sp
453             stmfd   sp!, {fp, ip, lr, pc}          push    {lr}
454             sub     fp, ip, #4
455             bl      _thumb                         bl       _arm
456             add     r0, r0, #1                     add      r0, r0, #2
457             ldmea   fp, {fp, sp, lr}               pop      {r1}
458             bx      lr                             bx       r1
459
460   Now the functions use BX to return their caller.  They have grown by
4614 and 2 bytes respectively, but they can now successfully be linked
462together and be expect to work.  The linker will replace the
463destinations of the two BL instructions with the addresses of calling
464stubs which convert to the correct mode before jumping to the called
465function.
466
467   `-O2 -mcallee-super-interworking':
468
469             .code 32                               .code 32
470             .global _arm                           .global _thumb
471     _arm:                                    _thumb:
472                                                    orr      r12, pc, #1
473                                                    bx       r12
474             mov     ip, sp                         .code 16
475             stmfd   sp!, {fp, ip, lr, pc}          push     {lr}
476             sub     fp, ip, #4
477             bl      _thumb                         bl       _arm
478             add     r0, r0, #1                     add      r0, r0, #2
479             ldmea   fp, {fp, sp, lr}               pop      {r1}
480             bx      lr                             bx       r1
481
482   The thumb function now has an ARM encoded prologue, and it no longer
483has the `.thumb-func' pseudo op attached to it.  The linker will not
484generate a calling stub for the call from arm() to thumb(), but it will
485still have to generate a stub for the call from thumb() to arm().  Also
486note how specifying `--mcallee-super-interworking' automatically
487implies `-mthumb-interworking'.
488
489
4909. Some Function Pointer Examples
491=================================
492
493   Given this test file:
494
495     	int func (void) { return 1; }
496     
497     	int call (int (* ptr)(void)) { return ptr (); }
498
499   The following varying pieces of assembler are produced by the Thumb
500version of GCC depending upon the command line options used:
501
502   `-O2':
503     		.code	16
504     		.globl	_func
505     		.thumb_func
506     	_func:
507     		mov	r0, #1
508     		bx	lr
509     
510     		.globl	_call
511     		.thumb_func
512     	_call:
513     		push	{lr}
514     		bl	__call_via_r0
515     		pop	{pc}
516
517   Note how the two functions have different exit sequences.  In
518particular call() uses pop {pc} to return, which would not work if the
519caller was in ARM mode.  func() however, uses the BX instruction, even
520though `-mthumb-interwork' has not been specified, as this is the most
521efficient way to exit a function when the return address is held in the
522link register.
523
524   `-O2 -mthumb-interwork':
525
526     		.code	16
527     		.globl	_func
528     		.thumb_func
529     	_func:
530     		mov	r0, #1
531     		bx	lr
532     
533     		.globl	_call
534     		.thumb_func
535     	_call:
536     		push	{lr}
537     		bl	__call_via_r0
538     		pop	{r1}
539     		bx	r1
540
541   This time both functions return by using the BX instruction.  This
542means that call() is now two bytes longer and several cycles slower
543than the previous version.
544
545   `-O2 -mcaller-super-interworking':
546     		.code	16
547     		.globl	_func
548     		.thumb_func
549     	_func:
550     		mov	r0, #1
551     		bx	lr
552     
553     		.globl	_call
554     		.thumb_func
555     	_call:
556     		push	{lr}
557     		bl	__interwork_call_via_r0
558     		pop	{pc}
559
560   Very similar to the first (non-interworking) version, except that a
561different stub is used to call via the function pointer.  This new stub
562will work even if the called function is not interworking aware, and
563tries to return to call() in ARM mode.  Note that the assembly code for
564call() is still not interworking aware itself, and so should not be
565called from ARM code.
566
567   `-O2 -mcallee-super-interworking':
568
569     		.code	32
570     		.globl	_func
571     	_func:
572     		orr	r12, pc, #1
573     		bx	r12
574     
575     		.code	16
576     		.globl .real_start_of_func
577     		.thumb_func
578     	.real_start_of_func:
579     		mov	r0, #1
580     		bx	lr
581     
582     		.code	32
583     		.globl	_call
584     	_call:
585     		orr	r12, pc, #1
586     		bx	r12
587     
588     		.code	16
589     		.globl .real_start_of_call
590     		.thumb_func
591     	.real_start_of_call:
592     		push	{lr}
593     		bl	__call_via_r0
594     		pop	{r1}
595     		bx	r1
596
597   Now both functions have an ARM coded prologue, and both functions
598return by using the BX instruction.  These functions are interworking
599aware therefore and can safely be called from ARM code.  The code for
600the call() function is now 10 bytes longer than the original, non
601interworking aware version, an increase of over 200%.
602
603   If a prototype for call() is added to the source code, and this
604prototype includes the `interfacearm' attribute:
605
606     	int __attribute__((interfacearm)) call (int (* ptr)(void));
607
608   then this code is produced (with only -O2 specified on the command
609line):
610
611     		.code	16
612     		.globl	_func
613     		.thumb_func
614     	_func:
615     		mov	r0, #1
616     		bx	lr
617     
618     		.globl	_call
619     		.code	32
620     	_call:
621     		orr	r12, pc, #1
622     		bx	r12
623     
624     		.code	16
625     		.globl .real_start_of_call
626     		.thumb_func
627     	.real_start_of_call:
628     		push	{lr}
629     		bl	__call_via_r0
630     		pop	{r1}
631     		bx	r1
632
633   So now both call() and func() can be safely called via
634non-interworking aware ARM code.  If, when such a file is assembled,
635the assembler detects the fact that call() is being called by another
636function in the same file, it will automatically adjust the target of
637the BL instruction to point to .real_start_of_call.  In this way there
638is no need for the linker to generate a Thumb-to-ARM calling stub so
639that call can be entered in ARM mode.
640
641
64210. How to use dlltool to build ARM/Thumb DLLs
643==============================================
644   Given a program (`prog.c') like this:
645
646             extern int func_in_dll (void);
647     
648             int main (void) { return func_in_dll(); }
649
650   And a DLL source file (`dll.c') like this:
651
652             int func_in_dll (void) { return 1; }
653
654   Here is how to build the DLL and the program for a purely ARM based
655environment:
656
657*Step One
658     Build a `.def' file describing the DLL:
659
660             ; example.def
661             ; This file describes the contents of the DLL
662             LIBRARY     example
663             HEAPSIZE    0x40000, 0x2000
664             EXPORTS
665                          func_in_dll  1
666
667*Step Two
668     Compile the DLL source code:
669
670            arm-pe-gcc -O2 -c dll.c
671
672*Step Three
673     Use `dlltool' to create an exports file and a library file:
674
675            dlltool --def example.def --output-exp example.o --output-lib example.a
676
677*Step Four
678     Link together the complete DLL:
679
680            arm-pe-ld dll.o example.o -o example.dll
681
682*Step Five
683     Compile the program's source code:
684
685            arm-pe-gcc -O2 -c prog.c
686
687*Step Six
688     Link together the program and the DLL's library file:
689
690            arm-pe-gcc prog.o example.a -o prog
691
692   If instead this was a Thumb DLL being called from an ARM program, the
693steps would look like this.  (To save space only those steps that are
694different from the previous version are shown):
695
696*Step Two
697     Compile the DLL source code (using the Thumb compiler):
698
699            thumb-pe-gcc -O2 -c dll.c -mthumb-interwork
700
701*Step Three
702     Build the exports and library files (and support interworking):
703
704            dlltool -d example.def -z example.o -l example.a --interwork -m thumb
705
706*Step Five
707     Compile the program's source code (and support interworking):
708
709            arm-pe-gcc -O2 -c prog.c -mthumb-interwork
710
711   If instead, the DLL was an old, ARM DLL which does not support
712interworking, and which cannot be rebuilt, then these steps would be
713used.
714
715*Step One
716     Skip.  If you do not have access to the sources of a DLL, there is
717     no point in building a `.def' file for it.
718
719*Step Two
720     Skip.  With no DLL sources there is nothing to compile.
721
722*Step Three
723     Skip.  Without a `.def' file you cannot use dlltool to build an
724     exports file or a library file.
725
726*Step Four
727     Skip.  Without a set of DLL object files you cannot build the DLL.
728     Besides it has already been built for you by somebody else.
729
730*Step Five
731     Compile the program's source code, this is the same as before:
732
733            arm-pe-gcc -O2 -c prog.c
734
735*Step Six
736     Link together the program and the DLL's library file, passing the
737     `--support-old-code' option to the linker:
738
739            arm-pe-gcc prog.o example.a -Wl,--support-old-code -o prog
740
741     Ignore the warning message about the input file not supporting
742     interworking as the --support-old-code switch has taken care if this.
743