Я пытаюсь понять, что делает этот фрагмент встроенной сборки, сгенерированный из макроса C DEFINE
:
#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
Он используется в какой-то магии для выполнения AArch64 smc
вызовы в linux-imx форке ядра.Место, где вышеупомянутые макросы C используются для определения значений: здесь :
// arch/arm64/kernel/asm-offsets.c
int main(void)
{
(...)
DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state));
(...)
}
И позже, эти определения используются в макросе сборки, доступном здесь (или, по крайней мере, так выглядит):
// arch/arm64/kernel/smccc-call.S
.macro SMCCC instr
.cfi_startproc
\instr #0
ldr x4, [sp]
stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
ldr x4, [sp, #8]
cbz x4, 1f /* no quirk structure */
ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6
b.ne 1f
str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
1: ret
.cfi_endproc
.endm
ENTRY(__arm_smccc_smc)
SMCCC smc
ENDPROC(__arm_smccc_smc)
Который, в конечном итоге, используется на практике, например, в gpc-psci driver .
Я попытался изолировать код в отдельной голой программе AArch64, чтобы увидеть, как макросы расширяются и работают на практике, но все, что я получаю, это ошибки компиляции.
// main.c
// the struct arm_smccc_res and others are inserted here to satisfy the compiler
int
main()
{
DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state));
return 0;
}
// gcc output
/tmp/cccqaaY3.s: Assembler messages:
/tmp/cccqaaY3.s:459: Error: junk at end of line, first unrecognized character is `-'
/tmp/cccqaaY3.s:464: Error: junk at end of line, first unrecognized character is `-'
/tmp/cccqaaY3.s:469: Error: junk at end of line, first unrecognized character is `-'
/tmp/cccqaaY3.s:474: Error: junk at end of line, first unrecognized character is `-'
Макрос offsetof
не требует пояснений, но у меня возникают проблемы с пониманием использования строкового преобразования и ->
в макросе DEFINE
.
Любые идеи, для чего он расширен, или как успешно скомпилировать это?