Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

Update ELF psABI spec to include new ABI types #20

Closed

Conversation

scylaac
Copy link
Contributor

@scylaac scylaac commented Oct 13, 2021

No description provided.

@scylaac scylaac force-pushed the update-abi-types-conventions-no-libpath branch from a775b9e to 0bea579 Compare October 15, 2021 01:17
@scylaac scylaac force-pushed the update-abi-types-conventions-no-libpath branch 2 times, most recently from e12efb8 to 525fe48 Compare October 22, 2021 01:39
@FreeFlyingSheep
Copy link
Collaborator

@yetist
Copy link
Contributor

yetist commented Oct 22, 2021

是不是分别说一下EI_CLASSe_machinee_flags等分别位于ELF格式头结构的第几位等信息对开发者会更友好一些?

|/lib64/ld-linux-loongarch-lp64-df.so.<abiversion>

|lp64/single
|/lib64/ld-linux-loongarch-lp64-sf.so.<abiversion>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我怎么感觉看到 sf 的第一反应,应该是 soft float?而现在是表示为 single float 的。

按目前的规则,缩写为2个字母,那么 single floatsoft float 都是可以缩写为 sf 的,这样存在比较明显的歧义,或者说不具备唯一性,建议重新考虑一下这里的命名方案。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

讨论了一下。我们认为在有-df的情况下,-sf的歧义并不是很大。

选用两个字母后缀单独标定浮点/扩展ABI类型的原因是:

  1. 我们希望编译器的ABI命令行选项 (-mabi / -mfloat-abi) 和动态链接器名称能有一个明显的对应关系。
  2. 为了让命令行界面的逻辑保持简单,我们不太希望提供功能较复杂的ABI选项别名 (例如-mabi=lp64d)。
    (这个是集体意见)

在满足这个要求的情况下,感觉并没有更好的方案。(RISC-V的MUSL动态链接器也用两个字母后缀标定浮点ABI,单精度对应-sp,软浮点对应-sf,也并没有特别一目了然)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在满足这个要求的情况下,感觉并没有更好的方案。(RISC-V的MUSL动态链接器也用两个字母后缀标定浮点ABI,单精度对应-sp,软浮点对应-sf,也并没有特别一目了然)

那是不是可以和它们保持一致呢(单精度对应-sp,软浮点对应-sf)?感觉没必要对相同的东西采用不同的缩写。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

它没有"-df"这种情况,64位整数 + 双精度浮点ABI对应的就是"ld-musl-riscv64.so.1"。我们还是比较希望保持各ABI类型的后缀格式一样。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有其他更好方案的话,就尽快按这个执行吧。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoongArch LP64 ABI 不隐含支持 SP/DP 硬浮点?

如果隐含支持的话,LP64 不需要特意标注。否则的话,RV 的做法是在 ABI 名字里带上“F/D”字样,建议是 LA 这边也一样写成“LP64/LP64F/LP64D”的形式,否则单说“LP64”不能精确指定一个 ABI 了。但考虑到先前已经进行的工作都把 LP64(-mabi=lp64)当作支持双精度硬浮点看待了,那可能我们得采用 LP64S/LP64F/LP64 之类的写法了。

无论如何,nf 表示软浮点都不是一个好的选择,我除了用中式英语理解为“non float”之外找不到任何可行的解释可以说明“n”的含义。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参见 #23 的讨论,lp64 确实不代表完整的 ABI 类型,也不隐含支持硬浮点,使用双精度硬浮点传参的 ABI 是 lp64/doublenf 代表 no fpu

@scylaac scylaac force-pushed the update-abi-types-conventions-no-libpath branch from 525fe48 to 2afa0cf Compare October 25, 2021 01:55
@scylaac scylaac force-pushed the update-abi-types-conventions-no-libpath branch from 2afa0cf to 04fc2f3 Compare October 25, 2021 01:57
@scylaac
Copy link
Contributor Author

scylaac commented Oct 25, 2021

是不是分别说一下EI_CLASSe_machinee_flags等分别位于ELF格式头结构的第几位等信息对开发者会更友好一些?

已加入到 SystemV generic ABI 文档 的链接。ELF相关的名称可以在那里找到定义。

=== e_flags: ABI 变体标记
[%header,cols="1,1,1,1"]
|=========================================
|`[1:0]` 位 | `[5:2]` 位 | `[17:16]` 位 | `[31:18]` `[15:6]` 位
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

