/* Copyright 2017 - 2024 R. Thomas
 * Copyright 2017 - 2024 Quarkslab
 *
 * 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.
 */

#include "LIEF/ELF/Relocation.hpp"
#include "frozen.hpp"

namespace LIEF {
namespace ELF {

int32_t get_R_X64(Relocation::TYPE type) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::X86_64_NONE,             0),
    std::pair(Relocation::TYPE::X86_64_64,              64),
    std::pair(Relocation::TYPE::X86_64_PC32,            32),
    std::pair(Relocation::TYPE::X86_64_GOT32,           32),
    std::pair(Relocation::TYPE::X86_64_PLT32,           32),
    std::pair(Relocation::TYPE::X86_64_COPY,            32),
    std::pair(Relocation::TYPE::X86_64_GLOB_DAT,        64),
    std::pair(Relocation::TYPE::X86_64_JUMP_SLOT,       64),
    std::pair(Relocation::TYPE::X86_64_RELATIVE,        64),
    std::pair(Relocation::TYPE::X86_64_GOTPCREL,        32),
    std::pair(Relocation::TYPE::X86_64_32,              32),
    std::pair(Relocation::TYPE::X86_64_32S,             32),
    std::pair(Relocation::TYPE::X86_64_16,              16),
    std::pair(Relocation::TYPE::X86_64_PC16,            16),
    std::pair(Relocation::TYPE::X86_64_8,                8),
    std::pair(Relocation::TYPE::X86_64_PC8,              8),
    std::pair(Relocation::TYPE::X86_64_DTPMOD64,        64),
    std::pair(Relocation::TYPE::X86_64_DTPOFF64,        64),
    std::pair(Relocation::TYPE::X86_64_TPOFF64,         64),
    std::pair(Relocation::TYPE::X86_64_TLSGD,           32),
    std::pair(Relocation::TYPE::X86_64_TLSLD,           32),
    std::pair(Relocation::TYPE::X86_64_DTPOFF32,        32),
    std::pair(Relocation::TYPE::X86_64_GOTTPOFF,        32),
    std::pair(Relocation::TYPE::X86_64_TPOFF32,         32),
    std::pair(Relocation::TYPE::X86_64_PC64,            64),
    std::pair(Relocation::TYPE::X86_64_GOTOFF64,        64),
    std::pair(Relocation::TYPE::X86_64_GOTPC32,         32),
    std::pair(Relocation::TYPE::X86_64_GOT64,           64),
    std::pair(Relocation::TYPE::X86_64_GOTPCREL64,      64),
    std::pair(Relocation::TYPE::X86_64_GOTPC64,         64),
    std::pair(Relocation::TYPE::X86_64_GOTPLT64,        64),
    std::pair(Relocation::TYPE::X86_64_PLTOFF64,        64),
    std::pair(Relocation::TYPE::X86_64_SIZE32,          32),
    std::pair(Relocation::TYPE::X86_64_SIZE64,          64),
    std::pair(Relocation::TYPE::X86_64_GOTPC32_TLSDESC, 32),
    std::pair(Relocation::TYPE::X86_64_TLSDESC_CALL,     0),
    std::pair(Relocation::TYPE::X86_64_TLSDESC,         64),
    std::pair(Relocation::TYPE::X86_64_IRELATIVE,       64),
    std::pair(Relocation::TYPE::X86_64_RELATIVE64,      64),
    std::pair(Relocation::TYPE::X86_64_PC32_BND,        32),
    std::pair(Relocation::TYPE::X86_64_PLT32_BND,       32),
    std::pair(Relocation::TYPE::X86_64_GOTPCRELX,       32),
    std::pair(Relocation::TYPE::X86_64_REX_GOTPCRELX,   32),
  };
  const auto it = SIZES.find(type);
  return it == SIZES.end() ? -1 : it->second;
}


