[2/9,libbacktrace] Add altlink field to struct dwarf_data

Message ID 20181211101411.7067-3-tdevries@suse.de
State New
Headers show
Series
  • Handle .gnu_debugaltlink
Related show

Commit Message

Tom de Vries Dec. 11, 2018, 10:14 a.m.
Add an altlink field to struct dwarf_data, and initialize it with the pointer
to the struct dwarf_data for the .gnu_debugaltlink.

2018-11-11  Tom de Vries  <tdevries@suse.de>

	* dwarf.c (struct dwarf_data): Add altlink field.
	(backtrace_dwarf_add): Add and handle fileline_entry and
	fileline_altlink parameters.
	* elf.c	(elf_add): Add and handle fileline_entry parameter.  Add args to
	backtrace_dwarf_add call.
	(phdr_callback, backtrace_initialize): Add arguments to elf_add calls.
	* internal.h (backtrace_dwarf_add): Add fileline_entry and
	fileline_altlink parameters.
	* pecoff.c (coff_add): Add args to backtrace_dwarf_add call.
	* xcoff.c (xcoff_add): Same.
---
 libbacktrace/dwarf.c    | 13 ++++++++++---
 libbacktrace/elf.c      | 24 +++++++++++++++---------
 libbacktrace/internal.h |  4 +++-
 libbacktrace/pecoff.c   |  3 ++-
 libbacktrace/xcoff.c    |  3 ++-
 5 files changed, 32 insertions(+), 15 deletions(-)

-- 
2.16.4

Comments

Ian Lance Taylor Jan. 16, 2019, 1:02 a.m. | #1
On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevries@suse.de> wrote:
>

> Add an altlink field to struct dwarf_data, and initialize it with the pointer

> to the struct dwarf_data for the .gnu_debugaltlink.

>

> 2018-11-11  Tom de Vries  <tdevries@suse.de>

>

>         * dwarf.c (struct dwarf_data): Add altlink field.

>         (backtrace_dwarf_add): Add and handle fileline_entry and

>         fileline_altlink parameters.

>         * elf.c (elf_add): Add and handle fileline_entry parameter.  Add args to

>         backtrace_dwarf_add call.

>         (phdr_callback, backtrace_initialize): Add arguments to elf_add calls.

>         * internal.h (backtrace_dwarf_add): Add fileline_entry and

>         fileline_altlink parameters.

>         * pecoff.c (coff_add): Add args to backtrace_dwarf_add call.

>         * xcoff.c (xcoff_add): Same.



> @@ -2968,7 +2970,7 @@ build_dwarf_data (struct backtrace_state *state,

>                   size_t dwarf_str_size,

>                   int is_bigendian,

>                   backtrace_error_callback error_callback,

> -                 void *data)

> +                 void *data, struct dwarf_data *altlink)

>  {


error_callback and data should remain the last two parameters, as they
are for many of the functions in this file.


>   @@ -3031,7 +3034,8 @@ backtrace_dwarf_add (struct backtrace_state *state,

>                      size_t dwarf_str_size,

>                      int is_bigendian,

>                      backtrace_error_callback error_callback,

> -                    void *data, fileline *fileline_fn)

> +                    void *data, fileline *fileline_fn, void **fileline_entry,

> +                    void *fileline_altlink)


The new fileline_altlink parameter should come before error_callback,
as it is not error_callback/data and is not a result parameter.

What is fileline_entry for?  Why is it void**?

Ian
Tom de Vries Jan. 16, 2019, 4:33 p.m. | #2
On 16-01-19 02:02, Ian Lance Taylor wrote:
> On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevries@suse.de> wrote:

>>

>> Add an altlink field to struct dwarf_data, and initialize it with the pointer

>> to the struct dwarf_data for the .gnu_debugaltlink.

>>

>> 2018-11-11  Tom de Vries  <tdevries@suse.de>

>>

>>         * dwarf.c (struct dwarf_data): Add altlink field.

>>         (backtrace_dwarf_add): Add and handle fileline_entry and

>>         fileline_altlink parameters.

>>         * elf.c (elf_add): Add and handle fileline_entry parameter.  Add args to

>>         backtrace_dwarf_add call.

>>         (phdr_callback, backtrace_initialize): Add arguments to elf_add calls.

>>         * internal.h (backtrace_dwarf_add): Add fileline_entry and

>>         fileline_altlink parameters.

>>         * pecoff.c (coff_add): Add args to backtrace_dwarf_add call.

>>         * xcoff.c (xcoff_add): Same.

> 

> 

>> @@ -2968,7 +2970,7 @@ build_dwarf_data (struct backtrace_state *state,

>>                   size_t dwarf_str_size,

>>                   int is_bigendian,

>>                   backtrace_error_callback error_callback,

>> -                 void *data)

>> +                 void *data, struct dwarf_data *altlink)

>>  {

> 

> error_callback and data should remain the last two parameters, as they

> are for many of the functions in this file.

> 

> 


Done.

>>   @@ -3031,7 +3034,8 @@ backtrace_dwarf_add (struct backtrace_state *state,

>>                      size_t dwarf_str_size,

>>                      int is_bigendian,

>>                      backtrace_error_callback error_callback,

>> -                    void *data, fileline *fileline_fn)

>> +                    void *data, fileline *fileline_fn, void **fileline_entry,

>> +                    void *fileline_altlink)

