Просмотр исходного кода

ldso: powerpc: assign static TLS before relocating TPREL32

An initial-exec TLS variable in a dlopened module reads garbage on
powerpc.  tst-tls15 loads such a module and expects its variable to be
zero; it returns 205.

R_PPC_TPREL32 is relocated with tls_tpnt->l_tls_offset, but a module that
was not part of the initial link has no offset yet -- l_tls_offset is
still NO_TLS_OFFSET, which is 0 here, so the access lands 0x7000 below
the thread pointer instead of inside the module's block.  The other
eighteen architectures with TLS relocations all call CHECK_STATIC_TLS
first, which assigns an offset out of the static TLS surplus; powerpc was
the only one that did not.

Verified on powerpc/6.1.60 under qemu-system-ppc: tst-tls15 and
tst-tls15-O2 pass.

Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
ramin 1 неделя назад
Родитель
Сommit
e4158c7f43
1 измененных файлов с 1 добавлено и 0 удалено
  1. 1 0
      ldso/ldso/powerpc/elfinterp.c

+ 1 - 0
ldso/ldso/powerpc/elfinterp.c

@@ -292,6 +292,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope,
 		*reloc_addr = finaladdr - TLS_DTV_OFFSET;
 		*reloc_addr = finaladdr - TLS_DTV_OFFSET;
 		break;
 		break;
 	case R_PPC_TPREL32:
 	case R_PPC_TPREL32:
+		CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
 		*reloc_addr = tls_tpnt->l_tls_offset + finaladdr - TLS_TP_OFFSET;
 		*reloc_addr = tls_tpnt->l_tls_offset + finaladdr - TLS_TP_OFFSET;
 		break;
 		break;
 #endif
 #endif