case R_IA64_PCREL64LSB:
*(grub_uint64_t *) addr += value - addr;
break;
+ case R_IA64_GPREL64I:
+ grub_ia64_set_immu64 (addr, value - (grub_addr_t) mod->base);
+ break;
case R_IA64_GPREL22:
if ((value - (grub_addr_t) mod->base) & ~MASK20)
return grub_error (GRUB_ERR_BAD_MODULE,
#define MASK20 ((1 << 20) - 1)
#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
grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
{
void
grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value);
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);
struct grub_ia64_trampoline
grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
addend + sym_addr);
break;
+ case R_IA64_GPREL64I:
+ grub_ia64_set_immu64 ((grub_addr_t) target,
+ addend + sym_addr);
+ break;
case R_IA64_PCREL64LSB:
*target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ addend + sym_addr
case R_IA64_LTOFF22X:
case R_IA64_LTOFF22:
case R_IA64_GPREL22:
+ case R_IA64_GPREL64I:
case R_IA64_SEGREL64LSB:
break;