This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: ld/2338: objdump -d -l doesn't work correctly
On Tue, Feb 21, 2006 at 12:32:26AM +0100, Eric Botcazou wrote:
> > _bfd_dwarf2_find_nearest_line can't tell the line number when more
> > than one lines have the same address.
>
> Yes, that was also the underlying problem with objdump -d -l.
>
> > I will see if I can implement Dan's approach when I find the time.
>
> Clearly the way to go. But since the relocations are not yet resolved in the
> debug info sections, I think you'll have to resolve them manually.
>
Here is the patch. It seems to work on all testcases I have.
H.J.
----
2006-02-21 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2338
* dwarf2.c (check_function_name): Removed.
(place_sections): New.
(_bfd_dwarf2_find_nearest_line): Updated. Call place_sections
on relocatable files.
(_bfd_dwarf2_find_line): Likewise.
--- bfd/dwarf2.c.rel 2006-02-16 10:08:05.000000000 -0800
+++ bfd/dwarf2.c 2006-02-21 11:40:40.000000000 -0800
@@ -2179,32 +2179,31 @@ find_debug_info (bfd *abfd, asection *af
return NULL;
}
-/* Return TRUE if there is no mismatch bewteen function FUNC and
- section SECTION from symbol table SYMBOLS in ABFD. */
+/* Set unique vmas for loadable sections in ABFD. */
-static bfd_boolean
-check_function_name (bfd *abfd, asection *section, asymbol **symbols,
- const char *func)
+static void
+place_sections (bfd *abfd)
{
- /* Mismatch can only happen when we have 2 functions with the same
- address. It can only occur in a relocatable file. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
- && func != NULL
- && section != NULL
- && symbols != NULL)
+ asection *sect;
+ bfd_vma current_vma = 0;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
- asymbol **p;
+ bfd_size_type sz;
+ bfd_vma vma;
- for (p = symbols; *p != NULL; p++)
- {
- if (((*p)->flags & BSF_FUNCTION) != 0
- && (*p)->name != NULL
- && strcmp ((*p)->name, func) == 0)
- return (*p)->section == section;
- }
- }
+ if ((sect->flags & SEC_LOAD) == 0)
+ continue;
- return TRUE;
+ sz = sect->rawsize ? sect->rawsize : sect->size;
+ if (sz == 0)
+ continue;
+
+ vma = sect->vma;
+ if (current_vma != 0)
+ sect->vma = current_vma;
+ current_vma += vma + sz + 1;
+ }
}
/* The DWARF2 version of find_nearest_line. Return TRUE if the line
@@ -2240,6 +2239,12 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
struct comp_unit* each;
stash = *pinfo;
+
+ /* In a relocatable file, 2 functions may have the same address.
+ We change the section vma so that they won't overlap. */
+ if (!stash && (abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ place_sections (abfd);
+
addr = offset;
if (section->output_section)
addr += section->output_section->vma + section->output_offset;
@@ -2328,9 +2333,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
if (comp_unit_contains_address (each, addr)
&& comp_unit_find_nearest_line (each, addr, filename_ptr,
functionname_ptr,
- linenumber_ptr, stash)
- && check_function_name (abfd, section, symbols,
- *functionname_ptr))
+ linenumber_ptr, stash))
return TRUE;
/* Read each remaining comp. units checking each as they are read. */
@@ -2398,9 +2401,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
filename_ptr,
functionname_ptr,
linenumber_ptr,
- stash)
- && check_function_name (abfd, section, symbols,
- *functionname_ptr))
+ stash))
return TRUE;
}
}
@@ -2442,6 +2443,13 @@ _bfd_dwarf2_find_line (bfd *abfd,
section = bfd_get_section (symbol);
+ stash = *pinfo;
+
+ /* In a relocatable file, 2 functions may have the same address.
+ We change the section vma so that they won't overlap. */
+ if (!stash && (abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ place_sections (abfd);
+
addr = symbol->value;
if (section->output_section)
addr += section->output_section->vma + section->output_offset;
@@ -2449,7 +2457,6 @@ _bfd_dwarf2_find_line (bfd *abfd,
addr += section->vma;
*filename_ptr = NULL;
- stash = *pinfo;
*filename_ptr = NULL;
*linenumber_ptr = 0;