Home | History | Annotate | Download | only in X86
      1 //===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements ELF writer information for the X86 backend.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "X86ELFWriterInfo.h"
     15 #include "X86Relocations.h"
     16 #include "llvm/Function.h"
     17 #include "llvm/Support/ELF.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include "llvm/Target/TargetData.h"
     20 #include "llvm/Target/TargetMachine.h"
     21 
     22 using namespace llvm;
     23 
     24 //===----------------------------------------------------------------------===//
     25 //  Implementation of the X86ELFWriterInfo class
     26 //===----------------------------------------------------------------------===//
     27 
     28 X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_)
     29   : TargetELFWriterInfo(is64Bit_, isLittleEndian_) {
     30     EMachine = is64Bit ? EM_X86_64 : EM_386;
     31   }
     32 
     33 X86ELFWriterInfo::~X86ELFWriterInfo() {}
     34 
     35 unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
     36   if (is64Bit) {
     37     switch(MachineRelTy) {
     38     case X86::reloc_pcrel_word:
     39       return ELF::R_X86_64_PC32;
     40     case X86::reloc_absolute_word:
     41       return ELF::R_X86_64_32;
     42     case X86::reloc_absolute_word_sext:
     43       return ELF::R_X86_64_32S;
     44     case X86::reloc_absolute_dword:
     45       return ELF::R_X86_64_64;
     46     case X86::reloc_picrel_word:
     47     default:
     48       llvm_unreachable("unknown x86_64 machine relocation type");
     49     }
     50   } else {
     51     switch(MachineRelTy) {
     52     case X86::reloc_pcrel_word:
     53       return ELF::R_386_PC32;
     54     case X86::reloc_absolute_word:
     55       return ELF::R_386_32;
     56     case X86::reloc_absolute_word_sext:
     57     case X86::reloc_absolute_dword:
     58     case X86::reloc_picrel_word:
     59     default:
     60       llvm_unreachable("unknown x86 machine relocation type");
     61     }
     62   }
     63   return 0;
     64 }
     65 
     66 long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
     67                                                     long int Modifier) const {
     68   if (is64Bit) {
     69     switch(RelTy) {
     70     case ELF::R_X86_64_PC32: return Modifier - 4;
     71     case ELF::R_X86_64_32:
     72     case ELF::R_X86_64_32S:
     73     case ELF::R_X86_64_64:
     74       return Modifier;
     75     default:
     76       llvm_unreachable("unknown x86_64 relocation type");
     77     }
     78   } else {
     79     switch(RelTy) {
     80     case ELF::R_386_PC32: return Modifier - 4;
     81     case ELF::R_386_32: return Modifier;
     82     default:
     83       llvm_unreachable("unknown x86 relocation type");
     84     }
     85   }
     86   return 0;
     87 }
     88 
     89 unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
     90   if (is64Bit) {
     91     switch(RelTy) {
     92     case ELF::R_X86_64_PC32:
     93     case ELF::R_X86_64_32:
     94     case ELF::R_X86_64_32S:
     95         return 32;
     96     case ELF::R_X86_64_64:
     97         return 64;
     98     default:
     99       llvm_unreachable("unknown x86_64 relocation type");
    100     }
    101   } else {
    102     switch(RelTy) {
    103     case ELF::R_386_PC32:
    104     case ELF::R_386_32:
    105         return 32;
    106     default:
    107       llvm_unreachable("unknown x86 relocation type");
    108     }
    109   }
    110   return 0;
    111 }
    112 
    113 bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
    114   if (is64Bit) {
    115     switch(RelTy) {
    116     case ELF::R_X86_64_PC32:
    117         return true;
    118     case ELF::R_X86_64_32:
    119     case ELF::R_X86_64_32S:
    120     case ELF::R_X86_64_64:
    121         return false;
    122     default:
    123       llvm_unreachable("unknown x86_64 relocation type");
    124     }
    125   } else {
    126     switch(RelTy) {
    127     case ELF::R_386_PC32:
    128         return true;
    129     case ELF::R_386_32:
    130         return false;
    131     default:
    132       llvm_unreachable("unknown x86 relocation type");
    133     }
    134   }
    135   return 0;
    136 }
    137 
    138 unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
    139   return is64Bit ?
    140     X86::reloc_absolute_dword : X86::reloc_absolute_word;
    141 }
    142 
    143 long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
    144                                              unsigned RelOffset,
    145                                              unsigned RelTy) const {
    146 
    147   if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
    148     return SymOffset - (RelOffset + 4);
    149   else
    150     assert(0 && "computeRelocation unknown for this relocation type");
    151 
    152   return 0;
    153 }
    154