119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file implements ELF writer information for the X86 backend.
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "X86ELFWriterInfo.h"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "X86Relocations.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ELF.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetData.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetMachine.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//  Implementation of the X86ELFWriterInfo class
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanX86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_)
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : TargetELFWriterInfo(is64Bit_, isLittleEndian_) {
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EMachine = is64Bit ? EM_X86_64 : EM_386;
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanX86ELFWriterInfo::~X86ELFWriterInfo() {}
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit) {
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(MachineRelTy) {
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_pcrel_word:
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_X86_64_PC32;
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_word:
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_X86_64_32;
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_word_sext:
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_X86_64_32S;
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_dword:
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_X86_64_64;
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_picrel_word:
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86_64 machine relocation type");
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(MachineRelTy) {
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_pcrel_word:
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_386_PC32;
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_word:
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ELF::R_386_32;
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_word_sext:
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_absolute_dword:
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case X86::reloc_picrel_word:
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86 machine relocation type");
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanlong int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                    long int Modifier) const {
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit) {
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_PC32: return Modifier - 4;
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32:
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32S:
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_64:
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Modifier;
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86_64 relocation type");
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_PC32: return Modifier - 4;
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_32: return Modifier;
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86 relocation type");
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit) {
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_PC32:
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32:
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32S:
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return 32;
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_64:
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return 64;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86_64 relocation type");
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_PC32:
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_32:
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return 32;
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86 relocation type");
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit) {
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_PC32:
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32:
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_32S:
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_X86_64_64:
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86_64 relocation type");
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch(RelTy) {
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_PC32:
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_386_32:
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unknown x86 relocation type");
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return is64Bit ?
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    X86::reloc_absolute_dword : X86::reloc_absolute_word;
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanlong int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             unsigned RelOffset,
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             unsigned RelTy) const {
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return SymOffset - (RelOffset + 4);
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(0 && "computeRelocation unknown for this relocation type");
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
154