aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-02-09 16:31:59 +0100
committerSverker Eriksson <[email protected]>2012-02-09 17:07:06 +0100
commit02deff1b04a12be50e346c104e73a6841859d602 (patch)
tree63bc27401d00bfb087ce81e582921a0dae28b7b2
parenta17eaa7e2cc2f68fbc9bf5c924c5a230d650b9f1 (diff)
downloadotp-02deff1b04a12be50e346c104e73a6841859d602.tar.gz
otp-02deff1b04a12be50e346c104e73a6841859d602.tar.bz2
otp-02deff1b04a12be50e346c104e73a6841859d602.zip
hipe: Fix address_to_mfa in hipe loader
Strange that the effect of this bug is not more fatal. Kudos to Fabian and Tom for spotting this one.
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl32
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 1b56cd8d90..8010bc6a91 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -730,7 +730,7 @@ find_const(ConstNo, []) ->
%%
add_ref(CalleeMFA, Address, Addresses, RefType, Trampoline, RemoteOrLocal) ->
- CallerMFA = address_to_mfa(Address, Addresses),
+ CallerMFA = address_to_mfa_lth(Address, Addresses),
%% just a sanity assertion below
true = case RemoteOrLocal of
local ->
@@ -743,11 +743,31 @@ add_ref(CalleeMFA, Address, Addresses, RefType, Trampoline, RemoteOrLocal) ->
%% io:format("Adding ref ~w\n",[{CallerMFA, CalleeMFA, Address, RefType}]),
hipe_bifs:add_ref(CalleeMFA, {CallerMFA,Address,RefType,Trampoline,RemoteOrLocal}).
-address_to_mfa(Address, [#fundef{address=Adr, mfa=MFA}|_Rest]) when Address >= Adr -> MFA;
-address_to_mfa(Address, [_ | Rest]) -> address_to_mfa(Address, Rest);
-address_to_mfa(Address, []) ->
- ?error_msg("Local adddress not found ~w\n",[Address]),
- exit({?MODULE, local_address_not_found}).
+% For FunDefs sorted from low to high addresses
+address_to_mfa_lth(Address, FunDefs) ->
+ case address_to_mfa_lth(Address, FunDefs, false) of
+ false ->
+ ?error_msg("Local adddress not found ~w\n",[Address]),
+ exit({?MODULE, local_address_not_found});
+ MFA ->
+ MFA
+ end.
+
+address_to_mfa_lth(Address, [#fundef{address=Adr, mfa=MFA}|Rest], Prev) ->
+ if Address < Adr ->
+ Prev;
+ true ->
+ address_to_mfa_lth(Address, Rest, MFA)
+ end;
+address_to_mfa_lth(_Address, [], Prev) ->
+ Prev.
+
+% For FunDefs sorted from high to low addresses
+%% address_to_mfa_htl(Address, [#fundef{address=Adr, mfa=MFA}|_Rest]) when Address >= Adr -> MFA;
+%% address_to_mfa_htl(Address, [_ | Rest]) -> address_to_mfa_htl(Address, Rest);
+%% address_to_mfa_htl(Address, []) ->
+%% ?error_msg("Local adddress not found ~w\n",[Address]),
+%% exit({?MODULE, local_address_not_found}).
%%----------------------------------------------------------------
%% Change callers of the given module to instead trap to BEAM.