[PATCH/RFA] elf64-alpha: Don't put DT_PLTGOT dynamic if no PLT
Jason R Thorpe
thorpej@wasabisystems.com
Thu Jul 18 14:16:00 GMT 2002
The following was found/fixed in NetBSD's 2.11.2-based binutils
by Charles Hannum. The problem is still present in binutils CVS.
The problem occurs when a shared object contains no external references,
and thus has no PLT. elf64_alpha_size_dynamic_sections() inserts a
DT_PLTGOT entry anyway, which confuses the dynamic linker, resulting in
a crash. Here is a test case:
--- a.c ---
fred () { }
---
--- b.c ---
#include <stdio.h>
#include <dlfcn.h>
extern int fred();
main()
{
void *handle;
void *symbol;
handle = dlopen("./a.so", RTLD_NOW);
if (handle == NULL) {
printf("dlopen failed");
exit(1);
}
dlclose(handle);
exit(0);
}
---
% /usr/local/gnu/bin/gcc -shared -o a.so a.c
% /usr/local/gnu/bin/gcc -o b b.c
% ./b
pid 1969 (b): unaligned access: va=0x16001447c pc=0x1600144dc ra=0x160026a68 sp=0x1fffff368 op=ldq
Memory fault (core dumped)
%
(FWIW, the test case was essentially extracted from autoconf tests performed
by perl and zsh.)
The following patch fixes the problem by only adding DT_PLTGOT if there
is a PLT.
OK for mainline?
OK for 2.13 branch?
OK for 2.12 branch?
* elf64-alpha.c (elf64_alpha_size_dynamic_sections): Only insert
DT_PLTGOT into the dynamic section if there is a PLT.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
-------------- next part --------------
Index: elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.77
diff -c -r1.77 elf64-alpha.c
*** elf64-alpha.c 7 Jul 2002 09:10:40 -0000 1.77
--- elf64-alpha.c 18 Jul 2002 20:49:40 -0000
***************
*** 4120,4131 ****
return false;
}
- if (!add_dynamic_entry (DT_PLTGOT, 0))
- return false;
-
if (relplt)
{
! if (!add_dynamic_entry (DT_PLTRELSZ, 0)
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0))
return false;
--- 4120,4129 ----
return false;
}
if (relplt)
{
! if (!add_dynamic_entry (DT_PLTGOT, 0)
! || !add_dynamic_entry (DT_PLTRELSZ, 0)
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0))
return false;
More information about the Binutils
mailing list