Iasm and obj lowering for advanced switch lowering.

Jump table emission is delayed until offsets are known. X86 local jumps can be
near or far. Sanboxing is applied to indirect jumps from jump table.

BUG=
R=stichnot@chromium.org, jvoung

Review URL: https://codereview.chromium.org/1257283004.
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index 37b1d58..f32a2b6 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -20,6 +20,7 @@
 #include "IceELFStreamer.h"
 #include "IceGlobalContext.h"
 #include "IceGlobalInits.h"
+#include "IceInst.h"
 #include "IceOperand.h"
 #include "llvm/Support/MathExtras.h"
 
@@ -553,6 +554,44 @@
   writeRelocationSections(RelRODataSections);
 }
 
+void ELFObjectWriter::writeJumpTable(const JumpTableData &JT,
+                                     FixupKind RelocationKind) {
+  ELFDataSection *Section;
+  ELFRelocationSection *RelSection;
+  const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType());
+  const Elf64_Xword ShAddralign = PointerSize;
+  const Elf64_Xword ShEntsize = PointerSize;
+  const IceString SectionName =
+      MangleSectionName(".rodata", JT.getFunctionName() + "$jumptable");
+  Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC,
+                                          ShAddralign, ShEntsize);
+  Section->setFileOffset(alignFileOffset(ShAddralign));
+  RODataSections.push_back(Section);
+  RelSection = createRelocationSection(Section);
+  RelRODataSections.push_back(RelSection);
+
+  const uint8_t SymbolType = STT_OBJECT;
+  Section->padToAlignment(Str, PointerSize);
+  bool IsExternal = Ctx.getFlags().getDisableInternal();
+  const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL;
+  IceString JumpTableName =
+      InstJumpTable::makeName(JT.getFunctionName(), JT.getId());
+  SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section,
+                           Section->getCurrentSize(), PointerSize);
+  StrTab->add(JumpTableName);
+
+  for (intptr_t TargetOffset : JT.getTargetOffsets()) {
+    AssemblerFixup NewFixup;
+    NewFixup.set_position(Section->getCurrentSize());
+    NewFixup.set_kind(RelocationKind);
+    constexpr bool SuppressMangling = true;
+    NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName(),
+                                          SuppressMangling));
+    RelSection->addRelocation(NewFixup);
+    Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset);
+  }
+}
+
 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
   for (const Constant *S : UndefSyms) {
     const auto Sym = llvm::cast<ConstantRelocatable>(S);