> 

> The new fileline_altlink parameter should come before error_callback,

> as it is not error_callback/data and is not a result parameter.

> 


Done.

> What is fileline_entry for? 


There are two bits to this patch:
- add fileline_entry parameter to elf_add.  This allows the callers of
  elf_add access to the struct dwarf_data pointer corresponding to the
  added elf.
- add an altlink field to struct dwarf_data, and initialize it with the
  pointer to the struct dwarf_data for the .gnu_debugaltlink.

I've split the patch up this way now, hoping it will make things clearer
and/or easier to review.

> Why is it void**?


It's really struct dwarf_data *, but struct dwarf_data is a type
declared in dwarf.c, so it's not known in other files.

Thanks,
- Tom

Here's the first part.
[libbacktrace] Return struct dwarf_data pointer from elf_add

Allow the caller of elf_add access to the struct dwarf_data pointer
corresponding to the added elf.

2018-11-11  Tom de Vries  <tdevries@suse.de>

	* internal.h (backtrace_dwarf_add): Add fileline_entry parameter.
	* dwarf.c (backtrace_dwarf_add): Add and handle fileline_entry parameter.
	* elf.c	(elf_add): Add and handle fileline_entry parameter.  Add
	argument to backtrace_dwarf_add call.
	(phdr_callback, backtrace_initialize): Add argument to elf_add calls.
	* pecoff.c (coff_add): Add argument to backtrace_dwarf_add call.
	* xcoff.c (xcoff_add): Same.

---
 libbacktrace/dwarf.c    |  6 +++++-
 libbacktrace/elf.c      | 23 ++++++++++++++---------
 libbacktrace/internal.h |  3 ++-
 libbacktrace/pecoff.c   |  3 ++-
 libbacktrace/xcoff.c    |  3 ++-
 5 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index af864d68b00..c7913f43617 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -3045,7 +3045,8 @@ backtrace_dwarf_add (struct backtrace_state *state,
 		     size_t dwarf_str_size,
 		     int is_bigendian,
 		     backtrace_error_callback error_callback,
-		     void *data, fileline *fileline_fn)
+		     void *data, fileline *fileline_fn,
+		     void **fileline_entry)
 {
   struct dwarf_data *fdata;
 
@@ -3057,6 +3058,9 @@ backtrace_dwarf_add (struct backtrace_state *state,
   if (fdata == NULL)
     return 0;
 
+  if (fileline_entry != NULL)
+    *fileline_entry = fdata;
+
   if (!state->threaded)
     {
       struct dwarf_data **pp;
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index e363e470525..6f99461db84 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2638,8 +2638,8 @@ static int
 elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	 uintptr_t base_address, backtrace_error_callback error_callback,
 	 void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
-	 int exe, int debuginfo, const char *with_buildid_data,
-	 uint32_t with_buildid_size)
+	 void **fileline_entry, int exe, int debuginfo,
+	 const char *with_buildid_data, uint32_t with_buildid_size)
 {
   struct backtrace_view ehdr_view;
   b_elf_ehdr ehdr;
@@ -3042,7 +3042,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3080,7 +3081,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3106,8 +3108,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	  int ret;
 
 	  ret = elf_add (state, filename, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1,
-			 debugaltlink_buildid_data, debugaltlink_buildid_size);
+			 fileline_fn, found_sym, found_dwarf, NULL,
+			 0, 1, debugaltlink_buildid_data,
+			 debugaltlink_buildid_size);
 	  backtrace_release_view (state, &debugaltlink_view, error_callback,
 				  data);
 	  debugaltlink_view_valid = 0;
@@ -3269,7 +3272,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    fileline_entry))
     goto fail;
 
   *found_dwarf = 1;
@@ -3359,7 +3363,7 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
 
   if (elf_add (pd->state, filename, descriptor, info->dlpi_addr,
 	       pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
-	       &found_dwarf, 0, 0, NULL, 0))
+	       &found_dwarf, NULL, 0, 0, NULL, 0))
     {
       if (found_dwarf)
 	{
@@ -3387,7 +3391,8 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
   struct phdr_data pd;
 
   ret = elf_add (state, filename, descriptor, 0, error_callback, data,
-		 &elf_fileline_fn, &found_sym, &found_dwarf, 1, 0, NULL, 0);
+		 &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL,
+		 0);
   if (!ret)
     return 0;
 
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index bf3e7d1989f..0664b2e10c3 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -302,7 +302,8 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				size_t dwarf_str_size,
 				int is_bigendian,
 				backtrace_error_callback error_callback,
-				void *data, fileline *fileline_fn);
+				void *data, fileline *fileline_fn,
+				void **fileline_entry);
 
 /* A test-only hook for elf_uncompress_zdebug.  */
 
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index f51fc0f13c5..cd20cbe17a7 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -867,7 +867,8 @@ coff_add (struct backtrace_state *state, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    0, /* FIXME */
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    NULL))
     goto fail;
 
   *found_dwarf = 1;
diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c
index 111134d4d21..095800b4f71 100644
--- a/libbacktrace/xcoff.c
+++ b/libbacktrace/xcoff.c
@@ -1315,7 +1315,8 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
 				dwsect[DWSECT_STR].data,
 				dwsect[DWSECT_STR].size,
 				1, /* big endian */
-				error_callback, data, fileline_fn))
+				error_callback, data, fileline_fn,
+				NULL))
 	goto fail;
     }
