diff options
author | Tor Lillqvist <tlillqvist@suse.com> | 2012-01-04 14:15:43 +0200 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@suse.com> | 2012-01-04 15:31:18 +0200 |
commit | 36ce37def3c7dde751098649763479ca21321a9a (patch) | |
tree | df753dfe7cb9e6a8b8d7d8d9e48359a2e738183d /sal/android | |
parent | d4b0e98d50916e9a0a2810bb0484bdeb76214254 (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.c | 7 |
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 |