Chromium Code Reviews| Index: src/IceCfg.cpp |
| diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp |
| index 7e915081700eec8a629c7d3f2fdbc61aba98a43c..3ff367579d6d45d57a92daca8c441f8706f3e467 100644 |
| --- a/src/IceCfg.cpp |
| +++ b/src/IceCfg.cpp |
| @@ -529,6 +529,12 @@ void Cfg::doBranchOpt() { |
| } |
| } |
| +void Cfg::markNodesForSandboxing() { |
| + for (const InstJumpTable *JT : JumpTables) |
| + for (SizeT I = 0; I < JT->getNumTargets(); ++I) |
| + JT->getTarget(I)->setNeedsAlignment(); |
| +} |
| + |
| // ======================== Dump routines ======================== // |
| // emitTextHeader() is not target-specific (apart from what is |
| @@ -554,6 +560,40 @@ void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx, |
| Str << MangledName << ":\n"; |
| } |
| +void Cfg::deleteJumpTableInsts() { |
| + for (InstJumpTable *JumpTable : JumpTables) |
| + JumpTable->setDeleted(); |
| +} |
| + |
| +void Cfg::emitJumpTables() { |
| + switch (Ctx->getFlags().getOutFileType()) { |
| + case FT_Elf: |
| + case FT_Iasm: { |
| + // The emission needs to be delayed until the after the text section so save |
| + // the offsets in the global context. |
| + IceString MangledName = Ctx->mangleName(getFunctionName()); |
| + for (const InstJumpTable *JumpTable : JumpTables) { |
| + SizeT NumTargets = JumpTable->getNumTargets(); |
| + JumpTableData &JT = |
| + Ctx->addJumpTable(MangledName, JumpTable->getId(), NumTargets); |
| + for (SizeT I = 0; I < NumTargets; ++I) { |
| + SizeT Index = JumpTable->getTarget(I)->getIndex(); |
| + JT.pushTarget( |
| + getAssembler()->getOrCreateCfgNodeLabel(Index)->getPosition()); |
| + } |
| + } |
| + } break; |
| + case FT_Asm: { |
| + // Emit the assembly directly so we don't need to hang on to all the names |
| + for (const InstJumpTable *JumpTable : JumpTables) |
| + getTarget()->emitJumpTable(this, JumpTable); |
| + } break; |
| + default: |
| + llvm::report_fatal_error("Invalid out file type."); |
| + break; |
| + } |
| +} |
| + |
| void Cfg::emit() { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -566,10 +606,20 @@ void Cfg::emit() { |
| } |
| OstreamLocker L(Ctx); |
| Ostream &Str = Ctx->getStrEmit(); |
| - IceString MangledName = getContext()->mangleName(getFunctionName()); |
| - emitTextHeader(MangledName, Ctx, getAssembler<>()); |
| - for (CfgNode *Node : Nodes) |
| + IceString MangledName = Ctx->mangleName(getFunctionName()); |
| + const Assembler *Asm = getAssembler<>(); |
| + const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
| + |
| + emitTextHeader(MangledName, Ctx, Asm); |
| + deleteJumpTableInsts(); |
| + for (CfgNode *Node : Nodes) { |
| + if (NeedSandboxing && Node->needsAlignment()) { |
| + Str << "\t" << Asm->getNonExecPadDirective() << " " |
|
jvoung (off chromium)
2015/07/29 21:31:17
Maybe just rename this from getNonExecPadDirective
ascull
2015/07/29 22:43:04
Done.
|
| + << Asm->getBundleAlignLog2Bytes() << "\n"; |
| + } |
| Node->emit(this); |
| + } |
| + emitJumpTables(); |
| Str << "\n"; |
| } |
| @@ -577,8 +627,14 @@ void Cfg::emitIAS() { |
| TimerMarker T(TimerStack::TT_emit, this); |
| // The emitIAS() routines emit into the internal assembler buffer, |
| // so there's no need to lock the streams. |
| - for (CfgNode *Node : Nodes) |
| + deleteJumpTableInsts(); |
| + const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
| + for (CfgNode *Node : Nodes) { |
| + if (NeedSandboxing && Node->needsAlignment()) |
| + getAssembler()->alignCfgNode(); |
| Node->emitIAS(this); |
| + } |
| + emitJumpTables(); |
| } |
| // Dumps the IR with an optional introductory message. |