0sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}(hhparenthuba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget,/translations/zh_CN/core-api/asm-annotationsmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}(hhhh2ubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/zh_TW/core-api/asm-annotationsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}(hhhhFubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/it_IT/core-api/asm-annotationsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}(hhhhZubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/ja_JP/core-api/asm-annotationsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}(hhhhnubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/ko_KR/core-api/asm-annotationsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}(hhhhubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/sp_SP/core-api/asm-annotationsmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(hAssembler Annotationsh]hAssembler Annotations}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhF/var/lib/git/docbuild/linux/Documentation/core-api/asm-annotations.rsthKubh paragraph)}(h"Copyright (c) 2017-2019 Jiri Slabyh]h"Copyright (c) 2017-2019 Jiri Slaby}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hThis document describes the new macros for annotation of data and code in assembly. In particular, it contains information about ``SYM_FUNC_START``, ``SYM_FUNC_END``, ``SYM_CODE_START``, and similar.h](hThis document describes the new macros for annotation of data and code in assembly. In particular, it contains information about }(hThis document describes the new macros for annotation of data and code in assembly. In particular, it contains information about hhhhhNhNubhliteral)}(h``SYM_FUNC_START``h]hSYM_FUNC_START}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh, }(h, hhhhhNhNubh)}(h``SYM_FUNC_END``h]h SYM_FUNC_END}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh, }(h, hhhhhNhNubh)}(h``SYM_CODE_START``h]hSYM_CODE_START}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh, and similar.}(h, and similar.hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Rationaleh]h Rationale}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK ubh)}(hX Some code like entries, trampolines, or boot code needs to be written in assembly. The same as in C, such code is grouped into functions and accompanied with data. Standard assemblers do not force users into precisely marking these pieces as code, data, or even specifying their length. Nevertheless, assemblers provide developers with such annotations to aid debuggers throughout assembly. On top of that, developers also want to mark some functions as *global* in order to be visible outside of their translation units.h](hXSome code like entries, trampolines, or boot code needs to be written in assembly. The same as in C, such code is grouped into functions and accompanied with data. Standard assemblers do not force users into precisely marking these pieces as code, data, or even specifying their length. Nevertheless, assemblers provide developers with such annotations to aid debuggers throughout assembly. On top of that, developers also want to mark some functions as }(hXSome code like entries, trampolines, or boot code needs to be written in assembly. The same as in C, such code is grouped into functions and accompanied with data. Standard assemblers do not force users into precisely marking these pieces as code, data, or even specifying their length. Nevertheless, assemblers provide developers with such annotations to aid debuggers throughout assembly. On top of that, developers also want to mark some functions as hj"hhhNhNubhemphasis)}(h*global*h]hglobal}(hhhj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j+hj"ubh; in order to be visible outside of their translation units.}(h; in order to be visible outside of their translation units.hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjhhubh)}(hXnOver time, the Linux kernel has adopted macros from various projects (like ``binutils``) to facilitate such annotations. So for historic reasons, developers have been using ``ENTRY``, ``END``, ``ENDPROC``, and other annotations in assembly. Due to the lack of their documentation, the macros are used in rather wrong contexts at some locations. Clearly, ``ENTRY`` was intended to denote the beginning of global symbols (be it data or code). ``END`` used to mark the end of data or end of special functions with *non-standard* calling convention. In contrast, ``ENDPROC`` should annotate only ends of *standard* functions.h](hKOver time, the Linux kernel has adopted macros from various projects (like }(hKOver time, the Linux kernel has adopted macros from various projects (like hjFhhhNhNubh)}(h ``binutils``h]hbinutils}(hhhjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubhV) to facilitate such annotations. So for historic reasons, developers have been using }(hV) to facilitate such annotations. So for historic reasons, developers have been using hjFhhhNhNubh)}(h ``ENTRY``h]hENTRY}(hhhjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh, }(h, hjFhhhNhNubh)}(h``END``h]hEND}(hhhjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh, }(hjthjFubh)}(h ``ENDPROC``h]hENDPROC}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh, and other annotations in assembly. Due to the lack of their documentation, the macros are used in rather wrong contexts at some locations. Clearly, }(h, and other annotations in assembly. Due to the lack of their documentation, the macros are used in rather wrong contexts at some locations. Clearly, hjFhhhNhNubh)}(h ``ENTRY``h]hENTRY}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubhN was intended to denote the beginning of global symbols (be it data or code). }(hN was intended to denote the beginning of global symbols (be it data or code). hjFhhhNhNubh)}(h``END``h]hEND}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh? used to mark the end of data or end of special functions with }(h? used to mark the end of data or end of special functions with hjFhhhNhNubj,)}(h*non-standard*h]h non-standard}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j+hjFubh" calling convention. In contrast, }(h" calling convention. In contrast, hjFhhhNhNubh)}(h ``ENDPROC``h]hENDPROC}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh should annotate only ends of }(h should annotate only ends of hjFhhhNhNubj,)}(h *standard*h]hstandard}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j+hjFubh functions.}(h functions.hjFhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hWhen these macros are used correctly, they help assemblers generate a nice object with both sizes and types set correctly. For example, the result of ``arch/x86/lib/putuser.S``::h](hWhen these macros are used correctly, they help assemblers generate a nice object with both sizes and types set correctly. For example, the result of }(hWhen these macros are used correctly, they help assemblers generate a nice object with both sizes and types set correctly. For example, the result of hjhhhNhNubh)}(h``arch/x86/lib/putuser.S``h]harch/x86/lib/putuser.S}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh:}(h:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(hXPNum: Value Size Type Bind Vis Ndx Name 25: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 __put_user_1 29: 0000000000000030 37 FUNC GLOBAL DEFAULT 1 __put_user_2 32: 0000000000000060 36 FUNC GLOBAL DEFAULT 1 __put_user_4 35: 0000000000000090 37 FUNC GLOBAL DEFAULT 1 __put_user_8h]hXPNum: Value Size Type Bind Vis Ndx Name 25: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 __put_user_1 29: 0000000000000030 37 FUNC GLOBAL DEFAULT 1 __put_user_2 32: 0000000000000060 36 FUNC GLOBAL DEFAULT 1 __put_user_4 35: 0000000000000090 37 FUNC GLOBAL DEFAULT 1 __put_user_8}(hhhj#ubah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j!hhhK#hjhhubh)}(hXThis is not only important for debugging purposes. When there are properly annotated objects like this, tools can be run on them to generate more useful information. In particular, on properly annotated objects, ``objtool`` can be run to check and fix the object if needed. Currently, ``objtool`` can report missing frame pointer setup/destruction in functions. It can also automatically generate annotations for the ORC unwinder (Documentation/arch/x86/orc-unwinder.rst) for most code. Both of these are especially important to support reliable stack traces which are in turn necessary for kernel live patching (Documentation/livepatch/livepatch.rst).h](hThis is not only important for debugging purposes. When there are properly annotated objects like this, tools can be run on them to generate more useful information. In particular, on properly annotated objects, }(hThis is not only important for debugging purposes. When there are properly annotated objects like this, tools can be run on them to generate more useful information. In particular, on properly annotated objects, hj3hhhNhNubh)}(h ``objtool``h]hobjtool}(hhhj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj3ubh> can be run to check and fix the object if needed. Currently, }(h> can be run to check and fix the object if needed. Currently, hj3hhhNhNubh)}(h ``objtool``h]hobjtool}(hhhjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj3ubhXd can report missing frame pointer setup/destruction in functions. It can also automatically generate annotations for the ORC unwinder (Documentation/arch/x86/orc-unwinder.rst) for most code. Both of these are especially important to support reliable stack traces which are in turn necessary for kernel live patching (Documentation/livepatch/livepatch.rst).}(hXd can report missing frame pointer setup/destruction in functions. It can also automatically generate annotations for the ORC unwinder (Documentation/arch/x86/orc-unwinder.rst) for most code. Both of these are especially important to support reliable stack traces which are in turn necessary for kernel live patching (Documentation/livepatch/livepatch.rst).hj3hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK)hjhhubeh}(h] rationaleah ]h"] rationaleah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(hCaveat and Discussionh]hCaveat and Discussion}(hjuhjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjphhhhhK5ubh)}(hAs one might realize, there were only three macros previously. That is indeed insufficient to cover all the combinations of cases:h]hAs one might realize, there were only three macros previously. That is indeed insufficient to cover all the combinations of cases:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjphhubh bullet_list)}(hhh](h list_item)}(hstandard/non-standard functionh]h)}(hjh]hstandard/non-standard function}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h code/datah]h)}(hjh]h code/data}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hglobal/local symbol h]h)}(hglobal/local symbolh]hglobal/local symbol}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK;hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1jhhhK9hjphhubh)}(hThere was a discussion_ and instead of extending the current ``ENTRY/END*`` macros, it was decided that brand new macros should be introduced instead::h](h There was a }(h There was a hjhhhNhNubh reference)}(h discussion_h]h discussion}(h discussionhjhhhNhNubah}(h]h ]h"]h$]h&]namejrefuri?https://lore.kernel.org/r/20170217104757.28588-1-jslaby@suse.czuh1jhjresolvedKubh& and instead of extending the current }(h& and instead of extending the current hjhhhNhNubh)}(h``ENTRY/END*``h]h ENTRY/END*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhK macros, it was decided that brand new macros should be introduced instead:}(hK macros, it was decided that brand new macros should be introduced instead:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK=hjphhubj")}(hSo how about using macro names that actually show the purpose, instead of importing all the crappy, historic, essentially randomly chosen debug symbol macro names from the binutils and older kernels?h]hSo how about using macro names that actually show the purpose, instead of importing all the crappy, historic, essentially randomly chosen debug symbol macro names from the binutils and older kernels?}(hhhj ubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhK@hjphhubhtarget)}(hO.. _discussion: https://lore.kernel.org/r/20170217104757.28588-1-jslaby@suse.czh]h}(h] discussionah ]h"] discussionah$]h&]jjuh1j.hKDhjphhhh referencedKubeh}(h]caveat-and-discussionah ]h"]caveat and discussionah$]h&]uh1hhhhhhhhK5ubh)}(hhh](h)}(hMacros Descriptionh]hMacros Description}(hjJhjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjEhhhhhKGubh)}(h_The new macros are prefixed with the ``SYM_`` prefix and can be divided into three main groups:h](h%The new macros are prefixed with the }(h%The new macros are prefixed with the hjVhhhNhNubh)}(h``SYM_``h]hSYM_}(hhhj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVubh2 prefix and can be divided into three main groups:}(h2 prefix and can be divided into three main groups:hjVhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKIhjEhhubhenumerated_list)}(hhh](j)}(hXS``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with standard C calling conventions. For example, on x86, this means that the stack contains a return address at the predefined place and a return from the function can happen in a standard way. When frame pointers are enabled, save/restore of frame pointer shall happen at the start/end of a function, respectively, too. Checking tools like ``objtool`` should ensure such marked functions conform to these rules. The tools can also easily annotate these functions with debugging information (like *ORC data*) automatically. h](h)}(hX``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with standard C calling conventions. For example, on x86, this means that the stack contains a return address at the predefined place and a return from the function can happen in a standard way. When frame pointers are enabled, save/restore of frame pointer shall happen at the start/end of a function, respectively, too.h](h)}(h``SYM_FUNC_*``h]h SYM_FUNC_*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhXx -- to annotate C-like functions. This means functions with standard C calling conventions. For example, on x86, this means that the stack contains a return address at the predefined place and a return from the function can happen in a standard way. When frame pointers are enabled, save/restore of frame pointer shall happen at the start/end of a function, respectively, too.}(hXx -- to annotate C-like functions. This means functions with standard C calling conventions. For example, on x86, this means that the stack contains a return address at the predefined place and a return from the function can happen in a standard way. When frame pointers are enabled, save/restore of frame pointer shall happen at the start/end of a function, respectively, too.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKLhj}ubh)}(hChecking tools like ``objtool`` should ensure such marked functions conform to these rules. The tools can also easily annotate these functions with debugging information (like *ORC data*) automatically.h](hChecking tools like }(hChecking tools like hjhhhNhNubh)}(h ``objtool``h]hobjtool}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh should ensure such marked functions conform to these rules. The tools can also easily annotate these functions with debugging information (like }(h should ensure such marked functions conform to these rules. The tools can also easily annotate these functions with debugging information (like hjhhhNhNubj,)}(h *ORC data*h]hORC data}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j+hjubh) automatically.}(h) automatically.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKShj}ubeh}(h]h ]h"]h$]h&]uh1jhjzhhhhhNubj)}(hXs``SYM_CODE_*`` -- special functions called with special stack. Be it interrupt handlers with special stack content, trampolines, or startup functions. Checking tools mostly ignore checking of these functions. But some debug information still can be generated automatically. For correct debug data, this code needs hints like ``UNWIND_HINT_REGS`` provided by developers. h](h)}(h``SYM_CODE_*`` -- special functions called with special stack. Be it interrupt handlers with special stack content, trampolines, or startup functions.h](h)}(h``SYM_CODE_*``h]h SYM_CODE_*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh -- special functions called with special stack. Be it interrupt handlers with special stack content, trampolines, or startup functions.}(h -- special functions called with special stack. Be it interrupt handlers with special stack content, trampolines, or startup functions.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKWhjubh)}(hChecking tools mostly ignore checking of these functions. But some debug information still can be generated automatically. For correct debug data, this code needs hints like ``UNWIND_HINT_REGS`` provided by developers.h](hChecking tools mostly ignore checking of these functions. But some debug information still can be generated automatically. For correct debug data, this code needs hints like }(hChecking tools mostly ignore checking of these functions. But some debug information still can be generated automatically. For correct debug data, this code needs hints like hjhhhNhNubh)}(h``UNWIND_HINT_REGS``h]hUNWIND_HINT_REGS}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh provided by developers.}(h provided by developers.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK[hjubeh}(h]h ]h"]h$]h&]uh1jhjzhhhhhNubj)}(hX``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to ``.text``. Data do not contain instructions, so they have to be treated specially by the tools: they should not treat the bytes as instructions, nor assign any debug information to them. h]h)}(hX``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to ``.text``. Data do not contain instructions, so they have to be treated specially by the tools: they should not treat the bytes as instructions, nor assign any debug information to them.h](h)}(h ``SYM_DATA*``h]h SYM_DATA*}(hhhj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj&ubh -- obviously data belonging to }(h -- obviously data belonging to hj&hhhNhNubh)}(h ``.data``h]h.data}(hhhj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj&ubh sections and not to }(h sections and not to hj&hhhNhNubh)}(h ``.text``h]h.text}(hhhjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj&ubh. Data do not contain instructions, so they have to be treated specially by the tools: they should not treat the bytes as instructions, nor assign any debug information to them.}(h. Data do not contain instructions, so they have to be treated specially by the tools: they should not treat the bytes as instructions, nor assign any debug information to them.hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK_hj"ubah}(h]h ]h"]h$]h&]uh1jhjzhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jxhjEhhhhhKLubh)}(hhh](h)}(hInstruction Macrosh]hInstruction Macros}(hjhj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjzhhhhhKeubh)}(hGThis section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above.h](hThis section covers }(hThis section covers hjhhhNhNubh)}(h``SYM_FUNC_*``h]h SYM_FUNC_*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_CODE_*``h]h SYM_CODE_*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh enumerated above.}(h enumerated above.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKfhjzhhubh)}(hX!``objtool`` requires that all code must be contained in an ELF symbol. Symbol names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` prefixed symbols can be used within a code region, but should be avoided for denoting a range of code via ``SYM_*_START/END`` annotations.h](h)}(h ``objtool``h]hobjtool}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhU requires that all code must be contained in an ELF symbol. Symbol names that have a }(hU requires that all code must be contained in an ELF symbol. Symbol names that have a hjhhhNhNubh)}(h``.L``h]h.L}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh* prefix do not emit symbol table entries. }(h* prefix do not emit symbol table entries. hjhhhNhNubh)}(h``.L``h]h.L}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhk prefixed symbols can be used within a code region, but should be avoided for denoting a range of code via }(hk prefixed symbols can be used within a code region, but should be avoided for denoting a range of code via hjhhhNhNubh)}(h``SYM_*_START/END``h]hSYM_*_START/END}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh annotations.}(h annotations.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhjzhhubj)}(hhh](j)}(hXx``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the most frequent markings**. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants for special cases where developers do not want this implicit alignment. ``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are also offered as an assembler counterpart to the *weak* attribute known from C. All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks the sequence of instructions as a function and computes its size to the generated object file. Second, it also eases checking and processing such object files as the tools can trivially find exact function boundaries. So in most cases, developers should write something like in the following example, having some asm instructions in between the macros, of course:: SYM_FUNC_START(memset) ... asm insns ... SYM_FUNC_END(memset) In fact, this kind of annotation corresponds to the now deprecated ``ENTRY`` and ``ENDPROC`` macros. h](h)}(hXw``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the most frequent markings**. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants for special cases where developers do not want this implicit alignment.h](h)}(h``SYM_FUNC_START``h]hSYM_FUNC_START}(hhhj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_FUNC_START_LOCAL``h]hSYM_FUNC_START_LOCAL}(hhhj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh are supposed to be }(h are supposed to be hjhhhNhNubhstrong)}(h**the most frequent markings**h]hthe most frequent markings}(hhhjIhhhNhNubah}(h]h ]h"]h$]h&]uh1jGhjubh. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to architecture specific }(h. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to architecture specific hjhhhNhNubh)}(h ``__ALIGN``h]h__ALIGN}(hhhj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh bytes. There are also }(h bytes. There are also hjhhhNhNubh)}(h ``_NOALIGN``h]h_NOALIGN}(hhhjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhQ variants for special cases where developers do not want this implicit alignment.}(hQ variants for special cases where developers do not want this implicit alignment.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKmhjubh)}(h``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are also offered as an assembler counterpart to the *weak* attribute known from C.h](h)}(h``SYM_FUNC_START_WEAK``h]hSYM_FUNC_START_WEAK}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_FUNC_START_WEAK_NOALIGN``h]hSYM_FUNC_START_WEAK_NOALIGN}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh> markings are also offered as an assembler counterpart to the }(h> markings are also offered as an assembler counterpart to the hjhhhNhNubj,)}(h*weak*h]hweak}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j+hjubh attribute known from C.}(h attribute known from C.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKshjubh)}(hX"All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks the sequence of instructions as a function and computes its size to the generated object file. Second, it also eases checking and processing such object files as the tools can trivially find exact function boundaries.h](h All of these }(h All of these hjhhhNhNubjH)}(h **shall**h]hshall}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jGhjubh be coupled with }(h be coupled with hjhhhNhNubh)}(h``SYM_FUNC_END``h]h SYM_FUNC_END}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh. First, it marks the sequence of instructions as a function and computes its size to the generated object file. Second, it also eases checking and processing such object files as the tools can trivially find exact function boundaries.}(h. First, it marks the sequence of instructions as a function and computes its size to the generated object file. Second, it also eases checking and processing such object files as the tools can trivially find exact function boundaries.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKwhjubh)}(hSo in most cases, developers should write something like in the following example, having some asm instructions in between the macros, of course::h]hSo in most cases, developers should write something like in the following example, having some asm instructions in between the macros, of course:}(hSo in most cases, developers should write something like in the following example, having some asm instructions in between the macros, of course:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjubj")}(hASYM_FUNC_START(memset) ... asm insns ... SYM_FUNC_END(memset)h]hASYM_FUNC_START(memset) ... asm insns ... SYM_FUNC_END(memset)}(hhhjubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhjubh)}(hdIn fact, this kind of annotation corresponds to the now deprecated ``ENTRY`` and ``ENDPROC`` macros.h](hCIn fact, this kind of annotation corresponds to the now deprecated }(hCIn fact, this kind of annotation corresponds to the now deprecated hjhhhNhNubh)}(h ``ENTRY``h]hENTRY}(hhhj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h ``ENDPROC``h]hENDPROC}(hhhj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh macros.}(h macros.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can be used to define multiple names for a function. The typical use is:: SYM_FUNC_START(__memset) ... asm insns ... SYN_FUNC_END(__memset) SYM_FUNC_ALIAS(memset, __memset) In this example, one can call ``__memset`` or ``memset`` with the same result, except the debug information for the instructions is generated to the object file only once -- for the non-``ALIAS`` case. h](h)}(h``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can be used to define multiple names for a function. The typical use is::h](h)}(h``SYM_FUNC_ALIAS``h]hSYM_FUNC_ALIAS}(hhhj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj\ubh, }(h, hj\hhhNhNubh)}(h``SYM_FUNC_ALIAS_LOCAL``h]hSYM_FUNC_ALIAS_LOCAL}(hhhjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhj\ubh, and }(h, and hj\hhhNhNubh)}(h``SYM_FUNC_ALIAS_WEAK``h]hSYM_FUNC_ALIAS_WEAK}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj\ubhI can be used to define multiple names for a function. The typical use is:}(hI can be used to define multiple names for a function. The typical use is:hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjXubj")}(hfSYM_FUNC_START(__memset) ... asm insns ... SYN_FUNC_END(__memset) SYM_FUNC_ALIAS(memset, __memset)h]hfSYM_FUNC_START(__memset) ... asm insns ... SYN_FUNC_END(__memset) SYM_FUNC_ALIAS(memset, __memset)}(hhhjubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhjXubh)}(hIn this example, one can call ``__memset`` or ``memset`` with the same result, except the debug information for the instructions is generated to the object file only once -- for the non-``ALIAS`` case.h](hIn this example, one can call }(hIn this example, one can call hjhhhNhNubh)}(h ``__memset``h]h__memset}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh or }(h or hjhhhNhNubh)}(h ``memset``h]hmemset}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh with the same result, except the debug information for the instructions is generated to the object file only once -- for the non-}(h with the same result, except the debug information for the instructions is generated to the object file only once -- for the non-hjhhhNhNubh)}(h ``ALIAS``h]hALIAS}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh case.}(h case.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjXubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXc``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in special cases -- if you know what you are doing. This is used exclusively for interrupt handlers and similar where the calling convention is not the C one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC`` category above:: SYM_CODE_START_LOCAL(bad_put_user) ... asm insns ... SYM_CODE_END(bad_put_user) Again, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``. To some extent, this category corresponds to deprecated ``ENTRY`` and ``END``. Except ``END`` had several other meanings too. h](h)}(hX<``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in special cases -- if you know what you are doing. This is used exclusively for interrupt handlers and similar where the calling convention is not the C one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC`` category above::h](h)}(h``SYM_CODE_START``h]hSYM_CODE_START}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_CODE_START_LOCAL``h]hSYM_CODE_START_LOCAL}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh should be used only in special cases -- if you know what you are doing. This is used exclusively for interrupt handlers and similar where the calling convention is not the C one. }(h should be used only in special cases -- if you know what you are doing. This is used exclusively for interrupt handlers and similar where the calling convention is not the C one. hjhhhNhNubh)}(h ``_NOALIGN``h]h_NOALIGN}(hhhj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh4 variants exist too. The use is the same as for the }(h4 variants exist too. The use is the same as for the hjhhhNhNubh)}(h``FUNC``h]hFUNC}(hhhj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh category above:}(h category above:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubj")}(hSSYM_CODE_START_LOCAL(bad_put_user) ... asm insns ... SYM_CODE_END(bad_put_user)h]hSSYM_CODE_START_LOCAL(bad_put_user) ... asm insns ... SYM_CODE_END(bad_put_user)}(hhhjUubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhjubh)}(hJAgain, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``.h](h Again, every }(h Again, every hjchhhNhNubh)}(h``SYM_CODE_START*``h]hSYM_CODE_START*}(hhhjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjcubh }(h hjchhhNhNubjH)}(h **shall**h]hshall}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jGhjcubh be coupled by }(h be coupled by hjchhhNhNubh)}(h``SYM_CODE_END``h]h SYM_CODE_END}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjcubh.}(hjyhjchhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h}To some extent, this category corresponds to deprecated ``ENTRY`` and ``END``. Except ``END`` had several other meanings too.h](h8To some extent, this category corresponds to deprecated }(h8To some extent, this category corresponds to deprecated hjhhhNhNubh)}(h ``ENTRY``h]hENTRY}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``END``h]hEND}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh . Except }(h . Except hjhhhNhNubh)}(h``END``h]hEND}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh had several other meanings too.}(h had several other meanings too.hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX ``SYM_INNER_LABEL*`` is used to denote a label inside some ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``. They are very similar to C labels, except they can be made global. An example of use:: SYM_CODE_START(ftrace_caller) /* save_mcount_regs fills in first two parameters */ ... SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) /* Load the ftrace_ops into the 3rd parameter */ ... SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) call ftrace_stub ... retq SYM_CODE_END(ftrace_caller) h](h)}(h``SYM_INNER_LABEL*`` is used to denote a label inside some ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``. They are very similar to C labels, except they can be made global. An example of use::h](h)}(h``SYM_INNER_LABEL*``h]hSYM_INNER_LABEL*}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh' is used to denote a label inside some }(h' is used to denote a label inside some hjhhhNhNubh)}(h``SYM_{CODE,FUNC}_START``h]hSYM_{CODE,FUNC}_START}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_{CODE,FUNC}_END``h]hSYM_{CODE,FUNC}_END}(hhhj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhX. They are very similar to C labels, except they can be made global. An example of use:}(hX. They are very similar to C labels, except they can be made global. An example of use:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubj")}(hX>SYM_CODE_START(ftrace_caller) /* save_mcount_regs fills in first two parameters */ ... SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) /* Load the ftrace_ops into the 3rd parameter */ ... SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) call ftrace_stub ... retq SYM_CODE_END(ftrace_caller)h]hX>SYM_CODE_START(ftrace_caller) /* save_mcount_regs fills in first two parameters */ ... SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) /* Load the ftrace_ops into the 3rd parameter */ ... SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) call ftrace_stub ... retq SYM_CODE_END(ftrace_caller)}(hhhj?ubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhKmhjzhhubeh}(h]instruction-macrosah ]h"]instruction macrosah$]h&]uh1hhjEhhhhhKeubh)}(hhh](h)}(h Data Macrosh]h Data Macros}(hjfhjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjahhhhhKubh)}(hVSimilar to instructions, there is a couple of macros to describe data in the assembly.h]hVSimilar to instructions, there is a couple of macros to describe data in the assembly.}(hjthjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjahhubj)}(hhh](j)}(hX``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data and shall be used in conjunction with either ``SYM_DATA_END``, or ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that people can use ``lstack`` and (local) ``lstack_end`` in the following example:: SYM_DATA_START_LOCAL(lstack) .skip 4096 SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end) h](h)}(hX&``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data and shall be used in conjunction with either ``SYM_DATA_END``, or ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that people can use ``lstack`` and (local) ``lstack_end`` in the following example::h](h)}(h``SYM_DATA_START``h]hSYM_DATA_START}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(h and hjhhhNhNubh)}(h``SYM_DATA_START_LOCAL``h]hSYM_DATA_START_LOCAL}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhJ mark the start of some data and shall be used in conjunction with either }(hJ mark the start of some data and shall be used in conjunction with either hjhhhNhNubh)}(h``SYM_DATA_END``h]h SYM_DATA_END}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh, or }(h, or hjhhhNhNubh)}(h``SYM_DATA_END_LABEL``h]hSYM_DATA_END_LABEL}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhB. The latter adds also a label to the end, so that people can use }(hB. The latter adds also a label to the end, so that people can use hjhhhNhNubh)}(h ``lstack``h]hlstack}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and (local) }(h and (local) hjhhhNhNubh)}(h``lstack_end``h]h lstack_end}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh in the following example:}(h in the following example:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubj")}(h_SYM_DATA_START_LOCAL(lstack) .skip 4096 SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end)h]h_SYM_DATA_START_LOCAL(lstack) .skip 4096 SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end)}(hhhj ubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line data:: SYM_DATA(HEAP, .long rm_heap) SYM_DATA(heap_end, .long rm_stack) In the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END`` internally. h](h)}(hS``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line data::h](h)}(h ``SYM_DATA``h]hSYM_DATA}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh and }(h and hj hhhNhNubh)}(h``SYM_DATA_LOCAL``h]hSYM_DATA_LOCAL}(hhhj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh/ are variants for simple, mostly one-line data:}(h/ are variants for simple, mostly one-line data:hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubj")}(hDSYM_DATA(HEAP, .long rm_heap) SYM_DATA(heap_end, .long rm_stack)h]hDSYM_DATA(HEAP, .long rm_heap) SYM_DATA(heap_end, .long rm_stack)}(hhhjK ubah}(h]h ]h"]h$]h&]j1j2uh1j!hhhKhj ubh)}(hOIn the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END`` internally.h](hIn the end, they expand to }(hIn the end, they expand to hjY hhhNhNubh)}(h``SYM_DATA_START``h]hSYM_DATA_START}(hhhjb hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjY ubh with }(h with hjY hhhNhNubh)}(h``SYM_DATA_END``h]h SYM_DATA_END}(hhhju hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjY ubh internally.}(h internally.hjY hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhKhjahhubeh}(h] data-macrosah ]h"] data macrosah$]h&]uh1hhjEhhhhhKubh)}(hhh](h)}(hSupport Macrosh]hSupport Macros}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hAll the above reduce themselves to some invocation of ``SYM_START``, ``SYM_END``, or ``SYM_ENTRY`` at last. Normally, developers should avoid using these.h](h6All the above reduce themselves to some invocation of }(h6All the above reduce themselves to some invocation of hj hhhNhNubh)}(h ``SYM_START``h]h SYM_START}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh, }(h, hj hhhNhNubh)}(h ``SYM_END``h]hSYM_END}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh, or }(h, or hj hhhNhNubh)}(h ``SYM_ENTRY``h]h SYM_ENTRY}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh8 at last. Normally, developers should avoid using these.}(h8 at last. Normally, developers should avoid using these.hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hX Further, in the above examples, one could see ``SYM_L_LOCAL``. There are also ``SYM_L_GLOBAL`` and ``SYM_L_WEAK``. All are intended to denote linkage of a symbol marked by them. They are used either in ``_LABEL`` variants of the earlier macros, or in ``SYM_START``.h](h.Further, in the above examples, one could see }(h.Further, in the above examples, one could see hj hhhNhNubh)}(h``SYM_L_LOCAL``h]h SYM_L_LOCAL}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh. There are also }(h. There are also hj hhhNhNubh)}(h``SYM_L_GLOBAL``h]h SYM_L_GLOBAL}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh and }(h and hj hhhNhNubh)}(h``SYM_L_WEAK``h]h SYM_L_WEAK}(hhhj* hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhY. All are intended to denote linkage of a symbol marked by them. They are used either in }(hY. All are intended to denote linkage of a symbol marked by them. They are used either in hj hhhNhNubh)}(h ``_LABEL``h]h_LABEL}(hhhj= hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh' variants of the earlier macros, or in }(h' variants of the earlier macros, or in hj hhhNhNubh)}(h ``SYM_START``h]h SYM_START}(hhhjP hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh.}(hjyhj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]support-macrosah ]h"]support macrosah$]h&]uh1hhjEhhhhhKubh)}(hhh](h)}(hOverriding Macrosh]hOverriding Macros}(hju hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjp hhhhhKubh)}(hXmArchitecture can also override any of the macros in their own ``asm/linkage.h``, including macros specifying the type of a symbol (``SYM_T_FUNC``, ``SYM_T_OBJECT``, and ``SYM_T_NONE``). As every macro described in this file is surrounded by ``#ifdef`` + ``#endif``, it is enough to define the macros differently in the aforementioned architecture-dependent header.h](h>Architecture can also override any of the macros in their own }(h>Architecture can also override any of the macros in their own hj hhhNhNubh)}(h``asm/linkage.h``h]h asm/linkage.h}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh4, including macros specifying the type of a symbol (}(h4, including macros specifying the type of a symbol (hj hhhNhNubh)}(h``SYM_T_FUNC``h]h SYM_T_FUNC}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh, }(h, hj hhhNhNubh)}(h``SYM_T_OBJECT``h]h SYM_T_OBJECT}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh, and }(h, and hj hhhNhNubh)}(h``SYM_T_NONE``h]h SYM_T_NONE}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh;). As every macro described in this file is surrounded by }(h;). As every macro described in this file is surrounded by hj hhhNhNubh)}(h ``#ifdef``h]h#ifdef}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh + }(h + hj hhhNhNubh)}(h ``#endif``h]h#endif}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhd, it is enough to define the macros differently in the aforementioned architecture-dependent header.}(hd, it is enough to define the macros differently in the aforementioned architecture-dependent header.hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjp hhubeh}(h]overriding-macrosah ]h"]overriding macrosah$]h&]uh1hhjEhhhhhKubeh}(h]macros-descriptionah ]h"]macros descriptionah$]h&]uh1hhhhhhhhKGubeh}(h]assembler-annotationsah ]h"]assembler annotationsah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj= error_encodingUTF-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confapep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacefile_insertion_enabled raw_enabledKline_length_limitM'syntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_link embed_imagesenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames} discussion]jasrefids}nameids}(j j jmjjjBj?j9j6j j j^j[j j jm jj j j u nametypes}(j NjmNjBNj9j Nj^Nj Njm Nj Nuh}(j hjjjj?jpj6j0j jEj[jzj jajj j j jp u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.