From f4171ebd34bd66db853c2005ac3dfde6a680878e Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 16 Dec 2013 14:24:19 +0100 Subject: [PATCH] Handle X86_64_PC64 relocation. Those are generated by some cygwin compilers. --- ChangeLog | 6 ++++++ grub-core/kern/x86_64/dl.c | 7 +++++++ include/grub/elf.h | 1 + util/grub-mkimagexx.c | 12 ++++++++++++ 4 files changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5405e5069..aae9c6977 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-16 Vladimir Serbinenko + + Handle X86_64_PC64 relocation. + + Those are generated by some cygwin compilers. + 2013-12-16 Vladimir Serbinenko Determine the need for mingw-related stubs at compile time rather than diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index e00e51d40..6cb88bfcc 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -80,6 +80,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, } break; + case R_X86_64_PC64: + { + *addr64 += rel->r_addend + sym->st_value - + (Elf64_Xword) seg->addr - rel->r_offset; + } + break; + case R_X86_64_32: { grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value; diff --git a/include/grub/elf.h b/include/grub/elf.h index 140d24d02..79f56c67b 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -1132,6 +1132,7 @@ typedef struct #define R_X86_64_PC16 13 #define R_X86_64_8 14 #define R_X86_64_PC8 15 +#define R_X86_64_PC64 24 /* Legal values for ST_TYPE subfield of st_info (symbol type). */ diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index d6feffd2a..832302e59 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -709,6 +709,18 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, break; } + case R_X86_64_PC64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%llx at the offset 0x%llx", + (unsigned long long) *target, + (unsigned long long) offset); + break; + } + case R_X86_64_32: case R_X86_64_32S: {