about summary refs log tree commit diff stats
path: root/src/elfs/elfloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/elfs/elfloader.c')
-rw-r--r--src/elfs/elfloader.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index efb0ef57..fab47ad6 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -784,12 +784,40 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
     }
     return bindnow?ret_ok:0;
 }
+
+int RelocateElfRELR(elfheader_t *head, int cnt, Elf64_Relr *relr) {
+    Elf64_Addr *where = NULL;
+    for (int i = 0; i < cnt; i++) {
+        Elf64_Relr p = relr[i];
+        if ((p & 1) == 0) {
+            where = (Elf64_Addr *)(p + head->delta);
+            printf_dump(LOG_NEVER, "Apply (even) RELR %p -> %p\n", *where, *where + head->delta);
+            *where++ += head->delta;
+        } else {
+            for (long j = 0; (p >>= 1) != 0; j++)
+                if ((p & 1) != 0) {
+                    printf_dump(LOG_NEVER, "Apply (odd) RELR %p -> %p\n", where[j], where[j] + head->delta);
+                    where[j] += head->delta;
+                }
+            where += CHAR_BIT * sizeof(Elf64_Relr) - 1;
+        }
+    }
+    return 0;
+}
+
 int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head)
 {
     if((head->flags&DF_BIND_NOW) && !bindnow) {
         bindnow = 1;
         printf_log(LOG_DEBUG, "Forcing %s to Bind Now\n", head->name);
     }
+    if(head->relr) {
+        int cnt = head->relrsz / head->relrent;
+        DumpRelRTable(head, cnt, (Elf64_Relr *)(head->relr + head->delta), "RelR");
+        printf_dump(LOG_DEBUG, "Applying %d Relocation(s) without Addend for %s bindnow=%d, deepbind=%d\n", cnt, head->name, bindnow, deepbind);
+        if(RelocateElfRELR(head, cnt, (Elf64_Relr *)(head->relr + head->delta)))
+            return -1;
+    }
     if(head->rel) {
         int cnt = head->relsz / head->relent;
         DumpRelTable(head, cnt, (Elf64_Rel *)(head->rel + head->delta), "Rel");