IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Raw symbol names in inline assembly

    MaskRay发表于 2024-01-31 06:15:39
    love 0

    GCC's aarch64 port, from the beginning (2012), supports the constraint"S" to reference a symbol or label. This is nice, as you can create anartificial reference for linker garbage collection, defining sections tohold symbol addresses, or even enabling more creative applications.

    1
    2
    3
    4
    5
    6
    7
    8
    namespace ns { extern int a[4]; }
    void fun();
    void foo() {
    label:
    asm(".pushsection .xxx,\"aw\"; .dc.a %0; .popsection" :: "S"(&ns::a[3]));
    asm(".reloc ., BFD_RELOC_NONE, %0" :: "S"(fun));
    asm("// %0" :: "S"(&&label));
    }

    Using the generic r or m constraint in suchcases would instruct GCC to generate instructions to compute theaddress, which can be wasteful if the materialized address isn'tactually needed.

    1
    2
    3
    4
    // aarch64
    asm("// %0" :: "r"(fun));
    // adrp x0, _GLOBAL_OFFSET_TABLE_
    // ldr x0, [x0, #:gotpage_lo15:_Z3funv]

    C++ templates can make this easier to use.

    1
    2
    3
    template <class T, T &x>
    void ref() { asm (".reloc ., BFD_RELOC_NONE, %0" :: "S"(x)); }
    void use() { ref<decltype(ns::a), ns::a>(); }

    RISC-V

    GCC's RISC-V port, from the beginning (2017), supports the constraint"S" for a similar purpose as well. However, the operand cannot be apreemptible symbol (non-local symbol in GCC's term). I have just filed[PATCH]RISC-V: Allow constraint "S" even if the symbol does not bindlocally to relax the condition.

    x86

    Unfortunately, there had been no suitable constraint for x86 for along time. We can use the constraint "i" with the modifier "p" to printraw symbol name without syntax-specific prefixes, but it does not workwhen:

    • -mcmodel=large is used
    • or the symbol is preemptible (similar to RISC-V's "S" problem)
    1
    2
    3
    4
    5
    void foo() {
    label:
    asm("// %p0" :: "i"(foo)); // Does not work if foo is preemptible
    asm("// %p0" :: "i"(&&label));
    }

    I filed the featurerequest for a new constraint in May 2022 and eventually decided toimplement it by myself. The patch landed today, catching the GCC 14release.

    BTW, there are a few other modifiers that work similarly to "p", like"c". I think having such a longlist of modifiers is unfortunate.



沪ICP备19023445号-2号
友情链接