int32_t get_R_X86(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::X86_NONE,            0),
    std::pair(Relocation::TYPE::X86_32,             32),
    std::pair(Relocation::TYPE::X86_PC32,           32),
    std::pair(Relocation::TYPE::X86_GOT32,          32),
    std::pair(Relocation::TYPE::X86_PLT32,          32),
    std::pair(Relocation::TYPE::X86_COPY,           32),
    std::pair(Relocation::TYPE::X86_GLOB_DAT,       32),
    std::pair(Relocation::TYPE::X86_JUMP_SLOT,      32),
    std::pair(Relocation::TYPE::X86_RELATIVE,       32),
    std::pair(Relocation::TYPE::X86_GOTOFF,         32),
    std::pair(Relocation::TYPE::X86_GOTPC,          32),
    std::pair(Relocation::TYPE::X86_32PLT,          32),
    std::pair(Relocation::TYPE::X86_TLS_TPOFF,      32),
    std::pair(Relocation::TYPE::X86_TLS_IE,         32),
    std::pair(Relocation::TYPE::X86_TLS_GOTIE,      32),
    std::pair(Relocation::TYPE::X86_TLS_LE,         32),
    std::pair(Relocation::TYPE::X86_TLS_GD,         32),
    std::pair(Relocation::TYPE::X86_TLS_LDM,        32),
    std::pair(Relocation::TYPE::X86_16,             16),
    std::pair(Relocation::TYPE::X86_PC16,           16),
    std::pair(Relocation::TYPE::X86_8,               8),
    std::pair(Relocation::TYPE::X86_PC8,             8),
    std::pair(Relocation::TYPE::X86_TLS_GD_32,      32),
    std::pair(Relocation::TYPE::X86_TLS_GD_PUSH,    32),
    std::pair(Relocation::TYPE::X86_TLS_GD_CALL,    32),
    std::pair(Relocation::TYPE::X86_TLS_GD_POP,     32),
    std::pair(Relocation::TYPE::X86_TLS_LDM_32,     32),
    std::pair(Relocation::TYPE::X86_TLS_LDM_PUSH,   32),
    std::pair(Relocation::TYPE::X86_TLS_LDM_CALL,    0),
    std::pair(Relocation::TYPE::X86_TLS_LDM_POP,    32),
    std::pair(Relocation::TYPE::X86_TLS_LDO_32,     32),
    std::pair(Relocation::TYPE::X86_TLS_IE_32,      32),
    std::pair(Relocation::TYPE::X86_TLS_LE_32,      32),
    std::pair(Relocation::TYPE::X86_TLS_DTPMOD32,   32),
    std::pair(Relocation::TYPE::X86_TLS_DTPOFF32,   32),
    std::pair(Relocation::TYPE::X86_TLS_TPOFF32,    32),
    std::pair(Relocation::TYPE::X86_TLS_GOTDESC,    32),
    std::pair(Relocation::TYPE::X86_TLS_DESC_CALL,  32),
    std::pair(Relocation::TYPE::X86_TLS_DESC,       32),
    std::pair(Relocation::TYPE::X86_IRELATIVE,      32),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_R_ARM(Relocation::TYPE R) {
  // From https://github.com/gittup/binutils/blob/gittup/bfd/elf32-arm.c#L75
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::ARM_NONE,                    0),
    std::pair(Relocation::TYPE::ARM_PC24,                   24),
    std::pair(Relocation::TYPE::ARM_ABS32,                  32),
    std::pair(Relocation::TYPE::ARM_REL32,                  32),
    std::pair(Relocation::TYPE::ARM_LDR_PC_G0,              32),
    std::pair(Relocation::TYPE::ARM_ABS16,                  16),
    std::pair(Relocation::TYPE::ARM_ABS12,                  12),
    std::pair(Relocation::TYPE::ARM_THM_ABS5,                5),
    std::pair(Relocation::TYPE::ARM_ABS8,                    8),
    std::pair(Relocation::TYPE::ARM_SBREL32,                32),
    std::pair(Relocation::TYPE::ARM_THM_CALL,               25),
    std::pair(Relocation::TYPE::ARM_THM_PC8,                 8),
    std::pair(Relocation::TYPE::ARM_BREL_ADJ,               32),
    std::pair(Relocation::TYPE::ARM_TLS_DESC,                0),
    std::pair(Relocation::TYPE::ARM_THM_SWI8,                0),
    std::pair(Relocation::TYPE::ARM_XPC25,                  25),
    std::pair(Relocation::TYPE::ARM_THM_XPC22,              22),
    std::pair(Relocation::TYPE::ARM_TLS_DTPMOD32,           32),
    std::pair(Relocation::TYPE::ARM_TLS_DTPOFF32,           32),
    std::pair(Relocation::TYPE::ARM_TLS_TPOFF32,            32),
    std::pair(Relocation::TYPE::ARM_COPY,                   32),
    std::pair(Relocation::TYPE::ARM_GLOB_DAT,               32),
    std::pair(Relocation::TYPE::ARM_JUMP_SLOT,              32),
    std::pair(Relocation::TYPE::ARM_RELATIVE,               32),
    std::pair(Relocation::TYPE::ARM_GOTOFF32,               32),
    std::pair(Relocation::TYPE::ARM_BASE_PREL,              32),
    std::pair(Relocation::TYPE::ARM_GOT_BREL,               32),
    std::pair(Relocation::TYPE::ARM_PLT32,                  24),
    std::pair(Relocation::TYPE::ARM_CALL,                   24),
    std::pair(Relocation::TYPE::ARM_JUMP24,                 24),
    std::pair(Relocation::TYPE::ARM_THM_JUMP24,             24),
    std::pair(Relocation::TYPE::ARM_BASE_ABS,               21),
    std::pair(Relocation::TYPE::ARM_ALU_PCREL_7_0,          12),
    std::pair(Relocation::TYPE::ARM_ALU_PCREL_15_8,         12),
    std::pair(Relocation::TYPE::ARM_ALU_PCREL_23_15,        12),
    std::pair(Relocation::TYPE::ARM_LDR_SBREL_11_0_NC,      12),
    std::pair(Relocation::TYPE::ARM_ALU_SBREL_19_12_NC,      8),
    std::pair(Relocation::TYPE::ARM_ALU_SBREL_27_20_CK,      8),
    std::pair(Relocation::TYPE::ARM_TARGET1,                32),
    std::pair(Relocation::TYPE::ARM_SBREL31,                32),
    std::pair(Relocation::TYPE::ARM_V4BX,                   32),
    std::pair(Relocation::TYPE::ARM_TARGET2,                32),
    std::pair(Relocation::TYPE::ARM_PREL31,                 31),
    std::pair(Relocation::TYPE::ARM_MOVW_ABS_NC,            16),
    std::pair(Relocation::TYPE::ARM_MOVT_ABS,               16),
    std::pair(Relocation::TYPE::ARM_MOVW_PREL_NC,           16),
    std::pair(Relocation::TYPE::ARM_MOVT_PREL,              16),
    std::pair(Relocation::TYPE::ARM_THM_MOVW_ABS_NC,        16),
    std::pair(Relocation::TYPE::ARM_THM_MOVT_ABS,           16),
    std::pair(Relocation::TYPE::ARM_THM_MOVW_PREL_NC,       16),
    std::pair(Relocation::TYPE::ARM_THM_MOVT_PREL,          16),
    std::pair(Relocation::TYPE::ARM_THM_JUMP19,             19),
    std::pair(Relocation::TYPE::ARM_THM_JUMP6,               6),
    std::pair(Relocation::TYPE::ARM_THM_ALU_PREL_11_0,      13),
    std::pair(Relocation::TYPE::ARM_THM_PC12,               13),
    std::pair(Relocation::TYPE::ARM_ABS32_NOI,              32),
    std::pair(Relocation::TYPE::ARM_REL32_NOI,              32),
    std::pair(Relocation::TYPE::ARM_ALU_PC_G0_NC,           32),
    std::pair(Relocation::TYPE::ARM_ALU_PC_G0,              32),
    std::pair(Relocation::TYPE::ARM_ALU_PC_G1_NC,           32),
    std::pair(Relocation::TYPE::ARM_ALU_PC_G1,              32),
    std::pair(Relocation::TYPE::ARM_ALU_PC_G2,              32),
    std::pair(Relocation::TYPE::ARM_LDR_PC_G1,              32),
    std::pair(Relocation::TYPE::ARM_LDR_PC_G2,              32),
    std::pair(Relocation::TYPE::ARM_LDRS_PC_G0,             32),
    std::pair(Relocation::TYPE::ARM_LDRS_PC_G1,             32),
    std::pair(Relocation::TYPE::ARM_LDRS_PC_G2,             32),
    std::pair(Relocation::TYPE::ARM_LDC_PC_G0,              32),
    std::pair(Relocation::TYPE::ARM_LDC_PC_G1,              32),
    std::pair(Relocation::TYPE::ARM_LDC_PC_G2,              32),
    std::pair(Relocation::TYPE::ARM_ALU_SB_G0_NC,           32),
    std::pair(Relocation::TYPE::ARM_ALU_SB_G0,              32),
    std::pair(Relocation::TYPE::ARM_ALU_SB_G1_NC,           32),
    std::pair(Relocation::TYPE::ARM_ALU_SB_G1,              32),
    std::pair(Relocation::TYPE::ARM_ALU_SB_G2,              32),
    std::pair(Relocation::TYPE::ARM_LDR_SB_G0,              32),
    std::pair(Relocation::TYPE::ARM_LDR_SB_G1,              32),
    std::pair(Relocation::TYPE::ARM_LDR_SB_G2,              32),
    std::pair(Relocation::TYPE::ARM_LDRS_SB_G0,             32),
    std::pair(Relocation::TYPE::ARM_LDRS_SB_G1,             32),
    std::pair(Relocation::TYPE::ARM_LDRS_SB_G2,             32),
    std::pair(Relocation::TYPE::ARM_LDC_SB_G0,              32),
    std::pair(Relocation::TYPE::ARM_LDC_SB_G1,              32),
    std::pair(Relocation::TYPE::ARM_LDC_SB_G2,              32),
    std::pair(Relocation::TYPE::ARM_MOVW_BREL_NC,           16),
    std::pair(Relocation::TYPE::ARM_MOVT_BREL,              16),
    std::pair(Relocation::TYPE::ARM_MOVW_BREL,              16),
    std::pair(Relocation::TYPE::ARM_THM_MOVW_BREL_NC,       16),
    std::pair(Relocation::TYPE::ARM_THM_MOVT_BREL,          16),
    std::pair(Relocation::TYPE::ARM_THM_MOVW_BREL,          16),
    std::pair(Relocation::TYPE::ARM_TLS_GOTDESC,             0),
    std::pair(Relocation::TYPE::ARM_TLS_CALL,                0),
    std::pair(Relocation::TYPE::ARM_TLS_DESCSEQ,             0),
    std::pair(Relocation::TYPE::ARM_THM_TLS_CALL,            0),
    std::pair(Relocation::TYPE::ARM_PLT32_ABS,              32),
    std::pair(Relocation::TYPE::ARM_GOT_ABS,                32),
    std::pair(Relocation::TYPE::ARM_GOT_PREL,               32),
    std::pair(Relocation::TYPE::ARM_GOT_BREL12,             12),
    std::pair(Relocation::TYPE::ARM_GOTOFF12,               12),
    std::pair(Relocation::TYPE::ARM_GOTRELAX,               12),
    std::pair(Relocation::TYPE::ARM_GNU_VTENTRY,             0),
    std::pair(Relocation::TYPE::ARM_GNU_VTINHERIT,           0),
    std::pair(Relocation::TYPE::ARM_THM_JUMP11,             11),
    std::pair(Relocation::TYPE::ARM_THM_JUMP8,               8),
    std::pair(Relocation::TYPE::ARM_TLS_GD32,               32),
    std::pair(Relocation::TYPE::ARM_TLS_LDM32,              32),
    std::pair(Relocation::TYPE::ARM_TLS_LDO32,              32),
    std::pair(Relocation::TYPE::ARM_TLS_IE32,               32),
    std::pair(Relocation::TYPE::ARM_TLS_LE32,               32),
    std::pair(Relocation::TYPE::ARM_TLS_LDO12,              12),
    std::pair(Relocation::TYPE::ARM_TLS_LE12,               12),
    std::pair(Relocation::TYPE::ARM_TLS_IE12GP,             12),
    std::pair(Relocation::TYPE::ARM_PRIVATE_0,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_1,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_2,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_3,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_4,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_5,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_6,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_7,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_8,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_9,               0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_10,              0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_11,              0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_12,              0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_13,              0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_14,              0),
    std::pair(Relocation::TYPE::ARM_PRIVATE_15,              0),
    std::pair(Relocation::TYPE::ARM_ME_TOO,                  0),
    std::pair(Relocation::TYPE::ARM_THM_TLS_DESCSEQ16,       0),
    std::pair(Relocation::TYPE::ARM_THM_TLS_DESCSEQ32,       0),
    std::pair(Relocation::TYPE::ARM_IRELATIVE,               0),
    std::pair(Relocation::TYPE::ARM_RXPC25,                 25),
    std::pair(Relocation::TYPE::ARM_RSBREL32,               32),
    std::pair(Relocation::TYPE::ARM_THM_RPC22,              22),
    std::pair(Relocation::TYPE::ARM_RREL32,                 32),
    std::pair(Relocation::TYPE::ARM_RPC24,                  24),
    std::pair(Relocation::TYPE::ARM_RBASE,                   0),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_R_AARCH64(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::AARCH64_NONE,                          0 ),
    std::pair(Relocation::TYPE::AARCH64_ABS64,                        64 ),
    std::pair(Relocation::TYPE::AARCH64_ABS32,                        32 ),
    std::pair(Relocation::TYPE::AARCH64_ABS16,                        16 ),
    std::pair(Relocation::TYPE::AARCH64_PREL64,                       64 ),
    std::pair(Relocation::TYPE::AARCH64_PREL32,                       32 ),
    std::pair(Relocation::TYPE::AARCH64_PREL16,                       16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G0,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G0_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G1,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G1_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G2,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G2_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_UABS_G3,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_SABS_G0,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_SABS_G1,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_SABS_G2,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_LD_PREL_LO19,                 19 ),
    std::pair(Relocation::TYPE::AARCH64_ADR_PREL_LO21,                21 ),
    std::pair(Relocation::TYPE::AARCH64_ADR_PREL_PG_HI21,             21 ),
    std::pair(Relocation::TYPE::AARCH64_ADR_PREL_PG_HI21_NC,          21 ),
    std::pair(Relocation::TYPE::AARCH64_ADD_ABS_LO12_NC,              12 ),
    std::pair(Relocation::TYPE::AARCH64_LDST8_ABS_LO12_NC,            12 ),
    std::pair(Relocation::TYPE::AARCH64_TSTBR14,                      14 ),
    std::pair(Relocation::TYPE::AARCH64_CONDBR19,                     19 ),
    std::pair(Relocation::TYPE::AARCH64_JUMP26,                       26 ),
    std::pair(Relocation::TYPE::AARCH64_CALL26,                       26 ),
    std::pair(Relocation::TYPE::AARCH64_LDST16_ABS_LO12_NC,           12 ),
    std::pair(Relocation::TYPE::AARCH64_LDST32_ABS_LO12_NC,           12 ),
    std::pair(Relocation::TYPE::AARCH64_LDST64_ABS_LO12_NC,           12 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G0,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G0_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G1,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G1_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G2,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G2_NC,              16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_PREL_G3,                 16 ),
    std::pair(Relocation::TYPE::AARCH64_LDST128_ABS_LO12_NC,          12 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G0,               16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G0_NC,            16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G1,               16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G1_NC,            16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G2,               16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G2_NC,            16 ),
    std::pair(Relocation::TYPE::AARCH64_MOVW_GOTOFF_G3,               16 ),
    std::pair(Relocation::TYPE::AARCH64_GOTREL64,                     64 ),
    std::pair(Relocation::TYPE::AARCH64_GOTREL32,                     64 ),
    std::pair(Relocation::TYPE::AARCH64_GOT_LD_PREL19,                19 ),
    std::pair(Relocation::TYPE::AARCH64_LD64_GOTOFF_LO15,             15 ),
    std::pair(Relocation::TYPE::AARCH64_ADR_GOT_PAGE,                 21 ),
    std::pair(Relocation::TYPE::AARCH64_LD64_GOT_LO12_NC,             12 ),
    std::pair(Relocation::TYPE::AARCH64_LD64_GOTPAGE_LO15,            15 ),
    std::pair(Relocation::TYPE::AARCH64_TLSGD_ADR_PREL21,             21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSGD_ADR_PAGE21,             21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSGD_ADD_LO12_NC,            12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSGD_MOVW_G1,                16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSGD_MOVW_G0_NC,             16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADR_PREL21,             21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADR_PAGE21,             21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADD_LO12_NC,             0 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_G1,                 0 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_G0_NC,              0 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LD_PREL19,              19 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_DTPREL_G2,         16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_DTPREL_G1,         16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_DTPREL_G1_NC,      16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_DTPREL_G0,         16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_MOVW_DTPREL_G0_NC,      16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADD_DTPREL_HI12,        12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADD_DTPREL_LO12,        12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_ADD_DTPREL_LO12_NC,     12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST8_DTPREL_LO12,      12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST8_DTPREL_LO12_NC,   12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST16_DTPREL_LO12,     12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST16_DTPREL_LO12_NC,  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST32_DTPREL_LO12,     12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST32_DTPREL_LO12_NC,  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST64_DTPREL_LO12,     12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST64_DTPREL_LO12_NC,  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSIE_MOVW_GOTTPREL_G1,       16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC,    16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSIE_ADR_GOTTPREL_PAGE21,    21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC,  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSIE_LD_GOTTPREL_PREL19,     19 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_MOVW_TPREL_G2,          16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_MOVW_TPREL_G1,          16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_MOVW_TPREL_G1_NC,       16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_MOVW_TPREL_G0,          16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_MOVW_TPREL_G0_NC,       16 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_ADD_TPREL_HI12,         12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_ADD_TPREL_LO12,         12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_ADD_TPREL_LO12_NC,      12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST8_TPREL_LO12,       12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST8_TPREL_LO12_NC,    12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST16_TPREL_LO12,      12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST16_TPREL_LO12_NC,   12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST32_TPREL_LO12,      12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST32_TPREL_LO12_NC,   12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST64_TPREL_LO12,      12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST64_TPREL_LO12_NC,   12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_LD_PREL19,            19 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_ADR_PREL21,           21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_ADR_PAGE21,           21 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_LD64_LO12_NC,         12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_ADD_LO12_NC,          12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_OFF_G1,               12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_OFF_G0_NC,            12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_LDR,                  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_ADD,                  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC_CALL,                 12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST128_TPREL_LO12,     12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLE_LDST128_TPREL_LO12_NC,  12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST128_DTPREL_LO12,    12 ),
    std::pair(Relocation::TYPE::AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 12 ),
    std::pair(Relocation::TYPE::AARCH64_COPY,                         64 ),
    std::pair(Relocation::TYPE::AARCH64_GLOB_DAT,                     64 ),
    std::pair(Relocation::TYPE::AARCH64_JUMP_SLOT,                    64 ),
    std::pair(Relocation::TYPE::AARCH64_RELATIVE,                     64 ),
    std::pair(Relocation::TYPE::AARCH64_TLS_DTPREL64,                 64 ),
    std::pair(Relocation::TYPE::AARCH64_TLS_DTPMOD64,                 64 ),
    std::pair(Relocation::TYPE::AARCH64_TLS_TPREL64,                  64 ),
    std::pair(Relocation::TYPE::AARCH64_TLSDESC,                      64 ),
    std::pair(Relocation::TYPE::AARCH64_IRELATIVE,                    64 ),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}



