Refactor soinfo::relocate

 Move common relocation types outside of ifdefs

Change-Id: I713800ce123a18178b5ac80c0b3c7bd6b21a02c2
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e2f514e..e0fec0f 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -53,6 +53,7 @@
 #include "linker_debug.h"
 #include "linker_environ.h"
 #include "linker_phdr.h"
+#include "linker_relocs.h"
 #include "linker_allocator.h"
 
 /* >>> IMPORTANT NOTE - READ ME BEFORE MODIFYING <<<
@@ -1288,7 +1289,7 @@
     const char* sym_name = nullptr;
 
     DEBUG("Processing '%s' relocation at index %zd", name, idx);
-    if (type == 0) { // R_*_NONE
+    if (type == R_GENERIC_NONE) {
       continue;
     }
 
@@ -1358,21 +1359,40 @@
     }
 
     switch (type) {
-#if defined(__aarch64__)
-      case R_AARCH64_JUMP_SLOT:
+      case R_GENERIC_JUMP_SLOT:
         count_relocation(kRelocAbsolute);
         MARK(rela->r_offset);
         TRACE_TYPE(RELO, "RELO JMP_SLOT %16llx <- %16llx %s\n",
                    reloc, (sym_addr + rela->r_addend), sym_name);
         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + rela->r_addend);
         break;
-      case R_AARCH64_GLOB_DAT:
+      case R_GENERIC_GLOB_DAT:
         count_relocation(kRelocAbsolute);
         MARK(rela->r_offset);
         TRACE_TYPE(RELO, "RELO GLOB_DAT %16llx <- %16llx %s\n",
                    reloc, (sym_addr + rela->r_addend), sym_name);
         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + rela->r_addend);
         break;
+      case R_GENERIC_RELATIVE:
+        count_relocation(kRelocRelative);
+        MARK(rela->r_offset);
+        if (sym) {
+          DL_ERR("error: encountered _RELATIVE relocation with a symbol");
+          return -1;
+        }
+        TRACE_TYPE(RELO, "RELO RELATIVE %16llx <- %16llx\n",
+                   reloc, (base + rela->r_addend));
+        *reinterpret_cast<ElfW(Addr)*>(reloc) = (base + rela->r_addend);
+        break;
+
+      case R_GENERIC_IRELATIVE:
+        count_relocation(kRelocRelative);
+        MARK(rela->r_offset);
+        TRACE_TYPE(RELO, "RELO IRELATIVE %16llx <- %16llx\n", reloc, (base + rela->r_addend));
+        *reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(base + rela->r_addend);
+        break;
+
+#if defined(__aarch64__)
       case R_AARCH64_ABS64:
         count_relocation(kRelocAbsolute);
         MARK(rela->r_offset);
@@ -1452,25 +1472,6 @@
         }
         break;
 
-      case R_AARCH64_RELATIVE:
-        count_relocation(kRelocRelative);
-        MARK(rela->r_offset);
-        if (sym) {
-          DL_ERR("odd RELATIVE form...");
-          return -1;
-        }
-        TRACE_TYPE(RELO, "RELO RELATIVE %16llx <- %16llx\n",
-                   reloc, (base + rela->r_addend));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = (base + rela->r_addend);
-        break;
-
-      case R_AARCH64_IRELATIVE:
-        count_relocation(kRelocRelative);
-        MARK(rela->r_offset);
-        TRACE_TYPE(RELO, "RELO IRELATIVE %16llx <- %16llx\n", reloc, (base + rela->r_addend));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(base + rela->r_addend);
-        break;
-
       case R_AARCH64_COPY:
         /*
          * ET_EXEC is not supported so this should not happen.
@@ -1492,37 +1493,6 @@
                    reloc, (sym_addr + rela->r_addend), rela->r_offset);
         break;
 #elif defined(__x86_64__)
-      case R_X86_64_JUMP_SLOT:
-        count_relocation(kRelocAbsolute);
-        MARK(rela->r_offset);
-        TRACE_TYPE(RELO, "RELO JMP_SLOT %08zx <- %08zx %s", static_cast<size_t>(reloc),
-                   static_cast<size_t>(sym_addr + rela->r_addend), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + rela->r_addend;
-        break;
-      case R_X86_64_GLOB_DAT:
-        count_relocation(kRelocAbsolute);
-        MARK(rela->r_offset);
-        TRACE_TYPE(RELO, "RELO GLOB_DAT %08zx <- %08zx %s", static_cast<size_t>(reloc),
-                   static_cast<size_t>(sym_addr + rela->r_addend), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + rela->r_addend;
-        break;
-      case R_X86_64_RELATIVE:
-        count_relocation(kRelocRelative);
-        MARK(rela->r_offset);
-        if (sym) {
-          DL_ERR("odd RELATIVE form...");
-          return -1;
-        }
-        TRACE_TYPE(RELO, "RELO RELATIVE %08zx <- +%08zx", static_cast<size_t>(reloc),
-                   static_cast<size_t>(base));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = base + rela->r_addend;
-        break;
-      case R_X86_64_IRELATIVE:
-        count_relocation(kRelocRelative);
-        MARK(rela->r_offset);
-        TRACE_TYPE(RELO, "RELO IRELATIVE %16llx <- %16llx\n", reloc, (base + rela->r_addend));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(base + rela->r_addend);
-        break;
       case R_X86_64_32:
         count_relocation(kRelocRelative);
         MARK(rela->r_offset);
@@ -1566,7 +1536,7 @@
     const char* sym_name = nullptr;
 
     DEBUG("Processing '%s' relocation at index %zd", name, idx);
-    if (type == 0) { // R_*_NONE
+    if (type == R_GENERIC_NONE) {
       continue;
     }
 
@@ -1598,21 +1568,21 @@
         */
 
         switch (type) {
+#if !defined(__mips__)
+          case R_GENERIC_JUMP_SLOT:
+          case R_GENERIC_GLOB_DAT:
+          case R_GENERIC_RELATIVE:
+          case R_GENERIC_IRELATIVE:
+#endif
+
 #if defined(__arm__)
-          case R_ARM_JUMP_SLOT:
-          case R_ARM_GLOB_DAT:
-          case R_ARM_ABS32:
-          case R_ARM_RELATIVE:    /* Don't care. */
+          case R_ARM_ABS32:    /* Don't care. */
             // sym_addr was initialized to be zero above or relocation
             // code below does not care about value of sym_addr.
             // No need to do anything.
             break;
 #elif defined(__i386__)
-          case R_386_JMP_SLOT:
-          case R_386_GLOB_DAT:
           case R_386_32:
-          case R_386_RELATIVE:    /* Don't care. */
-          case R_386_IRELATIVE:
             // sym_addr was initialized to be zero above or relocation
             // code below does not care about value of sym_addr.
             // No need to do anything.
@@ -1638,19 +1608,42 @@
     }
 
     switch (type) {
-#if defined(__arm__)
-      case R_ARM_JUMP_SLOT:
+#if !defined(__mips__)
+      case R_GENERIC_JUMP_SLOT:
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name);
         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr;
         break;
