summaryrefslogtreecommitdiffstats
path: root/libebl
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-06-14 17:15:37 +0200
committerMark Wielaard <[email protected]>2014-06-22 13:47:48 +0200
commitc1c1c06e30f0b3b4ae66fcfec6318a93b8f31569 (patch)
treee5b811236c230f2ea82749f0ad9c2c4ac1bcf396 /libebl
parentba9e5156207e3c2bb85adc747376e774af3c0df6 (diff)
libebl: Add ebl_func_addr_mask plus ARM backend implementation.
The ARM EABI says that the zero bit of function symbol st_value indicates whether the symbol points to a THUMB or ARM function. Also the return value address in an unwind will contain the same extra bit to indicate whether to return to a regular ARM or THUMB function. Add a new ebl function to mask off such bits and turn a function value into a function address so that we get the actual value that a function symbol or return address points to. It isn't easily possible to reuse the existing ebl_resolve_sym_value for this purpose, so we end up with another hook that can be used from dwfl_module_getsym, handle_cfi and elflint. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libebl')
-rw-r--r--libebl/ChangeLog6
-rw-r--r--libebl/ebl-hooks.h2
-rw-r--r--libebl/eblinitreg.c9
-rw-r--r--libebl/libebl.h13
-rw-r--r--libebl/libeblP.h8
5 files changed, 34 insertions, 4 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 7198d5ec..5ec71016 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-17 Mark Wielaard <[email protected]>
+
+ * eblinitreg.c (ebl_func_addr_mask): New function.
+ * libebl.h (ebl_func_addr_mask): Define.
+ * libeblP.h (struct ebl): Add func_addr_mask.
+
2014-05-19 Mark Wielaard <[email protected]>
* Makefile.am (gen_SOURCES): Add eblcheckreloctargettype.c.
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index 65c62ec6..e1186f86 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -187,7 +187,7 @@ bool EBLHOOK(unwind) (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc,
bool *signal_framep);
/* Returns true if the value can be resolved to an address in an
- allocated section, which will be returned in *SHNDXP.
+ allocated section, which will be returned in *ADDR.
(e.g. function descriptor resolving) */
bool EBLHOOK(resolve_sym_value) (Ebl *ebl, GElf_Addr *addr);
diff --git a/libebl/eblinitreg.c b/libebl/eblinitreg.c
index 8909c500..5729b3cc 100644
--- a/libebl/eblinitreg.c
+++ b/libebl/eblinitreg.c
@@ -1,5 +1,5 @@
/* Fetch live process Dwfl_Frame from PID.
- Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2013, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -49,3 +49,10 @@ ebl_frame_nregs (Ebl *ebl)
{
return ebl == NULL ? 0 : ebl->frame_nregs;
}
+
+GElf_Addr
+ebl_func_addr_mask (Ebl *ebl)
+{
+ return ((ebl == NULL || ebl->func_addr_mask == 0)
+ ? ~(GElf_Addr)0 : ebl->func_addr_mask);
+}
diff --git a/libebl/libebl.h b/libebl/libebl.h
index d05751fa..bb993bf0 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -1,5 +1,5 @@
/* Interface for libebl.
- Copyright (C) 2000-2010, 2013 Red Hat, Inc.
+ Copyright (C) 2000-2010, 2013, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -409,6 +409,17 @@ extern bool ebl_set_initial_registers_tid (Ebl *ebl,
extern size_t ebl_frame_nregs (Ebl *ebl)
__nonnull_attribute__ (1);
+/* Mask to use for function symbol or unwind return addresses in case
+ the architecture adds some extra non-address bits to it. This is
+ different from ebl_resolve_sym_value which only works for actual
+ symbol addresses (in non-ET_REL files) that might resolve to an
+ address in a different section. ebl_func_addr_mask is called to
+ turn a given function value into the a real address or offset (the
+ original value might not be a real address). This works for all
+ cases where an actual function address (or offset in ET_REL symbol
+ tables) is needed. */
+extern GElf_Addr ebl_func_addr_mask (Ebl *ebl);
+
/* Convert *REGNO as is in DWARF to a lower range suitable for
Dwarf_Frame->REGS indexing. */
extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
diff --git a/libebl/libeblP.h b/libebl/libeblP.h
index f91c2a0d..dbd67f3e 100644
--- a/libebl/libeblP.h
+++ b/libebl/libeblP.h
@@ -1,5 +1,5 @@
/* Internal definitions for interface for libebl.
- Copyright (C) 2000-2009, 2013 Red Hat, Inc.
+ Copyright (C) 2000-2009, 2013, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -64,6 +64,12 @@ struct ebl
Ebl architecture can unwind iff FRAME_NREGS > 0. */
size_t frame_nregs;
+ /* Mask to use to turn a function value into a real function address
+ in case the architecture adds some extra non-address bits to it.
+ If not initialized (0) then ebl_func_addr_mask will return ~0,
+ otherwise it should be the actual mask to use. */
+ GElf_Addr func_addr_mask;
+
/* Function descriptor load address and table as used by
ebl_resolve_sym_value if available for this arch. */
GElf_Addr fd_addr;