int32_t get_R_PPC(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::PPC_NONE,              0  ),
    std::pair(Relocation::TYPE::PPC_ADDR32,            32 ),
    std::pair(Relocation::TYPE::PPC_ADDR24,            32 ),
    std::pair(Relocation::TYPE::PPC_ADDR16,            16 ),
    std::pair(Relocation::TYPE::PPC_ADDR16_LO,         16 ),
    std::pair(Relocation::TYPE::PPC_ADDR16_HI,         16 ),
    std::pair(Relocation::TYPE::PPC_ADDR16_HA,         16 ),
    std::pair(Relocation::TYPE::PPC_ADDR14,            32 ),
    std::pair(Relocation::TYPE::PPC_ADDR14_BRTAKEN,    32 ),
    std::pair(Relocation::TYPE::PPC_ADDR14_BRNTAKEN,   32 ),
    std::pair(Relocation::TYPE::PPC_REL24,             32 ),
    std::pair(Relocation::TYPE::PPC_REL14,             32 ),
    std::pair(Relocation::TYPE::PPC_REL14_BRTAKEN,     32 ),
    std::pair(Relocation::TYPE::PPC_REL14_BRNTAKEN,    32 ),
    std::pair(Relocation::TYPE::PPC_GOT16,             16 ),
    std::pair(Relocation::TYPE::PPC_GOT16_LO,          16 ),
    std::pair(Relocation::TYPE::PPC_GOT16_HI,          16 ),
    std::pair(Relocation::TYPE::PPC_GOT16_HA,          16 ),
    std::pair(Relocation::TYPE::PPC_PLTREL24,          32 ),
    std::pair(Relocation::TYPE::PPC_JMP_SLOT,          0  ),
    std::pair(Relocation::TYPE::PPC_RELATIVE,          32 ),
    std::pair(Relocation::TYPE::PPC_LOCAL24PC,         32 ),
    std::pair(Relocation::TYPE::PPC_REL32,             32 ),
    std::pair(Relocation::TYPE::PPC_TLS,               32 ),
    std::pair(Relocation::TYPE::PPC_DTPMOD32,          32 ),
    std::pair(Relocation::TYPE::PPC_TPREL16,           16 ),
    std::pair(Relocation::TYPE::PPC_TPREL16_LO,        16 ),
    std::pair(Relocation::TYPE::PPC_TPREL16_HI,        16 ),
    std::pair(Relocation::TYPE::PPC_TPREL16_HA,        16 ),
    std::pair(Relocation::TYPE::PPC_TPREL32,           32 ),
    std::pair(Relocation::TYPE::PPC_DTPREL16,          16 ),
    std::pair(Relocation::TYPE::PPC_DTPREL16_LO,       16 ),
    std::pair(Relocation::TYPE::PPC_DTPREL16_HI,       16 ),
    std::pair(Relocation::TYPE::PPC_DTPREL16_HA,       16 ),
    std::pair(Relocation::TYPE::PPC_DTPREL32,          32 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSGD16,       16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSGD16_LO,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSGD16_HI,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSGD16_HA,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSLD16,       16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSLD16_LO,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSLD16_HI,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TLSLD16_HA,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TPREL16,       16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TPREL16_LO,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TPREL16_HI,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_TPREL16_HA,    16 ),
    std::pair(Relocation::TYPE::PPC_GOT_DTPREL16,      16 ),
    std::pair(Relocation::TYPE::PPC_GOT_DTPREL16_LO,   16 ),
    std::pair(Relocation::TYPE::PPC_GOT_DTPREL16_HI,   16 ),
    std::pair(Relocation::TYPE::PPC_GOT_DTPREL16_HA,   16 ),
    std::pair(Relocation::TYPE::PPC_TLSGD,             32 ),
    std::pair(Relocation::TYPE::PPC_TLSLD,             32 ),
    std::pair(Relocation::TYPE::PPC_REL16,             16 ),
    std::pair(Relocation::TYPE::PPC_REL16_LO,          16 ),
    std::pair(Relocation::TYPE::PPC_REL16_HI,          16 ),
    std::pair(Relocation::TYPE::PPC_REL16_HA,          16 ),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}


