summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Merey <[email protected]>2025-03-16 21:51:01 -0400
committerAaron Merey <[email protected]>2025-03-26 17:01:24 -0400
commit1b3aa450f3d50d3b4270f6fff4e7fa390af9d461 (patch)
tree5f406eccaef846c922d842be4989e6d76f81b7af
parente9cd1d2951f4abb00b6e9edec225dde9c378bec3 (diff)
libdw: Add locking to dwarf_getsrcfiles, dwarf_getsrclines, dwarf_macro_getsrcfiles
* libdw/dwarf_begin_elf.c (dwarf_begin_elf): Init macro_lock. * libdw/dwarf_end.c (cu_free): Free src_lock. (dwarf_end): Free macro_lock. * libdw/dwarf_getsrcfiles.c (dwarf_getsrcfiles): Use src_lock. * libdw/dwarf_getsrclines.c (dwarf_getsrclines): Ditto. * libdw/dwarf_macro_getsrclines.c (dwarf_macro_getsrclines): Use macro_lock. * libdw/libdwP.h (struct Dwarf): Define macro_lock. (struct Dwarf_CU): Define src_lock. * libdw/libdw_findcu.c (__libdw_intern_next_unit): Init src_lock. Signed-off-by: Aaron Merey <[email protected]>
-rw-r--r--libdw/dwarf_begin_elf.c1
-rw-r--r--libdw/dwarf_end.c2
-rw-r--r--libdw/dwarf_getsrcfiles.c11
-rw-r--r--libdw/dwarf_getsrclines.c25
-rw-r--r--libdw/dwarf_macro_getsrcfiles.c10
-rw-r--r--libdw/libdwP.h10
-rw-r--r--libdw/libdw_findcu.c1
7 files changed, 47 insertions, 13 deletions
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 8a3a939b..58a309e9 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -580,6 +580,7 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
return NULL;
}
mutex_init (result->dwarf_lock);
+ mutex_init (result->macro_lock);
eu_search_tree_init (&result->cu_tree);
eu_search_tree_init (&result->tu_tree);
eu_search_tree_init (&result->split_tree);
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 92389c07..c12815e1 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -70,6 +70,7 @@ cu_free (void *arg)
Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
rwlock_fini (p->abbrev_lock);
rwlock_fini (p->split_lock);
+ mutex_fini (p->src_lock);
/* Free split dwarf one way (from skeleton to split). */
if (p->unit_type == DW_UT_skeleton
@@ -130,6 +131,7 @@ dwarf_end (Dwarf *dwarf)
free (dwarf->mem_tails);
pthread_rwlock_destroy (&dwarf->mem_rwl);
mutex_fini (dwarf->dwarf_lock);
+ mutex_fini (dwarf->macro_lock);
/* Free the pubnames helper structure. */
free (dwarf->pubnames_sets);
diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
index 24e4b7d2..9becd1d5 100644
--- a/libdw/dwarf_getsrcfiles.c
+++ b/libdw/dwarf_getsrcfiles.c
@@ -47,9 +47,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
}
int res = -1;
+ struct Dwarf_CU *const cu = cudie->cu;
+ mutex_lock (cudie->cu->src_lock);
/* Get the information if it is not already known. */
- struct Dwarf_CU *const cu = cudie->cu;
if (cu->files == NULL)
{
/* For split units there might be a simple file table (without lines).
@@ -96,7 +97,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
Dwarf_Off debug_line_offset;
if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
NULL, &debug_line_offset) == NULL)
- return -1;
+ {
+ mutex_unlock (cudie->cu->src_lock);
+ return -1;
+ }
res = __libdw_getsrcfiles (cu->dbg, debug_line_offset,
__libdw_getcompdir (cudie),
@@ -115,8 +119,7 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
*nfiles = cu->files->nfiles;
}
- // XXX Eventually: unlocking here.
-
+ mutex_unlock (cudie->cu->src_lock);
return res;
}
INTDEF (dwarf_getsrcfiles)
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index da78db67..be10cdee 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -1442,8 +1442,10 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
return -1;
}
- /* Get the information if it is not already known. */
struct Dwarf_CU *const cu = cudie->cu;
+ mutex_lock (cu->src_lock);
+
+ /* Get the information if it is not already known. */
if (cu->lines == NULL)
{
/* For split units always pick the lines from the skeleton. */
@@ -1464,10 +1466,13 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
*lines = cu->lines;
*nlines = cu->lines->nlines;
}
+
+ mutex_unlock (cu->src_lock);
return res;
}
__libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
+ mutex_unlock (cu->src_lock);
return -1;
}
@@ -1485,21 +1490,29 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
Dwarf_Off debug_line_offset;
if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
NULL, &debug_line_offset) == NULL)
- return -1;
+ {
+ mutex_unlock (cu->src_lock);
+ return -1;
+ }
if (__libdw_getsrclines (cu->dbg, debug_line_offset,
__libdw_getcompdir (cudie),
cu->address_size, &cu->lines, &cu->files) < 0)
- return -1;
+ {
+ mutex_unlock (cu->src_lock);
+ return -1;
+ }
}
else if (cu->lines == (void *) -1l)
- return -1;
+ {
+ mutex_unlock (cu->src_lock);
+ return -1;
+ }
*lines = cu->lines;
*nlines = cu->lines->nlines;
- // XXX Eventually: unlocking here.
-
+ mutex_unlock (cu->src_lock);
return 0;
}
INTDEF(dwarf_getsrclines)
diff --git a/libdw/dwarf_macro_getsrcfiles.c b/libdw/dwarf_macro_getsrcfiles.c
index 5e02935d..6ccbeadb 100644
--- a/libdw/dwarf_macro_getsrcfiles.c
+++ b/libdw/dwarf_macro_getsrcfiles.c
@@ -41,6 +41,8 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
/* macro is declared NN */
Dwarf_Macro_Op_Table *const table = macro->table;
+
+ mutex_lock (table->dbg->macro_lock);
if (table->files == NULL)
{
Dwarf_Off line_offset = table->line_offset;
@@ -48,6 +50,7 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
{
*files = NULL;
*nfiles = 0;
+ mutex_unlock (table->dbg->macro_lock);
return 0;
}
@@ -80,9 +83,14 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
}
if (table->files == (void *) -1)
- return -1;
+ {
+ mutex_unlock (table->dbg->macro_lock);
+ return -1;
+ }
*files = table->files;
*nfiles = table->files->nfiles;
+
+ mutex_unlock (table->dbg->macro_lock);
return 0;
}
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index a9d4c0a7..3216f2a1 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -265,11 +265,13 @@ struct Dwarf
pthread_rwlock_t mem_rwl;
/* Recursive mutex intended for setting/getting alt_dwarf, next_tu_offset,
- and next_cu_offset. Covers dwarf_getsrclines, dwarf_getsrcfiles and
- dwarf_macro_getsrcfiles. Should also be held when calling
+ and next_cu_offset. Should be held when calling
__libdw_intern_next_unit. */
mutex_define(, dwarf_lock);
+ /* Synchronize access to dwarf_macro_getsrcfiles. */
+ mutex_define(, macro_lock);
+
/* Internal memory handling. This is basically a simplified thread-local
reimplementation of obstacks. Unfortunately the standard obstack
implementation is not usable in libraries. */
@@ -461,6 +463,10 @@ struct Dwarf_CU
Covers __libdw_find_split_unit. */
rwlock_define(, split_lock);
+ /* Synchronize access to the lines and files members.
+ Covers dwarf_getsrclines and dwarf_getsrcfiles. */
+ mutex_define(, src_lock);
+
/* Memory boundaries of this CU. */
void *startp;
void *endp;
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 613f61c8..f0243643 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -179,6 +179,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
eu_search_tree_init (&newp->locs_tree);
rwlock_init (newp->abbrev_lock);
rwlock_init (newp->split_lock);
+ mutex_init (newp->src_lock);
/* v4 debug type units have version == 4 and unit_type == DW_UT_type. */
if (debug_types)