Tom de Vries Jan. 16, 2019, 4:34 p.m. | #3
On 16-01-19 17:33, Tom de Vries wrote:
> On 16-01-19 02:02, Ian Lance Taylor wrote:

>> On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevries@suse.de> wrote:

>>>

>>> Add an altlink field to struct dwarf_data, and initialize it with the pointer

>>> to the struct dwarf_data for the .gnu_debugaltlink.

>>>

>>> 2018-11-11  Tom de Vries  <tdevries@suse.de>

>>>

>>>         * dwarf.c (struct dwarf_data): Add altlink field.

>>>         (backtrace_dwarf_add): Add and handle fileline_entry and

>>>         fileline_altlink parameters.

>>>         * elf.c (elf_add): Add and handle fileline_entry parameter.  Add args to

>>>         backtrace_dwarf_add call.

>>>         (phdr_callback, backtrace_initialize): Add arguments to elf_add calls.

>>>         * internal.h (backtrace_dwarf_add): Add fileline_entry and

>>>         fileline_altlink parameters.

>>>         * pecoff.c (coff_add): Add args to backtrace_dwarf_add call.

>>>         * xcoff.c (xcoff_add): Same.

>>

>>

>>> @@ -2968,7 +2970,7 @@ build_dwarf_data (struct backtrace_state *state,

>>>                   size_t dwarf_str_size,

>>>                   int is_bigendian,

>>>                   backtrace_error_callback error_callback,

>>> -                 void *data)

>>> +                 void *data, struct dwarf_data *altlink)

>>>  {

>>

>> error_callback and data should remain the last two parameters, as they

>> are for many of the functions in this file.

>>

>>

> 

> Done.

> 

>>>   @@ -3031,7 +3034,8 @@ backtrace_dwarf_add (struct backtrace_state *state,

>>>                      size_t dwarf_str_size,

>>>                      int is_bigendian,

>>>                      backtrace_error_callback error_callback,

>>> -                    void *data, fileline *fileline_fn)

>>> +                    void *data, fileline *fileline_fn, void **fileline_entry,

>>> +                    void *fileline_altlink)

>>

>> The new fileline_altlink parameter should come before error_callback,

>> as it is not error_callback/data and is not a result parameter.

>>

> 

> Done.

> 

>> What is fileline_entry for? 

> 

> There are two bits to this patch:

> - add fileline_entry parameter to elf_add.  This allows the callers of

>   elf_add access to the struct dwarf_data pointer corresponding to the

>   added elf.

> - add an altlink field to struct dwarf_data, and initialize it with the

>   pointer to the struct dwarf_data for the .gnu_debugaltlink.

> 

> I've split the patch up this way now, hoping it will make things clearer

> and/or easier to review.

> 

>> Why is it void**?

> 

> It's really struct dwarf_data *, but struct dwarf_data is a type

> declared in dwarf.c, so it's not known in other files.

> 

> Thanks,

> - Tom

> 

> Here's the first part.

> 


And here's the second part.
[libbacktrace] Add altlink field to struct dwarf_data

Add an altlink field to struct dwarf_data, and initialize it with the pointer
to the struct dwarf_data for the .gnu_debugaltlink.

2018-11-11  Tom de Vries  <tdevries@suse.de>

	* dwarf.c (struct dwarf_data): Add altlink field.
	(backtrace_dwarf_add): Add and handle fileline_altlink parameter.
	* elf.c	(elf_add): Add argument to backtrace_dwarf_add call.
	(phdr_callback, backtrace_initialize): Add argument to elf_add calls.
	* internal.h (backtrace_dwarf_add): Add fileline_altlink parameter.
	* pecoff.c (coff_add): Add argument to backtrace_dwarf_add call.
	* xcoff.c (xcoff_add): Same.

---
 libbacktrace/dwarf.c    | 7 ++++++-
 libbacktrace/elf.c      | 4 +++-
 libbacktrace/internal.h | 1 +
 libbacktrace/pecoff.c   | 1 +
 libbacktrace/xcoff.c    | 1 +
 5 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index c7913f43617..5469f968468 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -343,6 +343,8 @@ struct dwarf_data
 {
   /* The data for the next file we know about.  */
   struct dwarf_data *next;
+  /* The data for .gnu_debugaltlink.  */
+  struct dwarf_data *altlink;
   /* The base address for this file.  */
   uintptr_t base_address;
   /* A sorted list of address ranges.  */
@@ -2981,6 +2983,7 @@ build_dwarf_data (struct backtrace_state *state,
 		  const unsigned char *dwarf_str,
 		  size_t dwarf_str_size,
 		  int is_bigendian,
+		  struct dwarf_data *altlink,
 		  backtrace_error_callback error_callback,
 		  void *data)
 {
@@ -3009,6 +3012,7 @@ build_dwarf_data (struct backtrace_state *state,
     return NULL;
 
   fdata->next = NULL;
+  fdata->altlink = altlink;
   fdata->base_address = base_address;
   fdata->addrs = addrs;
   fdata->addrs_count = addrs_count;
@@ -3044,6 +3048,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
 		     const unsigned char *dwarf_str,
 		     size_t dwarf_str_size,
 		     int is_bigendian,
+		     void *fileline_altlink,
 		     backtrace_error_callback error_callback,
 		     void *data, fileline *fileline_fn,
 		     void **fileline_entry)
@@ -3054,7 +3059,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
 			    dwarf_line, dwarf_line_size, dwarf_abbrev,
 			    dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
 			    dwarf_str, dwarf_str_size, is_bigendian,
-			    error_callback, data);
+			    fileline_altlink, error_callback, data);
   if (fdata == NULL)
     return 0;
 
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 6f99461db84..88987edb6f4 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -3097,6 +3097,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
       debuglink_view_valid = 0;
     }
 
