119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- lib/MC/MCELFStreamer.cpp - ELF Object Output ------------===//
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 assembles .s files and emits ELF .o object files.
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MCELFStreamer.h"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MCELF.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCStreamer.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCCodeEmitter.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCELFSymbolFlags.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCExpr.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCInst.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSection.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSymbol.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCValue.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmBackend.h"
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ELF.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::InitSections() {
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // This emulates the same behavior of GNU as. This makes it easier
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // to compare the output as the major sections are in the same order.
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SetSectionText();
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SetSectionData();
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SetSectionBss();
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SetSectionText();
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCObjectStreamer::EmitLabel(Symbol);
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSectionELF &Section =
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static_cast<const MCSectionELF&>(Symbol->getSection());
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getSymbolData(*Symbol);
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Section.getFlags() & ELF::SHF_TLS)
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_TLS);
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Flag) {
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCAF_SyntaxUnified: return; // no-op here.
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCAF_Code16: return; // Change parsing mode; no-op here.
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCAF_Code32: return; // Change parsing mode; no-op here.
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCAF_Code64: return; // Change parsing mode; no-op here.
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCAF_SubsectionsViaSymbols:
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getAssembler().setSubsectionsViaSymbols(true);
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(0 && "invalid assembler flag!");
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Anything needed here to flag the function as thumb?
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getAssembler().setIsThumbFunc(Func);
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // MCObjectStreamer.
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Lift context changes into super class.
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getAssembler().getOrCreateSymbolData(*Symbol);
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Symbol->setVariableValue(AddValueSymbols(Value));
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::ChangeSection(const MCSection *Section) {
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Grp)
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getAssembler().getOrCreateSymbolData(*Grp);
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  this->MCObjectStreamer::ChangeSection(Section);
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getAssembler().getOrCreateSymbolData(*Symbol);
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext());
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Alias->setVariableValue(Value);
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          MCSymbolAttr Attribute) {
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Indirect symbols are handled differently, to match how 'as' handles
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // them. This makes writing matching .o files easier.
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Attribute == MCSA_IndirectSymbol) {
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Note that we intentionally cannot use the symbol data here; this is
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // important for matching the string table that 'as' generates.
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IndirectSymbolData ISD;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ISD.Symbol = Symbol;
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ISD.SectionData = getCurrentSectionData();
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getAssembler().getIndirectSymbols().push_back(ISD);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Adding a symbol attribute always introduces the symbol, note that an
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // important side effect of calling getOrCreateSymbolData here is to register
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the symbol with the assembler.
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The implementation of symbol attributes is designed to match 'as', but it
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // leaves much to desired. It doesn't really make sense to arbitrarily add and
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // remove flags, but 'as' allows this (in particular, see .desc).
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  //
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // In the future it might be worth trying to make these operations more well
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // defined.
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Attribute) {
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_LazyReference:
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Reference:
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_NoDeadStrip:
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_SymbolResolver:
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_PrivateExtern:
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_WeakDefinition:
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_WeakDefAutoPrivate:
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Invalid:
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeIndFunction:
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_IndirectSymbol:
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(0 && "Invalid symbol attribute for ELF!");
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeGnuUniqueObject:
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Ignore for now.
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Global:
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(SD, ELF::STB_GLOBAL);
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD.setExternal(true);
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BindingExplicitlySet.insert(Symbol);
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_WeakReference:
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Weak:
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(SD, ELF::STB_WEAK);
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD.setExternal(true);
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BindingExplicitlySet.insert(Symbol);
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Local:
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(SD, ELF::STB_LOCAL);
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD.setExternal(false);
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BindingExplicitlySet.insert(Symbol);
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeFunction:
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_FUNC);
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeObject:
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_OBJECT);
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeTLS:
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_TLS);
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeCommon:
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_COMMON);
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_ELF_TypeNoType:
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_NOTYPE);
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Protected:
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetVisibility(SD, ELF::STV_PROTECTED);
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Hidden:
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetVisibility(SD, ELF::STV_HIDDEN);
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCSA_Internal:
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetVisibility(SD, ELF::STV_INTERNAL);
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       unsigned ByteAlignment) {
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!BindingExplicitlySet.count(Symbol)) {
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetBinding(SD, ELF::STB_GLOBAL);
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD.setExternal(true);
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCELF::SetType(SD, ELF::STT_OBJECT);
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MCELF::GetBinding(SD) == ELF_STB_Local) {
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSection *Section = getAssembler().getContext().getELFSection(".bss",
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                    ELF::SHT_NOBITS,
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                    ELF::SHF_WRITE |
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                    ELF::SHF_ALLOC,
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                    SectionKind::getBSS());
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Symbol->setSection(*Section);
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    struct LocalCommon L = {&SD, Size, ByteAlignment};
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LocalCommons.push_back(L);
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD.setCommon(Size, ByteAlignment);
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SD.setSize(MCConstantExpr::Create(Size, getContext()));
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          unsigned ByteAlignment) {
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Should this be caught and done earlier?
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCELF::SetBinding(SD, ELF::STB_LOCAL);
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SD.setExternal(false);
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BindingExplicitlySet.insert(Symbol);
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EmitCommonSymbol(Symbol, Size, ByteAlignment);
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // MCObjectStreamer.
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           int64_t Value, unsigned ValueSize,
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           unsigned MaxBytesToEmit) {
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // MCObjectStreamer.
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MaxBytesToEmit == 0)
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MaxBytesToEmit = ByteAlignment;
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      getCurrentSectionData());
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Update the maximum alignment on the current section if necessary.
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ByteAlignment > getCurrentSectionData()->getAlignment())
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getCurrentSectionData()->setAlignment(ByteAlignment);
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        unsigned MaxBytesToEmit) {
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // MCObjectStreamer.
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MaxBytesToEmit == 0)
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MaxBytesToEmit = ByteAlignment;
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           getCurrentSectionData());
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  F->setEmitNops(true);
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Update the maximum alignment on the current section if necessary.
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ByteAlignment > getCurrentSectionData()->getAlignment())
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getCurrentSectionData()->setAlignment(ByteAlignment);
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Add a symbol for the file name of this module. This is the second
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// entry in the module's symbol table (the first being the null symbol).
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitFileDirective(StringRef Filename) {
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Symbol->setSection(*getCurrentSection());
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Symbol->setAbsolute();
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid  MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (expr->getKind()) {
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Constant:
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Binary: {
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    fixSymbolsInTLSFixups(be->getLHS());
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    fixSymbolsInTLSFixups(be->getRHS());
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::SymbolRef: {
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (symRef.getKind()) {
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_GOTTPOFF:
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_INDNTPOFF:
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_NTPOFF:
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_GOTNTPOFF:
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_TLSGD:
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_TLSLD:
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_TLSLDM:
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_TPOFF:
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_DTPOFF:
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_ARM_TLSGD:
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_ARM_TPOFF:
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCELF::SetType(SD, ELF::STT_TLS);
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Unary:
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  this->MCObjectStreamer::EmitInstToFragment(Inst);
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment());
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i)
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::EmitInstToData(const MCInst &Inst) {
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCDataFragment *DF = getOrCreateDataFragment();
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MCFixup, 4> Fixups;
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallString<256> Code;
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  raw_svector_ostream VecOS(Code);
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  VecOS.flush();
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    fixSymbolsInTLSFixups(Fixups[i].getValue());
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Add the fixups and data.
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DF->addFixup(Fixups[i]);
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DF->getContents().append(Code.begin(), Code.end());
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCELFStreamer::Finish() {
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EmitFrames(true);
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                e = LocalCommons.end();
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       i != e; ++i) {
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData *SD = i->SD;
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t Size = i->Size;
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned ByteAlignment = i->ByteAlignment;
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol &Symbol = SD->getSymbol();
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSection &Section = Symbol.getSection();
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section);
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SD->setFragment(F);
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Update the maximum alignment of the section if necessary.
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ByteAlignment > SectData.getAlignment())
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SectData.setAlignment(ByteAlignment);
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  this->MCObjectStreamer::Finish();
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    raw_ostream &OS, MCCodeEmitter *CE,
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    bool RelaxAll, bool NoExecStack) {
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RelaxAll)
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S->getAssembler().setRelaxAll(true);
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NoExecStack)
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S->getAssembler().setNoExecStack(true);
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return S;
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
388