mirror of
https://github.com/corda/corda.git
synced 2025-01-22 04:18:31 +00:00
fix return address code offset calculation on ARM
We have to be careful about how we calculate return addresses on ARM due to padding introduced by constant pools interspersed with code. When calculating the offset of code where we're inserting a constant pool, we want the offset of the end of the pool for jump targets, but we want the offset just prior to the beginning of the pool (i.e. the offset of the instruction responsible for jumping past the pool) when calculating a return address.
This commit is contained in:
parent
61fe7efd6d
commit
378f7086b7
15
src/arm.cpp
15
src/arm.cpp
@ -320,8 +320,8 @@ expect(Context* c, bool v)
|
||||
|
||||
class Offset: public Promise {
|
||||
public:
|
||||
Offset(Context* c, MyBlock* block, unsigned offset):
|
||||
c(c), block(block), offset(offset)
|
||||
Offset(Context* c, MyBlock* block, unsigned offset, bool forTrace):
|
||||
c(c), block(block), offset(offset), forTrace(forTrace)
|
||||
{ }
|
||||
|
||||
virtual bool resolved() {
|
||||
@ -332,19 +332,20 @@ class Offset: public Promise {
|
||||
assert(c, resolved());
|
||||
|
||||
unsigned o = offset - block->offset;
|
||||
return block->start + padding(block, o) + o;
|
||||
return block->start + padding(block, forTrace ? o - BytesPerWord : o) + o;
|
||||
}
|
||||
|
||||
Context* c;
|
||||
MyBlock* block;
|
||||
unsigned offset;
|
||||
bool forTrace;
|
||||
};
|
||||
|
||||
Promise*
|
||||
offset(Context* c)
|
||||
offset(Context* c, bool forTrace = false)
|
||||
{
|
||||
return new (c->zone->allocate(sizeof(Offset)))
|
||||
Offset(c, c->lastBlock, c->code.length());
|
||||
Offset(c, c->lastBlock, c->code.length(), forTrace);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2271,8 +2272,8 @@ class MyAssembler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
virtual Promise* offset() {
|
||||
return ::offset(&c);
|
||||
virtual Promise* offset(bool forTrace) {
|
||||
return ::offset(&c, forTrace);
|
||||
}
|
||||
|
||||
virtual Block* endBlock(bool startNew) {
|
||||
|
@ -414,7 +414,7 @@ class Assembler {
|
||||
|
||||
virtual void writeTo(uint8_t* dst) = 0;
|
||||
|
||||
virtual Promise* offset() = 0;
|
||||
virtual Promise* offset(bool forTrace = false) = 0;
|
||||
|
||||
virtual Block* endBlock(bool startNew) = 0;
|
||||
|
||||
|
@ -3098,7 +3098,8 @@ codePromise(Context* c, Event* e)
|
||||
CodePromise*
|
||||
codePromise(Context* c, Promise* offset)
|
||||
{
|
||||
return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset);
|
||||
return new (c->zone->allocate(sizeof(CodePromise)))
|
||||
CodePromise(c, offset);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3357,7 +3358,7 @@ class CallEvent: public Event {
|
||||
apply(c, op, BytesPerWord, address->source, address->source);
|
||||
|
||||
if (traceHandler) {
|
||||
traceHandler->handleTrace(codePromise(c, c->assembler->offset()),
|
||||
traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)),
|
||||
stackArgumentIndex);
|
||||
}
|
||||
|
||||
|
@ -2377,7 +2377,7 @@ class MyAssembler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
virtual Promise* offset() {
|
||||
virtual Promise* offset(bool) {
|
||||
return ::offset(&c);
|
||||
}
|
||||
|
||||
|
@ -3536,7 +3536,7 @@ class MyAssembler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
virtual Promise* offset() {
|
||||
virtual Promise* offset(bool) {
|
||||
return local::offset(&c);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user