Eliminate unaligned accesses that occurred when relocating the
DWARF2 exception tables emitted by the compiler for C++ sources. These tables are tightly packed, and they contain some relocated addresses which are not well-aligned.
This commit is contained in:
parent
4f14ee00f2
commit
a0f2601e13
|
@ -49,6 +49,23 @@
|
|||
|
||||
extern Elf_Dyn _DYNAMIC;
|
||||
|
||||
/*
|
||||
* Macros for loading/storing unaligned 64-bit values. These are
|
||||
* needed because relocations can point to unaligned data. This
|
||||
* occurs in the DWARF2 exception frame tables generated by the
|
||||
* compiler, for instance.
|
||||
*
|
||||
* We don't use these when relocating jump slots and GOT entries,
|
||||
* since they are guaranteed to be aligned.
|
||||
*/
|
||||
#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))
|
||||
|
||||
/* Relocate a non-PLT object with addend. */
|
||||
static int
|
||||
reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela)
|
||||
|
@ -63,33 +80,30 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela)
|
|||
case R_ALPHA_REFQUAD: {
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp_value;
|
||||
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp_value = (Elf_Addr) (defobj->relocbase +
|
||||
def->st_value) + *where + rela->r_addend;
|
||||
if (*where != tmp_value)
|
||||
*where = tmp_value;
|
||||
store64(where,
|
||||
(Elf_Addr) (defobj->relocbase + def->st_value) +
|
||||
load64(where) + rela->r_addend);
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ALPHA_GLOB_DAT: {
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr val;
|
||||
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
if (*where != (Elf_Addr) (defobj->relocbase +
|
||||
def->st_value + rela->r_addend))
|
||||
*where = (Elf_Addr) (defobj->relocbase +
|
||||
def->st_value + rela->r_addend);
|
||||
val = (Elf_Addr) (defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (load64(where) != val)
|
||||
store64(where, val);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -97,7 +111,8 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela)
|
|||
if (obj != obj_rtld ||
|
||||
(caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
|
||||
(caddr_t)where >= (caddr_t)&_DYNAMIC)
|
||||
*where += (Elf_Addr) obj->relocbase;
|
||||
store64(where,
|
||||
load64(where) + (Elf_Addr) obj->relocbase);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue