ELFObjectWriter.cpp revision 7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9
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"
183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h"
193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h"
203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h"
213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h"
223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h"
233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h"
243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h"
253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h"
263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h"
27953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim#include "llvm/ADT/StringSwitch.h"
283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "../Target/X86/X86FixupKinds.h"
304a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim#include "../Target/ARM/ARMFixupKinds.h"
313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector>
333565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm;
343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
352ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
362ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  const MCFixupKindInfo &FKI =
372ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
382ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  switch (Variant) {
442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  default:
452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return false;
462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOT:
472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_PLT:
482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTPCREL:
492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TPOFF:
502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSGD:
512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTTPOFF:
522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_INDNTPOFF:
532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_NTPOFF:
542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_GOTNTPOFF:
552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLDM:
562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_DTPOFF:
572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  case MCSymbolRefExpr::VK_TLSLD:
582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    return true;
592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  }
602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin}
612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
62d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter()
63d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
64d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header.
66115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
67115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  unsigned NumberOfSections) {
683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ELF Header
693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----------
703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Note
723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // ----
733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // emitWord method behaves differently for ELF32 and ELF64, writing
743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // 4 bytes in the former and 8 in the latter.
753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0x7f); // e_ident[EI_MAG0]
773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('E');  // e_ident[EI_MAG1]
783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('L');  // e_ident[EI_MAG2]
793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8('F');  // e_ident[EI_MAG3]
803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
81bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ident[EI_DATA]
84115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
875baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  // e_ident[EI_OSABI]
88bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  switch (TargetObjectWriter->getOSType()) {
895baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::FreeBSD:  Write8(ELF::ELFOSABI_FREEBSD); break;
905baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    case Triple::Linux:    Write8(ELF::ELFOSABI_LINUX); break;
915baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky    default:               Write8(ELF::ELFOSABI_NONE); break;
925baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky  }
933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write8(0);                  // e_ident[EI_ABIVERSION]
943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(ELF::ET_REL);             // e_type
983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
99bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(ELF::EV_CURRENT);         // e_version
1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_entry, no entry point in .o file
1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(0);                    // e_phoff, no program header for .o
104bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
105eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1072d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  // e_flags = whatever the target wants
1082d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  WriteEFlags();
1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_ehsize = ELF header size
111bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phentsize = prog header entry size
1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write16(0);                  // e_phnum = # prog header entries = 0
1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shentsize = Section header entry size
117bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shnum     = # of section header ents
1207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
1217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(0);
1227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
1237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(NumberOfSections);
1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // e_shstrndx  = Section # of '.shstrtab'
1267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NumberOfSections >= ELF::SHN_LORESERVE)
1277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ELF::SHN_XINDEX);
1287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  else
1297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Write16(ShstrtabIndex);
1303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
132115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
133115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
134115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t name,
135115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint8_t info, uint64_t value,
136115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t size, uint8_t other,
137115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t shndx,
138115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       bool Reserved) {
1397be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (ShndxF) {
1407be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
141af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, shndx);
1427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    else
143af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*ShndxF, 0);
1447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
1457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
146af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
147af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    uint16_t(ELF::SHN_XINDEX) : shndx;
1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
149bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
150af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
151af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
152af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
153af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
154af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, value); // st_value
155af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String64(*SymtabF, size);  // st_size
1563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  } else {
157af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, name);  // st_name
158af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, value); // st_value
159af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String32(*SymtabF, size);  // st_size
160af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, info);   // st_info
161af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String8(*SymtabF, other);  // st_other
162af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola    String16(*SymtabF, Index); // st_shndx
1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
1643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
1672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                      const MCAsmLayout &Layout) {
1682c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (Data.isCommon() && Data.isExternal())
1692c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return Data.getCommonAlignment();
1702c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
1712c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
172d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
173d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  if (Symbol.isAbsolute() && Symbol.isVariable()) {
174d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    if (const MCExpr *Value = Symbol.getVariableValue()) {
175d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      int64_t IntValue;
176d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky      if (Value->EvaluateAsAbsolute(IntValue, Layout))
177d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky	return (uint64_t)IntValue;
178d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky    }
179d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky  }
180d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky
1812c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  if (!Symbol.isInSection())
1822c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola    return 0;
1832c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
184ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola  if (Data.getFragment())
185ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola    return Layout.getSymbolOffset(&Data);
1862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
1872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  return 0;
1882c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola}
1892c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola
19085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
19185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola                                               const MCAsmLayout &Layout) {
19288182132470527e27231f09b25a885893e528c66Rafael Espindola  // The presence of symbol versions causes undefined symbols and
19388182132470527e27231f09b25a885893e528c66Rafael Espindola  // versions declared with @@@ to be renamed.
19488182132470527e27231f09b25a885893e528c66Rafael Espindola
19588182132470527e27231f09b25a885893e528c66Rafael Espindola  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
19688182132470527e27231f09b25a885893e528c66Rafael Espindola         ie = Asm.symbol_end(); it != ie; ++it) {
19788182132470527e27231f09b25a885893e528c66Rafael Espindola    const MCSymbol &Alias = it->getSymbol();
19894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &Symbol = Alias.AliasedSymbol();
199f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    MCSymbolData &SD = Asm.getSymbolData(Symbol);
200f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
201f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Not an alias.
202f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    if (&Symbol == &Alias)
203f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola      continue;
204f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
20507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef AliasName = Alias.getName();
20688182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = AliasName.find('@');
20788182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos == StringRef::npos)
20888182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
20988182132470527e27231f09b25a885893e528c66Rafael Espindola
210f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // Aliases defined with .symvar copy the binding from the symbol they alias.
211f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    // This is the first place we are able to copy this information.
212f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola    it->setExternal(SD.isExternal());
2132ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(*it, MCELF::GetBinding(SD));
214f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola
21507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    StringRef Rest = AliasName.substr(Pos);
21688182132470527e27231f09b25a885893e528c66Rafael Espindola    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
21788182132470527e27231f09b25a885893e528c66Rafael Espindola      continue;
21888182132470527e27231f09b25a885893e528c66Rafael Espindola
21983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    // FIXME: produce a better error message.
22083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola    if (Symbol.isUndefined() && Rest.startswith("@@") &&
22183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola        !Rest.startswith("@@@"))
22283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola      report_fatal_error("A @@ version cannot be undefined");
22383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola
22407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer    Renames.insert(std::make_pair(&Symbol, &Alias));
22588182132470527e27231f09b25a885893e528c66Rafael Espindola  }
22688182132470527e27231f09b25a885893e528c66Rafael Espindola}
22788182132470527e27231f09b25a885893e528c66Rafael Espindola
228115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
229115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  MCDataFragment *ShndxF,
230115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  ELFSymbolData &MSD,
231115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
232de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &OrigData = *MSD.SymbolData;
233de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola  MCSymbolData &Data =
23494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
235152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
2367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
2377be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Data.getSymbol().isVariable();
2387be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
2392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Binding = MCELF::GetBinding(OrigData);
2402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Visibility = MCELF::GetVisibility(OrigData);
2412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  uint8_t Type = MCELF::GetType(Data);
242152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
243152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
244152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola  uint8_t Other = Visibility;
245152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola
2462c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola  uint64_t Value = SymbolValue(Data, Layout);
2473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Size = 0;
2483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
249f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola  assert(!(Data.isCommon() && !Data.isExternal()));
250f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola
251f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  const MCExpr *ESize = Data.getSize();
252f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola  if (ESize) {
253f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    int64_t Res;
254f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    if (!ESize->EvaluateAsAbsolute(Res, Layout))
255f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola      report_fatal_error("Size expression must be absolute.");
256f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola    Size = Res;
2573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write out the symbol table entry
2607be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
2617be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                   Size, Other, MSD.SectionIndex, IsReserved);
2623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
2633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
264115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
265115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       MCDataFragment *ShndxF,
266115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAssembler &Asm,
267115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       const MCAsmLayout &Layout,
2684beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                                     const SectionIndexMapTy &SectionIndexMap) {
2693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The string table must be emitted first because we need the index
2703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // into the string table for all the symbol names.
2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  assert(StringTable.size() && "Missing string table");
2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // FIXME: Make sure the start of the symbol table is aligned.
2743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry is the undefined symbol entry.
2767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
2773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Write the symbol table entries.
2793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = LocalSymbolData[i];
2827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
2833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
28571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Write out a symbol table entry for each regular section.
2864beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
2874beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola       ++i) {
288a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    const MCSectionELF &Section =
2894beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola      static_cast<const MCSectionELF&>(i->getSection());
2904beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola    if (Section.getType() == ELF::SHT_RELA ||
2914beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_REL ||
2924beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_STRTAB ||
2934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola        Section.getType() == ELF::SHT_SYMTAB)
294a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman      continue;
2957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
2964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false);
297a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman    LastLocalSymbolIndex++;
298a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman  }
2993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
3013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = ExternalSymbolData[i];
3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
3033223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola    assert(((Data.getFlags() & ELF_STB_Global) ||
3043223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola            (Data.getFlags() & ELF_STB_Weak)) &&
3053223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola           "External symbol requires STB_GLOBAL or STB_WEAK flag");
3067be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
3072ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData &MSD = UndefinedSymbolData[i];
3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSymbolData &Data = *MSD.SymbolData;
3147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
3152ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      LastLocalSymbolIndex++;
3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
3201f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
3211f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCValue &Target,
3221f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola                                               const MCFragment &F) const {
3231f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
32494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
32594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol *Renamed = Renames.lookup(&Symbol);
32694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
32794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola
32894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (ASymbol.isUndefined()) {
32994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
33094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
33194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &ASymbol;
3321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
3331f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola
33494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  if (SD.isExternal()) {
33594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
33694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
33794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
33894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
3397eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
3407eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola  const MCSectionELF &Section =
34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    static_cast<const MCSectionELF&>(ASymbol.getSection());
34225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  const SectionKind secKind = Section.getKind();
3437eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
34425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isBSS())
345953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    return ExplicitRelSym(Asm, Target, F, true);
3467eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola
34725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  if (secKind.isThreadLocal()) {
34825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    if (Renamed)
34925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola      return Renamed;
35025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola    return &Symbol;
35125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola  }
35225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola
3538cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
3543729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola  const MCSectionELF &Sec2 =
3553729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola    static_cast<const MCSectionELF&>(F.getParent()->getSection());
3563729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
3578cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola  if (&Sec2 != &Section &&
358c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola      (Kind == MCSymbolRefExpr::VK_PLT ||
359c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
36025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
36194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
36294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
36394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
36494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  }
3653729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola
3661c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola  if (Section.getFlags() & ELF::SHF_MERGE) {
36794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Target.getConstant() == 0)
36894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return NULL;
36994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    if (Renamed)
37094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola      return Renamed;
37194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    return &Symbol;
3721f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola  }
373c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola
374953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  return ExplicitRelSym(Asm, Target, F, false);
37573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola}
37673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola
3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
37856a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
37956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCAsmLayout &Layout,
38056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFragment *Fragment,
38156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       const MCFixup &Fixup,
38256a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       MCValue Target,
38356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                       uint64_t &FixedValue) {
38456a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Addend = 0;
38556a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int Index = 0;
38656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  int64_t Value = Target.getConstant();
38756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  const MCSymbol *RelocSymbol = NULL;
38856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
389127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
39056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  if (!Target.isAbsolute()) {
39156a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
39256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
39356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim
39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      const MCSymbol &SymbolB = RefB->getSymbol();
39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim      IsPCRel = true;
39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim
40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t a = Layout.getSymbolOffset(&SDB);
40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
40356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Ofeset of the relocation in the section
40456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
40556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += b - a;
40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
40756a399023aba6cf1348533df04732950c43eaca7Jason W Kim
40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim    if (!RelocSymbol) {
40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim      MCFragment *F = SD.getFragment();
41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim
41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = F->getParent()->getOrdinal() + 1;
41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim
41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim      // Offset of the symbol in the section
41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value += Layout.getSymbolOffset(&SD);
41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim    } else {
41756a399023aba6cf1348533df04732950c43eaca7Jason W Kim      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim        WeakrefUsedInReloc.insert(RelocSymbol);
41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim      else
42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim        UsedInReloc.insert(RelocSymbol);
42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Index = -1;
42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim    }
42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Addend = Value;
42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    // Compensate for the addend on i386.
425bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit())
42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Value = 0;
42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim  }
42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim
42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  FixedValue = Value;
43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                               (RelocSymbol != 0), Addend);
4322ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin
43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim    Fixup.getOffset();
43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim
436bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (!hasRelocationAddend())
437bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    Addend = 0;
43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
43956a399023aba6cf1348533df04732950c43eaca7Jason W Kim  Relocations[Fragment->getParent()].push_back(ERE);
44056a399023aba6cf1348533df04732950c43eaca7Jason W Kim}
44156a399023aba6cf1348533df04732950c43eaca7Jason W Kim
44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim
4430b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t
444115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
445115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             const MCSymbol *S) {
4467b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer  MCSymbolData &SD = Asm.getSymbolData(*S);
447ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  return SD.getIndex();
4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
4502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
4512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 const MCSymbolData &Data,
4522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                 bool Used, bool Renamed) {
453484291c27319668ad99cb87def000254357736fbRafael Espindola  if (Data.getFlags() & ELF_Other_Weakref)
454484291c27319668ad99cb87def000254357736fbRafael Espindola    return false;
455484291c27319668ad99cb87def000254357736fbRafael Espindola
456bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Used)
457bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola    return true;
458bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola
45988182132470527e27231f09b25a885893e528c66Rafael Espindola  if (Renamed)
46088182132470527e27231f09b25a885893e528c66Rafael Espindola    return false;
46188182132470527e27231f09b25a885893e528c66Rafael Espindola
462737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
463a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
464d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
465d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola    return true;
466d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola
46794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &A = Symbol.AliasedSymbol();
46821451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
46921451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola    return false;
47021451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola
4712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin  bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
47221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola  if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
473a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    return false;
474a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola
475737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
476737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
477737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
478bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola  if (Symbol.isTemporary())
479737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
480737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
481737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
482737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
483737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
4842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
4852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                              bool isUsedInReloc) {
486737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  if (Data.isExternal())
487737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
488737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
489737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  const MCSymbol &Symbol = Data.getSymbol();
49094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
4911f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
4921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
4931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (isSignature && !isUsedInReloc)
4941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      return true;
4951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
496737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola    return false;
4971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  }
498737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
499737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola  return true;
500737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola}
501737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola
502115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
5037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      SectionIndexMapTy &SectionIndexMap,
5047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const RelMapTy &RelMap) {
505bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  unsigned Index = 1;
506bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
507bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
508bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    const MCSectionELF &Section =
509bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
5102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
5112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
5122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionIndexMap[&Section] = Index++;
5132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
5142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
5152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
5162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola         ie = Asm.end(); it != ie; ++it) {
5172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
5182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
5197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP ||
5207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_REL ||
5217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
5222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
523bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola    SectionIndexMap[&Section] = Index++;
5247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelSection = RelMap.lookup(&Section);
5257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (RelSection)
5267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      SectionIndexMap[RelSection] = Index++;
527bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  }
528bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola}
529bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
530115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
5311f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
5327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         RevGroupMapTy RevGroupMap,
5337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         unsigned NumRegularSections) {
5345c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  // FIXME: Is this the correct place to do this?
5355c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  if (NeedsGOT) {
5365c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
5375c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
5385c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
5395c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola    Data.setExternal(true);
5402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    MCELF::SetBinding(Data, ELF::STB_GLOBAL);
5415c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola  }
5425c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola
5433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Index 0 is always the empty string.
5443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringMap<uint64_t> StringIndexMap;
5453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StringTable += '\x00';
5463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
547a0949b50dcea35c08b50542091f97275f401529dRafael Espindola  // Add the data for the symbols.
5483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
5493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.symbol_end(); it != ie; ++it) {
5503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSymbol &Symbol = it->getSymbol();
5513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
552484291c27319668ad99cb87def000254357736fbRafael Espindola    bool Used = UsedInReloc.count(&Symbol);
553484291c27319668ad99cb87def000254357736fbRafael Espindola    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
5541f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool isSignature = RevGroupMap.count(&Symbol);
5551f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
5561f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    if (!isInSymtab(Asm, *it,
5571f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola                    Used || WeakrefUsed || isSignature,
55888182132470527e27231f09b25a885893e528c66Rafael Espindola                    Renames.count(&Symbol)))
5593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      continue;
5603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFSymbolData MSD;
5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MSD.SymbolData = it;
56394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
5651f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // Undefined symbols are global, but this is the first place we
5661f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    // are able to set it.
5671f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    bool Local = isLocal(*it, isSignature, Used);
5682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin    if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
5691f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
5702ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_GLOBAL);
5712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(SD, ELF::STB_GLOBAL);
5721f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    }
5731f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola
574484291c27319668ad99cb87def000254357736fbRafael Espindola    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
5752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin      MCELF::SetBinding(*it, ELF::STB_WEAK);
576484291c27319668ad99cb87def000254357736fbRafael Espindola
577f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola    if (it->isCommon()) {
578a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      assert(!Local);
579f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola      MSD.SectionIndex = ELF::SHN_COMMON;
580bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
581a0949b50dcea35c08b50542091f97275f401529dRafael Espindola      MSD.SectionIndex = ELF::SHN_ABS;
58288182132470527e27231f09b25a885893e528c66Rafael Espindola    } else if (RefSymbol.isUndefined()) {
5831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      if (isSignature && !Used)
5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
5851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola      else
5861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola        MSD.SectionIndex = ELF::SHN_UNDEF;
5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    } else {
588bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      const MCSectionELF &Section =
589bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola        static_cast<const MCSectionELF&>(RefSymbol.getSection());
590bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
5917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
5927be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola        NeedsSymtabShndx = true;
5933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      assert(MSD.SectionIndex && "Invalid section index!");
5945df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola    }
5955df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola
59688182132470527e27231f09b25a885893e528c66Rafael Espindola    // The @@@ in symbol version is replaced with @ in undefined symbols and
59788182132470527e27231f09b25a885893e528c66Rafael Espindola    // @@ in defined ones.
59888182132470527e27231f09b25a885893e528c66Rafael Espindola    StringRef Name = Symbol.getName();
5991261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    SmallString<32> Buf;
6001261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer
60188182132470527e27231f09b25a885893e528c66Rafael Espindola    size_t Pos = Name.find("@@@");
60288182132470527e27231f09b25a885893e528c66Rafael Espindola    if (Pos != StringRef::npos) {
6031261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(0, Pos);
6041261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
6051261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Buf += Name.substr(Pos + Skip);
6061261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      Name = Buf;
60788182132470527e27231f09b25a885893e528c66Rafael Espindola    }
60888182132470527e27231f09b25a885893e528c66Rafael Espindola
6091261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer    uint64_t &Entry = StringIndexMap[Name];
610a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (!Entry) {
611a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      Entry = StringTable.size();
6121261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer      StringTable += Name;
613a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      StringTable += '\x00';
6143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    }
615a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    MSD.StringIndex = Entry;
616a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    if (MSD.SectionIndex == ELF::SHN_UNDEF)
617a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      UndefinedSymbolData.push_back(MSD);
618a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else if (Local)
619a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      LocalSymbolData.push_back(MSD);
620a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola    else
621a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola      ExternalSymbolData.push_back(MSD);
6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Symbols are required to be in lexicographic order.
6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Set the symbol indices. Local symbols must come before all other
6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // symbols with non-local bindings.
631ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  unsigned Index = 1;
6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    LocalSymbolData[i].SymbolData->setIndex(Index++);
634ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
635ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola  Index += NumRegularSections;
636ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola
6373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
6383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ExternalSymbolData[i].SymbolData->setIndex(Index++);
6393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
6403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
6447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               MCAsmLayout &Layout,
6457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                               RelMapTy &RelMap) {
6467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
6477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
6487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
6497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Relocations[&SD].empty())
6507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
6517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCContext &Ctx = Asm.getContext();
6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming      static_cast<const MCSectionELF&>(SD.getSection());
6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const StringRef SectionName = Section.getSectionName();
657bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    RelaSectionName += SectionName;
659299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer
660299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    unsigned EntrySize;
661bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (hasRelocationAddend())
662bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
663299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer    else
664bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
6653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection =
6677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
6687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        ELF::SHT_RELA : ELF::SHT_REL, 0,
6697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        SectionKind::getReadOnly(),
6707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        EntrySize, "");
6717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    RelMap[&Section] = RelaSection;
6727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Asm.getOrCreateSectionData(*RelaSection);
6737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
6747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
6757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                       const RelMapTy &RelMap) {
6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(),
6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = *it;
6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF&>(SD.getSection());
6833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF *RelaSection = RelMap.lookup(&Section);
6857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (!RelaSection)
6867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      continue;
6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
688bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    RelaSD.setAlignment(is64Bit() ? 8 : 4);
6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
6903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    MCDataFragment *F = new MCDataFragment(&RelaSD);
6917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteRelocationsFragment(Asm, F, &*it);
6923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
6933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
6943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
695115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
696115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Flags, uint64_t Address,
697115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Offset, uint64_t Size,
698115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint32_t Link, uint32_t Info,
699115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t Alignment,
700115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                       uint64_t EntrySize) {
7013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Name);        // sh_name: index into string table
7023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Type);        // sh_type
7033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Flags);     // sh_flags
7043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Address);   // sh_addr
7053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Offset);    // sh_offset
7063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Size);      // sh_size
7073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Link);        // sh_link
7083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  Write32(Info);        // sh_info
7093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(Alignment); // sh_addralign
7103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  WriteWord(EntrySize); // sh_entsize
7113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
713115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
714115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               MCDataFragment *F,
715115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                               const MCSectionData *SD) {
7163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
7173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // sort by the r_offset just like gnu as does
7183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  array_pod_sort(Relocs.begin(), Relocs.end());
7193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
7213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    ELFRelocationEntry entry = Relocs[e - i - 1];
7223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
72312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    if (!entry.Index)
72412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      ;
72512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    else if (entry.Index < 0)
7268f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
7278f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola    else
72812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola      entry.Index += LocalSymbolData.size();
729bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola    if (is64Bit()) {
730af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, entry.r_offset);
7315e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
7328f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf64_Rela ERE64;
7338f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE64.setSymbolAndType(entry.Index, entry.Type);
734af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String64(*F, ERE64.r_info);
7355e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
736bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
737af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String64(*F, entry.r_addend);
7385e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    } else {
739af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, entry.r_offset);
7405e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
7418f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      struct ELF::Elf32_Rela ERE32;
7428f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola      ERE32.setSymbolAndType(entry.Index, entry.Type);
743af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola      String32(*F, ERE32.r_info);
7445e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer
745bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      if (hasRelocationAddend())
746af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola        String32(*F, entry.r_addend);
7475e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer    }
7483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
7503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
751115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
752115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             MCAsmLayout &Layout,
7537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             SectionIndexMapTy &SectionIndexMap,
7547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                             const RelMapTy &RelMap) {
7553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCContext &Ctx = Asm.getContext();
7563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCDataFragment *F;
7573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
758bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
7593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
76038738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
7614283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *ShstrtabSection =
7627be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
7633f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                      SectionKind::getReadOnly());
76471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
76571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  ShstrtabSD.setAlignment(1);
76671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
7674283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola  const MCSectionELF *SymtabSection =
7687be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
7697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola                      SectionKind::getReadOnly(),
7702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                      EntrySize, "");
7713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
772bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
7737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
7747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCSectionData *SymtabShndxSD = NULL;
7757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola
7767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
7774283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola    const MCSectionELF *SymtabShndxSection =
7787be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
7792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                        SectionKind::getReadOnly(), 4, "");
7807be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
7817be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    SymtabShndxSD->setAlignment(4);
7827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
7833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionELF *StrtabSection;
7853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
7863f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                    SectionKind::getReadOnly());
7873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
7883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  StrtabSD.setAlignment(1);
7893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
7907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
7917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
7927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
7937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
7947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  StringTableIndex = SectionIndexMap.lookup(StrtabSection);
79571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
79671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  // Symbol table
79771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola  F = new MCDataFragment(&SymtabSD);
7987be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  MCDataFragment *ShndxF = NULL;
7997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  if (NeedsSymtabShndx) {
8007be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola    ShndxF = new MCDataFragment(SymtabShndxSD);
8017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola  }
8024beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
80371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola
8043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&StrtabSD);
8053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents().append(StringTable.begin(), StringTable.end());
8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F = new MCDataFragment(&ShstrtabSD);
8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // Section header string table.
8103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  //
8113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // The first entry of a string table holds a null character so skip
8123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  // section 0.
8133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  uint64_t Index = 1;
8143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  F->getContents() += '\x00';
8153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  StringMap<uint64_t> SecStringMap;
8173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  for (MCAssembler::const_iterator it = Asm.begin(),
8183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming         ie = Asm.end(); it != ie; ++it) {
8193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    const MCSectionELF &Section =
820368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer      static_cast<const MCSectionELF&>(it->getSection());
82151efe7a253190b672519e8388ce5d45f1dcf1a24Rafael Espindola    // FIXME: We could merge suffixes like in .text and .rela.text.
8223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    StringRef Name = Section.getSectionName();
8242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (SecStringMap.count(Name)) {
8252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      SectionStringTableIndex[&Section] =  SecStringMap[Name];
8262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
8283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the index into the string table so we can write it
8293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // into the sh_name field of the section header table.
8302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionStringTableIndex[&Section] = Index;
8312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SecStringMap[Name] = Index;
8323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
8332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Index += Name.size() + 1;
8342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    F->getContents() += Name;
8353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    F->getContents() += '\x00';
8363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
8377070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola}
8387070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola
83996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
84096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            MCAsmLayout &Layout,
84196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                                            GroupMapTy &GroupMap,
8427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            RevGroupMapTy &RevGroupMap,
8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            SectionIndexMapTy &SectionIndexMap,
8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                            const RelMapTy &RelMap) {
84596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  // Create the .note.GNU-stack section if needed.
84696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  MCContext &Ctx = Asm.getContext();
84796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  if (Asm.getNoExecStack()) {
84896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    const MCSectionELF *GnuStackSection =
84996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
85096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola                        SectionKind::getReadOnly());
85196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola    Asm.getOrCreateSectionData(*GnuStackSection);
85296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola  }
85396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola
8542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Build the groups
8552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
8562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola       it != ie; ++it) {
8572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
8591c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
8602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSymbol *SignatureSymbol = Section.getGroup();
8632ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    Asm.getOrCreateSymbolData(*SignatureSymbol);
8641f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
8652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    if (!Group) {
86696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola      Group = Ctx.CreateELFGroupSection();
8672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
8682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      Data.setAlignment(4);
8692ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      MCDataFragment *F = new MCDataFragment(&Data);
8702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      String32(*F, ELF::GRP_COMDAT);
8712ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    }
8722ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupMap[Group] = SignatureSymbol;
8732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8742ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
8757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
8767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
8772ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  // Add sections to the groups
8782ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
8797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola       it != ie; ++it) {
8802ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section =
8812ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      static_cast<const MCSectionELF&>(it->getSection());
8821c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola    if (!(Section.getFlags() & ELF::SHF_GROUP))
8832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola      continue;
8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
8852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    // FIXME: we could use the previous fragment
8872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    MCDataFragment *F = new MCDataFragment(&Data);
8887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    unsigned Index = SectionIndexMap.lookup(&Section);
8897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    String32(*F, Index);
8902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
8912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
8922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
893115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
894115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const SectionIndexMapTy &SectionIndexMap,
895115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint32_t GroupSymbolIndex,
896115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Offset, uint64_t Size,
897115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   uint64_t Alignment,
898115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                   const MCSectionELF &Section) {
899c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_link = 0;
900c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  uint64_t sh_info = 0;
901c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
902c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  switch(Section.getType()) {
903c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNAMIC:
904c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionStringTableIndex[&Section];
905c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = 0;
906c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
907c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
908c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_REL:
909c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_RELA: {
910c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *SymtabSection;
911c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    const MCSectionELF *InfoSection;
912c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
913c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                   0,
9143f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                   SectionKind::getReadOnly());
915c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SectionIndexMap.lookup(SymtabSection);
916c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(sh_link && ".symtab not found");
917c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
918c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Remove ".rel" and ".rela" prefixes.
919c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
920c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
921c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
922c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    InfoSection = Asm.getContext().getELFSection(SectionName,
923c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                                                 ELF::SHT_PROGBITS, 0,
9243f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola                                                 SectionKind::getReadOnly());
925c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = SectionIndexMap.lookup(InfoSection);
926c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
927c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
928c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
929c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB:
930c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_DYNSYM:
931c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = StringTableIndex;
932c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_info = LastLocalSymbolIndex;
933c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
934c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
935c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_SYMTAB_SHNDX:
936c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    sh_link = SymbolTableIndex;
937c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
938c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
939c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_PROGBITS:
940c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_STRTAB:
941c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NOBITS:
94298976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola  case ELF::SHT_NOTE:
943c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_NULL:
944c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  case ELF::SHT_ARM_ATTRIBUTES:
94586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_INIT_ARRAY:
94686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_FINI_ARRAY:
94786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case ELF::SHT_PREINIT_ARRAY:
9480cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola  case ELF::SHT_X86_64_UNWIND:
949c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    // Nothing to do.
950c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
951c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
9522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  case ELF::SHT_GROUP: {
9532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_link = SymbolTableIndex;
9542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    sh_info = GroupSymbolIndex;
9552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    break;
9562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  }
9572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  default:
959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    assert(0 && "FIXME: sh_type value not supported!");
960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola    break;
961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  }
962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola                   Alignment, Section.getEntrySize());
966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola}
967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola
9682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
969f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola  return SD.getOrdinal() == ~UINT32_C(0) &&
9706db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    !SD.getSection().isVirtualSection();
9716db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
9726db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
9732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) {
9746db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  uint64_t Ret = 0;
9756db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
9766db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola       ++i) {
9776db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    const MCFragment &F = *i;
9786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    assert(F.getKind() == MCFragment::FT_Data);
9796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    Ret += cast<MCDataFragment>(F).getContents().size();
9806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
9816db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Ret;
9826db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
9836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
9842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout,
9852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                             const MCSectionData &SD) {
9866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
9876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
9886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  return Layout.getSectionFileSize(&SD);
9896db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
9906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
9912ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
9922ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin                                                const MCSectionData &SD) {
9936db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  if (IsELFMetaDataSection(SD))
9946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    return DataSectionSize(SD);
99585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  return Layout.getSectionAddressSize(&SD);
9966db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
9976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
9987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
9997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCAsmLayout &Layout,
10007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                           const MCSectionELF &Section) {
10017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FileOff = OS.tell();
10027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
10037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
10057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteZeros(Padding);
10067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += Padding;
10077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += GetSectionFileSize(Layout, SD);
10097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  if (IsELFMetaDataSection(SD)) {
10117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ++i) {
10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      const MCFragment &F = *i;
10147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      assert(F.getKind() == MCFragment::FT_Data);
10157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      WriteBytes(cast<MCDataFragment>(F).getContents().str());
10167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    }
10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  } else {
10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Asm.WriteSectionData(&SD, Layout);
10197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
10217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const GroupMapTy &GroupMap,
10247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                         const MCAsmLayout &Layout,
10257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                      const SectionIndexMapTy &SectionIndexMap,
10267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                   const SectionOffsetMapTy &SectionOffsetMap) {
10277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumSections = Asm.size() + 1;
10287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  std::vector<const MCSectionELF*> Sections;
10307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  Sections.resize(NumSections - 1);
10317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (SectionIndexMapTy::const_iterator i=
10337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
10347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
10357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    Sections[p.second - 1] = p.first;
10367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Null section first.
10397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t FirstSectionSize =
10407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
10417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint32_t FirstSectionLink =
10427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
10437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
10447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumSections - 1; ++i) {
10467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section = *Sections[i];
10477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
10487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint32_t GroupSymbolIndex;
10497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP)
10507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = 0;
10517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    else
10527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
10537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                                     GroupMap.lookup(&Section));
10547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    uint64_t Size = GetSectionAddressSize(Layout, SD);
10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SectionOffsetMap.lookup(&Section), Size,
10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                 SD.getAlignment(), Section);
10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola}
10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                                  std::vector<const MCSectionELF*> &Sections) {
10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_GROUP)
10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
10757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() != ELF::SHT_GROUP &&
10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_REL &&
10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() != ELF::SHT_RELA)
10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  }
10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (MCAssembler::iterator it = Asm.begin(),
10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola         ie = Asm.end(); it != ie; ++it) {
10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    const MCSectionELF &Section =
10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      static_cast<const MCSectionELF &>(it->getSection());
10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    if (Section.getType() == ELF::SHT_REL ||
10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola        Section.getType() == ELF::SHT_RELA)
10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola      Sections.push_back(&Section);
10906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola  }
10916db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola}
10926db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
1093115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
1094115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                  const MCAsmLayout &Layout) {
10952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  GroupMapTy GroupMap;
10961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola  RevGroupMapTy RevGroupMap;
1097bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola  SectionIndexMapTy SectionIndexMap;
1098bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumUserSections = Asm.size();
11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumUserAndRelocSections = Asm.size();
11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                        RevGroupMap, SectionIndexMap, RelMap);
11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned AllSections = Asm.size();
11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumRegularSections = NumUserSections + NumIndexedSections;
1111bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola
11128f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola  // Compute symbol table information.
11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
11178f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola
11183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
11194beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola                         const_cast<MCAsmLayout&>(Layout),
11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         SectionIndexMap,
11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                         RelMap);
11221d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola
1123bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1124bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
1125bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                    sizeof(ELF::Elf32_Ehdr);
1126a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t FileOff = HeaderSize;
11273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  std::vector<const MCSectionELF*> Sections;
11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  ComputeSectionOrder(Asm, Sections);
11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  unsigned NumSections = Sections.size();
11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  SectionOffsetMapTy SectionOffsetMap;
11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
11332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
11342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
11353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1136a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1137a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Remember the offset into the file for this section.
11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    SectionOffsetMap[&Section] = FileOff;
11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Get the size of the section in the output file (including padding).
11426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
11433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
11443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
1145a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
1146a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  const unsigned SectionHeaderOffset = FileOff - HeaderSize;
11483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  uint64_t SectionHeaderEntrySize = is64Bit() ?
11507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
11517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff += (NumSections + 1) * SectionHeaderEntrySize;
11523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
11542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionELF &Section = *Sections[i];
11552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
1156a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
1158a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming    // Remember the offset into the file for this section.
11602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    SectionOffsetMap[&Section] = FileOff;
116144cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer
11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    // Get the size of the section in the output file (including padding).
11636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola    FileOff += GetSectionFileSize(Layout, SD);
11643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming  }
11653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // Write out the ELF header ...
11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteHeader(SectionHeaderOffset, NumSections + 1);
11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the regular sections ...
11707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // + because of .shstrtab
11717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = 0; i < NumRegularSections + 1; ++i)
11727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
11737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola
11747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff = OS.tell();
1175a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
1176a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer  WriteZeros(Padding);
1177a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer
11787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... then the section header table ...
11797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
11807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola                     SectionOffsetMap);
11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
11827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  FileOff = OS.tell();
11836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola
11847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  // ... and then the remainting sections ...
11857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
11867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola    WriteDataSectionData(Asm, Layout, *Sections[i]);
11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
11883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming
118978c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool
119078c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
119178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCSymbolData &DataA,
119278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      const MCFragment &FB,
119378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool InSet,
119478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                      bool IsPCRel) const {
119578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  if (DataA.getFlags() & ELF_STB_Weak)
119678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman    return false;
119778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
119878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman                                                 Asm, DataA, FB,InSet, IsPCRel);
119978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman}
120078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman
12016024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
12026024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola                                            raw_ostream &OS,
1203bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                            bool IsLittleEndian) {
1204bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  switch (MOTW->getEMachine()) {
1205d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_386:
1206d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_X86_64:
1207bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
1208d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    case ELF::EM_ARM:
1209bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
12104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case ELF::EM_MBLAZE:
1211bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola      return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
12123285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer    default: llvm_unreachable("Unsupported architecture"); break;
1213d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1214d3443e99e43945fdb0742177da06a32fa225740dJason W Kim}
1215d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1216d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1217d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter
1218d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===//
1219d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
122031f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1221bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1222bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1223bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1224d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1225d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1226d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter()
1227d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1228d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
12292d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple.
12302d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() {
12312d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim  Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
12322d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim}
12332d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim
1234953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly.
1235953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol.
1236953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// This code is a first-cut approximation of what ARM/gcc does.
1237953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1238953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
1239953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim                                                   const MCValue &Target,
1240953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim                                                   const MCFragment &F,
1241953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim                                                   bool IsBSS) const {
1242953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
1243953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  bool EmitThisSym = false;
1244953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1245953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  if (IsBSS) {
1246953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    EmitThisSym = StringSwitch<bool>(Symbol.getName())
1247953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim      .Case("_MergedGlobals", true)
1248953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim      .Default(false);
1249953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  } else {
1250953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    EmitThisSym = StringSwitch<bool>(Symbol.getName())
1251953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim      .Case("_MergedGlobals", true)
1252953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim      .StartsWith(".L.str", true)
1253953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim      .Default(false);
1254953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  }
1255953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  if (EmitThisSym)
1256953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    return &Symbol;
1257953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  if (! Symbol.isTemporary())
1258953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim    return &Symbol;
1259953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim  return NULL;
1260953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim}
1261953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
126285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
126385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim                                          const MCFixup &Fixup,
126456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
126556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
126656a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          int64_t Addend) {
126785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
126885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
126985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
1270a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  unsigned Type = 0;
127185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (IsPCRel) {
127285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
127385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: assert(0 && "Unimplemented");
12743fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim    case FK_Data_4:
12753fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
12763fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier");
12773fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_None:
12781d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_BASE_PREL;
12791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
12803fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
12811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        assert(0 && "unimplemented");
12821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
12833fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
12843fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim        Type = ELF::R_ARM_TLS_IE32;
12851d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
12861d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
12871d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1288685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_uncondbranch:
12893fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      switch (Modifier) {
12903fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_PLT:
12911d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_PLT32;
12921d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
12933fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default:
12941d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_CALL;
12951d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
12961d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
12971d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1298685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_condbranch:
1299685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      Type = ELF::R_ARM_JUMP24;
1300685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      break;
130186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movt_hi16:
130286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movt_hi16_pcrel:
13031d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVT_PREL;
13041d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
130586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movw_lo16:
130686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim    case ARM::fixup_arm_movw_lo16_pcrel:
13071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVW_PREL_NC;
13081d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1309f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16:
1310f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16_pcrel:
1311f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVT_PREL;
1312f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
1313f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16:
1314f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16_pcrel:
1315f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVW_PREL_NC;
1316f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
131785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
131885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  } else {
131985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    switch ((unsigned)Fixup.getKind()) {
132085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    default: llvm_unreachable("invalid fixup kind!");
1321a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim    case FK_Data_4:
1322a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      switch (Modifier) {
13233fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      default: llvm_unreachable("Unsupported Modifier"); break;
13243fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOT:
13251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_GOT_BREL;
13261d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
13273fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_TLSGD:
13281d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_GD32;
13291d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1330f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_ARM_TPOFF:
13311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_LE32;
13321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1333a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
13341d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_TLS_IE32;
13351d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
1336f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim      case MCSymbolRefExpr::VK_None:
13371d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_ABS32;
13381d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
13393fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim      case MCSymbolRefExpr::VK_ARM_GOTOFF:
13401d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        Type = ELF::R_ARM_GOTOFF32;
13411d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim        break;
13421d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      }
13431d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1344dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_ldst_pcrel_12:
13459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    case ARM::fixup_arm_pcrel_10:
1346dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    case ARM::fixup_arm_adr_pcrel_12:
1347662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach    case ARM::fixup_arm_thumb_bl:
1348b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach    case ARM::fixup_arm_thumb_cb:
1349b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling    case ARM::fixup_arm_thumb_cp:
1350e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach    case ARM::fixup_arm_thumb_br:
13511d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      assert(0 && "Unimplemented");
13521d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1353685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_uncondbranch:
13541d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_CALL;
13551d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1356685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    case ARM::fixup_arm_condbranch:
1357685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      Type = ELF::R_ARM_JUMP24;
1358685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      break;
13591d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim    case ARM::fixup_arm_movt_hi16:
13601d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVT_ABS;
13611d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
136285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    case ARM::fixup_arm_movw_lo16:
13631d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      Type = ELF::R_ARM_MOVW_ABS_NC;
13641d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim      break;
1365f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movt_hi16:
1366f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVT_ABS;
1367f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
1368f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng    case ARM::fixup_t2_movw_lo16:
1369f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      Type = ELF::R_ARM_THM_MOVW_ABS_NC;
1370f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      break;
137185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    }
137285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  }
137385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
137485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim  if (RelocNeedsGOT(Modifier))
137585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim    NeedsGOT = true;
1376953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim
1377a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim  return Type;
137885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim}
137985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim
13804b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===//
1381d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
138231f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1383bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             raw_ostream &_OS,
1384bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                             bool IsLittleEndian)
1385bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
13864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
13874b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
13884b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
13894b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
13904b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck
139156a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
13924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck                                             const MCFixup &Fixup,
139356a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsPCRel,
139456a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             bool IsRelocWithSymbol,
139556a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                             int64_t Addend) {
13964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  // determine the type of the relocation
13974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  unsigned Type;
13984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  if (IsPCRel) {
13994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
14004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default:
14014b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      llvm_unreachable("Unimplemented");
1402e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_4:
14034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_64_PCREL;
14044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
1405e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola    case FK_PCRel_2:
14064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32_PCREL;
14074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
14084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
14094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  } else {
14104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    switch ((unsigned)Fixup.getKind()) {
14114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    default: llvm_unreachable("invalid fixup kind!");
14124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_4:
141356a399023aba6cf1348533df04732950c43eaca7Jason W Kim      Type = ((IsRelocWithSymbol || Addend !=0)
141456a399023aba6cf1348533df04732950c43eaca7Jason W Kim              ? ELF::R_MICROBLAZE_32
141556a399023aba6cf1348533df04732950c43eaca7Jason W Kim              : ELF::R_MICROBLAZE_64);
14164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
14174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    case FK_Data_2:
14184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      Type = ELF::R_MICROBLAZE_32;
14194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck      break;
14204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck    }
14214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck  }
142256a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
14234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck}
1424d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1425d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===//
1426d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1427d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
142831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1429bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       raw_ostream &_OS,
1430bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola                                       bool IsLittleEndian)
1431bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
1432d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1433d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1434d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter()
1435d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{}
1436d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
143756a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
143856a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          const MCFixup &Fixup,
143956a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsPCRel,
144056a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          bool IsRelocWithSymbol,
144156a399023aba6cf1348533df04732950c43eaca7Jason W Kim                                          int64_t Addend) {
1442d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  // determine the type of the relocation
1443d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
144412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
144512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
1446d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  unsigned Type;
1447bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola  if (is64Bit()) {
1448d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
14493a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
14503a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
14513a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_8:
14523a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
14533a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC64;
1454d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
14557a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola      case X86::reloc_signed_4byte:
1456c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola      case X86::reloc_riprel_4byte_movq_load:
14573a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_Data_4: // FIXME?
14583a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case X86::reloc_riprel_4byte:
14593a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_4:
14603a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        switch (Modifier) {
14613a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        default:
14623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          llvm_unreachable("Unimplemented");
14633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_None:
14643a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PC32;
14653a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
14663a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
14673a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_PLT32;
14683a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
14693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTPCREL:
14703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTPCREL;
14713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
14723a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_GOTTPOFF:
14733a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_GOTTPOFF;
1474d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
14753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSGD:
14763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSGD;
14773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
14783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        case MCSymbolRefExpr::VK_TLSLD:
14793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          Type = ELF::R_X86_64_TLSLD;
14803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola          break;
14813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        }
1482d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
14833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola      case FK_PCRel_2:
14843a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
14853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola        Type = ELF::R_X86_64_PC16;
1486d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1487d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger      case FK_PCRel_1:
1488d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        assert(Modifier == MCSymbolRefExpr::VK_None);
1489d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        Type = ELF::R_X86_64_PC8;
1490d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger        break;
1491d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1492d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1493d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1494d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1495d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_8: Type = ELF::R_X86_64_64; break;
1496d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1497d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        assert(isInt<32>(Target.getConstant()));
1498d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1499d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1500d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1501d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1502d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_32S;
1503d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1504d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1505d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOT32;
1506d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1507d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTPCREL:
1508d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_GOTPCREL;
1509d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1510d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1511d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_TPOFF32;
1512d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1513d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1514d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_X86_64_DTPOFF32;
1515d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1516d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1517d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1518d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1519d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_X86_64_32;
1520d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1521d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_X86_64_16; break;
1522e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1523d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_X86_64_8; break;
1524d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1525d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1526d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  } else {
1527d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    if (IsPCRel) {
1528d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch (Modifier) {
1529d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default:
1530d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        llvm_unreachable("Unimplemented");
1531d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_None:
1532d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PC32;
1533d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1534d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case MCSymbolRefExpr::VK_PLT:
1535d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_PLT32;
1536d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1537d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1538d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    } else {
1539d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      switch ((unsigned)Fixup.getKind()) {
1540d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      default: llvm_unreachable("invalid fixup kind!");
1541d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1542d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_global_offset_table:
1543d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        Type = ELF::R_386_GOTPC;
1544d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1545d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1546d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1547d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      // instead?
1548d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case X86::reloc_signed_4byte:
1549e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_4:
1550d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_4:
1551d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        switch (Modifier) {
1552d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        default:
1553d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          llvm_unreachable("Unimplemented");
1554d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_None:
1555d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_32;
1556d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1557d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOT:
1558d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOT32;
1559d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1560d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTOFF:
1561d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_GOTOFF;
1562d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1563d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSGD:
1564d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GD;
1565d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1566d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TPOFF:
1567d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE_32;
1568d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1569d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_INDNTPOFF:
1570d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_IE;
1571d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1572d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_NTPOFF:
1573d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LE;
1574d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1575d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_GOTNTPOFF:
1576d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_GOTIE;
1577d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1578d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_TLSLDM:
1579d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDM;
1580d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1581d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        case MCSymbolRefExpr::VK_DTPOFF:
1582d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          Type = ELF::R_386_TLS_LDO_32;
1583d3443e99e43945fdb0742177da06a32fa225740dJason W Kim          break;
1584d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        }
1585d3443e99e43945fdb0742177da06a32fa225740dJason W Kim        break;
1586d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_2: Type = ELF::R_386_16; break;
1587e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola      case FK_PCRel_1:
1588d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      case FK_Data_1: Type = ELF::R_386_8; break;
1589d3443e99e43945fdb0742177da06a32fa225740dJason W Kim      }
1590d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    }
1591d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  }
1592d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
1593d3443e99e43945fdb0742177da06a32fa225740dJason W Kim  if (RelocNeedsGOT(Modifier))
1594d3443e99e43945fdb0742177da06a32fa225740dJason W Kim    NeedsGOT = true;
1595d3443e99e43945fdb0742177da06a32fa225740dJason W Kim
159656a399023aba6cf1348533df04732950c43eaca7Jason W Kim  return Type;
15973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming}
1598