Subject: Re: port-amd64/30570: dlopen(..., RTLD_NOW) always returns non-null
To: Christos Zoulas <christos@zoulas.com>
From: Nick Hudson <nick.hudson@dsl.pipex.com>
List: netbsd-bugs
Date: 06/21/2005 07:21:04
--Boundary-00=_h/7tCyO/oKD8yup
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
On Tuesday 21 June 2005 04:22, Christos Zoulas wrote:
> On Jun 21, 4:16am, jlam@NetBSD.org (jlam@NetBSD.org) wrote:
> -- Subject: port-amd64/30570: dlopen(..., RTLD_NOW) always returns non-null
>
> | >Number: 30570
> | >Category: port-amd64
> | >Synopsis: dlopen(..., RTLD_NOW) always returns non-null
[...]
> Does this fix your problem?
>
> christos
>
> Index: reloc.c
> ===================================================================
> RCS file: /cvsroot/src/libexec/ld.elf_so/reloc.c,v
> retrieving revision 1.89
> diff -u -u -r1.89 reloc.c
> --- reloc.c 31 May 2005 19:30:38 -0000 1.89
> +++ reloc.c 21 Jun 2005 04:22:32 -0000
> @@ -192,7 +192,7 @@
> #endif
> #if defined(__i386__) || defined(__arm__) || defined(__hppa__) \
>
> || defined(__sparc64__) || defined(__sparc__) || defined(__alpha__) \
>
> - || defined(__sh3__)
> + || defined(__sh3__) || defined(__x86_64__)
> if (bind_now) {
> dbg(("doing immediate PLT binding"));
> if (_rtld_relocate_plt_objects(obj) < 0)
You'll need something similiar to the attached patch as well.
Nick
--Boundary-00=_h/7tCyO/oKD8yup
Content-Type: text/x-diff;
charset="iso-8859-1";
name="ld.elf_so.x86_64.diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="ld.elf_so.x86_64.diffs"
Index: arch/x86_64/mdreloc.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/arch/x86_64/mdreloc.c,v
retrieving revision 1.23
diff -u -r1.23 mdreloc.c
--- arch/x86_64/mdreloc.c 24 Jul 2003 10:12:30 -0000 1.23
+++ arch/x86_64/mdreloc.c 21 Jun 2005 06:18:18 -0000
@@ -84,6 +84,8 @@
void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);
+static inline int _rtld_relocate_plt_object(const Obj_Entry *obj,
+ const Elf_Rela *rela, Elf_Addr *tp);
void
_rtld_setup_pltgot(const Obj_Entry *obj)
@@ -248,10 +250,9 @@
return 0;
}
-caddr_t
-_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
+static inline int
+_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *tp)
{
- const Elf_Rela *rela = obj->pltrela + reloff;
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
Elf_Addr new_value;
const Elf_Sym *def;
@@ -261,7 +262,7 @@
def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
if (def == NULL)
- _rtld_die();
+ return -1;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
@@ -270,5 +271,34 @@
if (*where != new_value)
*where = new_value;
- return (caddr_t)(new_value - rela->r_addend);
+ if (tp)
+ *tp = new_value - rela->r_addend;
+
+ return 0;
+}
+
+caddr_t
+_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
+{
+ const Elf_Rela *rela = obj->pltrela + reloff;
+ Elf_Addr new_value;
+ int err;
+
+ err = _rtld_relocate_plt_object(obj, relX, &new_value);
+ if (err)
+ _rtld_die();
+
+ return (caddr_t)new_value;
+}
+
+int
+_rtld_relocate_plt_objects(const Obj_Entry *obj)
+{
+ const Elf_Rela *rela;
+
+ for (rela = obj->pltrela; rela < obj->pltrelalim; rela++)
+ if (_rtld_relocate_plt_object(obj, rela, NULL) < 0)
+ return -1;
+
+ return 0;
}
--Boundary-00=_h/7tCyO/oKD8yup--