reloc_non_plt_obj buggy

Richard Henderson rth at twiddle.net
Wed Jun 1 10:24:17 PDT 2005


>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~


More information about the freebsd-alpha mailing list