+  void *fileline_altlink = NULL;
   if (debugaltlink_name != NULL)
     {
       int d;
@@ -3108,7 +3109,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	  int ret;
 
 	  ret = elf_add (state, filename, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, NULL,
+			 fileline_fn, found_sym, found_dwarf, &fileline_altlink,
 			 0, 1, debugaltlink_buildid_data,
 			 debugaltlink_buildid_size);
 	  backtrace_release_view (state, &debugaltlink_view, error_callback,
@@ -3272,6 +3273,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
+			    fileline_altlink,
 			    error_callback, data, fileline_fn,
 			    fileline_entry))
     goto fail;
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 0664b2e10c3..febdaeebc21 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -301,6 +301,7 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				const unsigned char *dwarf_str,
 				size_t dwarf_str_size,
 				int is_bigendian,
+				void *fileline_altlink,
 				backtrace_error_callback error_callback,
 				void *data, fileline *fileline_fn,
 				void **fileline_entry);
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index cd20cbe17a7..da1982fd3ca 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -867,6 +867,7 @@ coff_add (struct backtrace_state *state, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    0, /* FIXME */
+			    NULL,
 			    error_callback, data, fileline_fn,
 			    NULL))
     goto fail;
diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c
index 095800b4f71..d50b5bc517e 100644
--- a/libbacktrace/xcoff.c
+++ b/libbacktrace/xcoff.c
@@ -1315,6 +1315,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
 				dwsect[DWSECT_STR].data,
 				dwsect[DWSECT_STR].size,
 				1, /* big endian */
+				NULL,
 				error_callback, data, fileline_fn,
 				NULL))
 	goto fail;
Ian Lance Taylor Jan. 16, 2019, 5:17 p.m. | #4
On Wed, Jan 16, 2019 at 8:33 AM Tom de Vries <tdevries@suse.de> wrote:
>

> > Why is it void**?

>

> It's really struct dwarf_data *, but struct dwarf_data is a type

> declared in dwarf.c, so it's not known in other files.


It woud be OK to add "struct dwarf_data;" to internal.h and refer to
the struct, without dereferencing it, in elf.c.

Ian
Tom de Vries Jan. 16, 2019, 10:19 p.m. | #5
On 16-01-19 18:17, Ian Lance Taylor wrote:
> On Wed, Jan 16, 2019 at 8:33 AM Tom de Vries <tdevries@suse.de> wrote:

>>

>>> Why is it void**?

>>

>> It's really struct dwarf_data *, but struct dwarf_data is a type

>> declared in dwarf.c, so it's not known in other files.

> 

> It woud be OK to add "struct dwarf_data;" to internal.h and refer to

> the struct, without dereferencing it, in elf.c.


Updated accordingly.

Thanks,
- Tom
[libbacktrace] Return struct dwarf_data pointer from elf_add

Allow the caller of elf_add access to the struct dwarf_data pointer
corresponding to the added elf.

2018-11-11  Tom de Vries  <tdevries@suse.de>

	* internal.h (backtrace_dwarf_add): Add fileline_entry parameter.
	* dwarf.c (backtrace_dwarf_add): Add and handle fileline_entry parameter.
	* elf.c	(elf_add): Add and handle fileline_entry parameter.  Add
	argument to backtrace_dwarf_add call.
	(phdr_callback, backtrace_initialize): Add argument to elf_add calls.
	* pecoff.c (coff_add): Add argument to backtrace_dwarf_add call.
	* xcoff.c (xcoff_add): Same.

---
 libbacktrace/dwarf.c    |  6 +++++-
 libbacktrace/elf.c      | 23 ++++++++++++++---------
 libbacktrace/internal.h |  5 ++++-
 libbacktrace/pecoff.c   |  3 ++-
 libbacktrace/xcoff.c    |  3 ++-
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index dca5d909d9f..190c6fc131f 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -3064,7 +3064,8 @@ backtrace_dwarf_add (struct backtrace_state *state,
 		     size_t dwarf_str_size,
 		     int is_bigendian,
 		     backtrace_error_callback error_callback,
-		     void *data, fileline *fileline_fn)
+		     void *data, fileline *fileline_fn,
+		     struct dwarf_data **fileline_entry)
 {
   struct dwarf_data *fdata;
 
@@ -3076,6 +3077,9 @@ backtrace_dwarf_add (struct backtrace_state *state,
   if (fdata == NULL)
     return 0;
 
+  if (fileline_entry != NULL)
+    *fileline_entry = fdata;
+
   if (!state->threaded)
     {
       struct dwarf_data **pp;
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index e363e470525..2841c06cdb2 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2638,8 +2638,8 @@ static int
 elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	 uintptr_t base_address, backtrace_error_callback error_callback,
 	 void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
-	 int exe, int debuginfo, const char *with_buildid_data,
-	 uint32_t with_buildid_size)
+	 struct dwarf_data **fileline_entry, int exe, int debuginfo,
+	 const char *with_buildid_data, uint32_t with_buildid_size)
 {
   struct backtrace_view ehdr_view;
   b_elf_ehdr ehdr;
@@ -3042,7 +3042,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3080,7 +3081,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3106,8 +3108,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	  int ret;
 
 	  ret = elf_add (state, filename, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1,
-			 debugaltlink_buildid_data, debugaltlink_buildid_size);
+			 fileline_fn, found_sym, found_dwarf, NULL,
+			 0, 1, debugaltlink_buildid_data,
+			 debugaltlink_buildid_size);
 	  backtrace_release_view (state, &debugaltlink_view, error_callback,
 				  data);
 	  debugaltlink_view_valid = 0;
@@ -3269,7 +3272,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    fileline_entry))
     goto fail;
 
   *found_dwarf = 1;
