summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@nwnk.net>2005-04-23 19:01:13 +0000
committerAdam Jackson <ajax@nwnk.net>2005-04-23 19:01:13 +0000
commit139f900c56a6f44df2b411fe4bbc025a147e3abe (patch)
tree0b4dbce331a9f8cf000d50dcddb05705b6ab3065
parent0e80fe0e607cc73856332563becd70ef92d1aa75 (diff)
Bug #3109: Handle R_ALPHA_BRSGP relocations in elfloader. (Sergey Tikhonov)
-rw-r--r--hw/xfree86/loader/elf.h1
-rw-r--r--hw/xfree86/loader/elfloader.c51
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: