[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