@@ -3359,7 +3363,7 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
 
   if (elf_add (pd->state, filename, descriptor, info->dlpi_addr,
 	       pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
-	       &found_dwarf, 0, 0, NULL, 0))
+	       &found_dwarf, NULL, 0, 0, NULL, 0))
     {
       if (found_dwarf)
 	{
@@ -3387,7 +3391,8 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
   struct phdr_data pd;
 
   ret = elf_add (state, filename, descriptor, 0, error_callback, data,
-		 &elf_fileline_fn, &found_sym, &found_dwarf, 1, 0, NULL, 0);
+		 &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL,
+		 0);
   if (!ret)
     return 0;
 
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index bf3e7d1989f..d9ab401ce41 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -286,6 +286,8 @@ extern int backtrace_initialize (struct backtrace_state *state,
 				 void *data,
 				 fileline *fileline_fn);
 
+struct dwarf_data;
+
 /* Add file/line information for a DWARF module.  */
 
 extern int backtrace_dwarf_add (struct backtrace_state *state,
@@ -302,7 +304,8 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				size_t dwarf_str_size,
 				int is_bigendian,
 				backtrace_error_callback error_callback,
-				void *data, fileline *fileline_fn);
+				void *data, fileline *fileline_fn,
+				struct dwarf_data **fileline_entry);
 
 /* A test-only hook for elf_uncompress_zdebug.  */
 
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index f51fc0f13c5..cd20cbe17a7 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -867,7 +867,8 @@ coff_add (struct backtrace_state *state, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    0, /* FIXME */
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    NULL))
     goto fail;
 
   *found_dwarf = 1;
diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c
index 111134d4d21..095800b4f71 100644
--- a/libbacktrace/xcoff.c
+++ b/libbacktrace/xcoff.c
@@ -1315,7 +1315,8 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
 				dwsect[DWSECT_STR].data,
 				dwsect[DWSECT_STR].size,
 				1, /* big endian */
-				error_callback, data, fileline_fn))
+				error_callback, data, fileline_fn,
+				NULL))
 	goto fail;
     }
Tom de Vries Jan. 16, 2019, 10:20 p.m. | #6
On 16-01-19 17:34, Tom de Vries wrote:
> On 16-01-19 17:33, Tom de Vries wrote:

>> On 16-01-19 02:02, Ian Lance Taylor wrote:

>>> On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevries@suse.de> wrote:

>>>>

>>>> Add an altlink field to struct dwarf_data, and initialize it with the pointer

>>>> to the struct dwarf_data for the .gnu_debugaltlink.

>>>>

>>>> 2018-11-11  Tom de Vries  <tdevries@suse.de>

>>>>

>>>>         * dwarf.c (struct dwarf_data): Add altlink field.

>>>>         (backtrace_dwarf_add): Add and handle fileline_entry and

>>>>         fileline_altlink parameters.

>>>>         * elf.c (elf_add): Add and handle fileline_entry parameter.  Add args to

>>>>         backtrace_dwarf_add call.

>>>>         (phdr_callback, backtrace_initialize): Add arguments to elf_add calls.

>>>>         * internal.h (backtrace_dwarf_add): Add fileline_entry and

>>>>         fileline_altlink parameters.

>>>>         * pecoff.c (coff_add): Add args to backtrace_dwarf_add call.

>>>>         * xcoff.c (xcoff_add): Same.

>>>

>>>

>>>> @@ -2968,7 +2970,7 @@ build_dwarf_data (struct backtrace_state *state,

>>>>                   size_t dwarf_str_size,

>>>>                   int is_bigendian,

>>>>                   backtrace_error_callback error_callback,

>>>> -                 void *data)

>>>> +                 void *data, struct dwarf_data *altlink)

>>>>  {

>>>

>>> error_callback and data should remain the last two parameters, as they

>>> are for many of the functions in this file.

>>>

>>>

>>

>> Done.

>>

>>>>   @@ -3031,7 +3034,8 @@ backtrace_dwarf_add (struct backtrace_state *state,

>>>>                      size_t dwarf_str_size,

>>>>                      int is_bigendian,

>>>>                      backtrace_error_callback error_callback,

>>>> -                    void *data, fileline *fileline_fn)

>>>> +                    void *data, fileline *fileline_fn, void **fileline_entry,

>>>> +                    void *fileline_altlink)

>>>

>>> The new fileline_altlink parameter should come before error_callback,

>>> as it is not error_callback/data and is not a result parameter.

>>>

>>

>> Done.

>>

