mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-14 13:09:34 +08:00
9d6b00511e
Augment the arm_asm.h header file to simplify function prologues and epilogues whilst adding support for PACBTI enablement via macros for hand-written assembly functions. For PACBTI, both prologues/epilogues as well as cfi-related directives are automatically amended accordingly, depending on the compile-time mbranch-protection argument values. It defines the following preprocessor macros: * HAVE_PAC_LEAF: Indicates whether pac-signing has been requested for leaf functions. * PAC_LEAF_PUSH_IP: Whether leaf functions should push the pac code to the stack irrespective of whether the ip register is clobbered in the function or not. * STACK_ALIGN_ENFORCE: Whether a dummy register should be added to the push list as necessary in the prologue to ensure stack alignment preservation at the start of assembly function. The epilogue behavior is likewise affected by this flag, ensuring any pushed dummy registers also get popped on function return. It also defines the following assembler macros: * prologue: In addition to pushing any callee-saved registers onto the stack, it generates any requested pacbti instructions. Pushed registers are specified via the optional `first', `last', `push_ip' and `push_lr' macro argument parameters. when a single register number is provided, it pushes that register. When two register numbers are provided, they specify a rage to save. If push_ip and/or push_lr are non-zero, the respective registers are also saved. Stack alignment is requested via the `align` argument, which defaults to the value of STACK_ALIGN_ENFORCE, unless manually overridden. For example: prologue push_ip=1 -> push {ip} prologue push_ip=1, align8=1 -> push {r2, ip} prologue push_ip=1, push_lr=1 -> push {ip, lr} prologue 1 -> push {r1} prologue 1, align8=1 -> push {r0, r1} prologue 1 push_ip=1 -> push {r1, ip} prologue 1 4 -> push {r1-r4} prologue 1 4 push_ip=1 -> push {r1-r4, ip} * epilogue: pops registers off the stack and emits pac key signing instruction, if requested. The `first', `last', `push_ip', `push_lr' and `align' function as per the prologue macro, generating pop instead of push instructions. Stack alignment is enforced via the following helper macro call-chain: {prologue|epilogue} ->_align8 -> _preprocess_reglist -> _preprocess_reglist1 -> {_prologue|_epilogue} Finally, the necessary cfi directives for adding debug information to prologue and epilogue are generated via the following macros: * cfisavelist - prologue macro helper function, generating necessary .cfi_offset directives associated with push instruction. Therefore, the net effect of calling `prologue 1 2 push_ip=1' is to generate the following: push {r1-r2, ip} .cfi_adjust_cfa_offset 12 .cfi_offset 143, -4 .cfi_offset 2, -8 .cfi_offset 1, -12 * cfirestorelist - epilogue macro helper function, emitting .cfi_restore instructions prior to resetting the cfa offset. As such, calling `epilogue 1 2 push_ip=1' will produce: pop {r1-r2, ip} .cfi_register 143, 12 .cfi_restore 2 .cfi_restore 1 .cfi_def_cfa_offset 0