FAQs

为什么static key应当被用在较少改变的特性上?

两点原因:

  • 对static key的修改需要绕过DEP,会带来潜在的安全风险。不过DEP会在修改结束后重新生效。
  • 对static key的修改比较慢,因为涉及到了许多系统调用。

为什么static key必须在单线程环境下修改?

在用户态,如果要修改别的线程可能会执行到的指令会非常复杂。Linux内核社区曾经提出过text_poke系统调用,但是如今仍不可用。顺带一提,Linus好像不太喜欢这个,并且他说的很有道理。

另一个原因是我们需要操作内存保护权限来绕过DEP,但是在多线程环境下,这会引发保护权限本身的race condition。尽管可以用mutex来解决数据竞争的问题,但是如果cargo解析出多版本的static-keys依赖,那么每个版本中都会有一个全局mutex实例,这种方法就失效了。这个可以被RFC 1977: public & private dependencies解决。rust-lang/cargo#2363亦可供参考。

为什么需要nightly Rust?

我们在内部使用了内联汇编,并且使用了asm_gotoasm_const这两个特性。只要这两个特性稳定了,我们就能使用stable Rust了。

为什么static_branch_likely!static_branch_unlikely!是宏?

因为内联汇编的sym参数需要是静态路径,这在函数里是做不到的。

如果要扩展到新的操作系统,需要实现哪些操作系统特性?

  • 标志一个自定义节的开始和结束的符号

    这是用来对static key排序,以及标志循环结束

  • 保证自定义节不会被链接器的GC回收的方案

  • 绕过DEP的方案

    用于更新static branch的指令

如果要扩展到新的指令集架构,需要实现哪些架构特性?

  • jmp等长的nop指令(或者可以整除,如2字节nop与4字节jmp
  • 在Linux上清除指令缓存的方式(需加入到Evian-Zhang/clear-cache
  • Rust支持的内联汇编

我可以在no_std环境中使用吗?

可以