Subzero: Add basic ELFObjectWriter (text section, symtab, strtab, headers).

Able to write out the ELF file header w/ a text section,
a symbol table, and string table. Write text buffer
directly to file after translating each CFG.
This means that the header is written out early w/ fake
data and then we seek back and write the real header
at the very end.

Does not yet handle relocations, data, rodata, constant
pools, bss, or -ffunction-sections, more than 64K sections
or more than 2^24 symbols.

Numbers w/ current NOASSERT=1 build on 176.gcc:

w/out -elf-writer:
    0.233771 (21.1%): [ 1287] emit
    28MB .s file

w/ -elf-writer:
    0.051056 ( 5.6%): [ 1287] emit
    2.4MB .o file

BUG=none
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/678533005
diff --git a/src/IceELFSection.cpp b/src/IceELFSection.cpp
new file mode 100644
index 0000000..1910e77
--- /dev/null
+++ b/src/IceELFSection.cpp
@@ -0,0 +1,159 @@
+//===- subzero/src/IceELFSection.cpp - Representation of ELF sections -----===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines how ELF sections are represented.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IceDefs.h"
+#include "IceELFSection.h"
+#include "IceELFStreamer.h"
+
+using namespace llvm::ELF;
+
+namespace Ice {
+
+// Text sections.
+
+void ELFTextSection::appendData(ELFStreamer &Str,
+                                const llvm::StringRef MoreData) {
+  Str.writeBytes(MoreData);
+  Header.sh_size += MoreData.size();
+}
+
+// Data sections.
+
+void ELFDataSection::appendData(ELFStreamer &Str,
+                                const llvm::StringRef MoreData) {
+  Str.writeBytes(MoreData);
+  Header.sh_size += MoreData.size();
+}
+
+// Relocation sections.
+
+// Symbol tables.
+
+void ELFSymbolTableSection::createDefinedSym(const IceString &Name,
+                                             uint8_t Type, uint8_t Binding,
+                                             ELFSection *Section,
+                                             RelocOffsetT Offset, SizeT Size) {
+  ELFSym NewSymbol = ELFSym();
+  NewSymbol.Sym.setBindingAndType(Binding, Type);
+  NewSymbol.Sym.st_value = Offset;
+  NewSymbol.Sym.st_size = Size;
+  NewSymbol.Number = ELFSym::UnknownNumber;
+  SymtabKey Key = {Name, Section};
+  bool Unique;
+  if (Type == STB_LOCAL)
+    Unique = LocalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
+  else
+    Unique = GlobalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
+  assert(Unique);
+}
+
+void ELFSymbolTableSection::noteUndefinedSym(const IceString &Name,
+                                             ELFSection *NullSection) {
+  ELFSym NewSymbol = ELFSym();
+  NewSymbol.Sym.setBindingAndType(STB_GLOBAL, STT_NOTYPE);
+  NewSymbol.Number = ELFSym::UnknownNumber;
+  SymtabKey Key = {Name, NullSection};
+  GlobalSymbols.insert(std::make_pair(Key, NewSymbol));
+}
+
+void ELFSymbolTableSection::updateIndices(const ELFStringTableSection *StrTab) {
+  SizeT SymNumber = 0;
+  for (auto &KeyValue : LocalSymbols) {
+    const IceString &Name = KeyValue.first.first;
+    ELFSection *Section = KeyValue.first.second;
+    Elf64_Sym &SymInfo = KeyValue.second.Sym;
+    if (!Name.empty())
+      SymInfo.st_name = StrTab->getIndex(Name);
+    SymInfo.st_shndx = Section->getNumber();
+    KeyValue.second.setNumber(SymNumber++);
+  }
+  for (auto &KeyValue : GlobalSymbols) {
+    const IceString &Name = KeyValue.first.first;
+    ELFSection *Section = KeyValue.first.second;
+    Elf64_Sym &SymInfo = KeyValue.second.Sym;
+    if (!Name.empty())
+      SymInfo.st_name = StrTab->getIndex(Name);
+    SymInfo.st_shndx = Section->getNumber();
+    KeyValue.second.setNumber(SymNumber++);
+  }
+}
+
+void ELFSymbolTableSection::writeData(ELFStreamer &Str, bool IsELF64) {
+  if (IsELF64) {
+    writeSymbolMap<true>(Str, LocalSymbols);
+    writeSymbolMap<true>(Str, GlobalSymbols);
+  } else {
+    writeSymbolMap<false>(Str, LocalSymbols);
+    writeSymbolMap<false>(Str, GlobalSymbols);
+  }
+}
+
+// String tables.
+
+void ELFStringTableSection::add(const IceString &Str) {
+  assert(!isLaidOut());
+  assert(!Str.empty());
+  StringToIndexMap.insert(std::make_pair(Str, UnknownIndex));
+}
+
+size_t ELFStringTableSection::getIndex(const IceString &Str) const {
+  assert(isLaidOut());
+  StringToIndexType::const_iterator It = StringToIndexMap.find(Str);
+  if (It == StringToIndexMap.end()) {
+    llvm_unreachable("String index not found");
+    return UnknownIndex;
+  }
+  return It->second;
+}
+
+bool ELFStringTableSection::SuffixComparator::
+operator()(const IceString &StrA, const IceString &StrB) const {
+  size_t LenA = StrA.size();
+  size_t LenB = StrB.size();
+  size_t CommonLen = std::min(LenA, LenB);
+  // If there is a difference in the common suffix, use that diff to sort.
+  for (size_t i = 0; i < CommonLen; ++i) {
+    char a = StrA[LenA - i - 1];
+    char b = StrB[LenB - i - 1];
+    if (a != b)
+      return a > b;
+  }
+  // If the common suffixes are completely equal, let the longer one come
+  // first, so that it can be laid out first and its characters shared.
+  return LenA > LenB;
+}
+
+void ELFStringTableSection::doLayout() {
+  assert(!isLaidOut());
+  llvm::StringRef Prev;
+
+  // String table starts with 0 byte.
+  StringData.push_back(0);
+
+  for (auto &StringIndex : StringToIndexMap) {
+    assert(StringIndex.second == UnknownIndex);
+    llvm::StringRef Cur = llvm::StringRef(StringIndex.first);
+    if (Prev.endswith(Cur)) {
+      // Prev is already in the StringData, and Cur is shorter than Prev
+      // based on the sort.
+      StringIndex.second = StringData.size() - Cur.size() - 1;
+      continue;
+    }
+    StringIndex.second = StringData.size();
+    std::copy(Cur.begin(), Cur.end(), back_inserter(StringData));
+    StringData.push_back(0);
+    Prev = Cur;
+  }
+}
+
+} // end of namespace Ice