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 }
     64 
     65 long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
     66                                                     long int Modifier) const {
     67   if (is64Bit) {
     68     switch(RelTy) {
     69     case ELF::R_X86_64_PC32: return Modifier - 4;
     70     case ELF::R_X86_64_32:
     71     case ELF::R_X86_64_32S:
     72     case ELF::R_X86_64_64:
     73       return Modifier;
     74     default:
     75       llvm_unreachable("unknown x86_64 relocation type");
     76     }
     77   } else {
     78     switch(RelTy) {
     79     case ELF::R_386_PC32: return Modifier - 4;
     80     case ELF::R_386_32: return Modifier;
     81     default:
     82       llvm_unreachable("unknown x86 relocation type");
     83     }
     84   }
     85 }
     86 
     87 unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
     88   if (is64Bit) {
     89     switch(RelTy) {
     90     case ELF::R_X86_64_PC32:
     91     case ELF::R_X86_64_32:
     92     case ELF::R_X86_64_32S:
     93         return 32;
     94     case ELF::R_X86_64_64:
     95         return 64;
     96     default:
     97       llvm_unreachable("unknown x86_64 relocation type");
     98     }
     99   } else {
    100     switch(RelTy) {
    101     case ELF::R_386_PC32:
    102     case ELF::R_386_32:
    103         return 32;
    104     default:
    105       llvm_unreachable("unknown x86 relocation type");
    106     }
    107   }
    108 }
    109 
    110 bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
    111   if (is64Bit) {
    112     switch(RelTy) {
    113     case ELF::R_X86_64_PC32:
    114         return true;
    115     case ELF::R_X86_64_32:
    116     case ELF::R_X86_64_32S:
    117     case ELF::R_X86_64_64:
    118         return false;
    119     default:
    120       llvm_unreachable("unknown x86_64 relocation type");
    121     }
    122   } else {
    123     switch(RelTy) {
    124     case ELF::R_386_PC32:
    125         return true;
    126     case ELF::R_386_32:
    127         return false;
    128     default:
    129       llvm_unreachable("unknown x86 relocation type");
    130     }
    131   }
    132 }
    133 
    134 unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
    135   return is64Bit ?
    136     X86::reloc_absolute_dword : X86::reloc_absolute_word;
    137 }
    138 
    139 long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
    140                                              unsigned RelOffset,
    141                                              unsigned RelTy) const {
    142 
    143   if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
    144     return SymOffset - (RelOffset + 4);
    145 
    146   llvm_unreachable("computeRelocation unknown for this relocation type");
    147 }
    148