mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203418 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			136 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//===-- 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 = 0;
 | 
						|
    // 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);
 | 
						|
}
 |