int32_t get_R_PPC64(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {

    std::pair(Relocation::TYPE::PPC64_NONE,                 0 ),
    std::pair(Relocation::TYPE::PPC64_ADDR32,              32 ),
    std::pair(Relocation::TYPE::PPC64_ADDR24,              32 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16,              16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_LO,           16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HI,           16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HA,           16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR14,              32 ),
    std::pair(Relocation::TYPE::PPC64_ADDR14_BRTAKEN,      32 ),
    std::pair(Relocation::TYPE::PPC64_ADDR14_BRNTAKEN,     32 ),
    std::pair(Relocation::TYPE::PPC64_REL24,               32 ),
    std::pair(Relocation::TYPE::PPC64_REL14,               32 ),
    std::pair(Relocation::TYPE::PPC64_REL14_BRTAKEN,       32 ),
    std::pair(Relocation::TYPE::PPC64_REL14_BRNTAKEN,      32 ),
    std::pair(Relocation::TYPE::PPC64_GOT16,               16 ),
    std::pair(Relocation::TYPE::PPC64_GOT16_LO,            16 ),
    std::pair(Relocation::TYPE::PPC64_GOT16_HI,            16 ),
    std::pair(Relocation::TYPE::PPC64_GOT16_HA,            16 ),
    std::pair(Relocation::TYPE::PPC64_JMP_SLOT,            64 ),
    std::pair(Relocation::TYPE::PPC64_RELATIVE,            64 ),
    std::pair(Relocation::TYPE::PPC64_REL32,               32 ),
    std::pair(Relocation::TYPE::PPC64_ADDR64,              64 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HIGHER,       16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HIGHERA,      16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HIGHEST,      16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_HIGHESTA,     16 ),
    std::pair(Relocation::TYPE::PPC64_REL64,               64 ),
    std::pair(Relocation::TYPE::PPC64_TOC16,               16 ),
    std::pair(Relocation::TYPE::PPC64_TOC16_LO,            16 ),
    std::pair(Relocation::TYPE::PPC64_TOC16_HI,            16 ),
    std::pair(Relocation::TYPE::PPC64_TOC16_HA,            16 ),
    std::pair(Relocation::TYPE::PPC64_TOC,                 16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_DS,           16 ),
    std::pair(Relocation::TYPE::PPC64_ADDR16_LO_DS,        16 ),
    std::pair(Relocation::TYPE::PPC64_GOT16_DS,            16 ),
    std::pair(Relocation::TYPE::PPC64_GOT16_LO_DS,         16 ),
    std::pair(Relocation::TYPE::PPC64_TOC16_DS,            16 ),
    std::pair(Relocation::TYPE::PPC64_TOC16_LO_DS,         16 ),
    std::pair(Relocation::TYPE::PPC64_TLS,                  0 ),
    std::pair(Relocation::TYPE::PPC64_DTPMOD64,            64 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16,             16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_LO,          16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HI,          16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HA,          16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL64,             64 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16,            16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_LO,         16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HI,         16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HA,         16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL64,            64 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSGD16,         16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSGD16_LO,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSGD16_HI,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSGD16_HA,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSLD16,         16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSLD16_LO,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSLD16_HI,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TLSLD16_HA,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TPREL16_DS,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TPREL16_LO_DS,   16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TPREL16_HI,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_TPREL16_HA,      16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_DTPREL16_DS,     16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_DTPREL16_LO_DS,  16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_DTPREL16_HI,     16 ),
    std::pair(Relocation::TYPE::PPC64_GOT_DTPREL16_HA,     16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_DS,          16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_LO_DS,       16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HIGHER,      16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HIGHERA,     16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HIGHEST,     16 ),
    std::pair(Relocation::TYPE::PPC64_TPREL16_HIGHESTA,    16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_DS,         16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_LO_DS,      16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HIGHER,     16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HIGHERA,    16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HIGHEST,    16 ),
    std::pair(Relocation::TYPE::PPC64_DTPREL16_HIGHESTA,   16 ),
    std::pair(Relocation::TYPE::PPC64_TLSGD,               64 ),
    std::pair(Relocation::TYPE::PPC64_TLSLD,               64 ),
    std::pair(Relocation::TYPE::PPC64_REL16,               16 ),
    std::pair(Relocation::TYPE::PPC64_REL16_LO,            16 ),
    std::pair(Relocation::TYPE::PPC64_REL16_HI,            16 ),
    std::pair(Relocation::TYPE::PPC64_REL16_HA,            16 ),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_R_MIPS(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::MICROMIPS_26_S1,           26 ),
    std::pair(Relocation::TYPE::MICROMIPS_CALL16,          16 ),
    std::pair(Relocation::TYPE::MICROMIPS_CALL_HI16,       16 ),
    std::pair(Relocation::TYPE::MICROMIPS_CALL_LO16,       16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT16,           16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT_DISP,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT_HI16,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT_LO16,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT_OFST,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GOT_PAGE,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GPREL16,         16 ),
    std::pair(Relocation::TYPE::MICROMIPS_GPREL7_S2,        7 ),
    std::pair(Relocation::TYPE::MICROMIPS_HI0_LO16,        16 ),
    std::pair(Relocation::TYPE::MICROMIPS_HI16,            16 ),
    std::pair(Relocation::TYPE::MICROMIPS_HIGHER,          16 ),
    std::pair(Relocation::TYPE::MICROMIPS_HIGHEST,         16 ),
    std::pair(Relocation::TYPE::MICROMIPS_JALR,            32 ),
    std::pair(Relocation::TYPE::MICROMIPS_LITERAL,         16 ),
    std::pair(Relocation::TYPE::MICROMIPS_LO16,            16 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC10_S1,         10 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC16_S1,         16 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC18_S3,         18 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC19_S2,         19 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC21_S2,         21 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC23_S2,         23 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC26_S2,         26 ),
    std::pair(Relocation::TYPE::MICROMIPS_PC7_S1,           7 ),
    std::pair(Relocation::TYPE::MICROMIPS_SCN_DISP,        32 ),
    std::pair(Relocation::TYPE::MICROMIPS_SUB,             64 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_DTPREL_HI16, 16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_DTPREL_LO16, 16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_GD,          16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_GOTTPREL,    16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_LDM,         16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_TPREL_HI16,  16 ),
    std::pair(Relocation::TYPE::MICROMIPS_TLS_TPREL_LO16,  16 ),
    std::pair(Relocation::TYPE::MIPS_16,                   16 ),
    std::pair(Relocation::TYPE::MIPS16_26,                 26 ),
    std::pair(Relocation::TYPE::MIPS16_CALL16,             16 ),
    std::pair(Relocation::TYPE::MIPS16_GOT16,              16 ),
    std::pair(Relocation::TYPE::MIPS16_GPREL,              16 ),
    std::pair(Relocation::TYPE::MIPS16_HI16,               16 ),
    std::pair(Relocation::TYPE::MIPS16_LO16,               16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_DTPREL_HI16,    16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_DTPREL_LO16,    16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_GD,             16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_GOTTPREL,       16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_LDM,            16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_TPREL_HI16,     16 ),
    std::pair(Relocation::TYPE::MIPS16_TLS_TPREL_LO16,     16 ),
    std::pair(Relocation::TYPE::MIPS_ADD_IMMEDIATE,         0 ),
    std::pair(Relocation::TYPE::MIPS_26,                   26 ),
    std::pair(Relocation::TYPE::MIPS_32,                   32 ),
    std::pair(Relocation::TYPE::MIPS_64,                   64 ),
    std::pair(Relocation::TYPE::MIPS_CALL16,               16 ),
    std::pair(Relocation::TYPE::MIPS_CALL_HI16,            16 ),
    std::pair(Relocation::TYPE::MIPS_CALL_LO16,            16 ),
    std::pair(Relocation::TYPE::MIPS_COPY,                  0 ),
    std::pair(Relocation::TYPE::MIPS_DELETE,               32 ),
    std::pair(Relocation::TYPE::MIPS_EH,                   32 ),
    std::pair(Relocation::TYPE::MIPS_GLOB_DAT,             32 ),
    std::pair(Relocation::TYPE::MIPS_GOT16,                16 ),
    std::pair(Relocation::TYPE::MIPS_GOT_DISP,             16 ),
    std::pair(Relocation::TYPE::MIPS_GOT_HI16,             16 ),
    std::pair(Relocation::TYPE::MIPS_GOT_LO16,             16 ),
    std::pair(Relocation::TYPE::MIPS_GOT_OFST,             16 ),
    std::pair(Relocation::TYPE::MIPS_GOT_PAGE,             16 ),
    std::pair(Relocation::TYPE::MIPS_GPREL16,              16 ),
    std::pair(Relocation::TYPE::MIPS_GPREL32,              32 ),
    std::pair(Relocation::TYPE::MIPS_HI16,                 16 ),
    std::pair(Relocation::TYPE::MIPS_HIGHER,               16 ),
    std::pair(Relocation::TYPE::MIPS_HIGHEST,              16 ),
    std::pair(Relocation::TYPE::MIPS_INSERT_A,             32 ),
    std::pair(Relocation::TYPE::MIPS_INSERT_B,             32 ),
    std::pair(Relocation::TYPE::MIPS_JALR,                 32 ),
    std::pair(Relocation::TYPE::MIPS_JUMP_SLOT,            64 ),
    std::pair(Relocation::TYPE::MIPS_LITERAL,              16 ),
    std::pair(Relocation::TYPE::MIPS_LO16,                 16 ),
    std::pair(Relocation::TYPE::MIPS_NONE,                  0 ),
    std::pair(Relocation::TYPE::MIPS_NUM,                   0 ),
    std::pair(Relocation::TYPE::MIPS_PC16,                 16 ),
    std::pair(Relocation::TYPE::MIPS_PC18_S3,              18 ),
    std::pair(Relocation::TYPE::MIPS_PC19_S2,              19 ),
    std::pair(Relocation::TYPE::MIPS_PC21_S2,              21 ),
    std::pair(Relocation::TYPE::MIPS_PC26_S2,              26 ),
    std::pair(Relocation::TYPE::MIPS_PC32,                 32 ),
    std::pair(Relocation::TYPE::MIPS_PCHI16,               16 ),
    std::pair(Relocation::TYPE::MIPS_PCLO16,               16 ),
    std::pair(Relocation::TYPE::MIPS_PJUMP,                 0 ),
    std::pair(Relocation::TYPE::MIPS_REL16,                16 ),
    std::pair(Relocation::TYPE::MIPS_REL32,                32 ),
    std::pair(Relocation::TYPE::MIPS_RELGOT,               32 ),
    std::pair(Relocation::TYPE::MIPS_SCN_DISP,             32 ),
    std::pair(Relocation::TYPE::MIPS_SHIFT5,                5 ),
    std::pair(Relocation::TYPE::MIPS_SHIFT6,                6 ),
    std::pair(Relocation::TYPE::MIPS_SUB,                  64 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPMOD32,         32 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPMOD64,         64 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPREL32,         32 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPREL64,         64 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPREL_HI16,      16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_DTPREL_LO16,      16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_GD,               16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_GOTTPREL,         16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_LDM,              16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_TPREL64,          32 ),
    std::pair(Relocation::TYPE::MIPS_TLS_TPREL64,          64 ),
    std::pair(Relocation::TYPE::MIPS_TLS_TPREL_HI16,       16 ),
    std::pair(Relocation::TYPE::MIPS_TLS_TPREL_LO16,       16 ),
    std::pair(Relocation::TYPE::MIPS_UNUSED1,               0 ),
    std::pair(Relocation::TYPE::MIPS_UNUSED2,               0 ),
    std::pair(Relocation::TYPE::MIPS_UNUSED3,               0 ),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_R_LARCH(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::LARCH_NONE,                        0),
    std::pair(Relocation::TYPE::LARCH_32,                         32),
    std::pair(Relocation::TYPE::LARCH_64,                         64),
    std::pair(Relocation::TYPE::LARCH_RELATIVE,                   32),
    std::pair(Relocation::TYPE::LARCH_COPY,                        0),
    std::pair(Relocation::TYPE::LARCH_JUMP_SLOT,                  64),
    std::pair(Relocation::TYPE::LARCH_TLS_DTPMOD32,               32),
    std::pair(Relocation::TYPE::LARCH_TLS_DTPMOD64,               64),
    std::pair(Relocation::TYPE::LARCH_TLS_DTPREL32,               32),
    std::pair(Relocation::TYPE::LARCH_TLS_DTPREL64,               64),
    std::pair(Relocation::TYPE::LARCH_TLS_TPREL32,                32),
    std::pair(Relocation::TYPE::LARCH_TLS_TPREL64,                64),
    std::pair(Relocation::TYPE::LARCH_IRELATIVE,                  32),
    std::pair(Relocation::TYPE::LARCH_MARK_LA,                     0),
    std::pair(Relocation::TYPE::LARCH_MARK_PCREL,                  0),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_PCREL,             32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_ABSOLUTE,          32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_DUP,               32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_GPREL,             32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_TLS_TPREL,         32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_TLS_GOT,           32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_TLS_GD,            32),
    std::pair(Relocation::TYPE::LARCH_SOP_PUSH_PLT_PCREL,         32),
    std::pair(Relocation::TYPE::LARCH_SOP_ASSERT,                 32),
    std::pair(Relocation::TYPE::LARCH_SOP_NOT,                    32),
    std::pair(Relocation::TYPE::LARCH_SOP_SUB,                    32),
    std::pair(Relocation::TYPE::LARCH_SOP_SL,                     32),
    std::pair(Relocation::TYPE::LARCH_SOP_SR,                     32),
    std::pair(Relocation::TYPE::LARCH_SOP_ADD,                    32),
    std::pair(Relocation::TYPE::LARCH_SOP_AND,                    32),
    std::pair(Relocation::TYPE::LARCH_SOP_IF_ELSE,                32),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_10_5,           5),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_U_10_12,         12),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_10_12,         12),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_10_16,         16),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_10_16_S2,      16),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_5_20,          20),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_0_5_10_16_S2,  21),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_S_0_10_10_16_S2, 26),
    std::pair(Relocation::TYPE::LARCH_SOP_POP_32_U,               32),
    std::pair(Relocation::TYPE::LARCH_ADD8,                       8),
    std::pair(Relocation::TYPE::LARCH_ADD16,                      16),
    std::pair(Relocation::TYPE::LARCH_ADD24,                      24),
    std::pair(Relocation::TYPE::LARCH_ADD32,                      32),
    std::pair(Relocation::TYPE::LARCH_ADD64,                      64),
    std::pair(Relocation::TYPE::LARCH_SUB8,                        8),
    std::pair(Relocation::TYPE::LARCH_SUB16,                      16),
    std::pair(Relocation::TYPE::LARCH_SUB24,                      24),
    std::pair(Relocation::TYPE::LARCH_SUB32,                      32),
    std::pair(Relocation::TYPE::LARCH_SUB64,                      64),
    std::pair(Relocation::TYPE::LARCH_GNU_VTINHERIT,               0),
    std::pair(Relocation::TYPE::LARCH_GNU_VTENTRY,                 0),
    std::pair(Relocation::TYPE::LARCH_B16,                        16),
    std::pair(Relocation::TYPE::LARCH_B21,                        21),
    std::pair(Relocation::TYPE::LARCH_B26,                        26),
    std::pair(Relocation::TYPE::LARCH_ABS_HI20,                   20),
    std::pair(Relocation::TYPE::LARCH_ABS_LO12,                   12),
    std::pair(Relocation::TYPE::LARCH_ABS64_LO20,                 20),
    std::pair(Relocation::TYPE::LARCH_ABS64_HI12,                 12),
    std::pair(Relocation::TYPE::LARCH_PCALA_HI20,                 20),
    std::pair(Relocation::TYPE::LARCH_PCALA_LO12,                 12),
    std::pair(Relocation::TYPE::LARCH_PCALA64_LO20,               20),
    std::pair(Relocation::TYPE::LARCH_PCALA64_HI12,               12),
    std::pair(Relocation::TYPE::LARCH_GOT_PC_HI20,                20),
    std::pair(Relocation::TYPE::LARCH_GOT_PC_LO12,                12),
    std::pair(Relocation::TYPE::LARCH_GOT64_PC_LO20,              20),
    std::pair(Relocation::TYPE::LARCH_GOT64_PC_HI12,              12),
    std::pair(Relocation::TYPE::LARCH_GOT_HI20,                   20),
    std::pair(Relocation::TYPE::LARCH_GOT_LO12,                   12),
    std::pair(Relocation::TYPE::LARCH_GOT64_LO20,                 20),
    std::pair(Relocation::TYPE::LARCH_GOT64_HI12,                 12),
    std::pair(Relocation::TYPE::LARCH_TLS_LE_HI20,                20),
    std::pair(Relocation::TYPE::LARCH_TLS_LE_LO12,                12),
    std::pair(Relocation::TYPE::LARCH_TLS_LE64_LO20,              20),
    std::pair(Relocation::TYPE::LARCH_TLS_LE64_HI12,              12),
    std::pair(Relocation::TYPE::LARCH_TLS_IE_PC_HI20,             20),
    std::pair(Relocation::TYPE::LARCH_TLS_IE_PC_LO12,             12),
    std::pair(Relocation::TYPE::LARCH_TLS_IE64_PC_LO20,           20),
    std::pair(Relocation::TYPE::LARCH_TLS_IE64_PC_HI12,           12),
    std::pair(Relocation::TYPE::LARCH_TLS_IE_HI20,                20),
    std::pair(Relocation::TYPE::LARCH_TLS_IE_LO12,                12),
    std::pair(Relocation::TYPE::LARCH_TLS_IE64_LO20,              20),
    std::pair(Relocation::TYPE::LARCH_TLS_IE64_HI12,              12),
    std::pair(Relocation::TYPE::LARCH_TLS_LD_PC_HI20,             20),
    std::pair(Relocation::TYPE::LARCH_TLS_LD_HI20,                20),
    std::pair(Relocation::TYPE::LARCH_TLS_GD_PC_HI20,             20),
    std::pair(Relocation::TYPE::LARCH_TLS_GD_HI20,                20),
    std::pair(Relocation::TYPE::LARCH_32_PCREL,                   32),
    std::pair(Relocation::TYPE::LARCH_RELAX,                       0),
};
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_R_RISCV(Relocation::TYPE R) {
  CONST_MAP_ALT SIZES {
    std::pair(Relocation::TYPE::RISCV_NONE,              0),
    std::pair(Relocation::TYPE::RISCV_32,                32),
    std::pair(Relocation::TYPE::RISCV_64,                64),
    std::pair(Relocation::TYPE::RISCV_RELATIVE,          -1),
    std::pair(Relocation::TYPE::RISCV_COPY,              -1),
    std::pair(Relocation::TYPE::RISCV_JUMP_SLOT,         -1),
    std::pair(Relocation::TYPE::RISCV_TLS_DTPMOD32,      32),
    std::pair(Relocation::TYPE::RISCV_TLS_DTPMOD64,      64),
    std::pair(Relocation::TYPE::RISCV_TLS_DTPREL32,      32),
    std::pair(Relocation::TYPE::RISCV_TLS_DTPREL64,      64),
    std::pair(Relocation::TYPE::RISCV_TLS_TPREL32,       32),
    std::pair(Relocation::TYPE::RISCV_TLS_TPREL64,       64),
    std::pair(Relocation::TYPE::RISCV_TLSDESC,           -1),
    std::pair(Relocation::TYPE::RISCV_BRANCH,            -1),
    std::pair(Relocation::TYPE::RISCV_JAL,               -1),
    std::pair(Relocation::TYPE::RISCV_CALL,              -1),
    std::pair(Relocation::TYPE::RISCV_CALL_PLT,          -1),
    std::pair(Relocation::TYPE::RISCV_GOT_HI20,          20),
    std::pair(Relocation::TYPE::RISCV_TLS_GOT_HI20,      20),
    std::pair(Relocation::TYPE::RISCV_TLS_GD_HI20,       20),
    std::pair(Relocation::TYPE::RISCV_PCREL_HI20,        20),
    std::pair(Relocation::TYPE::RISCV_PCREL_LO12_I,      12),
    std::pair(Relocation::TYPE::RISCV_PCREL_LO12_S,      12),
    std::pair(Relocation::TYPE::RISCV_HI20,              20),
    std::pair(Relocation::TYPE::RISCV_LO12_I,            12),
    std::pair(Relocation::TYPE::RISCV_LO12_S,            12),
    std::pair(Relocation::TYPE::RISCV_TPREL_HI20,        20),
    std::pair(Relocation::TYPE::RISCV_TPREL_LO12_I,      12),
    std::pair(Relocation::TYPE::RISCV_TPREL_LO12_S,      12),
    std::pair(Relocation::TYPE::RISCV_TPREL_ADD,         -1),
    std::pair(Relocation::TYPE::RISCV_ADD8,              8),
    std::pair(Relocation::TYPE::RISCV_ADD16,             16),
    std::pair(Relocation::TYPE::RISCV_ADD32,             32),
    std::pair(Relocation::TYPE::RISCV_ADD64,             64),
    std::pair(Relocation::TYPE::RISCV_SUB8,              8),
    std::pair(Relocation::TYPE::RISCV_SUB16,             16),
    std::pair(Relocation::TYPE::RISCV_SUB32,             32),
    std::pair(Relocation::TYPE::RISCV_SUB64,             64),
    std::pair(Relocation::TYPE::RISCV_GOT32_PCREL,       32),
    std::pair(Relocation::TYPE::RISCV_ALIGN,             -1),
    std::pair(Relocation::TYPE::RISCV_RVC_BRANCH,        -1),
    std::pair(Relocation::TYPE::RISCV_RVC_JUMP,          -1),
    std::pair(Relocation::TYPE::RISCV_RVC_LUI,           -1),
    std::pair(Relocation::TYPE::RISCV_RELAX,             -1),
    std::pair(Relocation::TYPE::RISCV_SUB6,              6),
    std::pair(Relocation::TYPE::RISCV_SET6,              6),
    std::pair(Relocation::TYPE::RISCV_SET8,              8),
    std::pair(Relocation::TYPE::RISCV_SET16,             16),
    std::pair(Relocation::TYPE::RISCV_SET32,             32),
    std::pair(Relocation::TYPE::RISCV_32_PCREL,          32),
    std::pair(Relocation::TYPE::RISCV_IRELATIVE,         0),
    std::pair(Relocation::TYPE::RISCV_PLT32,             32),
    std::pair(Relocation::TYPE::RISCV_SET_ULEB128,       -1),
    std::pair(Relocation::TYPE::RISCV_SUB_ULEB128,       -1),
    std::pair(Relocation::TYPE::RISCV_TLSDESC_HI20,      20),
    std::pair(Relocation::TYPE::RISCV_TLSDESC_LOAD_LO12, 12),
    std::pair(Relocation::TYPE::RISCV_TLSDESC_ADD_LO12,  12),
    std::pair(Relocation::TYPE::RISCV_TLSDESC_CALL,      -1),
  };
  const auto it = SIZES.find(R);
  return it == SIZES.end() ? -1 : it->second;
}

int32_t get_reloc_size(Relocation::TYPE type) {
  auto raw_type = static_cast<uint64_t>(type);
  const uint64_t ID = (raw_type >> Relocation::R_BIT) << Relocation::R_BIT;

  if (ID == Relocation::R_X64) {
    return get_R_X64(type);
  }
  if (ID == Relocation::R_X86) {
    return get_R_X86(type);
  }
  if (ID == Relocation::R_AARCH64) {
    return get_R_AARCH64(type);
  }
  if (ID == Relocation::R_ARM) {
    return get_R_ARM(type);
  }
  if (ID == Relocation::R_LARCH) {
    return get_R_LARCH(type);
  }
  if (ID == Relocation::R_MIPS) {
    return get_R_MIPS(type);
  }
  if (ID == Relocation::R_PPC) {
    return get_R_PPC(type);
  }
  if (ID == Relocation::R_PPC64) {
    return get_R_PPC64(type);
  }
  if (ID == Relocation::R_RISCV) {
    return get_R_RISCV(type);
  }
  return -1;
}

}
}