从左到右按低位到高位依次解释,/31:18... 1:0/,这样更好看一些?

|/lib64/ld-linux-loongarch-lp64-df.so.<abiversion>

|lp64/single
|/lib64/ld-linux-loongarch-lp64-sf.so.<abiversion>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有其他更好方案的话,就尽快按这个执行吧。

@xen0n
Copy link
Contributor

xen0n commented Oct 27, 2021

按照后缀“S/F/(空缺)”分别代表“软浮点/单精度硬浮点/双精度硬浮点”的顺序,可以这样设计:

ABI Program interpreter path
ILP32S /lib/ld-linux-loongarch32-ilp32s.so.1
ILP32F /lib/ld-linux-loongarch32-ilp32f.so.1
ILP32 /lib/ld-linux-loongarch32-ilp32.so.1
LP64S /lib64/ld-linux-loongarch64-lp64s.so.1
LP64F /lib64/ld-linux-loongarch64-lp64f.so.1
LP64 /lib64/ld-linux-loongarch64-lp64.so.1
  • 保持了既有的 LP64 隐含支持双精度硬浮点的语义,减少上游折腾。
  • 较为通行的 lib path 是 /lib /lib32 lib64 分别表示类似 x86_32、x32、x86_64(也就是 MIPS o32/n32/n64)的 ABI,许多程序默认也是照此理解,因此不建议 ILP32 系列 ABI 文件进 /lib32。FYI 从前的 Gentoo amd64 multilib 系统采用的是类似的布局,他们 /lib 符号链接到原生 ABI,/lib32 放 32 位库,/lib64 放 64 位库;前几年已经改掉了,改成 x86 界的通行方案了(/lib 放 32 位库和部分架构无关的程序代码如 Python、Perl 包等等,/lib64 放 64 位库,/libx32 放 x32 库)。
  • IIUC 32 位 ABI 不会用到 64 位指令,因此架构名建议是改成 loongarch32

最后重申对 nf 代表“软浮点”语义的反对。至少需要给出已有如此实践的架构的案例。

@yetist
Copy link
Contributor

yetist commented Oct 27, 2021

按照后缀“S/F/(空缺)”分别代表“软浮点/单精度硬浮点/双精度硬浮点”的顺序,可以这样设计:

这个方案感觉是好一些。

@xen0n
Copy link
Contributor

xen0n commented Oct 27, 2021

另外一种方案,参考了 AArch64 的安排;AArch64 架构本身一定是支持 64 位的,但可以有 32 位 ABI,因此默认不标记,ILP32 单独标记:

// glibc sysdeps/unix/sysv/linux/aarch64/ldconfig.h

