Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | From: Mark Wielaard <mjw@redhat.com> |
| 2 | Date: Sun, 15 Jun 2014 12:30:02 +0200 |
| 3 | Subject: libebl: Add ebl_unwind_ret_mask. |
| 4 | |
| 5 | Another ARM oddity. A return value address in an unwind will contain an |
| 6 | extra bit to indicate whether to return to a regular ARM or THUMB function. |
| 7 | Add a new ebl function to return a mask to use to get the actual return |
| 8 | address during an unwind ebl_unwind_ret_mask. |
| 9 | |
| 10 | Rebase arm_unwind_ret_mask.patch from 0.159 to 0.160 |
| 11 | |
| 12 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> |
| 13 | --- |
| 14 | backends/arm_init.c | 3 +++ |
| 15 | libebl/eblinitreg.c | 8 ++++++++ |
| 16 | libebl/libebl.h | 4 ++++ |
| 17 | libebl/libeblP.h | 6 ++++++ |
| 18 | 4 files changed, 21 insertions(+) |
| 19 | |
| 20 | diff --git a/backends/arm_init.c b/backends/arm_init.c |
| 21 | index 2266829..f8df042 100644 |
| 22 | --- a/backends/arm_init.c |
| 23 | +++ b/backends/arm_init.c |
| 24 | @@ -87,5 +87,8 @@ arm_init (elf, machine, eh, ehlen) |
| 25 | /* Bit zero encodes whether an function address is THUMB or ARM. */ |
| 26 | eh->func_addr_mask = ~(GElf_Addr)1; |
| 27 | |
| 28 | + /* Bit zero encodes whether to return to a THUMB or ARM function. */ |
| 29 | + eh->unwind_ret_mask = ~(GElf_Addr)1; |
| 30 | + |
| 31 | return MODVERSION; |
| 32 | } |
| 33 | diff --git a/libebl/eblinitreg.c b/libebl/eblinitreg.c |
| 34 | index 5729b3c..ca681c0 100644 |
| 35 | --- a/libebl/eblinitreg.c |
| 36 | +++ b/libebl/eblinitreg.c |
| 37 | @@ -56,3 +56,11 @@ ebl_func_addr_mask (Ebl *ebl) |
| 38 | return ((ebl == NULL || ebl->func_addr_mask == 0) |
| 39 | ? ~(GElf_Addr)0 : ebl->func_addr_mask); |
| 40 | } |
| 41 | + |
| 42 | +GElf_Addr |
| 43 | +ebl_unwind_ret_mask (Ebl *ebl) |
| 44 | +{ |
| 45 | + return ((ebl == NULL || ebl->unwind_ret_mask == 0) |
| 46 | + ? ~(GElf_Addr)0 : ebl->unwind_ret_mask); |
| 47 | +} |
| 48 | + |
| 49 | diff --git a/libebl/libebl.h b/libebl/libebl.h |
| 50 | index 40cf635..be70027 100644 |
| 51 | --- a/libebl/libebl.h |
| 52 | +++ b/libebl/libebl.h |
| 53 | @@ -420,6 +420,10 @@ extern size_t ebl_frame_nregs (Ebl *ebl) |
| 54 | tables) is needed. */ |
| 55 | extern GElf_Addr ebl_func_addr_mask (Ebl *ebl); |
| 56 | |
| 57 | +/* Mask to use for unwind return address in case the architecture adds |
| 58 | + some extra non-address bits to it. */ |
| 59 | +extern GElf_Addr ebl_unwind_ret_mask (Ebl *ebl); |
| 60 | + |
| 61 | /* Convert *REGNO as is in DWARF to a lower range suitable for |
| 62 | Dwarf_Frame->REGS indexing. */ |
| 63 | extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno) |
| 64 | diff --git a/libebl/libeblP.h b/libebl/libeblP.h |
| 65 | index dbd67f3..e18ace6 100644 |
| 66 | --- a/libebl/libeblP.h |
| 67 | +++ b/libebl/libeblP.h |
| 68 | @@ -70,6 +70,12 @@ struct ebl |
| 69 | otherwise it should be the actual mask to use. */ |
| 70 | GElf_Addr func_addr_mask; |
| 71 | |
| 72 | + /* Mask to use to get the return address from an unwind in case the |
| 73 | + architecture adds some extra non-address bits to it. When not |
| 74 | + initialized (0) then ebl_unwind_ret_mask will return ~0, otherwise |
| 75 | + it should be the actual mask to use. */ |
| 76 | + GElf_Addr unwind_ret_mask; |
| 77 | + |
| 78 | /* Function descriptor load address and table as used by |
| 79 | ebl_resolve_sym_value if available for this arch. */ |
| 80 | GElf_Addr fd_addr; |
| 81 | -- |
| 82 | 1.9.1 |
| 83 | |