ARM-Unwinding-Tutorial.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- This file documents the GNU Assembler "as".
  4. Copyright (C) 1991-2017 Free Software Foundation, Inc.
  5. Permission is granted to copy, distribute and/or modify this document
  6. under the terms of the GNU Free Documentation License, Version 1.3
  7. or any later version published by the Free Software Foundation;
  8. with no Invariant Sections, with no Front-Cover Texts, and with no
  9. Back-Cover Texts. A copy of the license is included in the
  10. section entitled "GNU Free Documentation License".
  11. -->
  12. <!-- Created by GNU Texinfo 5.2, http://www.gnu.org/software/texinfo/ -->
  13. <head>
  14. <title>Using as: ARM Unwinding Tutorial</title>
  15. <meta name="description" content="Using as: ARM Unwinding Tutorial">
  16. <meta name="keywords" content="Using as: ARM Unwinding Tutorial">
  17. <meta name="resource-type" content="document">
  18. <meta name="distribution" content="global">
  19. <meta name="Generator" content="makeinfo">
  20. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  21. <link href="index.html#Top" rel="start" title="Top">
  22. <link href="AS-Index.html#AS-Index" rel="index" title="AS Index">
  23. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  24. <link href="ARM_002dDependent.html#ARM_002dDependent" rel="up" title="ARM-Dependent">
  25. <link href="AVR_002dDependent.html#AVR_002dDependent" rel="next" title="AVR-Dependent">
  26. <link href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" rel="prev" title="ARM Mapping Symbols">
  27. <style type="text/css">
  28. <!--
  29. a.summary-letter {text-decoration: none}
  30. blockquote.smallquotation {font-size: smaller}
  31. div.display {margin-left: 3.2em}
  32. div.example {margin-left: 3.2em}
  33. div.indentedblock {margin-left: 3.2em}
  34. div.lisp {margin-left: 3.2em}
  35. div.smalldisplay {margin-left: 3.2em}
  36. div.smallexample {margin-left: 3.2em}
  37. div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
  38. div.smalllisp {margin-left: 3.2em}
  39. kbd {font-style:oblique}
  40. pre.display {font-family: inherit}
  41. pre.format {font-family: inherit}
  42. pre.menu-comment {font-family: serif}
  43. pre.menu-preformatted {font-family: serif}
  44. pre.smalldisplay {font-family: inherit; font-size: smaller}
  45. pre.smallexample {font-size: smaller}
  46. pre.smallformat {font-family: inherit; font-size: smaller}
  47. pre.smalllisp {font-size: smaller}
  48. span.nocodebreak {white-space:nowrap}
  49. span.nolinebreak {white-space:nowrap}
  50. span.roman {font-family:serif; font-weight:normal}
  51. span.sansserif {font-family:sans-serif; font-weight:normal}
  52. ul.no-bullet {list-style: none}
  53. -->
  54. </style>
  55. </head>
  56. <body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
  57. <a name="ARM-Unwinding-Tutorial"></a>
  58. <div class="header">
  59. <p>
  60. Previous: <a href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" accesskey="p" rel="prev">ARM Mapping Symbols</a>, Up: <a href="ARM_002dDependent.html#ARM_002dDependent" accesskey="u" rel="up">ARM-Dependent</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="AS-Index.html#AS-Index" title="Index" rel="index">Index</a>]</p>
  61. </div>
  62. <hr>
  63. <a name="Unwinding"></a>
  64. <h4 class="subsection">9.4.7 Unwinding</h4>
  65. <p>The ABI for the ARM Architecture specifies a standard format for
  66. exception unwind information. This information is used when an
  67. exception is thrown to determine where control should be transferred.
  68. In particular, the unwind information is used to determine which
  69. function called the function that threw the exception, and which
  70. function called that one, and so forth. This information is also used
  71. to restore the values of callee-saved registers in the function
  72. catching the exception.
  73. </p>
  74. <p>If you are writing functions in assembly code, and those functions
  75. call other functions that throw exceptions, you must use assembly
  76. pseudo ops to ensure that appropriate exception unwind information is
  77. generated. Otherwise, if one of the functions called by your assembly
  78. code throws an exception, the run-time library will be unable to
  79. unwind the stack through your assembly code and your program will not
  80. behave correctly.
  81. </p>
  82. <p>To illustrate the use of these pseudo ops, we will examine the code
  83. that G++ generates for the following C++ input:
  84. </p>
  85. <pre class="verbatim">void callee (int *);
  86. int
  87. caller ()
  88. {
  89. int i;
  90. callee (&amp;i);
  91. return i;
  92. }
  93. </pre>
  94. <p>This example does not show how to throw or catch an exception from
  95. assembly code. That is a much more complex operation and should
  96. always be done in a high-level language, such as C++, that directly
  97. supports exceptions.
  98. </p>
  99. <p>The code generated by one particular version of G++ when compiling the
  100. example above is:
  101. </p>
  102. <pre class="verbatim">_Z6callerv:
  103. .fnstart
  104. .LFB2:
  105. @ Function supports interworking.
  106. @ args = 0, pretend = 0, frame = 8
  107. @ frame_needed = 1, uses_anonymous_args = 0
  108. stmfd sp!, {fp, lr}
  109. .save {fp, lr}
  110. .LCFI0:
  111. .setfp fp, sp, #4
  112. add fp, sp, #4
  113. .LCFI1:
  114. .pad #8
  115. sub sp, sp, #8
  116. .LCFI2:
  117. sub r3, fp, #8
  118. mov r0, r3
  119. bl _Z6calleePi
  120. ldr r3, [fp, #-8]
  121. mov r0, r3
  122. sub sp, fp, #4
  123. ldmfd sp!, {fp, lr}
  124. bx lr
  125. .LFE2:
  126. .fnend
  127. </pre>
  128. <p>Of course, the sequence of instructions varies based on the options
  129. you pass to GCC and on the version of GCC in use. The exact
  130. instructions are not important since we are focusing on the pseudo ops
  131. that are used to generate unwind information.
  132. </p>
  133. <p>An important assumption made by the unwinder is that the stack frame
  134. does not change during the body of the function. In particular, since
  135. we assume that the assembly code does not itself throw an exception,
  136. the only point where an exception can be thrown is from a call, such
  137. as the <code>bl</code> instruction above. At each call site, the same saved
  138. registers (including <code>lr</code>, which indicates the return address)
  139. must be located in the same locations relative to the frame pointer.
  140. </p>
  141. <p>The <code>.fnstart</code> (see <a href="ARM-Directives.html#arm_005ffnstart">.fnstart pseudo op</a>) pseudo
  142. op appears immediately before the first instruction of the function
  143. while the <code>.fnend</code> (see <a href="ARM-Directives.html#arm_005ffnend">.fnend pseudo op</a>) pseudo
  144. op appears immediately after the last instruction of the function.
  145. These pseudo ops specify the range of the function.
  146. </p>
  147. <p>Only the order of the other pseudos ops (e.g., <code>.setfp</code> or
  148. <code>.pad</code>) matters; their exact locations are irrelevant. In the
  149. example above, the compiler emits the pseudo ops with particular
  150. instructions. That makes it easier to understand the code, but it is
  151. not required for correctness. It would work just as well to emit all
  152. of the pseudo ops other than <code>.fnend</code> in the same order, but
  153. immediately after <code>.fnstart</code>.
  154. </p>
  155. <p>The <code>.save</code> (see <a href="ARM-Directives.html#arm_005fsave">.save pseudo op</a>) pseudo op
  156. indicates registers that have been saved to the stack so that they can
  157. be restored before the function returns. The argument to the
  158. <code>.save</code> pseudo op is a list of registers to save. If a register
  159. is &ldquo;callee-saved&rdquo; (as specified by the ABI) and is modified by the
  160. function you are writing, then your code must save the value before it
  161. is modified and restore the original value before the function
  162. returns. If an exception is thrown, the run-time library restores the
  163. values of these registers from their locations on the stack before
  164. returning control to the exception handler. (Of course, if an
  165. exception is not thrown, the function that contains the <code>.save</code>
  166. pseudo op restores these registers in the function epilogue, as is
  167. done with the <code>ldmfd</code> instruction above.)
  168. </p>
  169. <p>You do not have to save callee-saved registers at the very beginning
  170. of the function and you do not need to use the <code>.save</code> pseudo op
  171. immediately following the point at which the registers are saved.
  172. However, if you modify a callee-saved register, you must save it on
  173. the stack before modifying it and before calling any functions which
  174. might throw an exception. And, you must use the <code>.save</code> pseudo
  175. op to indicate that you have done so.
  176. </p>
  177. <p>The <code>.pad</code> (see <a href="ARM-Directives.html#arm_005fpad">.pad</a>) pseudo op indicates a
  178. modification of the stack pointer that does not save any registers.
  179. The argument is the number of bytes (in decimal) that are subtracted
  180. from the stack pointer. (On ARM CPUs, the stack grows downwards, so
  181. subtracting from the stack pointer increases the size of the stack.)
  182. </p>
  183. <p>The <code>.setfp</code> (see <a href="ARM-Directives.html#arm_005fsetfp">.setfp pseudo op</a>) pseudo op
  184. indicates the register that contains the frame pointer. The first
  185. argument is the register that is set, which is typically <code>fp</code>.
  186. The second argument indicates the register from which the frame
  187. pointer takes its value. The third argument, if present, is the value
  188. (in decimal) added to the register specified by the second argument to
  189. compute the value of the frame pointer. You should not modify the
  190. frame pointer in the body of the function.
  191. </p>
  192. <p>If you do not use a frame pointer, then you should not use the
  193. <code>.setfp</code> pseudo op. If you do not use a frame pointer, then you
  194. should avoid modifying the stack pointer outside of the function
  195. prologue. Otherwise, the run-time library will be unable to find
  196. saved registers when it is unwinding the stack.
  197. </p>
  198. <p>The pseudo ops described above are sufficient for writing assembly
  199. code that calls functions which may throw exceptions. If you need to
  200. know more about the object-file format used to represent unwind
  201. information, you may consult the <cite>Exception Handling ABI for the
  202. ARM Architecture</cite> available from <a href="http://infocenter.arm.com">http://infocenter.arm.com</a>.
  203. </p>
  204. <hr>
  205. <div class="header">
  206. <p>
  207. Previous: <a href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" accesskey="p" rel="prev">ARM Mapping Symbols</a>, Up: <a href="ARM_002dDependent.html#ARM_002dDependent" accesskey="u" rel="up">ARM-Dependent</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="AS-Index.html#AS-Index" title="Index" rel="index">Index</a>]</p>
  208. </div>
  209. </body>
  210. </html>