-      case R_ARM_GLOB_DAT:
+
+      case R_GENERIC_GLOB_DAT:
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name);
         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr;
         break;
+
+      case R_GENERIC_RELATIVE:
+        count_relocation(kRelocRelative);
+        MARK(rel->r_offset);
+        if (sym) {
+          DL_ERR("odd RELATIVE form...");
+          return -1;
+        }
+        TRACE_TYPE(RELO, "RELO RELATIVE %p <- +%p",
+                   reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(base));
+        *reinterpret_cast<ElfW(Addr)*>(reloc) += base;
+        break;
+
+      case R_GENERIC_IRELATIVE:
+        count_relocation(kRelocRelative);
+        MARK(rel->r_offset);
+        TRACE_TYPE(RELO, "RELO IRELATIVE %p <- %p", reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(base));
+        *reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(base + *reinterpret_cast<ElfW(Addr)*>(reloc));
+        break;
+#endif
+
+#if defined(__arm__)
       case R_ARM_ABS32:
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
@@ -1677,18 +1670,6 @@
         DL_ERR("%s R_ARM_COPY relocations are not supported", name);
         return -1;
 #elif defined(__i386__)
-      case R_386_JMP_SLOT:
-        count_relocation(kRelocAbsolute);
-        MARK(rel->r_offset);
-        TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr;
-        break;
-      case R_386_GLOB_DAT:
-        count_relocation(kRelocAbsolute);
-        MARK(rel->r_offset);
-        TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr;
-        break;
       case R_386_32:
         count_relocation(kRelocRelative);
         MARK(rel->r_offset);
@@ -1727,30 +1708,6 @@
         break;
 #endif
 
-#if defined(__arm__)
-      case R_ARM_RELATIVE:
-#elif defined(__i386__)
-      case R_386_RELATIVE:
-#endif
-        count_relocation(kRelocRelative);
-        MARK(rel->r_offset);
-        if (sym) {
-          DL_ERR("odd RELATIVE form...");
-          return -1;
-        }
-        TRACE_TYPE(RELO, "RELO RELATIVE %p <- +%p",
-                   reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(base));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) += base;
-        break;
-#if defined(__i386__)
-      case R_386_IRELATIVE:
-        count_relocation(kRelocRelative);
-        MARK(rel->r_offset);
-        TRACE_TYPE(RELO, "RELO IRELATIVE %p <- %p", reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(base));
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(base + *reinterpret_cast<ElfW(Addr)*>(reloc));
-        break;
-#endif
-
       default:
         DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx);
         return -1;
diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h
new file mode 100644
index 0000000..12c1497
--- /dev/null
+++ b/linker/linker_relocs.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINKER_RELOCS_H
+#define __LINKER_RELOCS_H
+
+#include <elf.h>
+
+#define R_GENERIC_NONE 0 // R_*_NONE is always 0
+
+#if defined (__aarch64__)
+
+#define R_GENERIC_JUMP_SLOT R_AARCH64_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT  R_AARCH64_GLOB_DAT
+#define R_GENERIC_RELATIVE  R_AARCH64_RELATIVE
+#define R_GENERIC_IRELATIVE R_AARCH64_IRELATIVE
+
+#elif defined (__arm__)
+
+#define R_GENERIC_JUMP_SLOT R_ARM_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT  R_ARM_GLOB_DAT
+#define R_GENERIC_RELATIVE  R_ARM_RELATIVE
+#define R_GENERIC_IRELATIVE R_ARM_IRELATIVE
+
+#elif defined (__i386__)
+
+#define R_GENERIC_JUMP_SLOT R_386_JMP_SLOT
+#define R_GENERIC_GLOB_DAT  R_386_GLOB_DAT
+#define R_GENERIC_RELATIVE  R_386_RELATIVE
+#define R_GENERIC_IRELATIVE R_386_IRELATIVE
+
+#elif defined (__x86_64__)
+
+#define R_GENERIC_JUMP_SLOT R_X86_64_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT  R_X86_64_GLOB_DAT
+#define R_GENERIC_RELATIVE  R_X86_64_RELATIVE
+#define R_GENERIC_IRELATIVE R_X86_64_IRELATIVE
+
+#endif
+
+#endif // __LINKER_RELOCS_H