>>> What is fileline_entry for? 

>>

>> There are two bits to this patch:

>> - add fileline_entry parameter to elf_add.  This allows the callers of

>>   elf_add access to the struct dwarf_data pointer corresponding to the

>>   added elf.

>> - add an altlink field to struct dwarf_data, and initialize it with the

>>   pointer to the struct dwarf_data for the .gnu_debugaltlink.

>>

>> I've split the patch up this way now, hoping it will make things clearer

>> and/or easier to review.

>>

>>> Why is it void**?

>>

>> It's really struct dwarf_data *, but struct dwarf_data is a type

>> declared in dwarf.c, so it's not known in other files.

>>

>> Thanks,

>> - Tom

>>

>> Here's the first part.

>>

> 

> And here's the second part.


Updated to use 'struct dwarf_data' instead of 'void'.

Thanks,
- Tom
>
[libbacktrace] Add altlink field to struct dwarf_data

Add an altlink field to struct dwarf_data, and initialize it with the pointer
to the struct dwarf_data for the .gnu_debugaltlink.

2018-11-11  Tom de Vries  <tdevries@suse.de>

	* dwarf.c (struct dwarf_data): Add altlink field.
	(backtrace_dwarf_add): Add and handle fileline_altlink parameter.
	* elf.c	(elf_add): Add argument to backtrace_dwarf_add call.
	(phdr_callback, backtrace_initialize): Add argument to elf_add calls.
	* internal.h (backtrace_dwarf_add): Add fileline_altlink parameter.
	* pecoff.c (coff_add): Add argument to backtrace_dwarf_add call.
	* xcoff.c (xcoff_add): Same.

---
 libbacktrace/dwarf.c    | 7 ++++++-
 libbacktrace/elf.c      | 4 +++-
 libbacktrace/internal.h | 1 +
 libbacktrace/pecoff.c   | 1 +
 libbacktrace/xcoff.c    | 1 +
 5 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 190c6fc131f..83cdb52ef26 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -343,6 +343,8 @@ struct dwarf_data
 {
   /* The data for the next file we know about.  */
   struct dwarf_data *next;
+  /* The data for .gnu_debugaltlink.  */
+  struct dwarf_data *altlink;
   /* The base address for this file.  */
   uintptr_t base_address;
   /* A sorted list of address ranges.  */
@@ -3000,6 +3002,7 @@ build_dwarf_data (struct backtrace_state *state,
 		  const unsigned char *dwarf_str,
 		  size_t dwarf_str_size,
 		  int is_bigendian,
+		  struct dwarf_data *altlink,
 		  backtrace_error_callback error_callback,
 		  void *data)
 {
@@ -3028,6 +3031,7 @@ build_dwarf_data (struct backtrace_state *state,
     return NULL;
 
   fdata->next = NULL;
+  fdata->altlink = altlink;
   fdata->base_address = base_address;
   fdata->addrs = addrs;
   fdata->addrs_count = addrs_count;
@@ -3063,6 +3067,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
 		     const unsigned char *dwarf_str,
 		     size_t dwarf_str_size,
 		     int is_bigendian,
+		     struct dwarf_data *fileline_altlink,
 		     backtrace_error_callback error_callback,
 		     void *data, fileline *fileline_fn,
 		     struct dwarf_data **fileline_entry)
@@ -3073,7 +3078,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
 			    dwarf_line, dwarf_line_size, dwarf_abbrev,
 			    dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
 			    dwarf_str, dwarf_str_size, is_bigendian,
-			    error_callback, data);
+			    fileline_altlink, error_callback, data);
   if (fdata == NULL)
     return 0;
 
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 2841c06cdb2..36b20cba149 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -3097,6 +3097,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
       debuglink_view_valid = 0;
     }
 
+  struct dwarf_data *fileline_altlink = NULL;
   if (debugaltlink_name != NULL)
     {
       int d;
@@ -3108,7 +3109,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	  int ret;
 
 	  ret = elf_add (state, filename, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, NULL,
+			 fileline_fn, found_sym, found_dwarf, &fileline_altlink,
 			 0, 1, debugaltlink_buildid_data,
 			 debugaltlink_buildid_size);
 	  backtrace_release_view (state, &debugaltlink_view, error_callback,
@@ -3272,6 +3273,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
+			    fileline_altlink,
 			    error_callback, data, fileline_fn,
 			    fileline_entry))
     goto fail;
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index d9ab401ce41..e8389779322 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -303,6 +303,7 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				const unsigned char *dwarf_str,
 				size_t dwarf_str_size,
 				int is_bigendian,
+				struct dwarf_data *fileline_altlink,
 				backtrace_error_callback error_callback,
 				void *data, fileline *fileline_fn,
 				struct dwarf_data **fileline_entry);
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index cd20cbe17a7..da1982fd3ca 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -867,6 +867,7 @@ coff_add (struct backtrace_state *state, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    0, /* FIXME */
+			    NULL,
 			    error_callback, data, fileline_fn,
 			    NULL))
     goto fail;
diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c
index 095800b4f71..d50b5bc517e 100644
--- a/libbacktrace/xcoff.c
+++ b/libbacktrace/xcoff.c
@@ -1315,6 +1315,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
 				dwsect[DWSECT_STR].data,
 				dwsect[DWSECT_STR].size,
 				1, /* big endian */
+				NULL,
 				error_callback, data, fileline_fn,
 				NULL))
 	goto fail;
