Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Jun 2005 10:24:16 -0700
From:      Richard Henderson <rth@twiddle.net>
To:        freebsd-alpha@FreeBSD.org
Subject:   reloc_non_plt_obj buggy
Message-ID:  <20050601172416.GA4197@twiddle.net>

next in thread | raw e-mail | index | archive | help
>From src/libexec/rtld-elf/alpha/reloc.c:

---------------------
#define load64(p) ({						\
	Elf_Addr __res;						\
	__asm__("ldq_u %0,%1" : "=r"(__res) : "m"(*(p)));	\
	__res; })

#define store64(p, v)						\
	__asm__("stq_u %1,%0" : "=m"(*(p)) : "r"(v))
---------------------
		case R_ALPHA_REFQUAD: {
			const Elf_Sym *def;
			const Obj_Entry *defobj;

			def = find_symdef(ELF_R_SYM(rela->r_info), obj,
			    &defobj, false, cache);
			if (def == NULL)
				return -1;
			store64(where,
			    (Elf_Addr) (defobj->relocbase + def->st_value) +
			    load64(where) + rela->r_addend);
		}
---------------------

Someone wasn't very clear on what ldq_u/stq_u actually does.
You're not actually modifying the unaligned address, you're
modifying (address & ~7), and corrupting the dwarf2 data in
the process.

You need to use

struct ualong {
  Elf_Addr x __attribute__((packed));
};

#define load64(p)	(((struct ualong *)(p))->x)
#define store64(p,v)	(((struct ualong *)(p))->x = (v))



r~



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050601172416.GA4197>