diff options
author | Adam Jackson <ajax@nwnk.net> | 2005-04-23 19:01:13 +0000 |
---|---|---|
committer | Adam Jackson <ajax@nwnk.net> | 2005-04-23 19:01:13 +0000 |
commit | 139f900c56a6f44df2b411fe4bbc025a147e3abe (patch) | |
tree | 0b4dbce331a9f8cf000d50dcddb05705b6ab3065 | |
parent | 0e80fe0e607cc73856332563becd70ef92d1aa75 (diff) |
Bug #3109: Handle R_ALPHA_BRSGP relocations in elfloader. (Sergey Tikhonov)
-rw-r--r-- | hw/xfree86/loader/elf.h | 1 | ||||
-rw-r--r-- | hw/xfree86/loader/elfloader.c | 51 |
2 files changed, 52 insertions, 0 deletions
diff --git a/hw/xfree86/loader/elf.h b/hw/xfree86/loader/elf.h index a523eac84..51322a9e7 100644 --- a/hw/xfree86/loader/elf.h +++ b/hw/xfree86/loader/elf.h @@ -273,6 +273,7 @@ extern Elf32_Dyn _DYNAMIC[]; #define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ #define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ #define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_BRSGP 28 /* Calc displacement for BRS */ /* IA-64 relocations. */ #define R_IA64_NONE 0x00 /* none */ diff --git a/hw/xfree86/loader/elfloader.c b/hw/xfree86/loader/elfloader.c index d78fbdcc2..fd51e7cef 100644 --- a/hw/xfree86/loader/elfloader.c +++ b/hw/xfree86/loader/elfloader.c @@ -1623,6 +1623,57 @@ Elf_RelocateEntry(ELFModulePtr elffile, Elf_Word secn, Elf_Rel_t *rel, break; } + case R_ALPHA_BRSGP: + { + Elf_Sym *syms; + int Delta; + + dest32 = (unsigned int *)((secp + rel->r_offset) + rel->r_addend); + +# ifdef ELFDEBUG + ELFDEBUF("R_ALPHA_BRSGP %s\t", + ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info))); + + ELFDEBUG("secp=%lx\t", secp); + ELFDEBUG("symval=%lx\t", symval); + ELFDEBUG("dest32=%lx\t", dest32); + ELFDEBUG("*dest32=%8.8x\t", *dest32); +# endif + +# ifdef ELFDEBUG + ELFDEBUG("symval=%lx\t", symval); +# endif + syms = (Elf_Sym *) elffile->saddr[elffile->symndx]; + + if (syms[ELF_R_SYM(rel->r_info)].st_other & 0x8) + Delta = -4; + else + Delta = 4; + + symval -= (Elf_Addr) (((unsigned char *)dest32) + Delta); + if (symval % 4) { + ErrorF("R_ALPHA_BRSGP bad alignment of offset\n"); + } + symval = symval >> 2; + +# ifdef ELFDEBUG + ELFDEBUG("symval=%lx\t", symval); +# endif + + if (symval & 0xffe00000) { +# ifdef ELFDEBUG + ELFDEBUG("R_ALPHA_BRSGP symval too large\n"); +# endif + } + + *dest32 = (*dest32 & ~0x1fffff) | (symval & 0x1fffff); + +# ifdef ELFDEBUG + ELFDEBUG("*dest32=%8.8x\n", *dest32); +# endif + break; + } + #endif /* alpha */ #if defined(__mc68000__) case R_68K_32: |