summaryrefslogtreecommitdiffstats
path: root/libdw/libdwP.h
diff options
context:
space:
mode:
Diffstat (limited to 'libdw/libdwP.h')
-rw-r--r--libdw/libdwP.h164
1 files changed, 149 insertions, 15 deletions
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index f805295f..6d8c6d80 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -188,6 +188,9 @@ struct Dwarf
/* Registered OOM handler. */
Dwarf_OOM oom_handler;
+
+ /* Lock to handle multithreaded programs. */
+ rwlock_define (,lock);
};
@@ -330,7 +333,8 @@ struct Dwarf_Macro_s
extern void __libdw_seterrno (int value) internal_function;
-/* Memory handling, the easy parts. This macro does not do any locking. */
+/* Memory handling, the easy parts.
+ Callers need to hold a write lock. */
#define libdw_alloc(dbg, type, tsize, cnt) \
({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
size_t _required = (tsize) * (cnt); \
@@ -348,6 +352,7 @@ extern void __libdw_seterrno (int value) internal_function;
} \
_result; })
+/* Callers need to hold a write lock. */
#define libdw_typed_alloc(dbg, type) \
libdw_alloc (dbg, type, sizeof (type), 1)
@@ -359,36 +364,95 @@ extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
/* Find CU for given offset. */
-extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
+extern struct Dwarf_CU *__libdw_findcu_rdlock (Dwarf *dbg, Dwarf_Off offset)
+ __nonnull_attribute__ (1) internal_function;
+
+// XXX Maybe not useful and should be ditched.
+extern struct Dwarf_CU *__libdw_findcu_wrlock (Dwarf *dbg, Dwarf_Off offset)
__nonnull_attribute__ (1) internal_function;
+extern int __libdw_nextcu_rdlock (Dwarf *dwarf, Dwarf_Off off,
+ Dwarf_Off *next_off,
+ size_t *header_sizep,
+ Dwarf_Off *abbrev_offsetp,
+ uint8_t *address_sizep,
+ uint8_t *offset_sizep)
+ __nonnull_attribute__ (3) internal_function;
+
/* Return tag of given DIE. */
+/* May relock via getabbrev. */
extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
unsigned int code)
__nonnull_attribute__ (1) internal_function;
+extern Dwarf_Abbrev *__libdw_findabbrev_wrlock (struct Dwarf_CU *cu,
+ unsigned int code)
+ __nonnull_attribute__ (1) internal_function;
/* Get abbreviation at given offset. */
+/* XXX perhaps rename to __libdw_getabbrev_rdlock. */
+/* May relock. */
extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
Dwarf_Off offset, size_t *lengthp,
Dwarf_Abbrev *result)
__nonnull_attribute__ (1) internal_function;
+extern Dwarf_Abbrev *__libdw_getabbrev_wrlock (Dwarf *dbg, struct Dwarf_CU *cu,
+ Dwarf_Off offset,
+ size_t *lengthp,
+ Dwarf_Abbrev *result)
+ __nonnull_attribute__ (1) internal_function;
+
/* Helper functions for form handling. */
-extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
- unsigned int form,
- const unsigned char *valp)
+extern size_t __libdw_form_val_len_rdlock (Dwarf *dbg, struct Dwarf_CU *cu,
+ unsigned int form,
+ const unsigned char *valp)
__nonnull_attribute__ (1, 2, 4) internal_function;
-/* Helper function for DW_FORM_ref* handling. */
-extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
- __nonnull_attribute__ (1, 2) internal_function;
-
-
-/* Helper function to locate attribute. */
-extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
- unsigned int search_name,
- unsigned int *codep,
- unsigned int *formp)
+/* Helper function for DW_FORM_* handling. */
+extern int __libdw_formaddr_rdlock (Dwarf_Attribute *attr,
+ Dwarf_Addr *return_addr)
+ __nonnull_attribute__ (2) internal_function;
+
+extern int __libdw_formref_rdlock (Dwarf_Attribute *attr,
+ Dwarf_Off *return_offset)
+ __nonnull_attribute__ (2) internal_function;
+
+extern Dwarf_Die *__libdw_formref_die_rdlock (Dwarf_Attribute *attr,
+ Dwarf_Die *die_mem)
+ __nonnull_attribute__ (2) internal_function;
+
+extern int __libdw_formsdata_rdlock (Dwarf_Attribute *attr,
+ Dwarf_Sword *return_sval)
+ __nonnull_attribute__ (2) internal_function;
+extern int __libdw_formudata_rdlock (Dwarf_Attribute *attr,
+ Dwarf_Word *return_uval)
+ __nonnull_attribute__ (2) internal_function;
+extern const char * __libdw_formstring_rdlock (Dwarf_Attribute *attrp)
+ internal_function;
+
+
+/* Variants of dwarf_attr for cases where caller holds the right lock.
+ Note that _rdlock may need to relock to initialize the cache. */
+extern Dwarf_Attribute *__libdw_attr_rdlock (Dwarf_Die *die,
+ unsigned int search_name,
+ Dwarf_Attribute *result)
+ __nonnull_attribute__ (3) internal_function;
+extern Dwarf_Attribute *__libdw_attr_wrlock (Dwarf_Die *die,
+ unsigned int search_name,
+ Dwarf_Attribute *result)
+
+/* Helper functions to locate attribute.
+ Note that _rdlock may need to relock to initialize the cache. */
+ __nonnull_attribute__ (3) internal_function;
+extern unsigned char *__libdw_find_attr_rdlock (Dwarf_Die *die,
+ unsigned int search_name,
+ unsigned int *codep,
+ unsigned int *formp)
+ __nonnull_attribute__ (1) internal_function;
+extern unsigned char *__libdw_find_attr_wrlock (Dwarf_Die *die,
+ unsigned int search_name,
+ unsigned int *codep,
+ unsigned int *formp)
__nonnull_attribute__ (1) internal_function;
/* Helper function to access integer attribute. */
@@ -402,6 +466,15 @@ struct Dwarf_Die_Chain
struct Dwarf_Die_Chain *parent;
bool prune; /* The PREVISIT function can set this. */
};
+
+/* PREVISIT and POSTVISIT are assumed to relock. Some of them also
+ unlock to hand the control over to external callbacks, and then
+ relock to rdlock (i.e. may actually downgrade the lock). The
+ caller of functions that call visit_scopens have to take this into
+ account, and assume that their wrlock might have been lost, and
+ need to be regained.
+
+ XXX document the above at callers. */
extern int __libdw_visit_scopes (unsigned int depth,
struct Dwarf_Die_Chain *root,
int (*previsit) (unsigned int depth,
@@ -413,6 +486,67 @@ extern int __libdw_visit_scopes (unsigned int depth,
void *arg)
__nonnull_attribute__ (2, 3) internal_function;
+/* Helper function to return DIE at given offset. */
+extern Dwarf_Die *__libdw_offdie_rdlock (Dwarf *dbg, Dwarf_Off offset,
+ Dwarf_Die *result)
+ __nonnull_attribute__ (3) internal_function;
+
+/* Variants of getsrclines if the caller holds the right lock. Note
+ that _rdlock may need to relock to initialize the cache. */
+extern int __libdw_getsrclines_rdlock (Dwarf_Die *cudie,
+ Dwarf_Lines **lines,
+ size_t *nlines)
+ __nonnull_attribute__ (2, 3) internal_function;
+extern int __libdw_getsrclines_wrlock (Dwarf_Die *cudie,
+ Dwarf_Lines **lines,
+ size_t *nlines)
+ __nonnull_attribute__ (2, 3) internal_function;
+
+/* The following three may relock to wrlock via __libdw_attr. */
+extern int __libdw_entrypc_rdlock (Dwarf_Die *die, Dwarf_Addr *return_addr)
+ __nonnull_attribute__ (2) internal_function;
+extern int __libdw_highpc_rdlock (Dwarf_Die *die, Dwarf_Addr *return_addr)
+ __nonnull_attribute__ (2) internal_function;
+extern int __libdw_lowpc_rdlock (Dwarf_Die *die, Dwarf_Addr *return_addr)
+ __nonnull_attribute__ (2) internal_function;
+
+extern int __libdw_formblock_rdlock (Dwarf_Attribute *attr, Dwarf_Block *return_block)
+ __nonnull_attribute__ (2) internal_function;
+
+/* May upgrade lock to _wrlock via dwarf_attr call. */
+extern ptrdiff_t __libdw_ranges_rdlock (Dwarf_Die *die, ptrdiff_t offset,
+ Dwarf_Addr *basep,
+ Dwarf_Addr *startp, Dwarf_Addr *endp)
+ internal_function;
+
+/* May upgrade lock to _wrlock via dwarf_attr call. */
+extern int __libdw_child_rdlock (Dwarf_Die *die, Dwarf_Die *result)
+ __nonnull_attribute__ (2) internal_function;
+
+extern int __libdw_child_wrlock (Dwarf_Die *die, Dwarf_Die *result)
+ __nonnull_attribute__ (2) internal_function;
+
+/* May relock due to find_attr. */
+extern int __libdw_siblingof_rdlock (Dwarf_Die *die, Dwarf_Die *result)
+ __nonnull_attribute__ (2) internal_function;
+
+/* May upgrade lock to _wrlock via dwarf_ranges call. */
+extern int __libdw_haspc_rdlock (Dwarf_Die *die, Dwarf_Addr pc)
+ internal_function;
+
+/* May relock to wrlock via find_attr. */
+extern int __libdw_hasattr_rdlock (Dwarf_Die *die, unsigned int search_name)
+ internal_function;
+
+/* May relock via findabbrev */
+extern int __libdw_haschildren_rdlock (Dwarf_Die *die)
+ internal_function;
+
+/* May relock via findabbrev. */
+extern int __libdw_tag_rdlock (Dwarf_Die *die)
+ __nonnull_attribute__ (1) internal_function;
+
+
/* Return error code of last failing function call. This value is kept
separately for each thread. */
extern int __dwarf_errno_internal (void);