Start writing out some relocation sections (text).

Pass the full assembler pointer to the elf writer, so
that it has access to both the text buffer and the fixups.

Remove some child classes of AssemblerFixups. They didn't
really do much, and were pretty much identical to the
original AssemblerFixup class. Dart had a virtual method
for fixups to do necessary patching, but we currently
don't do the patching and just emit the relocations.
TODO see if patching is more efficient than writing out
relocations and letting the linker do the work.

This CL also makes AssemblerFixups POD.

Change the fixup kind to be a plain unsigned int, which
the target can fill w/ target/container-specific values.

Move the fwd declaration of Assembler to IceDefs and remove
the others. Do similar for fwd declaration refactoring for
ELFWriter.

Make the createAssembler method return a std::unique_ptr.

BUG=none
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/828873002
diff --git a/src/IceELFSection.cpp b/src/IceELFSection.cpp
index fd49e61..5dcc206 100644
--- a/src/IceELFSection.cpp
+++ b/src/IceELFSection.cpp
@@ -37,6 +37,29 @@
 
 // Relocation sections.
 
+void ELFRelocationSection::addRelocations(RelocOffsetT BaseOff,
+                                          const FixupRefList &FixupRefs) {
+  for (const AssemblerFixup *FR : FixupRefs) {
+    Fixups.push_back(*FR);
+    AssemblerFixup &F = Fixups.back();
+    F.set_position(BaseOff + F.position());
+  }
+}
+
+size_t ELFRelocationSection::getSectionDataSize(
+    const GlobalContext &Ctx, const ELFSymbolTableSection *SymTab) const {
+  size_t NumWriteableRelocs = 0;
+  for (const AssemblerFixup &Fixup : Fixups) {
+    const ELFSym *Symbol = SymTab->findSymbol(Fixup.symbol(&Ctx));
+    // TODO(jvoung): When the symbol table finally tracks everything,
+    // just use the Fixups.size() as the count, and remove the
+    // SymTab and Ctx params.
+    if (Symbol)
+      ++NumWriteableRelocs;
+  }
+  return NumWriteableRelocs * Header.sh_entsize;
+}
+
 // Symbol tables.
 
 void ELFSymbolTableSection::createDefinedSym(const IceString &Name,
@@ -47,13 +70,13 @@
   NewSymbol.Sym.setBindingAndType(Binding, Type);
   NewSymbol.Sym.st_value = Offset;
   NewSymbol.Sym.st_size = Size;
+  NewSymbol.Section = Section;
   NewSymbol.Number = ELFSym::UnknownNumber;
-  SymtabKey Key = {Name, Section};
   bool Unique;
   if (Type == STB_LOCAL)
-    Unique = LocalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
+    Unique = LocalSymbols.insert(std::make_pair(Name, NewSymbol)).second;
   else
-    Unique = GlobalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
+    Unique = GlobalSymbols.insert(std::make_pair(Name, NewSymbol)).second;
   assert(Unique);
   (void)Unique;
 }
@@ -62,16 +85,26 @@
                                              ELFSection *NullSection) {
   ELFSym NewSymbol = ELFSym();
   NewSymbol.Sym.setBindingAndType(STB_GLOBAL, STT_NOTYPE);
+  NewSymbol.Section = NullSection;
   NewSymbol.Number = ELFSym::UnknownNumber;
-  SymtabKey Key = {Name, NullSection};
-  GlobalSymbols.insert(std::make_pair(Key, NewSymbol));
+  GlobalSymbols.insert(std::make_pair(Name, NewSymbol));
+}
+
+const ELFSym *ELFSymbolTableSection::findSymbol(const IceString &Name) const {
+  auto I = LocalSymbols.find(Name);
+  if (I != LocalSymbols.end())
+    return &I->second;
+  I = GlobalSymbols.find(Name);
+  if (I != GlobalSymbols.end())
+    return &I->second;
+  return nullptr;
 }
 
 void ELFSymbolTableSection::updateIndices(const ELFStringTableSection *StrTab) {
   SizeT SymNumber = 0;
   for (auto &KeyValue : LocalSymbols) {
-    const IceString &Name = KeyValue.first.first;
-    ELFSection *Section = KeyValue.first.second;
+    const IceString &Name = KeyValue.first;
+    ELFSection *Section = KeyValue.second.Section;
     Elf64_Sym &SymInfo = KeyValue.second.Sym;
     if (!Name.empty())
       SymInfo.st_name = StrTab->getIndex(Name);
@@ -79,8 +112,8 @@
     KeyValue.second.setNumber(SymNumber++);
   }
   for (auto &KeyValue : GlobalSymbols) {
-    const IceString &Name = KeyValue.first.first;
-    ELFSection *Section = KeyValue.first.second;
+    const IceString &Name = KeyValue.first;
+    ELFSection *Section = KeyValue.second.Section;
     Elf64_Sym &SymInfo = KeyValue.second.Sym;
     if (!Name.empty())
       SymInfo.st_name = StrTab->getIndex(Name);