Ian Lance Taylor Jan. 16, 2019, 10:25 p.m. | #7
On Wed, Jan 16, 2019 at 2:20 PM Tom de Vries <tdevries@suse.de> wrote:
>

> On 16-01-19 17:34, Tom de Vries wrote:

> > On 16-01-19 17:33, Tom de Vries wrote:

> >> On 16-01-19 02:02, Ian Lance Taylor wrote:

> >>> On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevries@suse.de> wrote:

> >>>>

> >>>> Add an altlink field to struct dwarf_data, and initialize it with the pointer

> >>>> to the struct dwarf_data for the .gnu_debugaltlink.

> >>>>

> >>>> 2018-11-11  Tom de Vries  <tdevries@suse.de>

> >>>>

> >>>>         * dwarf.c (struct dwarf_data): Add altlink field.

> >>>>         (backtrace_dwarf_add): Add and handle fileline_entry and

> >>>>         fileline_altlink parameters.

> >>>>         * elf.c (elf_add): Add and handle fileline_entry parameter.  Add args to

> >>>>         backtrace_dwarf_add call.

> >>>>         (phdr_callback, backtrace_initialize): Add arguments to elf_add calls.

> >>>>         * internal.h (backtrace_dwarf_add): Add fileline_entry and

> >>>>         fileline_altlink parameters.

> >>>>         * pecoff.c (coff_add): Add args to backtrace_dwarf_add call.

> >>>>         * xcoff.c (xcoff_add): Same.

> >>>

> >>>

> >>>> @@ -2968,7 +2970,7 @@ build_dwarf_data (struct backtrace_state *state,

> >>>>                   size_t dwarf_str_size,

> >>>>                   int is_bigendian,

> >>>>                   backtrace_error_callback error_callback,

> >>>> -                 void *data)

> >>>> +                 void *data, struct dwarf_data *altlink)

> >>>>  {

> >>>

> >>> error_callback and data should remain the last two parameters, as they

> >>> are for many of the functions in this file.

> >>>

> >>>

> >>

> >> Done.

> >>

> >>>>   @@ -3031,7 +3034,8 @@ backtrace_dwarf_add (struct backtrace_state *state,

> >>>>                      size_t dwarf_str_size,

> >>>>                      int is_bigendian,

> >>>>                      backtrace_error_callback error_callback,

> >>>> -                    void *data, fileline *fileline_fn)

> >>>> +                    void *data, fileline *fileline_fn, void **fileline_entry,

> >>>> +                    void *fileline_altlink)

> >>>

> >>> The new fileline_altlink parameter should come before error_callback,

> >>> as it is not error_callback/data and is not a result parameter.

> >>>

> >>

> >> Done.

> >>

> >>> What is fileline_entry for?

> >>

> >> There are two bits to this patch:

> >> - add fileline_entry parameter to elf_add.  This allows the callers of

> >>   elf_add access to the struct dwarf_data pointer corresponding to the

> >>   added elf.

> >> - add an altlink field to struct dwarf_data, and initialize it with the

> >>   pointer to the struct dwarf_data for the .gnu_debugaltlink.

> >>

> >> I've split the patch up this way now, hoping it will make things clearer

> >> and/or easier to review.

> >>

> >>> Why is it void**?

> >>

> >> It's really struct dwarf_data *, but struct dwarf_data is a type

> >> declared in dwarf.c, so it's not known in other files.

> >>

> >> Thanks,

> >> - Tom

> >>

> >> Here's the first part.

> >>

> >

> > And here's the second part.

>

> Updated to use 'struct dwarf_data' instead of 'void'.


I think you need to explicitly add a standalone line

struct dwarf_data;

 in internal.h before the declaration of backtrace_dwarf_add to avoid
compiler warnings in some cases.  (Like the declaration of
backtrace_state in backtrace.h.)

This is OK with that change.

Thanks.

Ian
Ian Lance Taylor Jan. 16, 2019, 10:39 p.m. | #8
On Wed, Jan 16, 2019 at 2:18 PM Tom de Vries <tdevries@suse.de> wrote:
>

> On 16-01-19 18:17, Ian Lance Taylor wrote:

> > On Wed, Jan 16, 2019 at 8:33 AM Tom de Vries <tdevries@suse.de> wrote:

> >>

> >>> Why is it void**?

> >>

> >> It's really struct dwarf_data *, but struct dwarf_data is a type

> >> declared in dwarf.c, so it's not known in other files.

> >

> > It woud be OK to add "struct dwarf_data;" to internal.h and refer to

> > the struct, without dereferencing it, in elf.c.

>

> Updated accordingly.


This is OK.

Thanks.

I see that the struct declaration is in this patch.

Ian

