Bug 1455610: Prevent nop fills from happening in jump tables; r=lth

--HG--
extra : rebase_source : 7597099d50710e0b095a06e064a76404f88e4ecc
extra : amend_source : 0b97b9f26872b921410a91d229c5ea6d3e76ac58
This commit is contained in:
Benjamin Bouvier 2018-04-24 16:16:34 +02:00
Родитель ab372e51b4
Коммит de0dc7d191
7 изменённых файлов: 77 добавлений и 3 удалений

Просмотреть файл

@ -0,0 +1,12 @@
// |jit-test| --arm-asm-nop-fill=1
var f = wasmEvalText(`(module (func (result i32) (param i32)
(block $0
(block $1
(block $2
(block $default
(br_table $0 $1 $2 $default (get_local 0))))))
(return (i32.const 0)))
(export "" 0)
)`).exports[""];
f(0);

Просмотреть файл

@ -2756,6 +2756,18 @@ Assembler::leaveNoPool()
m_buffer.leaveNoPool();
}
void
Assembler::enterNoNops()
{
m_buffer.enterNoNops();
}
void
Assembler::leaveNoNops()
{
m_buffer.leaveNoNops();
}
ptrdiff_t
Assembler::GetBranchOffset(const Instruction* i_)
{

Просмотреть файл

@ -1958,6 +1958,8 @@ class Assembler : public AssemblerShared
void flushBuffer();
void enterNoPool(size_t maxInst);
void leaveNoPool();
void enterNoNops();
void leaveNoNops();
// This should return a BOffImm, but we didn't want to require everyplace
// that used the AssemblerBuffer to make that class.
static ptrdiff_t GetBranchOffset(const Instruction* i);
@ -2487,6 +2489,19 @@ class AutoForbidPools
}
};
// Forbids nop filling for testing purposes. Not nestable.
class AutoForbidNops
{
Assembler* masm_;
public:
explicit AutoForbidNops(Assembler* masm) : masm_(masm) {
masm_->enterNoNops();
}
~AutoForbidNops() {
masm_->leaveNoNops();
}
};
} // namespace jit
} // namespace js

Просмотреть файл

@ -521,19 +521,32 @@ void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label);
class AutoForbidPools
{
Assembler* asm_;
public:
AutoForbidPools(Assembler* asm_, size_t maxInst)
: asm_(asm_)
{
asm_->enterNoPool(maxInst);
}
~AutoForbidPools() {
asm_->leaveNoPool();
}
};
// Forbids nop filling for testing purposes. Not nestable.
class AutoForbidNops
{
Assembler* asm_;
public:
explicit AutoForbidNops(Assembler* asm_)
: asm_(asm_)
{
asm_->enterNoNops();
}
~AutoForbidNops() {
asm_->leaveNoNops();
}
};
} // namespace jit
} // namespace js

Просмотреть файл

@ -286,6 +286,13 @@ class MozBaseAssembler : public js::jit::AssemblerShared {
armbuffer_.leaveNoPool();
}
void enterNoNops() {
armbuffer_.enterNoNops();
}
void leaveNoNops() {
armbuffer_.leaveNoNops();
}
public:
// Static interface used by IonAssemblerBufferWithConstantPools.
static void InsertIndexIntoTag(uint8_t* load, uint32_t index);

Просмотреть файл

@ -642,6 +642,7 @@ struct AssemblerBufferWithConstantPools : public AssemblerBuffer<SliceSize, Inst
// followed.
const uint32_t nopFillInst_;
const unsigned nopFill_;
// For inhibiting the insertion of fill NOPs in the dynamic context in which
// they are being inserted.
bool inhibitNops_;
@ -1083,7 +1084,17 @@ struct AssemblerBufferWithConstantPools : public AssemblerBuffer<SliceSize, Inst
canNotPlacePool_ = false;
// Validate the maxInst argument supplied to enterNoPool().
MOZ_ASSERT(this->nextOffset().getOffset() - canNotPlacePoolStartOffset_ <= canNotPlacePoolMaxInst_ * InstSize);
MOZ_ASSERT(this->nextOffset().getOffset() - canNotPlacePoolStartOffset_ <=
canNotPlacePoolMaxInst_ * InstSize);
}
void enterNoNops() {
MOZ_ASSERT(!inhibitNops_);
inhibitNops_ = true;
}
void leaveNoNops() {
MOZ_ASSERT(inhibitNops_);
inhibitNops_ = false;
}
void align(unsigned alignment) {

Просмотреть файл

@ -3835,6 +3835,10 @@ class BaseCompiler final : public BaseCompilerInterface
// constant pool entries.
masm.flush();
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
// Prevent nop sequences to appear in the jump table.
AutoForbidNops afn(&masm);
#endif
masm.bind(theTable);
for (uint32_t i = 0; i < labels.length(); i++) {