#include "mold.h"

namespace mold::elf {

static std::string unknown_type(u32 r_type) {
  char buf[50];
  snprintf(buf, sizeof(buf), "unknown (0x%x)", r_type);
  return buf;
}

#define CASE(x) case x: return #x

template <>
std::string rel_to_string<X86_64>(u32 r_type) {
  switch (r_type) {
  CASE(R_X86_64_NONE);
  CASE(R_X86_64_64);
  CASE(R_X86_64_PC32);
  CASE(R_X86_64_GOT32);
  CASE(R_X86_64_PLT32);
  CASE(R_X86_64_COPY);
  CASE(R_X86_64_GLOB_DAT);
  CASE(R_X86_64_JUMP_SLOT);
  CASE(R_X86_64_RELATIVE);
  CASE(R_X86_64_GOTPCREL);
  CASE(R_X86_64_32);
  CASE(R_X86_64_32S);
  CASE(R_X86_64_16);
  CASE(R_X86_64_PC16);
  CASE(R_X86_64_8);
  CASE(R_X86_64_PC8);
  CASE(R_X86_64_DTPMOD64);
  CASE(R_X86_64_DTPOFF64);
  CASE(R_X86_64_TPOFF64);
  CASE(R_X86_64_TLSGD);
  CASE(R_X86_64_TLSLD);
  CASE(R_X86_64_DTPOFF32);
  CASE(R_X86_64_GOTTPOFF);
  CASE(R_X86_64_TPOFF32);
  CASE(R_X86_64_PC64);
  CASE(R_X86_64_GOTOFF64);
  CASE(R_X86_64_GOTPC32);
  CASE(R_X86_64_GOT64);
  CASE(R_X86_64_GOTPCREL64);
  CASE(R_X86_64_GOTPC64);
  CASE(R_X86_64_GOTPLT64);
  CASE(R_X86_64_PLTOFF64);
  CASE(R_X86_64_SIZE32);
  CASE(R_X86_64_SIZE64);
  CASE(R_X86_64_GOTPC32_TLSDESC);
  CASE(R_X86_64_TLSDESC_CALL);
  CASE(R_X86_64_TLSDESC);
  CASE(R_X86_64_IRELATIVE);
  CASE(R_X86_64_GOTPCRELX);
  CASE(R_X86_64_REX_GOTPCRELX);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<I386>(u32 r_type) {
  switch (r_type) {
  CASE(R_386_NONE);
  CASE(R_386_32);
  CASE(R_386_PC32);
  CASE(R_386_GOT32);
  CASE(R_386_PLT32);
  CASE(R_386_COPY);
  CASE(R_386_GLOB_DAT);
  CASE(R_386_JUMP_SLOT);
  CASE(R_386_RELATIVE);
  CASE(R_386_GOTOFF);
  CASE(R_386_GOTPC);
  CASE(R_386_32PLT);
  CASE(R_386_TLS_TPOFF);
  CASE(R_386_TLS_IE);
  CASE(R_386_TLS_GOTIE);
  CASE(R_386_TLS_LE);
  CASE(R_386_TLS_GD);
  CASE(R_386_TLS_LDM);
  CASE(R_386_16);
  CASE(R_386_PC16);
  CASE(R_386_8);
  CASE(R_386_PC8);
  CASE(R_386_TLS_GD_32);
  CASE(R_386_TLS_GD_PUSH);
  CASE(R_386_TLS_GD_CALL);
  CASE(R_386_TLS_GD_POP);
  CASE(R_386_TLS_LDM_32);
  CASE(R_386_TLS_LDM_PUSH);
  CASE(R_386_TLS_LDM_CALL);
  CASE(R_386_TLS_LDM_POP);
  CASE(R_386_TLS_LDO_32);
  CASE(R_386_TLS_IE_32);
  CASE(R_386_TLS_LE_32);
  CASE(R_386_TLS_DTPMOD32);
  CASE(R_386_TLS_DTPOFF32);
  CASE(R_386_TLS_TPOFF32);
  CASE(R_386_SIZE32);
  CASE(R_386_TLS_GOTDESC);
  CASE(R_386_TLS_DESC_CALL);
  CASE(R_386_TLS_DESC);
  CASE(R_386_IRELATIVE);
  CASE(R_386_GOT32X);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<ARM64>(u32 r_type) {
  switch (r_type) {
  CASE(R_AARCH64_NONE);
  CASE(R_AARCH64_ABS64);
  CASE(R_AARCH64_ABS32);
  CASE(R_AARCH64_ABS16);
  CASE(R_AARCH64_PREL64);
  CASE(R_AARCH64_PREL32);
  CASE(R_AARCH64_PREL16);
  CASE(R_AARCH64_MOVW_UABS_G0);
  CASE(R_AARCH64_MOVW_UABS_G0_NC);
  CASE(R_AARCH64_MOVW_UABS_G1);
  CASE(R_AARCH64_MOVW_UABS_G1_NC);
  CASE(R_AARCH64_MOVW_UABS_G2);
  CASE(R_AARCH64_MOVW_UABS_G2_NC);
  CASE(R_AARCH64_MOVW_UABS_G3);
  CASE(R_AARCH64_MOVW_SABS_G0);
  CASE(R_AARCH64_MOVW_SABS_G1);
  CASE(R_AARCH64_MOVW_SABS_G2);
  CASE(R_AARCH64_LD_PREL_LO19);
  CASE(R_AARCH64_ADR_PREL_LO21);
  CASE(R_AARCH64_ADR_PREL_PG_HI21);
  CASE(R_AARCH64_ADR_PREL_PG_HI21_NC);
  CASE(R_AARCH64_ADD_ABS_LO12_NC);
  CASE(R_AARCH64_LDST8_ABS_LO12_NC);
  CASE(R_AARCH64_TSTBR14);
  CASE(R_AARCH64_CONDBR19);
  CASE(R_AARCH64_JUMP26);
  CASE(R_AARCH64_CALL26);
  CASE(R_AARCH64_LDST16_ABS_LO12_NC);
  CASE(R_AARCH64_LDST32_ABS_LO12_NC);
  CASE(R_AARCH64_LDST64_ABS_LO12_NC);
  CASE(R_AARCH64_MOVW_PREL_G0);
  CASE(R_AARCH64_MOVW_PREL_G0_NC);
  CASE(R_AARCH64_MOVW_PREL_G1);
  CASE(R_AARCH64_MOVW_PREL_G1_NC);
  CASE(R_AARCH64_MOVW_PREL_G2);
  CASE(R_AARCH64_MOVW_PREL_G2_NC);
  CASE(R_AARCH64_MOVW_PREL_G3);
  CASE(R_AARCH64_LDST128_ABS_LO12_NC);
  CASE(R_AARCH64_ADR_GOT_PAGE);
  CASE(R_AARCH64_LD64_GOT_LO12_NC);
  CASE(R_AARCH64_LD64_GOTPAGE_LO15);
  CASE(R_AARCH64_PLT32);
  CASE(R_AARCH64_TLSGD_ADR_PREL21);
  CASE(R_AARCH64_TLSGD_ADR_PAGE21);
  CASE(R_AARCH64_TLSGD_ADD_LO12_NC);
  CASE(R_AARCH64_TLSGD_MOVW_G1);
  CASE(R_AARCH64_TLSGD_MOVW_G0_NC);
  CASE(R_AARCH64_TLSLD_ADR_PREL21);
  CASE(R_AARCH64_TLSLD_ADR_PAGE21);
  CASE(R_AARCH64_TLSLD_ADD_LO12_NC);
  CASE(R_AARCH64_TLSLD_MOVW_G1);
  CASE(R_AARCH64_TLSLD_MOVW_G0_NC);
  CASE(R_AARCH64_TLSLD_LD_PREL19);
  CASE(R_AARCH64_TLSLD_MOVW_DTPREL_G2);
  CASE(R_AARCH64_TLSLD_MOVW_DTPREL_G1);
  CASE(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC);
  CASE(R_AARCH64_TLSLD_MOVW_DTPREL_G0);
  CASE(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC);
  CASE(R_AARCH64_TLSLD_ADD_DTPREL_HI12);
  CASE(R_AARCH64_TLSLD_ADD_DTPREL_LO12);
  CASE(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC);
  CASE(R_AARCH64_TLSLD_LDST8_DTPREL_LO12);
  CASE(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC);
  CASE(R_AARCH64_TLSLD_LDST16_DTPREL_LO12);
  CASE(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC);
  CASE(R_AARCH64_TLSLD_LDST32_DTPREL_LO12);
  CASE(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC);
  CASE(R_AARCH64_TLSLD_LDST64_DTPREL_LO12);
  CASE(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC);
  CASE(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
  CASE(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
  CASE(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
  CASE(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
  CASE(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
  CASE(R_AARCH64_TLSLE_MOVW_TPREL_G2);
  CASE(R_AARCH64_TLSLE_MOVW_TPREL_G1);
  CASE(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC);
  CASE(R_AARCH64_TLSLE_MOVW_TPREL_G0);
  CASE(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC);
  CASE(R_AARCH64_TLSLE_ADD_TPREL_HI12);
  CASE(R_AARCH64_TLSLE_ADD_TPREL_LO12);
  CASE(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC);
  CASE(R_AARCH64_TLSLE_LDST8_TPREL_LO12);
  CASE(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC);
  CASE(R_AARCH64_TLSLE_LDST16_TPREL_LO12);
  CASE(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC);
  CASE(R_AARCH64_TLSLE_LDST32_TPREL_LO12);
  CASE(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC);
  CASE(R_AARCH64_TLSLE_LDST64_TPREL_LO12);
  CASE(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC);
  CASE(R_AARCH64_TLSDESC_ADR_PAGE21);
  CASE(R_AARCH64_TLSDESC_LD64_LO12);
  CASE(R_AARCH64_TLSDESC_ADD_LO12);
  CASE(R_AARCH64_TLSDESC_CALL);
  CASE(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC);
  CASE(R_AARCH64_COPY);
  CASE(R_AARCH64_GLOB_DAT);
  CASE(R_AARCH64_JUMP_SLOT);
  CASE(R_AARCH64_RELATIVE);
  CASE(R_AARCH64_TLS_DTPMOD64);
  CASE(R_AARCH64_TLS_DTPREL64);
  CASE(R_AARCH64_TLS_TPREL64);
  CASE(R_AARCH64_TLSDESC);
  CASE(R_AARCH64_IRELATIVE);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<ARM32>(u32 r_type) {
  switch (r_type) {
  CASE(R_ARM_NONE);
  CASE(R_ARM_PC24);
  CASE(R_ARM_ABS32);
  CASE(R_ARM_REL32);
  CASE(R_ARM_LDR_PC_G0);
  CASE(R_ARM_ABS16);
  CASE(R_ARM_ABS12);
  CASE(R_ARM_THM_ABS5);
  CASE(R_ARM_ABS8);
  CASE(R_ARM_SBREL32);
  CASE(R_ARM_THM_CALL);
  CASE(R_ARM_THM_PC8);
  CASE(R_ARM_BREL_ADJ);
  CASE(R_ARM_TLS_DESC);
  CASE(R_ARM_THM_SWI8);
  CASE(R_ARM_XPC25);
  CASE(R_ARM_THM_XPC22);
  CASE(R_ARM_TLS_DTPMOD32);
  CASE(R_ARM_TLS_DTPOFF32);
  CASE(R_ARM_TLS_TPOFF32);
  CASE(R_ARM_COPY);
  CASE(R_ARM_GLOB_DAT);
  CASE(R_ARM_JUMP_SLOT);
  CASE(R_ARM_RELATIVE);
  CASE(R_ARM_GOTOFF32);
  CASE(R_ARM_BASE_PREL);
  CASE(R_ARM_GOT_BREL);
  CASE(R_ARM_PLT32);
  CASE(R_ARM_CALL);
  CASE(R_ARM_JUMP24);
  CASE(R_ARM_THM_JUMP24);
  CASE(R_ARM_BASE_ABS);
  CASE(R_ARM_ALU_PCREL_7_0);
  CASE(R_ARM_ALU_PCREL_15_8);
  CASE(R_ARM_ALU_PCREL_23_15);
  CASE(R_ARM_LDR_SBREL_11_0_NC);
  CASE(R_ARM_ALU_SBREL_19_12_NC);
  CASE(R_ARM_ALU_SBREL_27_20_CK);
  CASE(R_ARM_TARGET1);
  CASE(R_ARM_SBREL31);
  CASE(R_ARM_V4BX);
  CASE(R_ARM_TARGET2);
  CASE(R_ARM_PREL31);
  CASE(R_ARM_MOVW_ABS_NC);
  CASE(R_ARM_MOVT_ABS);
  CASE(R_ARM_MOVW_PREL_NC);
  CASE(R_ARM_MOVT_PREL);
  CASE(R_ARM_THM_MOVW_ABS_NC);
  CASE(R_ARM_THM_MOVT_ABS);
  CASE(R_ARM_THM_MOVW_PREL_NC);
  CASE(R_ARM_THM_MOVT_PREL);
  CASE(R_ARM_THM_JUMP19);
  CASE(R_ARM_THM_JUMP6);
  CASE(R_ARM_THM_ALU_PREL_11_0);
  CASE(R_ARM_THM_PC12);
  CASE(R_ARM_ABS32_NOI);
  CASE(R_ARM_REL32_NOI);
  CASE(R_ARM_ALU_PC_G0_NC);
  CASE(R_ARM_ALU_PC_G0);
  CASE(R_ARM_ALU_PC_G1_NC);
  CASE(R_ARM_ALU_PC_G1);
  CASE(R_ARM_ALU_PC_G2);
  CASE(R_ARM_LDR_PC_G1);
  CASE(R_ARM_LDR_PC_G2);
  CASE(R_ARM_LDRS_PC_G0);
  CASE(R_ARM_LDRS_PC_G1);
  CASE(R_ARM_LDRS_PC_G2);
  CASE(R_ARM_LDC_PC_G0);
  CASE(R_ARM_LDC_PC_G1);
  CASE(R_ARM_LDC_PC_G2);
  CASE(R_ARM_ALU_SB_G0_NC);
  CASE(R_ARM_ALU_SB_G0);
  CASE(R_ARM_ALU_SB_G1_NC);
  CASE(R_ARM_ALU_SB_G1);
  CASE(R_ARM_ALU_SB_G2);
  CASE(R_ARM_LDR_SB_G0);
  CASE(R_ARM_LDR_SB_G1);
  CASE(R_ARM_LDR_SB_G2);
  CASE(R_ARM_LDRS_SB_G0);
  CASE(R_ARM_LDRS_SB_G1);
  CASE(R_ARM_LDRS_SB_G2);
  CASE(R_ARM_LDC_SB_G0);
  CASE(R_ARM_LDC_SB_G1);
  CASE(R_ARM_LDC_SB_G2);
  CASE(R_ARM_MOVW_BREL_NC);
  CASE(R_ARM_MOVT_BREL);
  CASE(R_ARM_MOVW_BREL);
  CASE(R_ARM_THM_MOVW_BREL_NC);
  CASE(R_ARM_THM_MOVT_BREL);
  CASE(R_ARM_THM_MOVW_BREL);
  CASE(R_ARM_TLS_GOTDESC);
  CASE(R_ARM_TLS_CALL);
  CASE(R_ARM_TLS_DESCSEQ);
  CASE(R_ARM_THM_TLS_CALL);
  CASE(R_ARM_PLT32_ABS);
  CASE(R_ARM_GOT_ABS);
  CASE(R_ARM_GOT_PREL);
  CASE(R_ARM_GOT_BREL12);
  CASE(R_ARM_GOTOFF12);
  CASE(R_ARM_GOTRELAX);
  CASE(R_ARM_GNU_VTENTRY);
  CASE(R_ARM_GNU_VTINHERIT);
  CASE(R_ARM_THM_JUMP11);
  CASE(R_ARM_THM_JUMP8);
  CASE(R_ARM_TLS_GD32);
  CASE(R_ARM_TLS_LDM32);
  CASE(R_ARM_TLS_LDO32);
  CASE(R_ARM_TLS_IE32);
  CASE(R_ARM_TLS_LE32);
  CASE(R_ARM_TLS_LDO12);
  CASE(R_ARM_TLS_LE12);
  CASE(R_ARM_TLS_IE12GP);
  CASE(R_ARM_PRIVATE_0);
  CASE(R_ARM_PRIVATE_1);
  CASE(R_ARM_PRIVATE_2);
  CASE(R_ARM_PRIVATE_3);
  CASE(R_ARM_PRIVATE_4);
  CASE(R_ARM_PRIVATE_5);
  CASE(R_ARM_PRIVATE_6);
  CASE(R_ARM_PRIVATE_7);
  CASE(R_ARM_PRIVATE_8);
  CASE(R_ARM_PRIVATE_9);
  CASE(R_ARM_PRIVATE_10);
  CASE(R_ARM_PRIVATE_11);
  CASE(R_ARM_PRIVATE_12);
  CASE(R_ARM_PRIVATE_13);
  CASE(R_ARM_PRIVATE_14);
  CASE(R_ARM_PRIVATE_15);
  CASE(R_ARM_ME_TOO);
  CASE(R_ARM_THM_TLS_DESCSEQ16);
  CASE(R_ARM_THM_TLS_DESCSEQ32);
  CASE(R_ARM_THM_BF16);
  CASE(R_ARM_THM_BF12);
  CASE(R_ARM_THM_BF18);
  CASE(R_ARM_IRELATIVE);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<RV64LE>(u32 r_type) {
  switch (r_type) {
  CASE(R_RISCV_NONE);
  CASE(R_RISCV_32);
  CASE(R_RISCV_64);
  CASE(R_RISCV_RELATIVE);
  CASE(R_RISCV_COPY);
  CASE(R_RISCV_JUMP_SLOT);
  CASE(R_RISCV_TLS_DTPMOD32);
  CASE(R_RISCV_TLS_DTPMOD64);
  CASE(R_RISCV_TLS_DTPREL32);
  CASE(R_RISCV_TLS_DTPREL64);
  CASE(R_RISCV_TLS_TPREL32);
  CASE(R_RISCV_TLS_TPREL64);
  CASE(R_RISCV_BRANCH);
  CASE(R_RISCV_JAL);
  CASE(R_RISCV_CALL);
  CASE(R_RISCV_CALL_PLT);
  CASE(R_RISCV_GOT_HI20);
  CASE(R_RISCV_TLS_GOT_HI20);
  CASE(R_RISCV_TLS_GD_HI20);
  CASE(R_RISCV_PCREL_HI20);
  CASE(R_RISCV_PCREL_LO12_I);
  CASE(R_RISCV_PCREL_LO12_S);
  CASE(R_RISCV_HI20);
  CASE(R_RISCV_LO12_I);
  CASE(R_RISCV_LO12_S);
  CASE(R_RISCV_TPREL_HI20);
  CASE(R_RISCV_TPREL_LO12_I);
  CASE(R_RISCV_TPREL_LO12_S);
  CASE(R_RISCV_TPREL_ADD);
  CASE(R_RISCV_ADD8);
  CASE(R_RISCV_ADD16);
  CASE(R_RISCV_ADD32);
  CASE(R_RISCV_ADD64);
  CASE(R_RISCV_SUB8);
  CASE(R_RISCV_SUB16);
  CASE(R_RISCV_SUB32);
  CASE(R_RISCV_SUB64);
  CASE(R_RISCV_ALIGN);
  CASE(R_RISCV_RVC_BRANCH);
  CASE(R_RISCV_RVC_JUMP);
  CASE(R_RISCV_RVC_LUI);
  CASE(R_RISCV_RELAX);
  CASE(R_RISCV_SUB6);
  CASE(R_RISCV_SET6);
  CASE(R_RISCV_SET8);
  CASE(R_RISCV_SET16);
  CASE(R_RISCV_SET32);
  CASE(R_RISCV_32_PCREL);
  CASE(R_RISCV_IRELATIVE);
  CASE(R_RISCV_PLT32);
  CASE(R_RISCV_SET_ULEB128);
  CASE(R_RISCV_SUB_ULEB128);
  CASE(R_RISCV_TLSDESC_HI20);
  CASE(R_RISCV_TLSDESC_LOAD_LO12);
  CASE(R_RISCV_TLSDESC_ADD_LO12);
  CASE(R_RISCV_TLSDESC_CALL);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<RV64BE>(u32 r_type) {
  return rel_to_string<RV64LE>(r_type);
}

template <>
std::string rel_to_string<RV32LE>(u32 r_type) {
  return rel_to_string<RV64LE>(r_type);
}

template <>
std::string rel_to_string<RV32BE>(u32 r_type) {
  return rel_to_string<RV64LE>(r_type);
}

template <>
std::string rel_to_string<PPC32>(u32 r_type) {
  switch (r_type) {
  CASE(R_PPC_NONE);
  CASE(R_PPC_ADDR32);
  CASE(R_PPC_ADDR24);
  CASE(R_PPC_ADDR16);
  CASE(R_PPC_ADDR16_LO);
  CASE(R_PPC_ADDR16_HI);
  CASE(R_PPC_ADDR16_HA);
  CASE(R_PPC_ADDR14);
  CASE(R_PPC_ADDR14_BRTAKEN);
  CASE(R_PPC_ADDR14_BRNTAKEN);
  CASE(R_PPC_REL24);
  CASE(R_PPC_REL14);
  CASE(R_PPC_REL14_BRTAKEN);
  CASE(R_PPC_REL14_BRNTAKEN);
  CASE(R_PPC_GOT16);
  CASE(R_PPC_GOT16_LO);
  CASE(R_PPC_GOT16_HI);
  CASE(R_PPC_GOT16_HA);
  CASE(R_PPC_PLTREL24);
  CASE(R_PPC_COPY);
  CASE(R_PPC_GLOB_DAT);
  CASE(R_PPC_JMP_SLOT);
  CASE(R_PPC_RELATIVE);
  CASE(R_PPC_LOCAL24PC);
  CASE(R_PPC_UADDR32);
  CASE(R_PPC_UADDR16);
  CASE(R_PPC_REL32);
  CASE(R_PPC_PLT32);
  CASE(R_PPC_PLTREL32);
  CASE(R_PPC_PLT16_LO);
  CASE(R_PPC_PLT16_HI);
  CASE(R_PPC_PLT16_HA);
  CASE(R_PPC_SDAREL16);
  CASE(R_PPC_SECTOFF);
  CASE(R_PPC_SECTOFF_LO);
  CASE(R_PPC_SECTOFF_HI);
  CASE(R_PPC_SECTOFF_HA);
  CASE(R_PPC_ADDR30);
  CASE(R_PPC_TLS);
  CASE(R_PPC_DTPMOD32);
  CASE(R_PPC_TPREL16);
  CASE(R_PPC_TPREL16_LO);
  CASE(R_PPC_TPREL16_HI);
  CASE(R_PPC_TPREL16_HA);
  CASE(R_PPC_TPREL32);
  CASE(R_PPC_DTPREL16);
  CASE(R_PPC_DTPREL16_LO);
  CASE(R_PPC_DTPREL16_HI);
  CASE(R_PPC_DTPREL16_HA);
  CASE(R_PPC_DTPREL32);
  CASE(R_PPC_GOT_TLSGD16);
  CASE(R_PPC_GOT_TLSGD16_LO);
  CASE(R_PPC_GOT_TLSGD16_HI);
  CASE(R_PPC_GOT_TLSGD16_HA);
  CASE(R_PPC_GOT_TLSLD16);
  CASE(R_PPC_GOT_TLSLD16_LO);
  CASE(R_PPC_GOT_TLSLD16_HI);
  CASE(R_PPC_GOT_TLSLD16_HA);
  CASE(R_PPC_GOT_TPREL16);
  CASE(R_PPC_GOT_TPREL16_LO);
  CASE(R_PPC_GOT_TPREL16_HI);
  CASE(R_PPC_GOT_TPREL16_HA);
  CASE(R_PPC_GOT_DTPREL16);
  CASE(R_PPC_GOT_DTPREL16_LO);
  CASE(R_PPC_GOT_DTPREL16_HI);
  CASE(R_PPC_GOT_DTPREL16_HA);
  CASE(R_PPC_TLSGD);
  CASE(R_PPC_TLSLD);
  CASE(R_PPC_PLTSEQ);
  CASE(R_PPC_PLTCALL);
  CASE(R_PPC_IRELATIVE);
  CASE(R_PPC_REL16);
  CASE(R_PPC_REL16_LO);
  CASE(R_PPC_REL16_HI);
  CASE(R_PPC_REL16_HA);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<PPC64V1>(u32 r_type) {
  switch (r_type) {
  CASE(R_PPC64_NONE);
  CASE(R_PPC64_ADDR32);
  CASE(R_PPC64_ADDR24);
  CASE(R_PPC64_ADDR16);
  CASE(R_PPC64_ADDR16_LO);
  CASE(R_PPC64_ADDR16_HI);
  CASE(R_PPC64_ADDR16_HA);
  CASE(R_PPC64_ADDR14);
  CASE(R_PPC64_ADDR14_BRTAKEN);
  CASE(R_PPC64_ADDR14_BRNTAKEN);
  CASE(R_PPC64_REL24);
  CASE(R_PPC64_REL14);
  CASE(R_PPC64_REL14_BRTAKEN);
  CASE(R_PPC64_REL14_BRNTAKEN);
  CASE(R_PPC64_GOT16);
  CASE(R_PPC64_GOT16_LO);
  CASE(R_PPC64_GOT16_HI);
  CASE(R_PPC64_GOT16_HA);
  CASE(R_PPC64_COPY);
  CASE(R_PPC64_GLOB_DAT);
  CASE(R_PPC64_JMP_SLOT);
  CASE(R_PPC64_RELATIVE);
  CASE(R_PPC64_REL32);
  CASE(R_PPC64_PLT16_LO);
  CASE(R_PPC64_PLT16_HI);
  CASE(R_PPC64_PLT16_HA);
  CASE(R_PPC64_ADDR64);
  CASE(R_PPC64_ADDR16_HIGHER);
  CASE(R_PPC64_ADDR16_HIGHERA);
  CASE(R_PPC64_ADDR16_HIGHEST);
  CASE(R_PPC64_ADDR16_HIGHESTA);
  CASE(R_PPC64_REL64);
  CASE(R_PPC64_TOC16);
  CASE(R_PPC64_TOC16_LO);
  CASE(R_PPC64_TOC16_HI);
  CASE(R_PPC64_TOC16_HA);
  CASE(R_PPC64_TOC);
  CASE(R_PPC64_ADDR16_DS);
  CASE(R_PPC64_ADDR16_LO_DS);
  CASE(R_PPC64_GOT16_DS);
  CASE(R_PPC64_GOT16_LO_DS);
  CASE(R_PPC64_PLT16_LO_DS);
  CASE(R_PPC64_TOC16_DS);
  CASE(R_PPC64_TOC16_LO_DS);
  CASE(R_PPC64_TLS);
  CASE(R_PPC64_DTPMOD64);
  CASE(R_PPC64_TPREL16);
  CASE(R_PPC64_TPREL16_LO);
  CASE(R_PPC64_TPREL16_HI);
  CASE(R_PPC64_TPREL16_HA);
  CASE(R_PPC64_TPREL64);
  CASE(R_PPC64_DTPREL16);
  CASE(R_PPC64_DTPREL16_LO);
  CASE(R_PPC64_DTPREL16_HI);
  CASE(R_PPC64_DTPREL16_HA);
  CASE(R_PPC64_DTPREL64);
  CASE(R_PPC64_GOT_TLSGD16);
  CASE(R_PPC64_GOT_TLSGD16_LO);
  CASE(R_PPC64_GOT_TLSGD16_HI);
  CASE(R_PPC64_GOT_TLSGD16_HA);
  CASE(R_PPC64_GOT_TLSLD16);
  CASE(R_PPC64_GOT_TLSLD16_LO);
  CASE(R_PPC64_GOT_TLSLD16_HI);
  CASE(R_PPC64_GOT_TLSLD16_HA);
  CASE(R_PPC64_GOT_TPREL16_DS);
  CASE(R_PPC64_GOT_TPREL16_LO_DS);
  CASE(R_PPC64_GOT_TPREL16_HI);
  CASE(R_PPC64_GOT_TPREL16_HA);
  CASE(R_PPC64_GOT_DTPREL16_DS);
  CASE(R_PPC64_GOT_DTPREL16_LO_DS);
  CASE(R_PPC64_GOT_DTPREL16_HI);
  CASE(R_PPC64_GOT_DTPREL16_HA);
  CASE(R_PPC64_TPREL16_DS);
  CASE(R_PPC64_TPREL16_LO_DS);
  CASE(R_PPC64_TPREL16_HIGHER);
  CASE(R_PPC64_TPREL16_HIGHERA);
  CASE(R_PPC64_TPREL16_HIGHEST);
  CASE(R_PPC64_TPREL16_HIGHESTA);
  CASE(R_PPC64_DTPREL16_DS);
  CASE(R_PPC64_DTPREL16_LO_DS);
  CASE(R_PPC64_DTPREL16_HIGHER);
  CASE(R_PPC64_DTPREL16_HIGHERA);
  CASE(R_PPC64_DTPREL16_HIGHEST);
  CASE(R_PPC64_DTPREL16_HIGHESTA);
  CASE(R_PPC64_TLSGD);
  CASE(R_PPC64_TLSLD);
  CASE(R_PPC64_ADDR16_HIGH);
  CASE(R_PPC64_ADDR16_HIGHA);
  CASE(R_PPC64_TPREL16_HIGH);
  CASE(R_PPC64_TPREL16_HIGHA);
  CASE(R_PPC64_DTPREL16_HIGH);
  CASE(R_PPC64_DTPREL16_HIGHA);
  CASE(R_PPC64_REL24_NOTOC);
  CASE(R_PPC64_PLTSEQ);
  CASE(R_PPC64_PLTCALL);
  CASE(R_PPC64_PLTSEQ_NOTOC);
  CASE(R_PPC64_PLTCALL_NOTOC);
  CASE(R_PPC64_PCREL_OPT);
  CASE(R_PPC64_PCREL34);
  CASE(R_PPC64_GOT_PCREL34);
  CASE(R_PPC64_PLT_PCREL34);
  CASE(R_PPC64_PLT_PCREL34_NOTOC);
  CASE(R_PPC64_TPREL34);
  CASE(R_PPC64_DTPREL34);
  CASE(R_PPC64_GOT_TLSGD_PCREL34);
  CASE(R_PPC64_GOT_TLSLD_PCREL34);
  CASE(R_PPC64_GOT_TPREL_PCREL34);
  CASE(R_PPC64_IRELATIVE);
  CASE(R_PPC64_REL16);
  CASE(R_PPC64_REL16_LO);
  CASE(R_PPC64_REL16_HI);
  CASE(R_PPC64_REL16_HA);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<PPC64V2>(u32 r_type) {
  return rel_to_string<PPC64V1>(r_type);
}

template <>
std::string rel_to_string<SPARC64>(u32 r_type) {
  switch (r_type) {
  CASE(R_SPARC_NONE);
  CASE(R_SPARC_8);
  CASE(R_SPARC_16);
  CASE(R_SPARC_32);
  CASE(R_SPARC_DISP8);
  CASE(R_SPARC_DISP16);
  CASE(R_SPARC_DISP32);
  CASE(R_SPARC_WDISP30);
  CASE(R_SPARC_WDISP22);
  CASE(R_SPARC_HI22);
  CASE(R_SPARC_22);
  CASE(R_SPARC_13);
  CASE(R_SPARC_LO10);
  CASE(R_SPARC_GOT10);
  CASE(R_SPARC_GOT13);
  CASE(R_SPARC_GOT22);
  CASE(R_SPARC_PC10);
  CASE(R_SPARC_PC22);
  CASE(R_SPARC_WPLT30);
  CASE(R_SPARC_COPY);
  CASE(R_SPARC_GLOB_DAT);
  CASE(R_SPARC_JMP_SLOT);
  CASE(R_SPARC_RELATIVE);
  CASE(R_SPARC_UA32);
  CASE(R_SPARC_PLT32);
  CASE(R_SPARC_HIPLT22);
  CASE(R_SPARC_LOPLT10);
  CASE(R_SPARC_PCPLT32);
  CASE(R_SPARC_PCPLT22);
  CASE(R_SPARC_PCPLT10);
  CASE(R_SPARC_10);
  CASE(R_SPARC_11);
  CASE(R_SPARC_64);
  CASE(R_SPARC_OLO10);
  CASE(R_SPARC_HH22);
  CASE(R_SPARC_HM10);
  CASE(R_SPARC_LM22);
  CASE(R_SPARC_PC_HH22);
  CASE(R_SPARC_PC_HM10);
  CASE(R_SPARC_PC_LM22);
  CASE(R_SPARC_WDISP16);
  CASE(R_SPARC_WDISP19);
  CASE(R_SPARC_7);
  CASE(R_SPARC_5);
  CASE(R_SPARC_6);
  CASE(R_SPARC_DISP64);
  CASE(R_SPARC_PLT64);
  CASE(R_SPARC_HIX22);
  CASE(R_SPARC_LOX10);
  CASE(R_SPARC_H44);
  CASE(R_SPARC_M44);
  CASE(R_SPARC_L44);
  CASE(R_SPARC_REGISTER);
  CASE(R_SPARC_UA64);
  CASE(R_SPARC_UA16);
  CASE(R_SPARC_TLS_GD_HI22);
  CASE(R_SPARC_TLS_GD_LO10);
  CASE(R_SPARC_TLS_GD_ADD);
  CASE(R_SPARC_TLS_GD_CALL);
  CASE(R_SPARC_TLS_LDM_HI22);
  CASE(R_SPARC_TLS_LDM_LO10);
  CASE(R_SPARC_TLS_LDM_ADD);
  CASE(R_SPARC_TLS_LDM_CALL);
  CASE(R_SPARC_TLS_LDO_HIX22);
  CASE(R_SPARC_TLS_LDO_LOX10);
  CASE(R_SPARC_TLS_LDO_ADD);
  CASE(R_SPARC_TLS_IE_HI22);
  CASE(R_SPARC_TLS_IE_LO10);
  CASE(R_SPARC_TLS_IE_LD);
  CASE(R_SPARC_TLS_IE_LDX);
  CASE(R_SPARC_TLS_IE_ADD);
  CASE(R_SPARC_TLS_LE_HIX22);
  CASE(R_SPARC_TLS_LE_LOX10);
  CASE(R_SPARC_TLS_DTPMOD32);
  CASE(R_SPARC_TLS_DTPMOD64);
  CASE(R_SPARC_TLS_DTPOFF32);
  CASE(R_SPARC_TLS_DTPOFF64);
  CASE(R_SPARC_TLS_TPOFF32);
  CASE(R_SPARC_TLS_TPOFF64);
  CASE(R_SPARC_GOTDATA_HIX22);
  CASE(R_SPARC_GOTDATA_LOX10);
  CASE(R_SPARC_GOTDATA_OP_HIX22);
  CASE(R_SPARC_GOTDATA_OP_LOX10);
  CASE(R_SPARC_GOTDATA_OP);
  CASE(R_SPARC_IRELATIVE);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<S390X>(u32 r_type) {
  switch (r_type) {
  CASE(R_390_NONE);
  CASE(R_390_8);
  CASE(R_390_12);
  CASE(R_390_16);
  CASE(R_390_32);
  CASE(R_390_PC32);
  CASE(R_390_GOT12);
  CASE(R_390_GOT32);
  CASE(R_390_PLT32);
  CASE(R_390_COPY);
  CASE(R_390_GLOB_DAT);
  CASE(R_390_JMP_SLOT);
  CASE(R_390_RELATIVE);
  CASE(R_390_GOTOFF32);
  CASE(R_390_GOTPC);
  CASE(R_390_GOT16);
  CASE(R_390_PC16);
  CASE(R_390_PC16DBL);
  CASE(R_390_PLT16DBL);
  CASE(R_390_PC32DBL);
  CASE(R_390_PLT32DBL);
  CASE(R_390_GOTPCDBL);
  CASE(R_390_64);
  CASE(R_390_PC64);
  CASE(R_390_GOT64);
  CASE(R_390_PLT64);
  CASE(R_390_GOTENT);
  CASE(R_390_GOTOFF16);
  CASE(R_390_GOTOFF64);
  CASE(R_390_GOTPLT12);
  CASE(R_390_GOTPLT16);
  CASE(R_390_GOTPLT32);
  CASE(R_390_GOTPLT64);
  CASE(R_390_GOTPLTENT);
  CASE(R_390_PLTOFF16);
  CASE(R_390_PLTOFF32);
  CASE(R_390_PLTOFF64);
  CASE(R_390_TLS_LOAD);
  CASE(R_390_TLS_GDCALL);
  CASE(R_390_TLS_LDCALL);
  CASE(R_390_TLS_GD32);
  CASE(R_390_TLS_GD64);
  CASE(R_390_TLS_GOTIE12);
  CASE(R_390_TLS_GOTIE32);
  CASE(R_390_TLS_GOTIE64);
  CASE(R_390_TLS_LDM32);
  CASE(R_390_TLS_LDM64);
  CASE(R_390_TLS_IE32);
  CASE(R_390_TLS_IE64);
  CASE(R_390_TLS_IEENT);
  CASE(R_390_TLS_LE32);
  CASE(R_390_TLS_LE64);
  CASE(R_390_TLS_LDO32);
  CASE(R_390_TLS_LDO64);
  CASE(R_390_TLS_DTPMOD);
  CASE(R_390_TLS_DTPOFF);
  CASE(R_390_TLS_TPOFF);
  CASE(R_390_20);
  CASE(R_390_GOT20);
  CASE(R_390_GOTPLT20);
  CASE(R_390_TLS_GOTIE20);
  CASE(R_390_IRELATIVE);
  CASE(R_390_PC12DBL);
  CASE(R_390_PLT12DBL);
  CASE(R_390_PC24DBL);
  CASE(R_390_PLT24DBL);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<M68K>(u32 r_type) {
  switch (r_type) {
  CASE(R_68K_NONE);
  CASE(R_68K_32);
  CASE(R_68K_16);
  CASE(R_68K_8);
  CASE(R_68K_PC32);
  CASE(R_68K_PC16);
  CASE(R_68K_PC8);
  CASE(R_68K_GOTPCREL32);
  CASE(R_68K_GOTPCREL16);
  CASE(R_68K_GOTPCREL8);
  CASE(R_68K_GOTOFF32);
  CASE(R_68K_GOTOFF16);
  CASE(R_68K_GOTOFF8);
  CASE(R_68K_PLT32);
  CASE(R_68K_PLT16);
  CASE(R_68K_PLT8);
  CASE(R_68K_PLTOFF32);
  CASE(R_68K_PLTOFF16);
  CASE(R_68K_PLTOFF8);
  CASE(R_68K_COPY);
  CASE(R_68K_GLOB_DAT);
  CASE(R_68K_JMP_SLOT);
  CASE(R_68K_RELATIVE);
  CASE(R_68K_TLS_GD32);
  CASE(R_68K_TLS_GD16);
  CASE(R_68K_TLS_GD8);
  CASE(R_68K_TLS_LDM32);
  CASE(R_68K_TLS_LDM16);
  CASE(R_68K_TLS_LDM8);
  CASE(R_68K_TLS_LDO32);
  CASE(R_68K_TLS_LDO16);
  CASE(R_68K_TLS_LDO8);
  CASE(R_68K_TLS_IE32);
  CASE(R_68K_TLS_IE16);
  CASE(R_68K_TLS_IE8);
  CASE(R_68K_TLS_LE32);
  CASE(R_68K_TLS_LE16);
  CASE(R_68K_TLS_LE8);
  CASE(R_68K_TLS_DTPMOD32);
  CASE(R_68K_TLS_DTPREL32);
  CASE(R_68K_TLS_TPREL32);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<SH4>(u32 r_type) {
  switch (r_type) {
  CASE(R_SH_NONE);
  CASE(R_SH_DIR32);
  CASE(R_SH_REL32);
  CASE(R_SH_DIR8WPN);
  CASE(R_SH_IND12W);
  CASE(R_SH_DIR8WPL);
  CASE(R_SH_DIR8WPZ);
  CASE(R_SH_DIR8BP);
  CASE(R_SH_DIR8W);
  CASE(R_SH_DIR8L);
  CASE(R_SH_TLS_GD_32);
  CASE(R_SH_TLS_LD_32);
  CASE(R_SH_TLS_LDO_32);
  CASE(R_SH_TLS_IE_32);
  CASE(R_SH_TLS_LE_32);
  CASE(R_SH_TLS_DTPMOD32);
  CASE(R_SH_TLS_DTPOFF32);
  CASE(R_SH_TLS_TPOFF32);
  CASE(R_SH_GOT32);
  CASE(R_SH_PLT32);
  CASE(R_SH_COPY);
  CASE(R_SH_GLOB_DAT);
  CASE(R_SH_JMP_SLOT);
  CASE(R_SH_RELATIVE);
  CASE(R_SH_GOTOFF);
  CASE(R_SH_GOTPC);
  CASE(R_SH_GOTPLT32);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<ALPHA>(u32 r_type) {
  switch (r_type) {
  CASE(R_ALPHA_NONE);
  CASE(R_ALPHA_REFLONG);
  CASE(R_ALPHA_REFQUAD);
  CASE(R_ALPHA_GPREL32);
  CASE(R_ALPHA_LITERAL);
  CASE(R_ALPHA_LITUSE);
  CASE(R_ALPHA_GPDISP);
  CASE(R_ALPHA_BRADDR);
  CASE(R_ALPHA_HINT);
  CASE(R_ALPHA_SREL16);
  CASE(R_ALPHA_SREL32);
  CASE(R_ALPHA_SREL64);
  CASE(R_ALPHA_GPRELHIGH);
  CASE(R_ALPHA_GPRELLOW);
  CASE(R_ALPHA_GPREL16);
  CASE(R_ALPHA_COPY);
  CASE(R_ALPHA_GLOB_DAT);
  CASE(R_ALPHA_JMP_SLOT);
  CASE(R_ALPHA_RELATIVE);
  CASE(R_ALPHA_BRSGP);
  CASE(R_ALPHA_TLSGD);
  CASE(R_ALPHA_TLSLDM);
  CASE(R_ALPHA_DTPMOD64);
  CASE(R_ALPHA_GOTDTPREL);
  CASE(R_ALPHA_DTPREL64);
  CASE(R_ALPHA_DTPRELHI);
  CASE(R_ALPHA_DTPRELLO);
  CASE(R_ALPHA_DTPREL16);
  CASE(R_ALPHA_GOTTPREL);
  CASE(R_ALPHA_TPREL64);
  CASE(R_ALPHA_TPRELHI);
  CASE(R_ALPHA_TPRELLO);
  CASE(R_ALPHA_TPREL16);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<LOONGARCH64>(u32 r_type) {
  switch (r_type) {
  CASE(R_LARCH_NONE);
  CASE(R_LARCH_32);
  CASE(R_LARCH_64);
  CASE(R_LARCH_RELATIVE);
  CASE(R_LARCH_COPY);
  CASE(R_LARCH_JUMP_SLOT);
  CASE(R_LARCH_TLS_DTPMOD32);
  CASE(R_LARCH_TLS_DTPMOD64);
  CASE(R_LARCH_TLS_DTPREL32);
  CASE(R_LARCH_TLS_DTPREL64);
  CASE(R_LARCH_TLS_TPREL32);
  CASE(R_LARCH_TLS_TPREL64);
  CASE(R_LARCH_IRELATIVE);
  CASE(R_LARCH_MARK_LA);
  CASE(R_LARCH_MARK_PCREL);
  CASE(R_LARCH_SOP_PUSH_PCREL);
  CASE(R_LARCH_SOP_PUSH_ABSOLUTE);
  CASE(R_LARCH_SOP_PUSH_DUP);
  CASE(R_LARCH_SOP_PUSH_GPREL);
  CASE(R_LARCH_SOP_PUSH_TLS_TPREL);
  CASE(R_LARCH_SOP_PUSH_TLS_GOT);
  CASE(R_LARCH_SOP_PUSH_TLS_GD);
  CASE(R_LARCH_SOP_PUSH_PLT_PCREL);
  CASE(R_LARCH_SOP_ASSERT);
  CASE(R_LARCH_SOP_NOT);
  CASE(R_LARCH_SOP_SUB);
  CASE(R_LARCH_SOP_SL);
  CASE(R_LARCH_SOP_SR);
  CASE(R_LARCH_SOP_ADD);
  CASE(R_LARCH_SOP_AND);
  CASE(R_LARCH_SOP_IF_ELSE);
  CASE(R_LARCH_SOP_POP_32_S_10_5);
  CASE(R_LARCH_SOP_POP_32_U_10_12);
  CASE(R_LARCH_SOP_POP_32_S_10_12);
  CASE(R_LARCH_SOP_POP_32_S_10_16);
  CASE(R_LARCH_SOP_POP_32_S_10_16_S2);
  CASE(R_LARCH_SOP_POP_32_S_5_20);
  CASE(R_LARCH_SOP_POP_32_S_0_5_10_16_S2);
  CASE(R_LARCH_SOP_POP_32_S_0_10_10_16_S2);
  CASE(R_LARCH_SOP_POP_32_U);
  CASE(R_LARCH_ADD8);
  CASE(R_LARCH_ADD16);
  CASE(R_LARCH_ADD24);
  CASE(R_LARCH_ADD32);
  CASE(R_LARCH_ADD64);
  CASE(R_LARCH_SUB8);
  CASE(R_LARCH_SUB16);
  CASE(R_LARCH_SUB24);
  CASE(R_LARCH_SUB32);
  CASE(R_LARCH_SUB64);
  CASE(R_LARCH_GNU_VTINHERIT);
  CASE(R_LARCH_GNU_VTENTRY);
  CASE(R_LARCH_B16);
  CASE(R_LARCH_B21);
  CASE(R_LARCH_B26);
  CASE(R_LARCH_ABS_HI20);
  CASE(R_LARCH_ABS_LO12);
  CASE(R_LARCH_ABS64_LO20);
  CASE(R_LARCH_ABS64_HI12);
  CASE(R_LARCH_PCALA_HI20);
  CASE(R_LARCH_PCALA_LO12);
  CASE(R_LARCH_PCALA64_LO20);
  CASE(R_LARCH_PCALA64_HI12);
  CASE(R_LARCH_GOT_PC_HI20);
  CASE(R_LARCH_GOT_PC_LO12);
  CASE(R_LARCH_GOT64_PC_LO20);
  CASE(R_LARCH_GOT64_PC_HI12);
  CASE(R_LARCH_GOT_HI20);
  CASE(R_LARCH_GOT_LO12);
  CASE(R_LARCH_GOT64_LO20);
  CASE(R_LARCH_GOT64_HI12);
  CASE(R_LARCH_TLS_LE_HI20);
  CASE(R_LARCH_TLS_LE_LO12);
  CASE(R_LARCH_TLS_LE64_LO20);
  CASE(R_LARCH_TLS_LE64_HI12);
  CASE(R_LARCH_TLS_IE_PC_HI20);
  CASE(R_LARCH_TLS_IE_PC_LO12);
  CASE(R_LARCH_TLS_IE64_PC_LO20);
  CASE(R_LARCH_TLS_IE64_PC_HI12);
  CASE(R_LARCH_TLS_IE_HI20);
  CASE(R_LARCH_TLS_IE_LO12);
  CASE(R_LARCH_TLS_IE64_LO20);
  CASE(R_LARCH_TLS_IE64_HI12);
  CASE(R_LARCH_TLS_LD_PC_HI20);
  CASE(R_LARCH_TLS_LD_HI20);
  CASE(R_LARCH_TLS_GD_PC_HI20);
  CASE(R_LARCH_TLS_GD_HI20);
  CASE(R_LARCH_32_PCREL);
  CASE(R_LARCH_RELAX);
  CASE(R_LARCH_DELETE);
  CASE(R_LARCH_ALIGN);
  CASE(R_LARCH_PCREL20_S2);
  CASE(R_LARCH_CFA);
  CASE(R_LARCH_ADD6);
  CASE(R_LARCH_SUB6);
  CASE(R_LARCH_ADD_ULEB128);
  CASE(R_LARCH_SUB_ULEB128);
  CASE(R_LARCH_64_PCREL);
  }
  return unknown_type(r_type);
}

template <>
std::string rel_to_string<LOONGARCH32>(u32 r_type) {
  return rel_to_string<LOONGARCH64>(r_type);
}

} // namespace mold::elf
