119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file implements ELF object file writer information.
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ELFObjectWriter.h"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/STLExtras.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringMap.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Twine.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmBackend.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmLayout.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCContext.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCExpr.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSectionELF.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCValue.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ELF.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CommandLine.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringSwitch.h"
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h"
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <vector>
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#undef  DEBUG_TYPE
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "reloc-info"
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCFixupKindInfo &FKI =
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) {
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Variant) {
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_GOT:
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_PLT:
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_GOTPCREL:
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_GOTOFF:
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_TPOFF:
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_TLSGD:
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_GOTTPOFF:
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_INDNTPOFF:
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_NTPOFF:
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_GOTNTPOFF:
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_TLSLDM:
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_DTPOFF:
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSymbolRefExpr::VK_TLSLD:
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanELFObjectWriter::~ELFObjectWriter()
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{}
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Emit the ELF header.
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  unsigned NumberOfSections) {
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ELF Header
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ----------
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  //
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Note
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ----
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // emitWord method behaves differently for ELF32 and ELF64, writing
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // 4 bytes in the former and 8 in the latter.
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8(0x7f); // e_ident[EI_MAG0]
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8('E');  // e_ident[EI_MAG1]
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8('L');  // e_ident[EI_MAG2]
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8('F');  // e_ident[EI_MAG3]
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_ident[EI_DATA]
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_ident[EI_OSABI]
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (TargetObjectWriter->getOSType()) {
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Triple::FreeBSD:  Write8(ELF::ELFOSABI_FREEBSD); break;
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Triple::Linux:    Write8(ELF::ELFOSABI_LINUX); break;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:               Write8(ELF::ELFOSABI_NONE); break;
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write8(0);                  // e_ident[EI_ABIVERSION]
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(ELF::ET_REL);             // e_type
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(TargetObjectWriter->getEMachine()); // e_machine = target
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(ELF::EV_CURRENT);         // e_version
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(0);                    // e_entry, no entry point in .o file
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(0);                    // e_phoff, no program header for .o
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            sizeof(ELF::Elf32_Ehdr)));  // e_shoff = sec hdr table off in bytes
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_flags = whatever the target wants
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteEFlags();
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_ehsize = ELF header size
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(0);                  // e_phentsize = prog header entry size
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(0);                  // e_phnum = # prog header entries = 0
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_shentsize = Section header entry size
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_shnum     = # of section header ents
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NumberOfSections >= ELF::SHN_LORESERVE)
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Write16(ELF::SHN_UNDEF);
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Write16(NumberOfSections);
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // e_shstrndx  = Section # of '.shstrtab'
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ShstrtabIndex >= ELF::SHN_LORESERVE)
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Write16(ELF::SHN_XINDEX);
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Write16(ShstrtabIndex);
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       MCDataFragment *ShndxF,
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t name,
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint8_t info, uint64_t value,
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t size, uint8_t other,
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint32_t shndx,
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       bool Reserved) {
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ShndxF) {
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String32(*ShndxF, shndx);
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String32(*ShndxF, 0);
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint16_t(ELF::SHN_XINDEX) : shndx;
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit()) {
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String32(*SymtabF, name);  // st_name
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String8(*SymtabF, info);   // st_info
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String8(*SymtabF, other);  // st_other
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String16(*SymtabF, Index); // st_shndx
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String64(*SymtabF, value); // st_value
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String64(*SymtabF, size);  // st_size
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String32(*SymtabF, name);  // st_name
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String32(*SymtabF, value); // st_value
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String32(*SymtabF, size);  // st_size
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String8(*SymtabF, info);   // st_info
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String8(*SymtabF, other);  // st_other
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String16(*SymtabF, Index); // st_shndx
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      const MCAsmLayout &Layout) {
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Data.isCommon() && Data.isExternal())
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Data.getCommonAlignment();
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &Symbol = Data.getSymbol();
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Symbol.isAbsolute() && Symbol.isVariable()) {
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const MCExpr *Value = Symbol.getVariableValue()) {
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      int64_t IntValue;
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Value->EvaluateAsAbsolute(IntValue, Layout))
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	return (uint64_t)IntValue;
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Symbol.isInSection())
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Data.getFragment()) {
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Data.getFlags() & ELF_Other_ThumbFunc)
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Layout.getSymbolOffset(&Data)+1;
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Layout.getSymbolOffset(&Data);
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCAsmLayout &Layout) {
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The presence of symbol versions causes undefined symbols and
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // versions declared with @@@ to be renamed.
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.symbol_end(); it != ie; ++it) {
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &Alias = it->getSymbol();
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &Symbol = Alias.AliasedSymbol();
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &SD = Asm.getSymbolData(Symbol);
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Not an alias.
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (&Symbol == &Alias)
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef AliasName = Alias.getName();
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    size_t Pos = AliasName.find('@');
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Pos == StringRef::npos)
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Aliases defined with .symvar copy the binding from the symbol they alias.
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // This is the first place we are able to copy this information.
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    it->setExternal(SD.isExternal());
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(*it, MCELF::GetBinding(SD));
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef Rest = AliasName.substr(Pos);
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: produce a better error message.
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Symbol.isUndefined() && Rest.startswith("@@") &&
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        !Rest.startswith("@@@"))
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      report_fatal_error("A @@ version cannot be undefined");
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Renames.insert(std::make_pair(&Symbol, &Alias));
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  MCDataFragment *ShndxF,
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  ELFSymbolData &MSD,
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  const MCAsmLayout &Layout) {
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &OrigData = *MSD.SymbolData;
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &Data =
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Data.getSymbol().isVariable();
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Binding = MCELF::GetBinding(OrigData);
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Visibility = MCELF::GetVisibility(OrigData);
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Type = MCELF::GetType(Data);
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Other = Visibility;
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Value = SymbolValue(Data, Layout);
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Size = 0;
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(!(Data.isCommon() && !Data.isExternal()));
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCExpr *ESize = Data.getSize();
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ESize) {
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    int64_t Res;
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!ESize->EvaluateAsAbsolute(Res, Layout))
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      report_fatal_error("Size expression must be absolute.");
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Size = Res;
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Write out the symbol table entry
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   Size, Other, MSD.SectionIndex, IsReserved);
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       MCDataFragment *ShndxF,
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const MCAssembler &Asm,
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const MCAsmLayout &Layout,
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     const SectionIndexMapTy &SectionIndexMap) {
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The string table must be emitted first because we need the index
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // into the string table for all the symbol names.
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(StringTable.size() && "Missing string table");
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Make sure the start of the symbol table is aligned.
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The first entry is the undefined symbol entry.
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Write the symbol table entries.
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LastLocalSymbolIndex = LocalSymbolData.size() + 1;
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ELFSymbolData &MSD = LocalSymbolData[i];
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Write out a symbol table entry for each regular section.
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ++i) {
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(i->getSection());
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() == ELF::SHT_RELA ||
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_REL ||
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_STRTAB ||
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_SYMTAB ||
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_SYMTAB_SHNDX)
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false);
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LastLocalSymbolIndex++;
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ELFSymbolData &MSD = ExternalSymbolData[i];
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &Data = *MSD.SymbolData;
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(((Data.getFlags() & ELF_STB_Global) ||
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            (Data.getFlags() & ELF_STB_Weak)) &&
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           "External symbol requires STB_GLOBAL or STB_WEAK flag");
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      LastLocalSymbolIndex++;
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ELFSymbolData &MSD = UndefinedSymbolData[i];
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &Data = *MSD.SymbolData;
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      LastLocalSymbolIndex++;
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCValue &Target,
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCFragment &F,
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCFixup &Fixup,
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               bool IsPCRel) const {
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol *Renamed = Renames.lookup(&Symbol);
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ASymbol.isUndefined()) {
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Renamed)
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Renamed;
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &ASymbol;
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (SD.isExternal()) {
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Renamed)
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Renamed;
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF &Section =
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static_cast<const MCSectionELF&>(ASymbol.getSection());
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const SectionKind secKind = Section.getKind();
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (secKind.isBSS())
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (secKind.isThreadLocal()) {
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Renamed)
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Renamed;
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF &Sec2 =
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static_cast<const MCSectionELF&>(F.getParent()->getSection());
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (&Sec2 != &Section &&
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (Kind == MCSymbolRefExpr::VK_PLT ||
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       Kind == MCSymbolRefExpr::VK_GOTPCREL ||
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Renamed)
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Renamed;
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Section.getFlags() & ELF::SHF_MERGE) {
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Target.getConstant() == 0)
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Renamed)
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Renamed;
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const MCAsmLayout &Layout,
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const MCFragment *Fragment,
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const MCFixup &Fixup,
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       MCValue Target,
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t &FixedValue) {
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Addend = 0;
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int Index = 0;
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Value = Target.getConstant();
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol *RelocSymbol = NULL;
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Target.isAbsolute()) {
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &Symbol = Target.getSymA()->getSymbol();
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &ASymbol = Symbol.AliasedSymbol();
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCSymbol &SymbolB = RefB->getSymbol();
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IsPCRel = true;
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Offset of the symbol in the section
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      int64_t a = Layout.getSymbolOffset(&SDB);
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Ofeset of the relocation in the section
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value += b - a;
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!RelocSymbol) {
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCFragment *F = SD.getFragment();
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Index = F->getParent()->getOrdinal() + 1;
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Offset of the symbol in the section
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value += Layout.getSymbolOffset(&SD);
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        WeakrefUsedInReloc.insert(RelocSymbol);
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        UsedInReloc.insert(RelocSymbol);
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Index = -1;
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Addend = Value;
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Compensate for the addend on i386.
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (is64Bit())
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value = 0;
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FixedValue = Value;
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               (RelocSymbol != 0), Addend);
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Fixup.getOffset();
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  adjustFixupOffset(Fixup, RelocOffset);
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!hasRelocationAddend())
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Addend = 0;
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit())
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(isInt<64>(Addend));
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(isInt<32>(Addend));
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Relocations[Fragment->getParent()].push_back(ERE);
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             const MCSymbol *S) {
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = Asm.getSymbolData(*S);
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return SD.getIndex();
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 const MCSymbolData &Data,
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 bool Used, bool Renamed) {
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Data.getFlags() & ELF_Other_Weakref)
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Used)
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Renamed)
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &Symbol = Data.getSymbol();
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &A = Symbol.AliasedSymbol();
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Symbol.isTemporary())
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              bool isUsedInReloc) {
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Data.isExternal())
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &Symbol = Data.getSymbol();
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (isSignature && !isUsedInReloc)
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      SectionIndexMapTy &SectionIndexMap,
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      const RelMapTy &RelMap) {
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Index = 1;
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::iterator it = Asm.begin(),
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF &>(it->getSection());
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() != ELF::SHT_GROUP)
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionIndexMap[&Section] = Index++;
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::iterator it = Asm.begin(),
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF &>(it->getSection());
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() == ELF::SHT_GROUP ||
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_REL ||
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_RELA)
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionIndexMap[&Section] = Index++;
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *RelSection = RelMap.lookup(&Section);
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (RelSection)
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SectionIndexMap[RelSection] = Index++;
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      const SectionIndexMapTy &SectionIndexMap,
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         RevGroupMapTy RevGroupMap,
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         unsigned NumRegularSections) {
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Is this the correct place to do this?
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NeedsGOT) {
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Data.setExternal(true);
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(Data, ELF::STB_GLOBAL);
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Index 0 is always the empty string.
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringMap<uint64_t> StringIndexMap;
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringTable += '\x00';
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: We could optimize suffixes in strtab in the same way we
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // optimize them in shstrtab.
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Add the data for the symbols.
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.symbol_end(); it != ie; ++it) {
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &Symbol = it->getSymbol();
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Used = UsedInReloc.count(&Symbol);
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool isSignature = RevGroupMap.count(&Symbol);
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isInSymtab(Asm, *it,
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    Used || WeakrefUsed || isSignature,
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    Renames.count(&Symbol)))
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ELFSymbolData MSD;
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MSD.SymbolData = it;
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Undefined symbols are global, but this is the first place we
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // are able to set it.
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Local = isLocal(*it, isSignature, Used);
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCELF::SetBinding(*it, ELF::STB_GLOBAL);
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCELF::SetBinding(SD, ELF::STB_GLOBAL);
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCELF::SetBinding(*it, ELF::STB_WEAK);
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (it->isCommon()) {
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(!Local);
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MSD.SectionIndex = ELF::SHN_COMMON;
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MSD.SectionIndex = ELF::SHN_ABS;
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else if (RefSymbol.isUndefined()) {
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isSignature && !Used)
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MSD.SectionIndex = ELF::SHN_UNDEF;
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCSectionELF &Section =
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        static_cast<const MCSectionELF&>(RefSymbol.getSection());
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MSD.SectionIndex = SectionIndexMap.lookup(&Section);
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        NeedsSymtabShndx = true;
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(MSD.SectionIndex && "Invalid section index!");
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // The @@@ in symbol version is replaced with @ in undefined symbols and
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // @@ in defined ones.
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef Name = Symbol.getName();
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallString<32> Buf;
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    size_t Pos = Name.find("@@@");
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Pos != StringRef::npos) {
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Buf += Name.substr(0, Pos);
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Buf += Name.substr(Pos + Skip);
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Name = Buf;
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t &Entry = StringIndexMap[Name];
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Entry) {
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Entry = StringTable.size();
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringTable += Name;
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringTable += '\x00';
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MSD.StringIndex = Entry;
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MSD.SectionIndex == ELF::SHN_UNDEF)
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      UndefinedSymbolData.push_back(MSD);
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (Local)
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      LocalSymbolData.push_back(MSD);
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ExternalSymbolData.push_back(MSD);
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Symbols are required to be in lexicographic order.
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Set the symbol indices. Local symbols must come before all other
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // symbols with non-local bindings.
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Index = 1;
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LocalSymbolData[i].SymbolData->setIndex(Index++);
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Index += NumRegularSections;
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ExternalSymbolData[i].SymbolData->setIndex(Index++);
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NumRegularSections > ELF::SHN_LORESERVE)
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NeedsSymtabShndx = true;
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               MCAsmLayout &Layout,
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               RelMapTy &RelMap) {
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator it = Asm.begin(),
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionData &SD = *it;
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Relocations[&SD].empty())
68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCContext &Ctx = Asm.getContext();
68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(SD.getSection());
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const StringRef SectionName = Section.getSectionName();
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RelaSectionName += SectionName;
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned EntrySize;
69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (hasRelocationAddend())
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *RelaSection =
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        ELF::SHT_RELA : ELF::SHT_REL, 0,
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        SectionKind::getReadOnly(),
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        EntrySize, "");
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RelMap[&Section] = RelaSection;
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Asm.getOrCreateSectionData(*RelaSection);
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const RelMapTy &RelMap) {
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator it = Asm.begin(),
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionData &SD = *it;
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(SD.getSection());
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *RelaSection = RelMap.lookup(&Section);
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!RelaSection)
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RelaSD.setAlignment(is64Bit() ? 8 : 4);
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCDataFragment *F = new MCDataFragment(&RelaSD);
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteRelocationsFragment(Asm, F, &*it);
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t Flags, uint64_t Address,
72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t Offset, uint64_t Size,
72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint32_t Link, uint32_t Info,
73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t Alignment,
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       uint64_t EntrySize) {
73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(Name);        // sh_name: index into string table
73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(Type);        // sh_type
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(Flags);     // sh_flags
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(Address);   // sh_addr
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(Offset);    // sh_offset
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(Size);      // sh_size
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(Link);        // sh_link
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(Info);        // sh_info
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(Alignment); // sh_addralign
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteWord(EntrySize); // sh_entsize
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               MCDataFragment *F,
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCSectionData *SD) {
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // sort by the r_offset just like gnu as does
74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  array_pod_sort(Relocs.begin(), Relocs.end());
75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ELFRelocationEntry entry = Relocs[e - i - 1];
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!entry.Index)
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ;
75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (entry.Index < 0)
75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      entry.Index += LocalSymbolData.size();
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (is64Bit()) {
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String64(*F, entry.r_offset);
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      struct ELF::Elf64_Rela ERE64;
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ERE64.setSymbolAndType(entry.Index, entry.Type);
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String64(*F, ERE64.r_info);
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (hasRelocationAddend())
76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        String64(*F, entry.r_addend);
76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String32(*F, entry.r_offset);
77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      struct ELF::Elf32_Rela ERE32;
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ERE32.setSymbolAndType(entry.Index, entry.Type);
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String32(*F, ERE32.r_info);
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (hasRelocationAddend())
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        String32(*F, entry.r_addend);
77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic int compareBySuffix(const void *a, const void *b) {
78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const StringRef &NameA = secA->getSectionName();
78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const StringRef &NameB = secB->getSectionName();
78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned sizeA = NameA.size();
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned sizeB = NameB.size();
78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned len = std::min(sizeA, sizeB);
79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned int i = 0; i < len; ++i) {
79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    char ca = NameA[sizeA - i - 1];
79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    char cb = NameB[sizeB - i - 1];
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ca != cb)
79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return cb - ca;
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return sizeB - sizeA;
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             MCAsmLayout &Layout,
80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             SectionIndexMapTy &SectionIndexMap,
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             const RelMapTy &RelMap) {
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCContext &Ctx = Asm.getContext();
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCDataFragment *F;
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF *ShstrtabSection =
81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      SectionKind::getReadOnly());
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ShstrtabSD.setAlignment(1);
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF *SymtabSection =
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      SectionKind::getReadOnly(),
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      EntrySize, "");
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SymtabSD.setAlignment(is64Bit() ? 8 : 4);
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSectionData *SymtabShndxSD = NULL;
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NeedsSymtabShndx) {
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *SymtabShndxSection =
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        SectionKind::getReadOnly(), 4, "");
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SymtabShndxSD->setAlignment(4);
83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF *StrtabSection;
83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    SectionKind::getReadOnly());
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StrtabSD.setAlignment(1);
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringTableIndex = SectionIndexMap.lookup(StrtabSection);
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Symbol table
84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F = new MCDataFragment(&SymtabSD);
84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCDataFragment *ShndxF = NULL;
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NeedsSymtabShndx) {
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ShndxF = new MCDataFragment(SymtabShndxSD);
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F = new MCDataFragment(&StrtabSD);
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F->getContents().append(StringTable.begin(), StringTable.end());
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F = new MCDataFragment(&ShstrtabSD);
85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<const MCSectionELF*> Sections;
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator it = Asm.begin(),
86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
86219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(it->getSection());
86319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sections.push_back(&Section);
86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
86719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Section header string table.
86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  //
86919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The first entry of a string table holds a null character so skip
87019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // section 0.
87119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Index = 1;
87219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F->getContents() += '\x00';
87319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
87419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section = *Sections[I];
87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef Name = Section.getSectionName();
87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (I != 0) {
87919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef PreviousName = Sections[I - 1]->getSectionName();
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (PreviousName.endswith(Name)) {
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SectionStringTableIndex[&Section] = Index - Name.size() - 1;
88219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Remember the index into the string table so we can write it
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // into the sh_name field of the section header table.
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionStringTableIndex[&Section] = Index;
88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Index += Name.size() + 1;
89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    F->getContents() += Name;
89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    F->getContents() += '\x00';
89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            MCAsmLayout &Layout,
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            GroupMapTy &GroupMap,
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            RevGroupMapTy &RevGroupMap,
89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            SectionIndexMapTy &SectionIndexMap,
90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            const RelMapTy &RelMap) {
90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Create the .note.GNU-stack section if needed.
90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCContext &Ctx = Asm.getContext();
90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Asm.getNoExecStack()) {
90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *GnuStackSection =
90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        SectionKind::getReadOnly());
90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Asm.getOrCreateSectionData(*GnuStackSection);
90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Build the groups
91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       it != ie; ++it) {
91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(it->getSection());
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!(Section.getFlags() & ELF::SHF_GROUP))
91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol *SignatureSymbol = Section.getGroup();
91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Asm.getOrCreateSymbolData(*SignatureSymbol);
92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Group) {
92219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Group = Ctx.CreateELFGroupSection();
92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Data.setAlignment(4);
92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCDataFragment *F = new MCDataFragment(&Data);
92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      String32(*F, ELF::GRP_COMDAT);
92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GroupMap[Group] = SignatureSymbol;
92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ComputeIndexMap(Asm, SectionIndexMap, RelMap);
93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Add sections to the groups
93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       it != ie; ++it) {
93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF&>(it->getSection());
93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!(Section.getFlags() & ELF::SHF_GROUP))
93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *Group = RevGroupMap[Section.getGroup()];
94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: we could use the previous fragment
94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCDataFragment *F = new MCDataFragment(&Data);
94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned Index = SectionIndexMap.lookup(&Section);
94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    String32(*F, Index);
94619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
94719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSection(MCAssembler &Asm,
95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   const SectionIndexMapTy &SectionIndexMap,
95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   uint32_t GroupSymbolIndex,
95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   uint64_t Offset, uint64_t Size,
95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   uint64_t Alignment,
95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   const MCSectionELF &Section) {
95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t sh_link = 0;
95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t sh_info = 0;
95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch(Section.getType()) {
95919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_DYNAMIC:
96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_link = SectionStringTableIndex[&Section];
96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_info = 0;
96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_REL:
96519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_RELA: {
96619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *SymtabSection;
96719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF *InfoSection;
96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB,
96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   0,
97019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   SectionKind::getReadOnly());
97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_link = SectionIndexMap.lookup(SymtabSection);
97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(sh_link && ".symtab not found");
97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Remove ".rel" and ".rela" prefixes.
97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef SectionName = Section.getSectionName().substr(SecNameLen);
97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InfoSection = Asm.getContext().getELFSection(SectionName,
97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 ELF::SHT_PROGBITS, 0,
98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 SectionKind::getReadOnly());
98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_info = SectionIndexMap.lookup(InfoSection);
98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_SYMTAB:
98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_DYNSYM:
98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_link = StringTableIndex;
98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_info = LastLocalSymbolIndex;
98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_SYMTAB_SHNDX:
99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_link = SymbolTableIndex;
99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_PROGBITS:
99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_STRTAB:
99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_NOBITS:
99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_NOTE:
99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_NULL:
100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_ARM_ATTRIBUTES:
100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_INIT_ARRAY:
100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_FINI_ARRAY:
100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_PREINIT_ARRAY:
100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_X86_64_UNWIND:
100519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Nothing to do.
100619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
100719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
100819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ELF::SHT_GROUP:
100919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_link = SymbolTableIndex;
101019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sh_info = GroupSymbolIndex;
101119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
101219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
101319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(0 && "FIXME: sh_type value not supported!");
101519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
101619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
101719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
101819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
101919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
102019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   Alignment, Section.getEntrySize());
102119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
102219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
102419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return SD.getOrdinal() == ~UINT32_C(0) &&
102519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    !SD.getSection().isVirtualSection();
102619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
102719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) {
102919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Ret = 0;
103019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
103119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ++i) {
103219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCFragment &F = *i;
103319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(F.getKind() == MCFragment::FT_Data);
103419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Ret += cast<MCDataFragment>(F).getContents().size();
103519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
103619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Ret;
103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout,
104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             const MCSectionData &SD) {
104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsELFMetaDataSection(SD))
104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return DataSectionSize(SD);
104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Layout.getSectionFileSize(&SD);
104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
104719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                const MCSectionData &SD) {
104819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsELFMetaDataSection(SD))
104919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return DataSectionSize(SD);
105019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Layout.getSectionAddressSize(&SD);
105119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
105219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
105319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
105419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           const MCAsmLayout &Layout,
105519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           const MCSectionELF &Section) {
105619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t FileOff = OS.tell();
105719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteZeros(Padding);
106119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff += Padding;
106219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
106319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff += GetSectionFileSize(Layout, SD);
106419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
106519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsELFMetaDataSection(SD)) {
106619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ++i) {
106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCFragment &F = *i;
106919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(F.getKind() == MCFragment::FT_Data);
107019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WriteBytes(cast<MCDataFragment>(F).getContents().str());
107119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
107219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
107319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Asm.WriteSectionData(&SD, Layout);
107419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
107519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
107719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         const GroupMapTy &GroupMap,
107919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         const MCAsmLayout &Layout,
108019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      const SectionIndexMapTy &SectionIndexMap,
108119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   const SectionOffsetMapTy &SectionOffsetMap) {
108219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned NumSections = Asm.size() + 1;
108319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<const MCSectionELF*> Sections;
108519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Sections.resize(NumSections - 1);
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SectionIndexMapTy::const_iterator i=
108819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
108919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const std::pair<const MCSectionELF*, uint32_t> &p = *i;
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sections[p.second - 1] = p.first;
109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
109219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
109319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Null section first.
109419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t FirstSectionSize =
109519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
109619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t FirstSectionLink =
109719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
109819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
109919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0; i < NumSections - 1; ++i) {
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section = *Sections[i];
110219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
110319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint32_t GroupSymbolIndex;
110419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() != ELF::SHT_GROUP)
110519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GroupSymbolIndex = 0;
110619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
110719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
110819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                     GroupMap.lookup(&Section));
110919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
111019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t Size = GetSectionAddressSize(Layout, SD);
111119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
111219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
111319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 SectionOffsetMap.lookup(&Section), Size,
111419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 SD.getAlignment(), Section);
111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
111719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
111819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  std::vector<const MCSectionELF*> &Sections) {
112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::iterator it = Asm.begin(),
112119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
112219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
112319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF &>(it->getSection());
112419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() == ELF::SHT_GROUP)
112519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sections.push_back(&Section);
112619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
112719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::iterator it = Asm.begin(),
112919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF &>(it->getSection());
113219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() != ELF::SHT_GROUP &&
113319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() != ELF::SHT_REL &&
113419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() != ELF::SHT_RELA)
113519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sections.push_back(&Section);
113619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
113819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MCAssembler::iterator it = Asm.begin(),
113919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = Asm.end(); it != ie; ++it) {
114019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section =
114119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      static_cast<const MCSectionELF &>(it->getSection());
114219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Section.getType() == ELF::SHT_REL ||
114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Section.getType() == ELF::SHT_RELA)
114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sections.push_back(&Section);
114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
114619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
114719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
114819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ELFObjectWriter::WriteObject(MCAssembler &Asm,
114919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  const MCAsmLayout &Layout) {
115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  GroupMapTy GroupMap;
115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RevGroupMapTy RevGroupMap;
115219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SectionIndexMapTy SectionIndexMap;
115319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NumUserSections = Asm.size();
115519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
115819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned NumUserAndRelocSections = Asm.size();
116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
116119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        RevGroupMap, SectionIndexMap, RelMap);
116219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned AllSections = Asm.size();
116319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
116419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NumRegularSections = NumUserSections + NumIndexedSections;
116619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Compute symbol table information.
116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
117219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CreateMetadataSections(const_cast<MCAssembler&>(Asm),
117419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         const_cast<MCAsmLayout&>(Layout),
117519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         SectionIndexMap,
117619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         RelMap);
117719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
117919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    sizeof(ELF::Elf32_Ehdr);
118119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t FileOff = HeaderSize;
118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<const MCSectionELF*> Sections;
118419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ComputeSectionOrder(Asm, Sections);
118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NumSections = Sections.size();
118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SectionOffsetMapTy SectionOffsetMap;
118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section = *Sections[i];
118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
119219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Remember the offset into the file for this section.
119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionOffsetMap[&Section] = FileOff;
119519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get the size of the section in the output file (including padding).
119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FileOff += GetSectionFileSize(Layout, SD);
119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned SectionHeaderOffset = FileOff - HeaderSize;
120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t SectionHeaderEntrySize = is64Bit() ?
120519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff += (NumSections + 1) * SectionHeaderEntrySize;
120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
120919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionELF &Section = *Sections[i];
121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Remember the offset into the file for this section.
121519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionOffsetMap[&Section] = FileOff;
121619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get the size of the section in the output file (including padding).
121819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FileOff += GetSectionFileSize(Layout, SD);
121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Write out the ELF header ...
122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteHeader(SectionHeaderOffset, NumSections + 1);
122319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ... then the regular sections ...
122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // + because of .shstrtab
122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0; i < NumRegularSections + 1; ++i)
122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteDataSectionData(Asm, Layout, *Sections[i]);
122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff = OS.tell();
123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteZeros(Padding);
123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ... then the section header table ...
123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     SectionOffsetMap);
123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FileOff = OS.tell();
123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ... and then the remaining sections ...
124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteDataSectionData(Asm, Layout, *Sections[i]);
124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      const MCSymbolData &DataA,
124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      const MCFragment &FB,
124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      bool InSet,
124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      bool IsPCRel) const {
125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (DataA.getFlags() & ELF_STB_Weak)
125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
125219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
125319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 Asm, DataA, FB,InSet, IsPCRel);
125419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
125719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            raw_ostream &OS,
125819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            bool IsLittleEndian) {
125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (MOTW->getEMachine()) {
126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_386:
126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_X86_64:
126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_ARM:
126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_MBLAZE:
126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_PPC:
126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_PPC64:
126919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break;
127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::EM_MIPS:
127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break;
127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: llvm_unreachable("Unsupported architecture"); break;
127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
127719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// START OF SUBCLASSES for ELFObjectWriter
127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- ARMELFObjectWriter -------------------------------------------===//
127919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
128119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       raw_ostream &_OS,
128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       bool IsLittleEndian)
128319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{}
128519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMELFObjectWriter::~ARMELFObjectWriter()
128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{}
128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// FIXME: get the real EABI Version from the Triple.
129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMELFObjectWriter::WriteEFlags() {
129119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
129419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// In ARM, _MergedGlobals and other most symbols get emitted directly.
129519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// I.e. not as an offset to a section symbol.
129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This code is an approximation of what ARM/gcc does.
129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(PCRelCount, "Total number of PIC Relocations");
129919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NonPCRelCount, "Total number of non-PIC relocations");
130019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
130219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   const MCValue &Target,
130319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   const MCFragment &F,
130419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   const MCFixup &Fixup,
130519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   bool IsPCRel) const {
130619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol &Symbol = Target.getSymA()->getSymbol();
130719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool EmitThisSym = false;
130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF &Section =
131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static_cast<const MCSectionELF&>(Symbol.getSection());
131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool InNormalSection = true;
131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned RelocType = 0;
131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);
131419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DEBUG(
131619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
131719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbolRefExpr::VariantKind Kind2;
131819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Kind2 = Target.getSymB() ?  Target.getSymB()->getKind() :
131919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MCSymbolRefExpr::VK_None;
132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      dbgs() << "considering symbol "
132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << Section.getSectionName() << "/"
132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << Symbol.getName() << "/"
132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << " Rel:" << (unsigned)RelocType
132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << " Kind: " << (int)Kind << "/" << (int)Kind2
132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << " Tmp:"
132619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"
132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << Symbol.isVariable() << "/" << Symbol.isTemporary()
132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n");
132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsPCRel) { ++PCRelCount;
133119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (RelocType) {
133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Most relocation types are emitted as explicit symbols
133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InNormalSection =
133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        StringSwitch<bool>(Section.getSectionName())
133619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".data.rel.ro.local", false)
133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".data.rel", false)
133819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".bss", false)
133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Default(true);
134019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EmitThisSym = true;
134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_ARM_ABS32:
134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // But things get strange with R_ARM_ABS32
134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // In this case, most things that go in .rodata show up
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // as section relative relocations
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InNormalSection =
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        StringSwitch<bool>(Section.getSectionName())
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".data.rel.ro.local", false)
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".data.rel", false)
135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".rodata", false)
135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Case(".bss", false)
135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        .Default(true);
135319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EmitThisSym = false;
135419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
135719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NonPCRelCount++;
135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InNormalSection =
135919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringSwitch<bool>(Section.getSectionName())
136019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Case(".data.rel.ro.local", false)
136119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Case(".rodata", false)
136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Case(".data.rel", false)
136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Case(".bss", false)
136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Default(true);
136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (RelocType) {
136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: EmitThisSym = true; break;
136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ELF::R_ARM_ABS32: EmitThisSym = false; break;
136919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
137019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
137119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (EmitThisSym)
137319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
137419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (! Symbol.isTemporary() && InNormalSection) {
137519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return &Symbol;
137619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
137719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NULL;
137819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
137919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Need to examine the Fixup when determining whether to
138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// emit the relocation as an explicit symbol or as a section relative
138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// offset
138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          const MCFixup &Fixup,
138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool IsPCRel,
138619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool IsRelocWithSymbol,
138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          int64_t Addend) {
138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel);
139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RelocNeedsGOT(Modifier))
139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NeedsGOT = true;
139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Type;
139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               const MCFixup &Fixup,
140119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               bool IsPCRel) const  {
140219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
140319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
140419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
140519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type = 0;
140619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsPCRel) {
140719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
140819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: assert(0 && "Unimplemented");
140919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_4:
141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Modifier) {
141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("Unsupported Modifier");
141219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_None:
141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_REL32;
141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
141519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_TLSGD:
141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(0 && "unimplemented");
141719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
141819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_TLS_IE32;
142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_uncondbranch:
142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Modifier) {
142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_PLT:
142619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_PLT32;
142719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default:
142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_CALL;
143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
143219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_condbranch:
143419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_JUMP24;
143519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
143619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movt_hi16:
143719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movt_hi16_pcrel:
143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_MOVT_PREL;
143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movw_lo16:
144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movw_lo16_pcrel:
144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_MOVW_PREL_NC;
144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movt_hi16:
144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movt_hi16_pcrel:
144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_THM_MOVT_PREL;
144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movw_lo16:
144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movw_lo16_pcrel:
145019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_THM_MOVW_PREL_NC;
145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
145219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_bl:
145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_blx:
145419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Modifier) {
145519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_PLT:
145619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_THM_CALL;
145719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default:
145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_NONE;
146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
146119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: llvm_unreachable("invalid fixup kind!");
146719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_4:
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Modifier) {
146919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("Unsupported Modifier"); break;
147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_GOT:
147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_GOT_BREL;
147219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
147319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_TLSGD:
147419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_TLS_GD32;
147519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
147619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_TPOFF:
147719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_TLS_LE32;
147819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
147919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
148019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_TLS_IE32;
148119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_None:
148319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_ABS32;
148419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
148519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_ARM_GOTOFF:
148619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_ARM_GOTOFF32;
148719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
148819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
148919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
149019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_ldst_pcrel_12:
149119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_pcrel_10:
149219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_adr_pcrel_12:
149319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_bl:
149419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_cb:
149519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_cp:
149619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_thumb_br:
149719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(0 && "Unimplemented");
149819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
149919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_uncondbranch:
150019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_CALL;
150119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
150219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_condbranch:
150319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_JUMP24;
150419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
150519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movt_hi16:
150619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_MOVT_ABS;
150719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
150819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_arm_movw_lo16:
150919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_MOVW_ABS_NC;
151019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
151119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movt_hi16:
151219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_THM_MOVT_ABS;
151319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
151419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARM::fixup_t2_movw_lo16:
151519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_ARM_THM_MOVW_ABS_NC;
151619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
151719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
151819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
151919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Type;
152119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
152219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- PPCELFObjectWriter -------------------------------------------===//
152419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
152619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             raw_ostream &_OS,
152719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsLittleEndian)
152819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
152919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
153019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
153119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPPCELFObjectWriter::~PPCELFObjectWriter() {
153219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
153319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
153419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
153519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             const MCFixup &Fixup,
153619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsPCRel,
153719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsRelocWithSymbol,
153819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             int64_t Addend) {
153919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // determine the type of the relocation
154019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type;
154119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsPCRel) {
154219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
154319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
154419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("Unimplemented");
154519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_br24:
154619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_REL24;
154719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
154819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_PCRel_4:
154919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_REL32;
155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
155119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
155219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
155319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
155419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("invalid fixup kind!");
155519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_br24:
155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR24;
155719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
155819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_brcond14:
155919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_
156019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
156119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_ha16:
156219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR16_HA;
156319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
156419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_lo16:
156519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR16_LO;
156619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
156719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_lo14:
156819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR14;
156919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
157019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_4:
157119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR32;
157219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
157319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_2:
157419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_PPC_ADDR16;
157519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
157619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
157719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
157819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Type;
157919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
158019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
158119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
158219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPPCELFObjectWriter::adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) {
158319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch ((unsigned)Fixup.getKind()) {
158419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_ha16:
158519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case PPC::fixup_ppc_lo16:
158619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      RelocOffset += 2;
158719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
158819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
158919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
159019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
159119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
159219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
159319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- MBlazeELFObjectWriter -------------------------------------------===//
159419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
159519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
159619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             raw_ostream &_OS,
159719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsLittleEndian)
159819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
159919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
160019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
160119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
160219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
160319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
160419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
160519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             const MCFixup &Fixup,
160619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsPCRel,
160719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool IsRelocWithSymbol,
160819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             int64_t Addend) {
160919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // determine the type of the relocation
161019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type;
161119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsPCRel) {
161219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
161319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
161419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("Unimplemented");
161519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_PCRel_4:
161619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_MICROBLAZE_64_PCREL;
161719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
161819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_PCRel_2:
161919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_MICROBLAZE_32_PCREL;
162019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
162119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
162219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
162319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch ((unsigned)Fixup.getKind()) {
162419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: llvm_unreachable("invalid fixup kind!");
162519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_4:
162619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ((IsRelocWithSymbol || Addend !=0)
162719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ? ELF::R_MICROBLAZE_32
162819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              : ELF::R_MICROBLAZE_64);
162919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
163019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case FK_Data_2:
163119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type = ELF::R_MICROBLAZE_32;
163219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
163319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
163419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
163519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Type;
163619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
163719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
163819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- X86ELFObjectWriter -------------------------------------------===//
163919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
164019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
164119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
164219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       raw_ostream &_OS,
164319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       bool IsLittleEndian)
164419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
164519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{}
164619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
164719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanX86ELFObjectWriter::~X86ELFObjectWriter()
164819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{}
164919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
165019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
165119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          const MCFixup &Fixup,
165219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool IsPCRel,
165319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool IsRelocWithSymbol,
165419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          int64_t Addend) {
165519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // determine the type of the relocation
165619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
165719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
165819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
165919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Type;
166019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64Bit()) {
166119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsPCRel) {
166219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch ((unsigned)Fixup.getKind()) {
166319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("invalid fixup kind!");
166419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
166519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
166619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
166719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
166819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
166919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_8:
167019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(Modifier == MCSymbolRefExpr::VK_None);
167119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_X86_64_PC64;
167219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
167319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_signed_4byte:
167419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_riprel_4byte_movq_load:
167519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_riprel_4byte:
167619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_4:
167719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (Modifier) {
167819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        default:
167919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("Unimplemented");
168019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_None:
168119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_PC32;
168219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
168319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_PLT:
168419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_PLT32;
168519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
168619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTPCREL:
168719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_GOTPCREL;
168819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
168919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTTPOFF:
169019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_GOTTPOFF;
169119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
169219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TLSGD:
169319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_TLSGD;
169419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
169519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TLSLD:
169619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_TLSLD;
169719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
169819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
169919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
170019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_2:
170119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(Modifier == MCSymbolRefExpr::VK_None);
170219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_X86_64_PC16;
170319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
170419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_1:
170519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(Modifier == MCSymbolRefExpr::VK_None);
170619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_X86_64_PC8;
170719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
170819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
170919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
171019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch ((unsigned)Fixup.getKind()) {
171119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("invalid fixup kind!");
171219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_8: Type = ELF::R_X86_64_64; break;
171319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_signed_4byte:
171419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (Modifier) {
171519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        default:
171619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("Unimplemented");
171719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_None:
171819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_32S;
171919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
172019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOT:
172119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_GOT32;
172219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
172319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTPCREL:
172419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_GOTPCREL;
172519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
172619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TPOFF:
172719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_TPOFF32;
172819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
172919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_DTPOFF:
173019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_X86_64_DTPOFF32;
173119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
173219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
173319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
173419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_4:
173519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_X86_64_32;
173619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
173719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_2: Type = ELF::R_X86_64_16; break;
173819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_1:
173919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_1: Type = ELF::R_X86_64_8; break;
174019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
174119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
174219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
174319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsPCRel) {
174419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Modifier) {
174519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default:
174619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("Unimplemented");
174719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_None:
174819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_386_PC32;
174919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
175019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case MCSymbolRefExpr::VK_PLT:
175119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_386_PLT32;
175219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
175319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
175419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
175519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch ((unsigned)Fixup.getKind()) {
175619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: llvm_unreachable("invalid fixup kind!");
175719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
175819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_global_offset_table:
175919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type = ELF::R_386_GOTPC;
176019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
176119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
176219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
176319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // instead?
176419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case X86::reloc_signed_4byte:
176519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_4:
176619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_4:
176719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (Modifier) {
176819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        default:
176919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("Unimplemented");
177019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_None:
177119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_32;
177219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
177319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOT:
177419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_GOT32;
177519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
177619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTOFF:
177719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_GOTOFF;
177819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
177919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TLSGD:
178019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_GD;
178119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
178219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TPOFF:
178319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_LE_32;
178419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
178519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_INDNTPOFF:
178619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_IE;
178719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
178819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_NTPOFF:
178919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_LE;
179019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
179119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTNTPOFF:
179219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_GOTIE;
179319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
179419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_TLSLDM:
179519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_LDM;
179619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
179719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_DTPOFF:
179819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_LDO_32;
179919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
180019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case MCSymbolRefExpr::VK_GOTTPOFF:
180119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type = ELF::R_386_TLS_IE_32;
180219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
180319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
180419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
180519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_2: Type = ELF::R_386_16; break;
180619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_PCRel_1:
180719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case FK_Data_1: Type = ELF::R_386_8; break;
180819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
180919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
181019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
181119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
181219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RelocNeedsGOT(Modifier))
181319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NeedsGOT = true;
181419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
181519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Type;
181619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
181719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
181819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
181919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         raw_ostream &_OS,
182019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         bool IsLittleEndian)
182119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {}
182219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
182319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMipsELFObjectWriter::~MipsELFObjectWriter() {}
182419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
182519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
182619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           const MCFixup &Fixup,
182719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           bool IsPCRel,
182819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           bool IsRelocWithSymbol,
182919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           int64_t Addend) {
183019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // tbd
183119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 1;
183219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
1833