Patch

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 0f8f70881f8..b571c9fbb06 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -343,6 +343,8 @@  struct dwarf_data
 {
   /* The data for the next file we know about.  */
   struct dwarf_data *next;
+  /* The data for .gnu_debugaltlink.  */
+  struct dwarf_data *altlink;
   /* The base address for this file.  */
   uintptr_t base_address;
   /* A sorted list of address ranges.  */
@@ -2968,7 +2970,7 @@  build_dwarf_data (struct backtrace_state *state,
 		  size_t dwarf_str_size,
 		  int is_bigendian,
 		  backtrace_error_callback error_callback,
-		  void *data)
+		  void *data, struct dwarf_data *altlink)
 {
   struct unit_addrs_vector addrs_vec;
   struct unit_addrs *addrs;
@@ -2995,6 +2997,7 @@  build_dwarf_data (struct backtrace_state *state,
     return NULL;
 
   fdata->next = NULL;
+  fdata->altlink = altlink;
   fdata->base_address = base_address;
   fdata->addrs = addrs;
   fdata->addrs_count = addrs_count;
@@ -3031,7 +3034,8 @@  backtrace_dwarf_add (struct backtrace_state *state,
 		     size_t dwarf_str_size,
 		     int is_bigendian,
 		     backtrace_error_callback error_callback,
-		     void *data, fileline *fileline_fn)
+		     void *data, fileline *fileline_fn, void **fileline_entry,
+		     void *fileline_altlink)
 {
   struct dwarf_data *fdata;
 
@@ -3039,10 +3043,13 @@  backtrace_dwarf_add (struct backtrace_state *state,
 			    dwarf_line, dwarf_line_size, dwarf_abbrev,
 			    dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
 			    dwarf_str, dwarf_str_size, is_bigendian,
-			    error_callback, data);
+			    error_callback, data, fileline_altlink);
   if (fdata == NULL)
     return 0;
 
+  if (fileline_entry != NULL)
+    *fileline_entry = fdata;
+
   if (!state->threaded)
     {
       struct dwarf_data **pp;
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index f3bc2119c07..aeb248ec5e3 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2638,8 +2638,8 @@  static int
 elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	 uintptr_t base_address, backtrace_error_callback error_callback,
 	 void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
-	 int exe, int debuginfo, const char *with_buildid_data,
-	 uint32_t with_buildid_size)
+	 void **fileline_entry, int exe, int debuginfo,
+	 const char *with_buildid_data, uint32_t with_buildid_size)
 {
   struct backtrace_view ehdr_view;
   b_elf_ehdr ehdr;
@@ -3037,7 +3037,8 @@  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3075,7 +3076,8 @@  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	    backtrace_release_view (state, &debugaltlink_view, error_callback,
 				    data);
 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1, NULL, 0);
+			 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL,
+			 0);
 	  if (ret < 0)
 	    backtrace_close (d, error_callback, data);
 	  else
@@ -3090,6 +3092,7 @@  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
       debuglink_view_valid = 0;
     }
 
+  void *fileline_altlink = NULL;
   if (debugaltlink_name != NULL)
     {
       int d;
@@ -3101,8 +3104,9 @@  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 	  int ret;
 
 	  ret = elf_add (state, filename, d, base_address, error_callback, data,
-			 fileline_fn, found_sym, found_dwarf, 0, 1,
-			 debugaltlink_buildid_data, debugaltlink_buildid_size);
+			 fileline_fn, found_sym, found_dwarf, &fileline_altlink,
+			 0, 1, debugaltlink_buildid_data,
+			 debugaltlink_buildid_size);
 	  backtrace_release_view (state, &debugaltlink_view, error_callback,
 				  data);
 	  debugaltlink_view_valid = 0;
@@ -3264,7 +3268,8 @@  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    fileline_entry, fileline_altlink))
     goto fail;
 
   *found_dwarf = 1;
@@ -3354,7 +3359,7 @@  phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
 
   if (elf_add (pd->state, filename, descriptor, info->dlpi_addr,
 	       pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
-	       &found_dwarf, 0, 0, NULL, 0))
+	       &found_dwarf, NULL, 0, 0, NULL, 0))
     {
       if (found_dwarf)
 	{
@@ -3382,7 +3387,8 @@  backtrace_initialize (struct backtrace_state *state, const char *filename,
   struct phdr_data pd;
 
   ret = elf_add (state, filename, descriptor, 0, error_callback, data,
-		 &elf_fileline_fn, &found_sym, &found_dwarf, 1, 0, NULL, 0);
+		 &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL,
+		 0);
   if (!ret)
     return 0;
 
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 548f9d70905..bcf5a31da68 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -302,7 +302,9 @@  extern int backtrace_dwarf_add (struct backtrace_state *state,
 				size_t dwarf_str_size,
 				int is_bigendian,
 				backtrace_error_callback error_callback,
-				void *data, fileline *fileline_fn);
+				void *data, fileline *fileline_fn,
+				void **fileline_entry,
+				void *fileline_altlink);
 
 /* A test-only hook for elf_uncompress_zdebug.  */
 
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 85737d61d49..fbe481cbbb6 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -867,7 +867,8 @@  coff_add (struct backtrace_state *state, int descriptor,
 			    sections[DEBUG_STR].data,
 			    sections[DEBUG_STR].size,
 			    0, /* FIXME */
-			    error_callback, data, fileline_fn))
+			    error_callback, data, fileline_fn,
+			    NULL, NULL))
     goto fail;
 
   *found_dwarf = 1;
diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c
index 84d0340d744..dc8265c59a8 100644
--- a/libbacktrace/xcoff.c
+++ b/libbacktrace/xcoff.c
@@ -1315,7 +1315,8 @@  xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
 				dwsect[DWSECT_STR].data,
 				dwsect[DWSECT_STR].size,
 				1, /* big endian */
-				error_callback, data, fileline_fn))
+				error_callback, data, fileline_fn,
+				NULL, NULL))
 	goto fail;
     }