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