/*
 * Copyright 2011-2012, 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 ELF_OBJECT_HXX
#define ELF_OBJECT_HXX

#include "ELFHeader.h"
#include "ELFReloc.h"
#include "ELFSection.h"
#include "ELFSectionHeaderTable.h"
#include "StubLayout.h"
#include "GOT.h"
#include "ELF.h"

#include <llvm/ADT/SmallVector.h>

#include "utils/rsl_assert.h"

template <unsigned Bitwidth>
template <typename Archiver>
inline ELFObject<Bitwidth> *
ELFObject<Bitwidth>::read(Archiver &AR) {
  llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy());

  // Read header
  object->header.reset(ELFHeaderTy::read(AR));
  if (!object->header) {
    return 0;
  }

  // Read section table
  object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get()));
  if (!object->shtab) {
    return 0;
  }

  // Read each section
  llvm::SmallVector<size_t, 4> progbits_ndx;
  for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) {
    if ((*object->shtab)[i]->getType() == SHT_PROGBITS) {
      object->stab.push_back(NULL);
      progbits_ndx.push_back(i);
    } else {
      llvm::OwningPtr<ELFSectionTy> sec(
        ELFSectionTy::read(AR, object.get(), (*object->shtab)[i]));
      object->stab.push_back(sec.take());
    }
  }

  object->shtab->buildNameMap();
  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");
  symtab->buildNameMap();

  for (size_t i = 0; i < progbits_ndx.size(); ++i) {
    size_t index = progbits_ndx[i];

    llvm::OwningPtr<ELFSectionTy> sec(
      ELFSectionTy::read(AR, object.get(), (*object->shtab)[index]));
    object->stab[index] = sec.take();
  }

  return object.take();
}

template <unsigned Bitwidth>
inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const {
  ELFSectionTy const *sec = stab[header->getStringSectionIndex()];

  if (sec) {
    ELFSectionStrTabTy const &st =
      static_cast<ELFSectionStrTabTy const &>(*sec);
    return st[i];
  }

  return NULL;
}

template <unsigned Bitwidth>
inline ELFSection<Bitwidth> const *
ELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
  return stab[i];
}

template <unsigned Bitwidth>
inline ELFSection<Bitwidth> *
ELFObject<Bitwidth>::getSectionByIndex(size_t i) {
  return stab[i];
}

template <unsigned Bitwidth>
inline ELFSection<Bitwidth> const *
ELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
  size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
  return stab[idx];
}

template <unsigned Bitwidth>
inline ELFSection<Bitwidth> *
ELFObject<Bitwidth>::getSectionByName(std::string const &str) {
  ELFObjectTy const *const_this = this;
  ELFSectionTy const *sptr = const_this->getSectionByName(str);
  // Const cast for the same API's const and non-const versions.
  return const_cast<ELFSectionTy *>(sptr);
}


template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocateARM(void *(*find_sym)(void *context, char const *name),
            void *context,
            ELFSectionRelTableTy *reltab,
            ELFSectionProgBitsTy *text) {
  // FIXME: Should be implement in independent files.
  rsl_assert(Bitwidth == 32 && "ARM only have 32 bits.");

  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");

  for (size_t i = 0; i < reltab->size(); ++i) {
    // FIXME: Can not implement here, use Fixup!
    ELFRelocTy *rel = (*reltab)[i];
    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];

    // FIXME: May be not uint32_t *.
    typedef int32_t Inst_t;
    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    Inst_t P = (Inst_t)(int64_t)inst;
    Inst_t A = 0;
    Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_ARM);
    Inst_t T = 0;

    if (sym->isConcreteFunc() && (sym->getValue() & 0x1)) {
      T = 1;
    }

    switch (rel->getType()) {
    default:
      rsl_assert(0 && "Not implemented relocation type.");
      break;

    case R_ARM_ABS32:
      {
        if (S == 0 && sym->getType() == STT_NOTYPE) {
          void *ext_sym = find_sym(context, sym->getName());
          if (!ext_sym) {
            missingSymbols = true;
          }
          S = (Inst_t)(uintptr_t)ext_sym;
          sym->setAddress(ext_sym);
        }
        A = *inst;
        *inst = (S + A) | T;
      }
      break;

      // FIXME: Predefine relocation codes.
    case R_ARM_CALL:
    case R_ARM_THM_CALL:
      {
#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
        if (rel->getType() == R_ARM_CALL) {
          A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
          A <<= 2;
        } else {
          // Hack for two 16bit.
          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
          Inst_t s  = (*inst >> 26) & 0x1u,    // 26
                 u  = (*inst >> 16) & 0x3FFu,  // 25-16
                 l  =  *inst        & 0x7FFu, // 10-0
                 j1 = (*inst >> 13) & 0x1u,    // 13
                 j2 = (*inst >> 11) & 0x1u;    // 11
          Inst_t i1 = (~(j1 ^ s)) & 0x1u,
                 i2 = (~(j2 ^ s)) & 0x1u;
          // [31-25][24][23][22][21-12][11-1][0]
          //      0   s  i1  i2      u     l  0
          A = SIGN_EXTEND((s << 23) | (i1 << 22) | (i2 << 21) | (u << 11) | l, 24);
          A <<= 1;
        }
#undef SIGN_EXTEND

        void *callee_addr = sym->getAddress(EM_ARM);

        switch (sym->getType()) {
        default:
          rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
          abort();
          break;

        case STT_FUNC:
          // NOTE: Callee function is in the object file, but it may be
          // in different PROGBITS section (which may be far call).

          if (callee_addr == 0) {
            rsl_assert(0 && "We should get function address at previous "
                   "sym->getAddress(EM_ARM) function call.");
            abort();
          }
          break;

        case STT_NOTYPE:
          // NOTE: Callee function is an external function.  Call find_sym
          // if it has not resolved yet.

          if (callee_addr == 0) {
            callee_addr = find_sym(context, sym->getName());
            if (!callee_addr) {
              missingSymbols = true;
            }
            sym->setAddress(callee_addr);
          }
          break;
        }

        // Get the stub for this function
        StubLayout *stub_layout = text->getStubLayout();

        if (!stub_layout) {
          llvm::errs() << "unable to get stub layout." << "\n";
          abort();
        }

        void *stub = stub_layout->allocateStub(callee_addr);

        if (!stub) {
          llvm::errs() << "unable to allocate stub." << "\n";
          abort();
        }

        //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
        S = (uint32_t)(uintptr_t)stub;

        if (rel->getType() == R_ARM_CALL) {
          // Relocate the R_ARM_CALL relocation type
          uint32_t result = (S + A - P) >> 2;

          if (result > 0x007FFFFF && result < 0xFF800000) {
            rsl_assert(0 && "Stub is still too far");
            abort();
          }

          *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
        } else {
          P &= ~0x3;  // Base address align to 4 bytes.  (For BLX.)

          // Relocate the R_ARM_THM_CALL relocation type
          uint32_t result = (S + A - P) >> 1;

          if (result > 0x007FFFFF && result < 0xFF800000) {
            rsl_assert(0 && "Stub is still too far");
            abort();
          }

          //*inst &= 0xF800D000u;
          // Rewrite instruction to BLX.  (Stub is always ARM.)
          *inst &= 0xF800C000u;
          // [31-25][24][23][22][21-12][11-1][0]
          //      0   s  i1  i2      u     l  0
          Inst_t s  = (result >> 23) & 0x1u,   // 26
                 u  = (result >> 11) & 0x3FFu, // 25-16
                 // For BLX, bit [0] is 0.
                 l  =  result        & 0x7FEu, // 10-0
                 i1 = (result >> 22) & 0x1u,
                 i2 = (result >> 21) & 0x1u;
          Inst_t j1 = ((~i1) ^ s) & 0x01u,       // 13
                 j2 = ((~i2) ^ s) & 0x01u;       // 11
          *inst |= s << 26;
          *inst |= u << 16;
          *inst |= l;
          *inst |= j1 << 13;
          *inst |= j2 << 11;
          // Hack for two 16bit.
          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
        }
      }
      break;
    case R_ARM_MOVT_ABS:
    case R_ARM_MOVW_ABS_NC:
    case R_ARM_THM_MOVW_ABS_NC:
    case R_ARM_THM_MOVT_ABS:
      {
        if (S == 0 && sym->getType() == STT_NOTYPE) {
          void *ext_sym = find_sym(context, sym->getName());
          if (!ext_sym) {
            missingSymbols = true;
          }
          S = (Inst_t)(uintptr_t)ext_sym;
          sym->setAddress(ext_sym);
        }
        if (rel->getType() == R_ARM_MOVT_ABS
            || rel->getType() == R_ARM_THM_MOVT_ABS) {
          S >>= 16;
        }

        if (rel->getType() == R_ARM_MOVT_ABS
            || rel->getType() == R_ARM_MOVW_ABS_NC) {
          // No need sign extend.
          A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
          uint32_t result = (S + A);
          *inst = (((result) & 0xF000) << 4) |
            ((result) & 0xFFF) |
            (*inst & 0xFFF0F000);
        } else {
          // Hack for two 16bit.
          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
          // imm16: [19-16][26][14-12][7-0]
          A = (((*inst >>  4) & 0xF000u) |
               ((*inst >> 15) & 0x0800u) |
               ((*inst >>  4) & 0x0700u) |
               ( *inst        & 0x00FFu));
          uint32_t result;
          if (rel->getType() == R_ARM_THM_MOVT_ABS) {
            result = (S + A);
          } else {
            result = (S + A) | T;
          }
          // imm16: [19-16][26][14-12][7-0]
          *inst &= 0xFBF08F00u;
          *inst |= (result & 0xF000u) << 4;
          *inst |= (result & 0x0800u) << 15;
          *inst |= (result & 0x0700u) << 4;
          *inst |= (result & 0x00FFu);
          // Hack for two 16bit.
          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
        }
      }
      break;
    }
    //llvm::errs() << "S:     " << (void *)S << '\n';
    //llvm::errs() << "A:     " << (void *)A << '\n';
    //llvm::errs() << "P:     " << (void *)P << '\n';
    //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
    //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
  }
}

template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocateX86_64(void *(*find_sym)(void *context, char const *name),
               void *context,
               ELFSectionRelTableTy *reltab,
               ELFSectionProgBitsTy *text) {
  rsl_assert(Bitwidth == 64 && "Only support X86_64.");

  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");

  for (size_t i = 0; i < reltab->size(); ++i) {
    // FIXME: Can not implement here, use Fixup!
    ELFRelocTy *rel = (*reltab)[i];
    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];

    //typedef uint64_t Inst_t;
    typedef int32_t Inst_t;
    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    Inst_t P = (Inst_t)(int64_t)inst;
    Inst_t A = (Inst_t)(int64_t)rel->getAddend();
    Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_X86_64);

    if (S == 0) {
      S = (Inst_t)(int64_t)find_sym(context, sym->getName());
      if (!S) {
        missingSymbols = true;
      }
      sym->setAddress((void *)S);
    }

    switch (rel->getType()) {
      default:
        rsl_assert(0 && "Not implemented relocation type.");
        break;

      // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here.
      case 1: // R_X86_64_64
        *inst = (S+A);
        break;

      case 2: // R_X86_64_PC32
        *inst = (S+A-P);
        break;

      case 10: // R_X86_64_32
      case 11: // R_X86_64_32S
        *inst = (S+A);
        break;
    }
  }
}

template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocateX86_32(void *(*find_sym)(void *context, char const *name),
               void *context,
               ELFSectionRelTableTy *reltab,
               ELFSectionProgBitsTy *text) {
  rsl_assert(Bitwidth == 32 && "Only support X86.");

  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");

  for (size_t i = 0; i < reltab->size(); ++i) {
    // FIXME: Can not implement here, use Fixup!
    ELFRelocTy *rel = (*reltab)[i];
    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];

    //typedef uint64_t Inst_t;
    typedef int32_t Inst_t;
    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    Inst_t P = (Inst_t)(uintptr_t)inst;
    Inst_t A = (Inst_t)(uintptr_t)*inst;
    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_386);

    if (S == 0) {
      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
      if (!S) {
        missingSymbols = true;
      }
      sym->setAddress((void *)S);
    }

    switch (rel->getType()) {
    default:
      rsl_assert(0 && "Not implemented relocation type.");
      break;

    case R_386_PC32:
      *inst = (S+A-P);
      break;

    case R_386_32:
      *inst = (S+A);
      break;
    }
  }
}

template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocateMIPS(void *(*find_sym)(void *context, char const *name),
             void *context,
             ELFSectionRelTableTy *reltab,
             ELFSectionProgBitsTy *text) {
  rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");

  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");

  for (size_t i = 0; i < reltab->size(); ++i) {
    // FIXME: Can not implement here, use Fixup!
    ELFRelocTy *rel = (*reltab)[i];
    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];

    typedef int32_t Inst_t;
    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    Inst_t P = (Inst_t)(uintptr_t)inst;
    Inst_t A = (Inst_t)(uintptr_t)*inst;
    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS);

    bool need_stub = false;

    if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) {
      need_stub = true;
      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
      if (!S) {
        missingSymbols = true;
      }
      sym->setAddress((void *)S);
    }

    switch (rel->getType()) {
    default:
      rsl_assert(0 && "Not implemented relocation type.");
      break;

    case R_MIPS_NONE:
    case R_MIPS_JALR: // ignore this
      break;

    case R_MIPS_16:
      *inst &= 0xFFFF0000;
      A = A & 0xFFFF;
      A = S + (short)A;
      rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow.");
      *inst |= (A & 0xFFFF);
      break;

    case R_MIPS_32:
      *inst = S + A;
      break;

    case R_MIPS_26:
      *inst &= 0xFC000000;
      if (need_stub == false) {
        A = (A & 0x3FFFFFF) << 2;
        if (sym->getBindingAttribute() == STB_LOCAL) { // local binding
          A |= ((P + 4) & 0xF0000000);
          A += S;
          *inst |= ((A >> 2) & 0x3FFFFFF);
        } else { // external binding
          if (A & 0x08000000) // Sign extend from bit 27
            A |= 0xF0000000;
          A += S;
          *inst |= ((A >> 2) & 0x3FFFFFF);
          if (((P + 4) >> 28) != (A >> 28)) { // far local call
            void *stub = text->getStubLayout()->allocateStub((void *)A);
            rsl_assert(stub && "cannot allocate stub.");
            sym->setAddress(stub);
            S = (int32_t)(intptr_t)stub;
            *inst |= ((S >> 2) & 0x3FFFFFF);
            rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
          }
        }
      } else { // shared-library call
        A = (A & 0x3FFFFFF) << 2;
        rsl_assert(A == 0 && "R_MIPS_26 addend is not zero.");
        void *stub = text->getStubLayout()->allocateStub((void *)S);
        rsl_assert(stub && "cannot allocate stub.");
        sym->setAddress(stub);
        S = (int32_t)(intptr_t)stub;
        *inst |= ((S >> 2) & 0x3FFFFFF);
        rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
      }
      break;

    case R_MIPS_HI16:
      *inst &= 0xFFFF0000;
      A = (A & 0xFFFF) << 16;
      // Find the nearest LO16 relocation type after this entry
      for (size_t j = i + 1; j < reltab->size(); j++) {
        ELFRelocTy *this_rel = (*reltab)[j];
        ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
        if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
          Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
          Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
          this_A = this_A & 0xFFFF;
          A += (short)this_A;
          break;
        }
      }
      if (strcmp (sym->getName(), "_gp_disp") == 0) {
          S = (int)(intptr_t)got_address() + GP_OFFSET - (int)P;
          sym->setAddress((void *)S);
      }
      *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF);
      break;

    case R_MIPS_LO16:
      *inst &= 0xFFFF0000;
      A = A & 0xFFFF;
      if (strcmp (sym->getName(), "_gp_disp") == 0) {
          S = (Inst_t)(intptr_t)sym->getAddress(EM_MIPS);
      }
      *inst |= ((S + A) & 0xFFFF);
      break;

    case R_MIPS_GOT16:
    case R_MIPS_CALL16:
      {
        *inst &= 0xFFFF0000;
        A = A & 0xFFFF;
        if (rel->getType() == R_MIPS_GOT16) {
          if (sym->getBindingAttribute() == STB_LOCAL) {
            A <<= 16;

            // Find the nearest LO16 relocation type after this entry
            for (size_t j = i + 1; j < reltab->size(); j++) {
              ELFRelocTy *this_rel = (*reltab)[j];
              ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
              if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
                Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
                Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
                this_A = this_A & 0xFFFF;
                A += (short)this_A;
                break;
              }
            }
          } else {
            rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0.");
          }
        } else { // R_MIPS_CALL16
          rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0.");
        }
        int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A),
                                   sym->getBindingAttribute());
        int got_offset = (got_index << 2) - GP_OFFSET;
        *inst |= (got_offset & 0xFFFF);
      }
      break;

    case R_MIPS_GPREL32:
      *inst = A + S - ((int)(intptr_t)got_address() + GP_OFFSET);
      break;
    }
  }
}


// TODO: Refactor all relocations.
template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocate(void *(*find_sym)(void *context, char const *name), void *context) {
  // Init SHNCommonDataSize.
  // Need refactoring
  size_t SHNCommonDataSize = 0;

  ELFSectionSymTabTy *symtab =
    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
  rsl_assert(symtab && "Symtab is required.");

  for (size_t i = 0; i < symtab->size(); ++i) {
    ELFSymbolTy *sym = (*symtab)[i];

    if (sym->getType() != STT_OBJECT) {
      continue;
    }

    size_t idx = (size_t)sym->getSectionIndex();
    switch (idx) {
    default:
      if ((*shtab)[idx]->getType() == SHT_NOBITS) {
        // FIXME(logan): This is a workaround for .lcomm directives
        // bug of LLVM ARM MC code generator.  Remove this when the
        // LLVM bug is fixed.

        size_t align = 16;
        SHNCommonDataSize += (size_t)sym->getSize() + align;
      }
      break;

    case SHN_COMMON:
      {
        size_t align = (size_t)sym->getValue();
        SHNCommonDataSize += (size_t)sym->getSize() + align;
      }
      break;

    case SHN_ABS:
    case SHN_UNDEF:
    case SHN_XINDEX:
      break;
    }
  }
  if (!initSHNCommonDataSize(SHNCommonDataSize)) {
    rsl_assert("Allocate memory for common variable fail!");
  }

  for (size_t i = 0; i < stab.size(); ++i) {
    ELFSectionHeaderTy *sh = (*shtab)[i];
    if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
      continue;
    }
    ELFSectionRelTableTy *reltab =
      static_cast<ELFSectionRelTableTy *>(stab[i]);
    rsl_assert(reltab && "Relocation section can't be NULL.");

    const char *reltab_name = sh->getName();
    const char *need_rel_name;
    if (sh->getType() == SHT_REL) {
      need_rel_name = reltab_name + 4;
      // ".rel.xxxx"
      //      ^ start from here.
    } else {
      need_rel_name = reltab_name + 5;
    }

    ELFSectionProgBitsTy *need_rel =
      static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
    rsl_assert(need_rel && "Need be relocated section can't be NULL.");

    switch (getHeader()->getMachine()) {
      case EM_ARM:
        relocateARM(find_sym, context, reltab, need_rel);
        break;
      case EM_386:
        relocateX86_32(find_sym, context, reltab, need_rel);
        break;
      case EM_X86_64:
        relocateX86_64(find_sym, context, reltab, need_rel);
        break;
      case EM_MIPS:
        relocateMIPS(find_sym, context, reltab, need_rel);
        break;

      default:
        rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
        break;
    }
  }

  for (size_t i = 0; i < stab.size(); ++i) {
    ELFSectionHeaderTy *sh = (*shtab)[i];
    if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
      if (stab[i]) {
        static_cast<ELFSectionBitsTy *>(stab[i])->protect();
      }
    }
  }
}

template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::print() const {
  header->print();
  shtab->print();

  for (size_t i = 0; i < stab.size(); ++i) {
    ELFSectionTy *sec = stab[i];
    if (sec) {
      sec->print();
    }
  }
}

#endif // ELF_OBJECT_HXX
