summaryrefslogtreecommitdiff
path: root/sal/android
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@suse.com>2012-01-04 14:15:43 +0200
committerTor Lillqvist <tlillqvist@suse.com>2012-01-04 15:31:18 +0200
commit36ce37def3c7dde751098649763479ca21321a9a (patch)
treedf753dfe7cb9e6a8b8d7d8d9e48359a2e738183d /sal/android
parentd4b0e98d50916e9a0a2810bb0484bdeb76214254 (diff)
Fix the monkey patching to work for an arbitrary offset
We used to patch in a simple "b" instruction with a relative offset that has to fit in 24(+2) bits. Which was not enough in practice. Now patch in a "ldr pc, [pc, #-4]" instead which loads PC from the next word; in ARM code PC cotains the address of the executing instruction + 8), and put the full address of the replacement code into the next word.
Diffstat (limited to 'sal/android')
-rw-r--r--sal/android/lo-bootstrap.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c
index 7fc171ba90ae..4800545fad8b 100644
--- a/sal/android/lo-bootstrap.c
+++ b/sal/android/lo-bootstrap.c
@@ -1241,10 +1241,9 @@ patch(const char *symbol,
return;
}
- /* Poke a "b replacement_code" into it instead */
- *((unsigned *) code) =
- (0xEA000000 |
- ((((int) replacement_code - ((int) code + 8)) / 4) & 0x00FFFFFF));
+ /* Poke in a jump to replacement_code instead */
+ ((unsigned *) code)[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
+ ((unsigned *) code)[1] = (unsigned) replacement_code;
}
static void