//===-- X86ELFRelocationInfo.cpp ----------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86MCTargetDesc.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/ELF.h"

using namespace llvm;
using namespace object;
using namespace ELF;

namespace {
class X86_64ELFRelocationInfo : public MCRelocationInfo {
public:
  X86_64ELFRelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {}

  const MCExpr *createExprForRelocation(RelocationRef Rel) override {
    uint64_t RelType; Rel.getType(RelType);
    symbol_iterator SymI = Rel.getSymbol();

    StringRef SymName; SymI->getName(SymName);
    uint64_t  SymAddr; SymI->getAddress(SymAddr);
    uint64_t  SymSize; SymI->getSize(SymSize);
    int64_t  Addend;  getELFRelocationAddend(Rel, Addend);

    MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName);
    // FIXME: check that the value is actually the same.
    if (Sym->isVariable() == false)
      Sym->setVariableValue(MCConstantExpr::Create(SymAddr, Ctx));

    const MCExpr *Expr = nullptr;
    // If hasAddend is true, then we need to add Addend (r_addend) to Expr.
    bool hasAddend = false;

    // The AMD64 SysV ABI says:
    // A: the addend used to compute the value of the relocatable field.
    // B: the base address at which a shared object has been loaded into memory
    //    during execution. Generally, a shared object is built with a 0 base
    //    virtual address, but the execution address will be different.
    // G: the offset into the global offset table at which the relocation
    //    entry's symbol will reside during execution.
    // GOT: the address of the global offset table.
    // L: the place (section offset or address) of the Procedure Linkage Table
    //    entry for a symbol.
    // P: the place (section offset or address) of the storage unit being
    //    relocated (computed using r_offset).
    // S: the value of the symbol whose index resides in the relocation entry.
    // Z: the size of the symbol whose index resides in the relocation entry.

    switch(RelType) {
    case R_X86_64_NONE:
    case R_X86_64_COPY:
      // none
      break;
    case R_X86_64_64:
    case R_X86_64_16:
    case R_X86_64_8:
      // S + A
    case R_X86_64_32:
    case R_X86_64_32S:
      // S + A (We don't care about the result not fitting in 32 bits.)
    case R_X86_64_PC32:
    case R_X86_64_PC16:
    case R_X86_64_PC8:
    case R_X86_64_PC64:
      // S + A - P (P/pcrel is implicit)
      hasAddend = true;
      Expr = MCSymbolRefExpr::Create(Sym, Ctx);
      break;
    case R_X86_64_GOT32:
    case R_X86_64_GOT64:
    case R_X86_64_GOTPC32:
    case R_X86_64_GOTPC64:
    case R_X86_64_GOTPLT64:
      // G + A
      hasAddend = true;
      Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOT, Ctx);
      break;
    case R_X86_64_PLT32:
      // L + A - P -> S@PLT + A
      hasAddend = true;
      Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_PLT, Ctx);
      break;
    case R_X86_64_GLOB_DAT:
    case R_X86_64_JUMP_SLOT:
      // S
      Expr = MCSymbolRefExpr::Create(Sym, Ctx);
      break;
    case R_X86_64_GOTPCREL:
    case R_X86_64_GOTPCREL64:
      // G + GOT + A - P -> S@GOTPCREL + A
      hasAddend = true;
      Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
      break;
    case R_X86_64_GOTOFF64:
      // S + A - GOT
      Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTOFF, Ctx);
      break;
    case R_X86_64_PLTOFF64:
      // L + A - GOT
      break;
    case R_X86_64_SIZE32:
    case R_X86_64_SIZE64:
      // Z + A
      Expr = MCConstantExpr::Create(SymSize, Ctx);
      break;
    default:
      Expr = MCSymbolRefExpr::Create(Sym, Ctx);
      break;
    }
    if (Expr && hasAddend && Addend != 0)
      Expr = MCBinaryExpr::CreateAdd(Expr,
                                     MCConstantExpr::Create(Addend, Ctx),
                                     Ctx);
    return Expr;
  }
};
} // End unnamed namespace

/// createX86ELFRelocationInfo - Construct an X86 Mach-O RelocationInfo.
MCRelocationInfo *llvm::createX86_64ELFRelocationInfo(MCContext &Ctx) {
  // We only handle x86-64 for now.
  return new X86_64ELFRelocationInfo(Ctx);
}
