ELFObjectWriter.cpp revision dc9a8a378daf432d8dcfc178507afe149706f9a6
13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//                     The LLVM Compiler Infrastructure
43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source
63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details.
73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information.
113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//
123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===//
133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1424b17c673076af1bb77dd24096c8d17c734c94bcJan Sjödin#include "ELFObjectWriter.h"
153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.h"
163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h"
173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/Twine.h"
1878c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
27e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#include "llvm/Support/CommandLine.h"
28e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#include "llvm/ADT/Statistic.h"
29a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/ADT/StringSwitch.h"
303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
31a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes#include "../Target/Mips/MCTargetDesc/MipsFixupKinds.h"
328c3fee59038d8fd98db2a01b6a309a8941a16a3fEvan Cheng#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
33be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h"
342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h"
353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
373565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef  DEBUG_TYPE
40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info"
41e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  const MCFixupKindInfo &FKI =
442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  switch (Variant) {
512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  default:
522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return false;
532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOT:
542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_PLT:
552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTPCREL:
56378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  case MCSymbolRefExpr::VK_GOTOFF:
572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TPOFF:
582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSGD:
592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTTPOFF:
602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_INDNTPOFF:
612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_NTPOFF:
622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTNTPOFF:
632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLDM:
642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_DTPOFF:
652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLD:
662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return true;
672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  }
682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
70d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
71d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
72d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
74115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
75115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
89bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
92115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
955baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
96dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola  Write8(TargetObjectWriter->getOSABI());
973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
103bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
108bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
109eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1112d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  // e_flags = whatever the target wants
1122d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  WriteEFlags();
1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
115bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
121bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
1247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
125aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky    Write16(ELF::SHN_UNDEF);
1267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
1277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
1283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
130b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky  if (ShstrtabIndex >= ELF::SHN_LORESERVE)
1317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
1327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
1337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
1343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
136115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
137115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
138115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
139115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
140115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
141115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
142115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
1437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
1447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
145af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
1467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
147af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
1487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
1497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
150af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
151af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
1523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
153bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
154af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
155af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
156af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
157af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
158af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
159af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
161af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
162af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
163af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
164af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
165af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
166af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1702ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
1712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                      const MCAsmLayout &Layout) {
1722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
1732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
1742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
1752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
176d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
177d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  if (Symbol.isAbsolute() && Symbol.isVariable()) {
178d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    if (const MCExpr *Value = Symbol.getVariableValue()) {
179d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      int64_t IntValue;
180d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      if (Value->EvaluateAsAbsolute(IntValue, Layout))
181f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach        return (uint64_t)IntValue;
182d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    }
183d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  }
184d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
1852c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
1862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
1872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
1886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
1896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (Data.getFragment()) {
1906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Data.getFlags() & ELF_Other_ThumbFunc)
1916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data)+1;
1926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    else
1936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Layout.getSymbolOffset(&Data);
1946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
1952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
1962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
1972c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
1982c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
19985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
20085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
20188182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
20288182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
20388182132470527e27231f09b25a885893e528c66Rafael Espindola
20488182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
20588182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
20688182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
20794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
208f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
209f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
210f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
211f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
212f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
213f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
21407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
21588182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
21688182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
21788182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
21888182132470527e27231f09b25a885893e528c66Rafael Espindola
219f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
220f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
221f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
2222ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(*it, MCELF::GetBinding(SD));
223f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
22407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
22588182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
22688182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
22788182132470527e27231f09b25a885893e528c66Rafael Espindola
22883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
22983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
23083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
23183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
23283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
23307ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
23488182132470527e27231f09b25a885893e528c66Rafael Espindola  }
23588182132470527e27231f09b25a885893e528c66Rafael Espindola}
23688182132470527e27231f09b25a885893e528c66Rafael Espindola
237115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
238115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
239115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
240115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
241de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
242de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
24394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
244152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
2457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
2467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
2477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
2482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Binding = MCELF::GetBinding(OrigData);
2492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Visibility = MCELF::GetVisibility(OrigData);
2502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Type = MCELF::GetType(Data);
251152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
252152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
253152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Other = Visibility;
254152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
2552c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
2563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
2573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
258f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
259f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
260f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  const MCExpr *ESize = Data.getSize();
261f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
262f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
263f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    if (!ESize->EvaluateAsAbsolute(Res, Layout))
264f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
265f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
2663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
2697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
2707be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
273115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
274115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
275115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
276115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
277a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                                    const SectionIndexMapTy &SectionIndexMap) {
2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
2793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
2833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
2857be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
2863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
2883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
2903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
2917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
2923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
29471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
2954beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
2964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
297a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
2984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
2994beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
3004beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
3014beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
302d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB ||
303d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky        Section.getType() == ELF::SHT_SYMTAB_SHNDX)
304a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
3057be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
306a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section),
307a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes                     false);
308a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
309a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
3143223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
3153223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
3163223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
3177be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
3182ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
3257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
3262ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3311f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
3321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               const MCFragment &F,
334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               const MCFixup &Fixup,
335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               bool IsPCRel) const {
3361f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
33794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
33894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
33994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
34094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
34294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
34394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
34494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &ASymbol;
3451f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
3461f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
34794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
34894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
34994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
35094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
35194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
3527eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
3537eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
35494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
35525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
3567eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
35725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
3597eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
36025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
36125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
36225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
36325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
36425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
36525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
3668cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
3673729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
3683729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
3693729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
3708cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
371c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
372c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
37325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
37494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
37594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
37694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
37794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
3783729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
3791c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola  if (Section.getFlags() & ELF::SHF_MERGE) {
38094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
381e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
38294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
38394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
38494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
3851f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
386c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
387e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
388e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
38973ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
39073ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
39256a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
39356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFixup &Fixup,
39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       MCValue Target,
39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       uint64_t &FixedValue) {
39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Addend = 0;
39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int Index = 0;
40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Value = Target.getConstant();
40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  const MCSymbol *RelocSymbol = NULL;
40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
403127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
40456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  if (!Target.isAbsolute()) {
40556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
407e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      IsPCRel = true;
41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t a = Layout.getSymbolOffset(&SDB);
41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim
417a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes      // Offset of the relocation in the section
41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += b - a;
42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim
42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (!RelocSymbol) {
42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCFragment *F = SD.getFragment();
42556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = F->getParent()->getOrdinal() + 1;
42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim
42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += Layout.getSymbolOffset(&SD);
43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim    } else {
43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
43256a399023aba6cf1348533df04732950c43eaca7Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      else
43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim        UsedInReloc.insert(RelocSymbol);
43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = -1;
43656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
43756a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Addend = Value;
43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    // Compensate for the addend on i386.
439bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit())
44056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value = 0;
44156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
44356a399023aba6cf1348533df04732950c43eaca7Jason W Kim  FixedValue = Value;
44456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
44556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                               (RelocSymbol != 0), Addend);
446c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
447c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
448c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  if (RelocNeedsGOT(Modifier))
449c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola    NeedsGOT = true;
4502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
45156a399023aba6cf1348533df04732950c43eaca7Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
45256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Fixup.getOffset();
4532a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky
4542a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky  adjustFixupOffset(Fixup, RelocOffset);
45556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
456bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (!hasRelocationAddend())
457bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    Addend = 0;
458bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
459bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  if (is64Bit())
460bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<64>(Addend));
461bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola  else
462bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola    assert(isInt<32>(Addend));
463bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola
46456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
46556a399023aba6cf1348533df04732950c43eaca7Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
46656a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
46756a399023aba6cf1348533df04732950c43eaca7Jason W Kim
46856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
4690b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
470115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
471115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
4727b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
473ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
4772ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 const MCSymbolData &Data,
4782ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 bool Used, bool Renamed) {
479484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
480484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
481484291c27319668ad99cb87def000254357736fbRafael Espindola
482bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
483bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
484bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
48588182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
48688182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
48788182132470527e27231f09b25a885893e528c66Rafael Espindola
488737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
489a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
490d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
491d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
492d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
49394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
49421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
49521451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola    return false;
49621451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola
4972ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
49821451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
499a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
500a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
501737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
502737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
503737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
504bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
505737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
506737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
507737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
508737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
509737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
5102ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
5112ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                              bool isUsedInReloc) {
512737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
513737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
514737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
515737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
51694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
5171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
5181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
5191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
5201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
5211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
522737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
5231f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
524737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
525737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
526737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
527737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
528115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
5297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      SectionIndexMapTy &SectionIndexMap,
5307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const RelMapTy &RelMap) {
531bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
532bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
533bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
534bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
535bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
5362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
5372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
5382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
5392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
5402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
5412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
5422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
5432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
5442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
5457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP ||
5467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_REL ||
5477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
5482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
549bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
5507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelSection = RelMap.lookup(&Section);
5517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (RelSection)
5527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      SectionIndexMap[RelSection] = Index++;
553bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
554bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
555bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
556115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
5571f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
5587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         RevGroupMapTy RevGroupMap,
5597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         unsigned NumRegularSections) {
5605c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
561378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola  // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
5625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
5635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
5645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
5655c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
5665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
5672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(Data, ELF::STB_GLOBAL);
5685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
5695c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
5713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
5723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
5733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
574d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // FIXME: We could optimize suffixes in strtab in the same way we
575d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  // optimize them in shstrtab.
576d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
577a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
5803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
5813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
582484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
583484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
5851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
5861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
5871f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
58888182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
5923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
59394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
5943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
5961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
5971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
5982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
5991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
6002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_GLOBAL);
6012ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(SD, ELF::STB_GLOBAL);
6021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
6031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
604484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
6052ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_WEAK);
606484291c27319668ad99cb87def000254357736fbRafael Espindola
607f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
608a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
609f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
610bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
611a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
61288182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
6131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
6141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
6151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
6161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
618bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
619bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
620bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
6217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
6227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
6245df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
6255df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
62688182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
62788182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
62888182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
6291261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
6301261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
63188182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
63288182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
6331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
6341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
6351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
6361261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
63788182132470527e27231f09b25a885893e528c66Rafael Espindola    }
63888182132470527e27231f09b25a885893e528c66Rafael Espindola
6391261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
640a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
641a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
6421261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
643a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
6443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
645a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
646a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
647a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
648a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
649a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
650a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
651a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
661ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
6623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
6633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
664ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
665ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
666ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
6693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
6703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
6717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky
6727aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky  if (NumRegularSections > ELF::SHN_LORESERVE)
6737aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky    NeedsSymtabShndx = true;
6743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               MCAsmLayout &Layout,
6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               RelMapTy &RelMap) {
6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Relocations[&SD].empty())
6837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
6847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
6853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
6863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
6883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
690bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
6913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
692299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
693299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
694bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (hasRelocationAddend())
695bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
696299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
697bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
6983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection =
7007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
7017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        ELF::SHT_RELA : ELF::SHT_REL, 0,
7027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        SectionKind::getReadOnly(),
7037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        EntrySize, "");
7047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    RelMap[&Section] = RelaSection;
7057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Asm.getOrCreateSectionData(*RelaSection);
7067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
7077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
7087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
7097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
7107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                       const RelMapTy &RelMap) {
7117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
7127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
7137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
7147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
7157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF&>(SD.getSection());
7163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection = RelMap.lookup(&Section);
7187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (!RelaSection)
7197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
721bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSD.setAlignment(is64Bit() ? 8 : 4);
7223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
7247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteRelocationsFragment(Asm, F, &*it);
7253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
7263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
728115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
729115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
730115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
731115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
732115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
733115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
7343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
7353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
7363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
7373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
7383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
7393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
7403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
7413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
7423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
7433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
7443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
746115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
747115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
748115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
7503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // sort by the r_offset just like gnu as does
7513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(Relocs.begin(), Relocs.end());
7523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
7543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
7553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
75612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
75712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
75812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
7598f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
7608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
76112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
762bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
763af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
7645e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
7658f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf64_Rela ERE64;
7668f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE64.setSymbolAndType(entry.Index, entry.Type);
767af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, ERE64.r_info);
7685e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
769bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
770af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
7715e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
772af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
7735e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
7748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
7758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
776af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
7775e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
778bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
779af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
7805e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
7813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
7823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
784d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) {
785d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
786d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
787d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameA = secA->getSectionName();
788d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const StringRef &NameB = secB->getSectionName();
789d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeA = NameA.size();
790d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned sizeB = NameB.size();
791d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  const unsigned len = std::min(sizeA, sizeB);
792d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int i = 0; i < len; ++i) {
793d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char ca = NameA[sizeA - i - 1];
794d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    char cb = NameB[sizeB - i - 1];
795d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (ca != cb)
796d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      return cb - ca;
797d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
798d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
799d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  return sizeB - sizeA;
800d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola}
801d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
802115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
803115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
8047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             SectionIndexMapTy &SectionIndexMap,
8057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             const RelMapTy &RelMap) {
8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
8073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
809bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
8103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
81138738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
8124283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
8137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
8143f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
81571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
81671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
81771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
8184283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
8197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
8207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
8212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
8223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
823bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
8247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
8257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
8267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
8277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
8284283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
8297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
8302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
8317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
8327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
8337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
8343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionELF *StrtabSection;
8363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
8373f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
8383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
8393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
8403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
8427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
8457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  StringTableIndex = SectionIndexMap.lookup(StrtabSection);
84671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
84771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
84871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
8497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
8507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
8517be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
8527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
8534beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
85471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
8553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
8563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
8573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
8593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
860d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  std::vector<const MCSectionELF*> Sections;
861d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
862d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
863d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section =
864d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
865d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    Sections.push_back(&Section);
866d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  }
867d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
868d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola
8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
8733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
8743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents() += '\x00';
8753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
876d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola  for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
877d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    const MCSectionELF &Section = *Sections[I];
8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
880d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola    if (I != 0) {
881d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      StringRef PreviousName = Sections[I - 1]->getSectionName();
882d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      if (PreviousName.endswith(Name)) {
883d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        SectionStringTableIndex[&Section] = Index - Name.size() - 1;
884d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola        continue;
885d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola      }
8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
8892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
8922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    F->getContents() += Name;
8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    F->getContents() += '\x00';
8943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
8957070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
8967070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
89796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
89896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            MCAsmLayout &Layout,
89996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            GroupMapTy &GroupMap,
9007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            RevGroupMapTy &RevGroupMap,
9017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            SectionIndexMapTy &SectionIndexMap,
9027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            const RelMapTy &RelMap) {
90396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  // Create the .note.GNU-stack section if needed.
90496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  MCContext &Ctx = Asm.getContext();
90596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  if (Asm.getNoExecStack()) {
90696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    const MCSectionELF *GnuStackSection =
90796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
90896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                        SectionKind::getReadOnly());
90996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    Asm.getOrCreateSectionData(*GnuStackSection);
91096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  }
91196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola
9122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
9132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
9142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
9152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
9162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
9171c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
9182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
9192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
9202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
9212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
9221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
9232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
92496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Group = Ctx.CreateELFGroupSection();
9252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
9262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
9272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
9282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
9292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
9302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
9312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
9322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
9337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
9347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
9352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
9362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
9377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola       it != ie; ++it) {
9382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
9392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
9401c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
9412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
9421f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
9432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
9442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
9452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
9467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    unsigned Index = SectionIndexMap.lookup(&Section);
9477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    String32(*F, Index);
9482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
9492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
9502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
951115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
952115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
953115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
954115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
955115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
956115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
957c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
968c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
969c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
970c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
971c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
9723f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
973c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
974c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
975c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
976c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
977c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
978c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
979c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
980c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
981c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
9823f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
983c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
984c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
985c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
986c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
987c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
988c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
989c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
990c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
991c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
992c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
993c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
994c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
995c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
996c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
997c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
998c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
999c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
100098976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola  case ELF::SHT_NOTE:
1001c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
1002c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
100386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_INIT_ARRAY:
100486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_FINI_ARRAY:
100586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_PREINIT_ARRAY:
10060cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola  case ELF::SHT_X86_64_UNWIND:
1007c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
1008c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1009c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
10104a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky  case ELF::SHT_GROUP:
10112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
10122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
10132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
10142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1015c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
1016c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
1017c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
1018c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
1019c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
1020c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1021c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
1022c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
1023c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
1024c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
10252ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
1026f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola  return SD.getOrdinal() == ~UINT32_C(0) &&
10276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    !SD.getSection().isVirtualSection();
10286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
10296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
10302ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) {
10316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  uint64_t Ret = 0;
10326db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
10336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
10346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
10356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
10366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    Ret += cast<MCDataFragment>(F).getContents().size();
10376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
10386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Ret;
10396db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
10406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
10412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout,
10422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                             const MCSectionData &SD) {
10436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
10446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
10456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Layout.getSectionFileSize(&SD);
10466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
10476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
10482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
10492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                                const MCSectionData &SD) {
10506db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
10516db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
105285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  return Layout.getSectionAddressSize(&SD);
10536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
10546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCAsmLayout &Layout,
10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCSectionELF &Section) {
10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FileOff = OS.tell();
10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteZeros(Padding);
10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += Padding;
10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += GetSectionFileSize(Layout, SD);
10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  if (IsELFMetaDataSection(SD)) {
10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ++i) {
10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      const MCFragment &F = *i;
10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      assert(F.getKind() == MCFragment::FT_Data);
10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      WriteBytes(cast<MCDataFragment>(F).getContents().str());
10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    }
10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  } else {
1075f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach    Asm.writeSectionData(&SD, Layout);
10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const GroupMapTy &GroupMap,
10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const MCAsmLayout &Layout,
10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                   const SectionOffsetMapTy &SectionOffsetMap) {
10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumSections = Asm.size() + 1;
10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  std::vector<const MCSectionELF*> Sections;
10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  Sections.resize(NumSections - 1);
10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (SectionIndexMapTy::const_iterator i=
10907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
10917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
10927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Sections[p.second - 1] = p.first;
10937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Null section first.
10967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FirstSectionSize =
10977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
10987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint32_t FirstSectionLink =
10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumSections - 1; ++i) {
11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section = *Sections[i];
11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint32_t GroupSymbolIndex;
11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = 0;
11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    else
11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                                     GroupMap.lookup(&Section));
11117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint64_t Size = GetSectionAddressSize(Layout, SD);
11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SectionOffsetMap.lookup(&Section), Size,
11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SD.getAlignment(), Section);
11177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
11187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
11197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                  std::vector<const MCSectionELF*> &Sections) {
11227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
11237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
11247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
11257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
11267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
11337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
11347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP &&
11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_REL &&
11367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_RELA)
11377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
11427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
11437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_REL ||
11457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
11467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
11476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
11486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
11496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1150115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1151115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
11522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
11531f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
1154bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1155bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumUserSections = Asm.size();
11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
11607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumUserAndRelocSections = Asm.size();
11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
11637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        RevGroupMap, SectionIndexMap, RelMap);
11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned AllSections = Asm.size();
11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumRegularSections = NumUserSections + NumIndexedSections;
1168bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
11698f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
11707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
11717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
11748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
11753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
11764beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
11777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         SectionIndexMap,
11787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         RelMap);
11791d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
1180bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1181bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
1182bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                    sizeof(ELF::Elf32_Ehdr);
1183a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
11843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
11867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSectionOrder(Asm, Sections);
11877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumSections = Sections.size();
11887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SectionOffsetMapTy SectionOffsetMap;
11897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
11902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
11912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
11923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1193a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1194a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Remember the offset into the file for this section.
11967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    SectionOffsetMap[&Section] = FileOff;
11977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
11996db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
12003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
12013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1202a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1203a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
12047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned SectionHeaderOffset = FileOff - HeaderSize;
12053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t SectionHeaderEntrySize = is64Bit() ?
12077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
12087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += (NumSections + 1) * SectionHeaderEntrySize;
12093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
12112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1213a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
12147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1215a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
12163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
12172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
121844cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
12197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Get the size of the section in the output file (including padding).
12206db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
12213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
12223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Write out the ELF header ...
12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteHeader(SectionHeaderOffset, NumSections + 1);
12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the regular sections ...
12277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // + because of .shstrtab
12287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i)
12297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
12307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
12317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff = OS.tell();
1232a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
1233a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1234a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
12357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the section header table ...
12367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
12377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                     SectionOffsetMap);
12383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
12397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff = OS.tell();
12406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1241aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky  // ... and then the remaining sections ...
12427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
12437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
12443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
12453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
124678c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool
124778c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
124878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCSymbolData &DataA,
124978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCFragment &FB,
125078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool InSet,
125178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool IsPCRel) const {
125278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  if (DataA.getFlags() & ELF_STB_Weak)
125378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman    return false;
125478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
125578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                 Asm, DataA, FB,InSet, IsPCRel);
125678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman}
125778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman
12586024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
12596024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola                                            raw_ostream &OS,
1260bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
1261bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  switch (MOTW->getEMachine()) {
1262d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_386:
1263d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_X86_64:
1264bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
1265d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_ARM:
1266bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
12674b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case ELF::EM_MBLAZE:
1268bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
12692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case ELF::EM_PPC:
12702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case ELF::EM_PPC64:
12712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break;
1272291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka    case ELF::EM_MIPS:
1273291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka      return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break;
12743285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer    default: llvm_unreachable("Unsupported architecture"); break;
1275d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1276d3443e99e43945fdb0742177da06a32fa225740dJason W Kim}
1277d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1278d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter
1279d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===//
1280d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
128131f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1282bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1283bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1284bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1285d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1286d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1287d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter()
1288d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1289d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
12902d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple.
12912d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() {
12922d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
12932d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim}
12942d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim
1295953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly.
1296953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol.
1297e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// This code is an approximation of what ARM/gcc does.
1298e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1299e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(PCRelCount, "Total number of PIC Relocations");
1300e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(NonPCRelCount, "Total number of non-PIC relocations");
1301953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1302953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
1303953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim                                                   const MCValue &Target,
1304953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim                                                   const MCFragment &F,
1305e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                                   const MCFixup &Fixup,
1306e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                                   bool IsPCRel) const {
1307953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
1308953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  bool EmitThisSym = false;
1309953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1310e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  const MCSectionELF &Section =
1311e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    static_cast<const MCSectionELF&>(Symbol.getSection());
1312e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  bool InNormalSection = true;
1313e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  unsigned RelocType = 0;
1314e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);
1315e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
13166dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay  DEBUG(
13176dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay      const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
13186dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay      MCSymbolRefExpr::VariantKind Kind2;
13196dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay      Kind2 = Target.getSymB() ?  Target.getSymB()->getKind() :
13206dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay        MCSymbolRefExpr::VK_None;
13216dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay      dbgs() << "considering symbol "
1322e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << Section.getSectionName() << "/"
1323e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << Symbol.getName() << "/"
1324e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << " Rel:" << (unsigned)RelocType
1325e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << " Kind: " << (int)Kind << "/" << (int)Kind2
1326e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << " Tmp:"
1327e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"
1328e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << Symbol.isVariable() << "/" << Symbol.isTemporary()
1329e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n");
1330e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1331bebd44a95a94189e79b02cd15edc2d41bc2628feJason W Kim  if (IsPCRel) { ++PCRelCount;
1332e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    switch (RelocType) {
1333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    default:
1334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      // Most relocation types are emitted as explicit symbols
1335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      InNormalSection =
1336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        StringSwitch<bool>(Section.getSectionName())
1337e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".data.rel.ro.local", false)
1338e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".data.rel", false)
1339e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".bss", false)
1340e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Default(true);
1341e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      EmitThisSym = true;
1342e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      break;
1343e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    case ELF::R_ARM_ABS32:
1344e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      // But things get strange with R_ARM_ABS32
1345e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      // In this case, most things that go in .rodata show up
1346e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      // as section relative relocations
1347e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      InNormalSection =
1348e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        StringSwitch<bool>(Section.getSectionName())
1349e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".data.rel.ro.local", false)
1350e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".data.rel", false)
1351e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".rodata", false)
1352e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Case(".bss", false)
1353e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        .Default(true);
1354e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      EmitThisSym = false;
1355e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      break;
1356e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    }
1357953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  } else {
1358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    NonPCRelCount++;
1359e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    InNormalSection =
1360e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      StringSwitch<bool>(Section.getSectionName())
1361e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      .Case(".data.rel.ro.local", false)
1362e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      .Case(".rodata", false)
1363e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      .Case(".data.rel", false)
1364e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      .Case(".bss", false)
1365e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim      .Default(true);
1366e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1367e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    switch (RelocType) {
1368e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    default: EmitThisSym = true; break;
1369e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    case ELF::R_ARM_ABS32: EmitThisSym = false; break;
1370e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    }
1371953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  }
1372e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1373953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  if (EmitThisSym)
1374953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    return &Symbol;
1375e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  if (! Symbol.isTemporary() && InNormalSection) {
1376953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    return &Symbol;
1377e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  }
1378953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  return NULL;
1379953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim}
1380953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1381e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// Need to examine the Fixup when determining whether to
1382e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// emit the relocation as an explicit symbol or as a section relative
1383e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// offset
138485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
138585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                                          const MCFixup &Fixup,
138656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
138756a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
1388c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola                                          int64_t Addend) const {
1389c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola  return GetRelocTypeInner(Target, Fixup, IsPCRel);
1390e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim}
1391e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1392e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kimunsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
1393e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               const MCFixup &Fixup,
1394e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim                                               bool IsPCRel) const  {
1395e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
1396e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
1397e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim
1398a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  unsigned Type = 0;
139985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (IsPCRel) {
140085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
140185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: assert(0 && "Unimplemented");
14023fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim    case FK_Data_4:
14033fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
14043fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier");
14053fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_None:
1406e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim        Type = ELF::R_ARM_REL32;
14071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14083fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
14091d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        assert(0 && "unimplemented");
14101d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14113fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
14123fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_TLS_IE32;
14131d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14141d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
14151d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1416685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_uncondbranch:
14173fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
14183fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_PLT:
14191d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_PLT32;
14201d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14213fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default:
14221d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_CALL;
14231d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14241d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
14251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1426685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_condbranch:
1427685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      Type = ELF::R_ARM_JUMP24;
1428685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      break;
142986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movt_hi16:
143086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movt_hi16_pcrel:
14311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVT_PREL;
14321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
143386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movw_lo16:
143486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movw_lo16_pcrel:
14351d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVW_PREL_NC;
14361d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1437f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16:
1438f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16_pcrel:
1439f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVT_PREL;
1440f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
1441f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16:
1442f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16_pcrel:
1443f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVW_PREL_NC;
1444f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
1445298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola    case ARM::fixup_arm_thumb_bl:
1446298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola    case ARM::fixup_arm_thumb_blx:
1447298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola      switch (Modifier) {
1448298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola      case MCSymbolRefExpr::VK_ARM_PLT:
1449298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola        Type = ELF::R_ARM_THM_CALL;
1450298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola        break;
1451298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola      default:
1452298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola        Type = ELF::R_ARM_NONE;
1453298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola        break;
1454298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola      }
1455298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola      break;
145685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
145785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  } else {
145885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
145985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: llvm_unreachable("invalid fixup kind!");
1460a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim    case FK_Data_4:
1461a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      switch (Modifier) {
14623fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier"); break;
14633fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOT:
14641d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_GOT_BREL;
14651d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14663fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
14671d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_GD32;
14681d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1469f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_ARM_TPOFF:
14701d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_LE32;
14711d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1472a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
14731d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_IE32;
14741d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1475f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_None:
14761d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_ABS32;
14771d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14783fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTOFF:
14791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_GOTOFF32;
14801d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
14811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
14821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1483dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_ldst_pcrel_12:
14849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    case ARM::fixup_arm_pcrel_10:
1485dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_adr_pcrel_12:
1486662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach    case ARM::fixup_arm_thumb_bl:
1487b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach    case ARM::fixup_arm_thumb_cb:
1488b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling    case ARM::fixup_arm_thumb_cp:
1489e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach    case ARM::fixup_arm_thumb_br:
14901d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      assert(0 && "Unimplemented");
14911d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1492685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_uncondbranch:
14931d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_CALL;
14941d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1495685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_condbranch:
1496685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      Type = ELF::R_ARM_JUMP24;
1497685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      break;
14981d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim    case ARM::fixup_arm_movt_hi16:
14991d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVT_ABS;
15001d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
150185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movw_lo16:
15021d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVW_ABS_NC;
15031d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1504f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16:
1505f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVT_ABS;
1506f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
1507f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16:
1508f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVW_ABS_NC;
1509f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
151085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
151185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  }
151285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
1513a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  return Type;
151485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim}
151585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
15162c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky//===- PPCELFObjectWriter -------------------------------------------===//
15172c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky
15182c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
15192c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky                                             raw_ostream &_OS,
15202c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky                                             bool IsLittleEndian)
15212c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
15222c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky}
15232c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky
15242c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::~PPCELFObjectWriter() {
15252c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky}
15262c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky
15272c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divackyunsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
15282c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky                                             const MCFixup &Fixup,
15292c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky                                             bool IsPCRel,
15302c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky                                             bool IsRelocWithSymbol,
1531c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola                                             int64_t Addend) const {
15322c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  // determine the type of the relocation
15332c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  unsigned Type;
15342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  if (IsPCRel) {
15352c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    switch ((unsigned)Fixup.getKind()) {
15362c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    default:
15372c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      llvm_unreachable("Unimplemented");
15382c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_br24:
15392c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_REL24;
15402c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15412c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case FK_PCRel_4:
15422c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_REL32;
15432c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15442c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    }
15452c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  } else {
15462c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    switch ((unsigned)Fixup.getKind()) {
15472c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      default: llvm_unreachable("invalid fixup kind!");
15482c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_br24:
15492c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR24;
15502c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15512c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_brcond14:
15522c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_
15532c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15542c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_ha16:
15552c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR16_HA;
15562c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15572c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_lo16:
15582c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR16_LO;
15592c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15602c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case PPC::fixup_ppc_lo14:
15612c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR14;
15622c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15632c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case FK_Data_4:
15642c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR32;
15652c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15662c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    case FK_Data_2:
15672c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      Type = ELF::R_PPC_ADDR16;
15682c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky      break;
15692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky    }
15702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  }
15712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky  return Type;
15722c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky}
15732c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky
1574946227d64afcc8cb3f4db94b6ee0cdb1aa55fa31Jim Grosbachvoid PPCELFObjectWriter::
1575946227d64afcc8cb3f4db94b6ee0cdb1aa55fa31Jim GrosbachadjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) {
15762a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky  switch ((unsigned)Fixup.getKind()) {
15772a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky    case PPC::fixup_ppc_ha16:
15782a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky    case PPC::fixup_ppc_lo16:
15792a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky      RelocOffset += 2;
15802a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky      break;
15812a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky    default:
15822a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky      break;
15832a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky  }
15842a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky}
15852a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky
15864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===//
1587d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
158831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1589bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             raw_ostream &_OS,
1590bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             bool IsLittleEndian)
1591bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
15924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
15944b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
15954b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
15964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
159756a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
15984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCFixup &Fixup,
159956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsPCRel,
160056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsRelocWithSymbol,
1601c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola                                             int64_t Addend) const {
16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  // determine the type of the relocation
16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  unsigned Type;
16044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (IsPCRel) {
16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
16064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default:
16074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      llvm_unreachable("Unimplemented");
1608e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_4:
16094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_64_PCREL;
16104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
1611e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_2:
16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32_PCREL;
16134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
16154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  } else {
16164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
16174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default: llvm_unreachable("invalid fixup kind!");
16184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_4:
161956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Type = ((IsRelocWithSymbol || Addend !=0)
162056a399023aba6cf1348533df04732950c43eaca7Jason W Kim              ? ELF::R_MICROBLAZE_32
162156a399023aba6cf1348533df04732950c43eaca7Jason W Kim              : ELF::R_MICROBLAZE_64);
16224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_2:
16244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32;
16254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
16264b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
16274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  }
162856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
16294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
1630d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1631d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===//
1632d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1633d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
163431f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1635bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1636bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1637bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1638d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1639d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1640d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter()
1641d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1642d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
164356a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
164456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          const MCFixup &Fixup,
164556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
164656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
1647c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola                                          int64_t Addend) const {
1648d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  // determine the type of the relocation
1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
165012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
165112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
1652d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  unsigned Type;
1653bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
1654d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
16553a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
16563a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
1657debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola
1658debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola      case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
1659debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola      case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
1660debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola      case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
1661debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola
16623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_8:
16633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
16643a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC64;
1665d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16667a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola      case X86::reloc_signed_4byte:
1667c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola      case X86::reloc_riprel_4byte_movq_load:
16683a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case X86::reloc_riprel_4byte:
16693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_4:
16703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        switch (Modifier) {
16713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        default:
16723a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          llvm_unreachable("Unimplemented");
16733a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_None:
16743a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PC32;
16753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
16773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PLT32;
16783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTPCREL:
16803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTPCREL;
16813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16823a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTTPOFF:
16833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTTPOFF;
1684d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSGD:
16863a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSGD;
16873a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16883a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSLD:
16893a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSLD;
16903a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
16913a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        }
1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
16933a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_2:
16943a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
16953a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC16;
1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1697d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger      case FK_PCRel_1:
1698d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        assert(Modifier == MCSymbolRefExpr::VK_None);
1699d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        Type = ELF::R_X86_64_PC8;
1700d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        break;
1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_8: Type = ELF::R_X86_64_64; break;
1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_32S;
1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOT32;
1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTPCREL:
1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOTPCREL;
1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_TPOFF32;
1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_DTPOFF32;
1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_32;
1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_X86_64_16; break;
1731e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_X86_64_8; break;
1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  } else {
1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
17371d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
17381d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
17391d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola
17401d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola      case X86::reloc_global_offset_table:
17411d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        Type = ELF::R_386_GOTPC;
1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
17431d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola
17443c68acd202d061c38e9b7744012094b4009d932aRafael Espindola      case X86::reloc_signed_4byte:
17451d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola      case FK_PCRel_4:
17461d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola      case FK_Data_4:
17471d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        switch (Modifier) {
17481d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        default:
17491d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola          llvm_unreachable("Unimplemented");
17501d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        case MCSymbolRefExpr::VK_None:
17511d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola          Type = ELF::R_386_PC32;
17521d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola          break;
17531d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
17541d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola          Type = ELF::R_386_PLT32;
17551d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola          break;
17561d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola        }
1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_global_offset_table:
1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_GOTPC;
1765d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // instead?
1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1770e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1773d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1774d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_32;
1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOT32;
1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTOFF:
1782d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOTOFF;
1783d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1784d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSGD:
1785d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GD;
1786d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1787d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1788d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE_32;
1789d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1790d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_INDNTPOFF:
1791d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_IE;
1792d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1793d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_NTPOFF:
1794d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE;
1795d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1796d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTNTPOFF:
1797d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GOTIE;
1798d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1799d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSLDM:
1800d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDM;
1801d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1802d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1803d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDO_32;
1804d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1805e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky        case MCSymbolRefExpr::VK_GOTTPOFF:
1806e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky          Type = ELF::R_386_TLS_IE_32;
1807e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky          break;
1808d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1809d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1810d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_386_16; break;
1811e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1812d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_386_8; break;
1813d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1814d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1815d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1816d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
181756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
18183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1819291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka
1820a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes//===- MipsELFObjectWriter -------------------------------------------===//
1821a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes
1822291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1823291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka                                         raw_ostream &_OS,
1824291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka                                         bool IsLittleEndian)
1825291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {}
1826291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka
1827291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::~MipsELFObjectWriter() {}
1828291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka
182984bfc2f090639f933df06cc675c4385511516befAkira Hatanaka// FIXME: get the real EABI Version from the Triple.
183084bfc2f090639f933df06cc675c4385511516befAkira Hatanakavoid MipsELFObjectWriter::WriteEFlags() {
183184bfc2f090639f933df06cc675c4385511516befAkira Hatanaka  Write32(ELF::EF_MIPS_NOREORDER |
183284bfc2f090639f933df06cc675c4385511516befAkira Hatanaka          ELF::EF_MIPS_ARCH_32R2);
183384bfc2f090639f933df06cc675c4385511516befAkira Hatanaka}
183484bfc2f090639f933df06cc675c4385511516befAkira Hatanaka
1835a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopesconst MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
1836a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes                                                    const MCValue &Target,
1837a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes                                                    const MCFragment &F,
1838a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes                                                    const MCFixup &Fixup,
1839a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes                                                    bool IsPCRel) const {
1840a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes  assert(Target.getSymA() && "SymA cannot be 0.");
1841a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes  const MCSymbol &Sym = Target.getSymA()->getSymbol();
1842a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes
1843f3315cf65f9574cd1e4e784d2860c943cfa65ce9Akira Hatanaka  if (Sym.getSection().getKind().isMergeableCString() ||
1844f3315cf65f9574cd1e4e784d2860c943cfa65ce9Akira Hatanaka      Sym.getSection().getKind().isMergeableConst())
1845a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes    return &Sym;
1846a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes
1847a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes  return NULL;
1848a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes}
1849a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes
1850291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanakaunsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
1851291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka                                           const MCFixup &Fixup,
1852291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka                                           bool IsPCRel,
1853291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka                                           bool IsRelocWithSymbol,
1854c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola                                           int64_t Addend) const {
1855a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  // determine the type of the relocation
1856a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  unsigned Type = (unsigned)ELF::R_MIPS_NONE;
1857a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  unsigned Kind = (unsigned)Fixup.getKind();
1858a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes
1859a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  switch (Kind) {
1860a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  default:
1861a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    llvm_unreachable("invalid fixup kind!");
1862a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case FK_Data_4:
1863a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_32;
1864a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
186584bfc2f090639f933df06cc675c4385511516befAkira Hatanaka  case FK_GPRel_4:
186684bfc2f090639f933df06cc675c4385511516befAkira Hatanaka    Type = ELF::R_MIPS_GPREL32;
186784bfc2f090639f933df06cc675c4385511516befAkira Hatanaka    break;
1868a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_GPREL16:
1869a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_GPREL16;
1870a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1871a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_26:
1872a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_26;
1873a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1874a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_CALL16:
1875a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_CALL16;
1876a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1877e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case Mips::fixup_Mips_GOT_Global:
1878e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case Mips::fixup_Mips_GOT_Local:
1879a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_GOT16;
1880a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1881a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_HI16:
1882a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_HI16;
1883a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1884a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_LO16:
1885a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_LO16;
1886a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1887a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_TLSGD:
1888a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_TLS_GD;
1889a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1890a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_GOTTPREL:
1891a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_TLS_GOTTPREL;
1892a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1893a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_TPREL_HI:
1894a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_TLS_TPREL_HI16;
1895a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1896a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_TPREL_LO:
1897a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_TLS_TPREL_LO16;
1898a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1899a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_Branch_PCRel:
1900a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  case Mips::fixup_Mips_PC16:
1901a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    Type = ELF::R_MIPS_PC16;
1902a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes    break;
1903a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  }
1904a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes
1905a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes  return Type;
1906291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka}
1907