#define SYSDEP_KNOWN_INTERPRETER_NAMES \
  { "/lib/ld-linux-aarch64.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_be.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_ilp32.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_be_ilp32.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux.so.3", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-armhf.so.3", FLAG_ELF_LIBC6 },

出于一些目前不清楚的原因,他们 32 位和 64 位的 ld.so 都放在 /lib 下面,因此 ilp32 字样需要完整露出。

当然,看代码他们似乎只是预留了 ilp32 的位置,真正实现的只有一个 ABI:

# glibc sysdeps/unix/sysv/linux/aarch64/shlib-versions

DEFAULT                 GLIBC_2.17

%ifdef HAVE_AARCH64_BE
ld=ld-linux-aarch64_be.so.1
%else
ld=ld-linux-aarch64.so.1
%endif

由于目前 LoongArch 的 32、64 位版本,各只有一个 ABI 已经实现了(计划实现),可以考虑把 lp64 ilp32 字样隐去,缩短几个字符(已经由 lib 目录的名字和架构名体现了),这样的话可以安排如下:

ABI Program interpreter path
ILP32S /lib/ld-linux-loongarch32-s.so.1
ILP32F /lib/ld-linux-loongarch32-f.so.1
ILP32 /lib/ld-linux-loongarch32.so.1
LP64S /lib64/ld-linux-loongarch64-s.so.1
LP64F /lib64/ld-linux-loongarch64-f.so.1
LP64 /lib64/ld-linux-loongarch64.so.1

当然这么做也有坏处,主要在于 ABI 名称没有完整、明显体现,在一些字符串处理能力受限的场合,不便操作。能想到的比前述方案唯一的好处是 CLFS、Gentoo 等已经制作的发行版,LP64 的部分不用动了,可以省一次全系统重编译。

(Disclaimer:对于重编译,我个人是全力支持的:在架构草创期间,“没人用”是个宝贵的、不可再生的优势。能力所及,不应该留下任何不一致、不对称、不优雅的地方,给后人挖坑,提高无数人的记忆量、学习成本。)

@ChenghuaXu
Copy link
Contributor

另外一种方案,参考了 AArch64 的安排;AArch64 架构本身一定是支持 64 位的,但可以有 32 位 ABI,因此默认不标记,ILP32 单独标记:

这个默认不标记,不好吧,目前实现和计划实现没问题,最好还要预留可能的实现。

// glibc sysdeps/unix/sysv/linux/aarch64/ldconfig.h

#define SYSDEP_KNOWN_INTERPRETER_NAMES \
  { "/lib/ld-linux-aarch64.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_be.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_ilp32.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-aarch64_be_ilp32.so.1", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux.so.3", FLAG_ELF_LIBC6 }, \
  { "/lib/ld-linux-armhf.so.3", FLAG_ELF_LIBC6 },

出于一些目前不清楚的原因,他们 32 位和 64 位的 ld.so 都放在 /lib 下面,因此 ilp32 字样需要完整露出。

当然,看代码他们似乎只是预留了 ilp32 的位置,真正实现的只有一个 ABI:

# glibc sysdeps/unix/sysv/linux/aarch64/shlib-versions

DEFAULT                 GLIBC_2.17

%ifdef HAVE_AARCH64_BE
ld=ld-linux-aarch64_be.so.1
%else
ld=ld-linux-aarch64.so.1
%endif

由于目前 LoongArch 的 32、64 位版本,各只有一个 ABI 已经实现了(计划实现),可以考虑把 lp64 ilp32 字样隐去,缩短几个字符(已经由 lib 目录的名字和架构名体现了),这样的话可以安排如下:

ABI Program interpreter path
ILP32S /lib/ld-linux-loongarch32-s.so.1
ILP32F /lib/ld-linux-loongarch32-f.so.1
ILP32 /lib/ld-linux-loongarch32.so.1
LP64S /lib64/ld-linux-loongarch64-s.so.1
LP64F /lib64/ld-linux-loongarch64-f.so.1
LP64 /lib64/ld-linux-loongarch64.so.1

这样不对称了,不好看吧。

当然这么做也有坏处,主要在于 ABI 名称没有完整、明显体现,在一些字符串处理能力受限的场合,不便操作。能想到的比前述方案唯一的好处是 CLFS、Gentoo 等已经制作的发行版,LP64 的部分不用动了,可以省一次全系统重编译。

(Disclaimer:对于重编译,我个人是全力支持的:在架构草创期间,“没人用”是个宝贵的、不可再生的优势。能力所及,不应该留下任何不一致、不对称、不优雅的地方,给后人挖坑,提高无数人的记忆量、学习成本。)

@xen0n
Copy link
Contributor

xen0n commented Oct 27, 2021

另外一种方案,参考了 AArch64 的安排;AArch64 架构本身一定是支持 64 位的,但可以有 32 位 ABI,因此默认不标记,ILP32 单独标记:

这个默认不标记,不好吧,目前实现和计划实现没问题,最好还要预留可能的实现。

由于目前 LoongArch 的 32、64 位版本,各只有一个 ABI 已经实现了(计划实现),可以考虑把 lp64 ilp32 字样隐去,缩短几个字符(已经由 lib 目录的名字和架构名体现了),这样的话可以安排如下:
ABI Program interpreter path
ILP32S /lib/ld-linux-loongarch32-s.so.1
ILP32F /lib/ld-linux-loongarch32-f.so.1
ILP32 /lib/ld-linux-loongarch32.so.1
LP64S /lib64/ld-linux-loongarch64-s.so.1
LP64F /lib64/ld-linux-loongarch64-f.so.1
LP64 /lib64/ld-linux-loongarch64.so.1

这样不对称了,不好看吧。

当然这么做也有坏处,主要在于 ABI 名称没有完整、明显体现,在一些字符串处理能力受限的场合,不便操作。能想到的比前述方案唯一的好处是 CLFS、Gentoo 等已经制作的发行版,LP64 的部分不用动了,可以省一次全系统重编译。
(Disclaimer:对于重编译,我个人是全力支持的:在架构草创期间,“没人用”是个宝贵的、不可再生的优势。能力所及,不应该留下任何不一致、不对称、不优雅的地方,给后人挖坑,提高无数人的记忆量、学习成本。)

见上述的 Disclaimer,这里只是提供多种方案供参考,这个方案的坏处我是明确知道的。For the record,我对此问题个人所持的态度是我提出的第一种方案。

@scylaac
Copy link
Contributor Author

scylaac commented Oct 27, 2021

较为通行的 lib path 是 /lib /lib32 lib64 分别表示类似 x86_32、x32、x86_64(也就是 MIPS o32/n32/n64)的 ABI,许多程序默认也是照此理解,因此不建议 ILP32 系列 ABI 文件进 /lib32。FYI 从前的 Gentoo amd64 multilib 系统采用的是类似的布局,他们 /lib 符号链接到原生 ABI,/lib32 放 32 位库,/lib64 放 64 位库;前几年已经改掉了,改成 x86 界的通行方案了(/lib 放 32 位库和部分架构无关的程序代码如 Python、Perl 包等等,/lib64 放 64 位库,/libx32 放 x32 库)。

参考 Gentoo Wiki,提到切换布局的主要原因是这个:

Why lib and not lib32?
Using lib is beneficial to compatibility with prebuilt x86 software, e.g. old games. All that software is naturally built to use lib as libdir, and using the same directory on multilib amd64 systems improves compatibility and reduces the need for custom hacks to keep things working.

la32上目前还没有二进制程序兼容的问题,统一使用 "lib32" 会比较明确。

@xen0n
Copy link
Contributor

xen0n commented Oct 27, 2021

la32上目前还没有二进制程序兼容的问题,统一使用 "lib32" 会比较明确。

这样确实 /lib /usr/lib 会干净许多,毕竟只剩下架构无关的库文件、预装配置文件了。这一点建议大家还是回去沉淀一下,我也再思考一下。

@xry111
Copy link
Contributor

xry111 commented Oct 27, 2021

由于目前 LoongArch 的 32、64 位版本,各只有一个 ABI 已经实现了(计划实现),可以考虑把 lp64 ilp32 字样隐去,缩短几个字符(已经由 lib 目录的名字和架构名体现了),这样的话可以安排如下:
ABI Program interpreter path
ILP32S /lib/ld-linux-loongarch32-s.so.1
ILP32F /lib/ld-linux-loongarch32-f.so.1
ILP32 /lib/ld-linux-loongarch32.so.1
LP64S /lib64/ld-linux-loongarch64-s.so.1
LP64F /lib64/ld-linux-loongarch64-f.so.1
LP64 /lib64/ld-linux-loongarch64.so.1

这样不对称了,不好看吧。

我比较倾向于 LPxxS/LPxxF/LPxxD。

说实话如果完全不考虑“历史和惯例”的话我会选择 LP64F0, LP64F32, 以及 LP64F64,这样如果之后有 F80 或者 F128 就不用再争论一遍 :)

当然这么做也有坏处,主要在于 ABI 名称没有完整、明显体现,在一些字符串处理能力受限的场合,不便操作。能想到的比前述方案唯一的好处是 CLFS、Gentoo 等已经制作的发行版,LP64 的部分不用动了,可以省一次全系统重编译。

这个我是感觉问题不大,过渡期可以 ln -sv ld-linux-loongarch64-d.so.1 /lib64/ld-linux-loongarch64.so.1 (目前 x86 也有 ld-lsb-x86-64.so.3 这种链接)。

(Disclaimer:对于重编译,我个人是全力支持的:在架构草创期间,“没人用”是个宝贵的、不可再生的优势。能力所及,不应该留下任何不一致、不对称、不优雅的地方,给后人挖坑,提高无数人的记忆量、学习成本。)

@xry111
Copy link
Contributor

xry111 commented Oct 27, 2021

la32上目前还没有二进制程序兼容的问题,统一使用 "lib32" 会比较明确。

这样确实 /lib /usr/lib 会干净许多,毕竟只剩下架构无关的库文件、预装配置文件了。这一点建议大家还是回去沉淀一下,我也再思考一下。

同意 lib32/lib64 的方案,lib 如果在纯 64 位发行版上发行版可以把它弄成一个指向 lib64 的链接 (或者反过来链接也行)。

x32 这种东西首先就算在 x86_64 生态里面也没人真的用,一般是拿来跑分的,其次为啥不叫 libx32……

@scylaac
Copy link
Contributor Author

scylaac commented Nov 1, 2021

已参考各位意见更新:#24

@scylaac scylaac closed this Nov 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants