s390x: .hash table entries should have 8 bytes instead of 4 bytes!
Closed this issue · 3 comments
A simple test on s390x shows that a .hash table with 4 byte entries is created by mold:
$ gcc -fuse-ld=mold -Wl,--hash-style=sysv -shared -o libXYZ.so XYZ.o
$ readelf -S libXYZ.so | grep -A1 -e "\.hash" -e "\[Nr\]"
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
--
[ 2] .hash HASH 0000000000000294 00000294
0000000000000040 0000000000000004 A 3 0 4
According to the ELF specification, the .hash table contains Elf32_Word objects. But unfortunately on s390x (and also on alpha), Elf64_Word objects are used! Therefore we need a special handling here.
If .hash table is used while execution of the library/binary, it most likely crashs with a segmentation fault.
Here are some references to other projects regarding those 8byte entries:
/* 64 bit Linux for S/390 is exceptional as it has .hash section with
64 bit entries. */
typedef uint64_t Elf_Symndx;
- musl:
typedef uint64_t Elf_Symndx;
/* Why was the hash table entry size definition changed from
ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
this is the only reason for the s390_elf64_size_info structure. */
const struct elf_size_info s390_elf64_size_info =
{
...
8, /* hash-table entry size. */
Target::Target_info Target_s390<64>::s390_info =
{
...
64, // hash_entry_size
if ((filedata->file_header.e_machine == EM_ALPHA
|| filedata->file_header.e_machine == EM_S390
|| filedata->file_header.e_machine == EM_S390_OLD)
&& filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
hash_ent_size = 8;
- lld:
lld currently also uses the wrong 4 byte entries on s390x, but there is already this pull-request:
Make hashtable entry size configurable #113431
Thank you for your report. The above change should address the issue.
@rui314 FYI: I've build mold with your commit and checked on s390x:
$ gcc -fuse-ld=mold -Wl,--hash-style=sysv -shared -o libXYZ.so XYZ.o
$ readelf -S libXYZ.so | grep -A1 -e "\.hash" -e "\[Nr\]"
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
--
[ 2] .hash HASH 0000000000000298 00000298
0000000000000080 0000000000000008 A 3 0 8
Now I see 8byte entries and a small testprogram runs without segmentation fault.
Thanks a lot.
Thank you for testing. Feel free to submit more bugs if mold doesn't work for s390x.