diff options
Diffstat (limited to 'lib/kernel/src/hipe_unified_loader.erl')
-rw-r--r-- | lib/kernel/src/hipe_unified_loader.erl | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl index 514c002d87..06d404905d 100644 --- a/lib/kernel/src/hipe_unified_loader.erl +++ b/lib/kernel/src/hipe_unified_loader.erl @@ -337,11 +337,16 @@ exports(ExportMap, BaseAddress) -> exports(ExportMap, BaseAddress, [], []). exports([Offset,M,F,A,IsClosure,IsExported|Rest], BaseAddress, MFAs, Addresses) -> - MFA = {M,F,A}, - Address = BaseAddress + Offset, - FunDef = #fundef{address=Address, mfa=MFA, is_closure=IsClosure, - is_exported=IsExported}, - exports(Rest, BaseAddress, [MFA|MFAs], [FunDef|Addresses]); + case IsExported andalso erlang:is_builtin(M, F, A) of + true -> + exports(Rest, BaseAddress, MFAs, Addresses); + _false -> + MFA = {M,F,A}, + Address = BaseAddress + Offset, + FunDef = #fundef{address=Address, mfa=MFA, is_closure=IsClosure, + is_exported=IsExported}, + exports(Rest, BaseAddress, [MFA|MFAs], [FunDef|Addresses]) + end; exports([], _, MFAs, Addresses) -> {MFAs, Addresses}. @@ -505,7 +510,7 @@ patch_offset(Type, Data, Address, ConstAndZone, Addresses) -> Atom = Data, patch_atom(Address, Atom); sdesc -> - patch_sdesc(Data, Address, ConstAndZone); + patch_sdesc(Data, Address, ConstAndZone, Addresses); x86_abs_pcrel -> patch_instr(Address, Data, x86_abs_pcrel) %% _ -> @@ -518,14 +523,16 @@ patch_atom(Address, Atom) -> patch_instr(Address, hipe_bifs:atom_to_word(Atom), atom). patch_sdesc(?STACK_DESC(SymExnRA, FSize, Arity, Live), - Address, {_ConstMap2,CodeAddress}) -> + Address, {_ConstMap2,CodeAddress}, _Addresses) -> ExnRA = case SymExnRA of [] -> 0; % No catch LabelOffset -> CodeAddress + LabelOffset end, ?ASSERT(assert_local_patch(Address)), - hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live}). + DBG_MFA = ?IF_DEBUG(address_to_mfa_lth(Address, _Addresses), {undefined,undefined,0}), + hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live, DBG_MFA}). + %%---------------------------------------------------------------- %% Handle a 'load_address'-type patch. @@ -732,7 +739,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 -> @@ -745,11 +752,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. |