ia64: Add support for R_IA64_GPREL64I.
Recent GCC generates those relocations, so we need to support them.
This commit is contained in:
parent
255b9e0bea
commit
a134ef1ab9
5 changed files with 45 additions and 0 deletions
|
@ -104,6 +104,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||||
case R_IA64_PCREL64LSB:
|
case R_IA64_PCREL64LSB:
|
||||||
*(grub_uint64_t *) addr += value - addr;
|
*(grub_uint64_t *) addr += value - addr;
|
||||||
break;
|
break;
|
||||||
|
case R_IA64_GPREL64I:
|
||||||
|
grub_ia64_set_immu64 (addr, value - (grub_addr_t) mod->base);
|
||||||
|
break;
|
||||||
case R_IA64_GPREL22:
|
case R_IA64_GPREL22:
|
||||||
if ((value - (grub_addr_t) mod->base) & ~MASK20)
|
if ((value - (grub_addr_t) mod->base) & ~MASK20)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
|
|
|
@ -30,6 +30,40 @@
|
||||||
#define MASK20 ((1 << 20) - 1)
|
#define MASK20 ((1 << 20) - 1)
|
||||||
#define MASK3 (~(grub_addr_t) 3)
|
#define MASK3 (~(grub_addr_t) 3)
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_ia64_set_immu64 (grub_addr_t addr, grub_uint64_t val)
|
||||||
|
{
|
||||||
|
/* Copied from binutils. */
|
||||||
|
grub_uint64_t *ptr = ((grub_uint64_t *) (addr & MASK3));
|
||||||
|
grub_uint64_t t0, t1;
|
||||||
|
|
||||||
|
t0 = grub_le_to_cpu64 (ptr[0]);
|
||||||
|
t1 = grub_le_to_cpu64 (ptr[1]);
|
||||||
|
|
||||||
|
/* tmpl/s: bits 0.. 5 in t0
|
||||||
|
slot 0: bits 5..45 in t0
|
||||||
|
slot 1: bits 46..63 in t0, bits 0..22 in t1
|
||||||
|
slot 2: bits 23..63 in t1 */
|
||||||
|
|
||||||
|
/* First, clear the bits that form the 64 bit constant. */
|
||||||
|
t0 &= ~(0x3ffffLL << 46);
|
||||||
|
t1 &= ~(0x7fffffLL
|
||||||
|
| (( (0x07fLL << 13) | (0x1ffLL << 27)
|
||||||
|
| (0x01fLL << 22) | (0x001LL << 21)
|
||||||
|
| (0x001LL << 36)) << 23));
|
||||||
|
|
||||||
|
t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
|
||||||
|
t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
|
||||||
|
t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
|
||||||
|
| (((val >> 7) & 0x1ff) << 27) /* imm9d */
|
||||||
|
| (((val >> 16) & 0x01f) << 22) /* imm5c */
|
||||||
|
| (((val >> 21) & 0x001) << 21) /* ic */
|
||||||
|
| (((val >> 63) & 0x001) << 36)) << 23; /* i */
|
||||||
|
|
||||||
|
ptr[0] = t0;
|
||||||
|
ptr[1] = t1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
|
grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,8 @@ grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value);
|
||||||
void
|
void
|
||||||
grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value);
|
grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value);
|
||||||
void
|
void
|
||||||
|
grub_ia64_set_immu64 (grub_addr_t addr, grub_uint64_t value);
|
||||||
|
void
|
||||||
grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr);
|
grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr);
|
||||||
|
|
||||||
struct grub_ia64_trampoline
|
struct grub_ia64_trampoline
|
||||||
|
|
|
@ -920,6 +920,10 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
|
grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
|
||||||
addend + sym_addr);
|
addend + sym_addr);
|
||||||
break;
|
break;
|
||||||
|
case R_IA64_GPREL64I:
|
||||||
|
grub_ia64_set_immu64 ((grub_addr_t) target,
|
||||||
|
addend + sym_addr);
|
||||||
|
break;
|
||||||
case R_IA64_PCREL64LSB:
|
case R_IA64_PCREL64LSB:
|
||||||
*target = grub_host_to_target64 (grub_target_to_host64 (*target)
|
*target = grub_host_to_target64 (grub_target_to_host64 (*target)
|
||||||
+ addend + sym_addr
|
+ addend + sym_addr
|
||||||
|
@ -1286,6 +1290,7 @@ translate_relocation_pe (struct translate_context *ctx,
|
||||||
case R_IA64_LTOFF22X:
|
case R_IA64_LTOFF22X:
|
||||||
case R_IA64_LTOFF22:
|
case R_IA64_LTOFF22:
|
||||||
case R_IA64_GPREL22:
|
case R_IA64_GPREL22:
|
||||||
|
case R_IA64_GPREL64I:
|
||||||
case R_IA64_SEGREL64LSB:
|
case R_IA64_SEGREL64LSB:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct grub_module_verifier_arch archs[] = {
|
||||||
R_IA64_PCREL64LSB,
|
R_IA64_PCREL64LSB,
|
||||||
R_IA64_LTOFF22X,
|
R_IA64_LTOFF22X,
|
||||||
R_IA64_LTOFF22,
|
R_IA64_LTOFF22,
|
||||||
|
R_IA64_GPREL64I,
|
||||||
R_IA64_LTOFF_FPTR22,
|
R_IA64_LTOFF_FPTR22,
|
||||||
R_IA64_LDXMOV,
|
R_IA64_LDXMOV,
|
||||||
-1
|
-1
|
||||||
|
|
Loading…
Reference in a new issue