rui314/mold

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;
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;

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.