This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: as/ld silently creates programs with undefined references/symbols
- From: Nick Clifton <nickc at redhat dot com>
- To: Russell King <rmk at arm dot linux dot org dot uk>
- Cc: Richard Earnshaw <rearnsha at gcc dot gnu dot org>, binutils at sources dot redhat dot com
- Date: Fri, 13 Aug 2004 18:26:50 +0100
- Subject: Re: as/ld silently creates programs with undefined references/symbols
- References: <40E44A25.6090406@redhat.com> <20040701195056.D8389@flint.arm.linux.org.uk> <40E5447C.1080401@redhat.com> <20040702123710.A24028@flint.arm.linux.org.uk> <40E66B86.4000200@redhat.com> <20040711121944.B13616@flint.arm.linux.org.uk> <40F243E2.2070506@redhat.com> <1089620642.8278.68.camel@pc960.cambridge.arm.com> <20040712092625.A2623@flint.arm.linux.org.uk> <1089621632.8278.72.camel@pc960.cambridge.arm.com> <20040808165653.B17968@flint.arm.linux.org.uk>
Hi Russell,
Actually, it's the bfd that needs fixing to split the mapping symbols
out from the table of values it presents to the rest of the toolchain.
Then other tools would work correctly as well. A separate interface can
then be used to get the map.
Has this been implemented yet? Any ideas when a toolchain with these
fixes in will be officially released?
This is not an implementation of symbol table separation, but I think
that it might help you. The attached patch modifies the
elf32_arm_find_nearest_line() function which is used by tools like the
linker to find a function name associated with a particular address when
it is reporting errors. The modification is to make the function skip
any ARM mapping symbols it encounters in its search.
Would you like to try out this patch and let me know what you think ?
(Note the patch has been made against today's binutils sources in the
CVS repository. Thus you may have trouble if you want to apply it to
say the 2.15 binutils sources. Especially since I converted elf32-arm.h
to ISO C90 this morning...)
Cheers
Nick
bfd/ChangeLog
2004-08-13 Nick Clifton <nickc@redhat.com>
* (is_arm_mapping_symbol_name): New function - return true
when a symbol name matches the requirements for an ARM mapping
symbol name.
(arm_elf_find_function): New function based on
elf_find_function in elf.c but skipping ARM mapping symbols
and including thumb function symbols.
(elf32_arm_find_nearest_line): Use arm_elf_find_function.
(elf32_arm_output_symbol_hook): Use is_arm_mapping_symbol_name.
Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.135
diff -c -3 -p -r1.135 elf32-arm.h
*** bfd/elf32-arm.h 13 Aug 2004 15:35:22 -0000 1.135
--- bfd/elf32-arm.h 13 Aug 2004 17:18:35 -0000
*************** elf32_arm_check_relocs (bfd *abfd, struc
*** 2993,3038 ****
return TRUE;
}
- /* Find the nearest line to a particular section and offset, for error
- reporting. This code is a duplicate of the code in elf.c, except
- that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
-
static bfd_boolean
! elf32_arm_find_nearest_line (bfd * abfd,
! asection * section,
! asymbol ** symbols,
! bfd_vma offset,
! const char ** filename_ptr,
! const char ** functionname_ptr,
! unsigned int * line_ptr)
{
! bfd_boolean found;
! const char *filename;
! asymbol *func;
! bfd_vma low_func;
! asymbol **p;
!
! if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
! filename_ptr, functionname_ptr,
! line_ptr, 0,
! &elf_tdata (abfd)->dwarf2_find_line_info))
! return TRUE;
!
! if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
! &found, filename_ptr,
! functionname_ptr, line_ptr,
! &elf_tdata (abfd)->line_info))
! return FALSE;
! if (found)
! return TRUE;
! if (symbols == NULL)
! return FALSE;
!
! filename = NULL;
! func = NULL;
! low_func = 0;
for (p = symbols; *p != NULL; p++)
{
--- 2993,3023 ----
return TRUE;
}
static bfd_boolean
! is_arm_mapping_symbol_name (const char * name)
{
! return (name != NULL)
! && (name[0] == '$')
! && ((name[1] == 'a') || (name[1] == 't') || (name[1] == 'd'))
! && (name[2] == 0);
! }
! /* This is a copy of elf_find_function() from elf.c except that
! ARM mapping symbols are ignored when looking for function names
! and STT_ARM_TFUNC is considered to a function type. */
! static bfd_boolean
! arm_elf_find_function (bfd * abfd ATTRIBUTE_UNUSED,
! asection * section,
! asymbol ** symbols,
! bfd_vma offset,
! const char ** filename_ptr,
! const char ** functionname_ptr)
! {
! const char * filename = NULL;
! asymbol * func = NULL;
! bfd_vma low_func = 0;
! asymbol ** p;
for (p = symbols; *p != NULL; p++)
{
*************** elf32_arm_find_nearest_line (bfd *
*** 3050,3058 ****
case STT_FILE:
filename = bfd_asymbol_name (&q->symbol);
break;
- case STT_NOTYPE:
case STT_FUNC:
case STT_ARM_TFUNC:
if (q->symbol.section == section
&& q->symbol.value >= low_func
&& q->symbol.value <= offset)
--- 3035,3048 ----
case STT_FILE:
filename = bfd_asymbol_name (&q->symbol);
break;
case STT_FUNC:
case STT_ARM_TFUNC:
+ /* Skip $a and $t symbols. */
+ if ((q->symbol.flags & BSF_LOCAL)
+ && is_arm_mapping_symbol_name (q->symbol.name))
+ continue;
+ /* Fall through. */
+ case STT_NOTYPE:
if (q->symbol.section == section
&& q->symbol.value >= low_func
&& q->symbol.value <= offset)
*************** elf32_arm_find_nearest_line (bfd *
*** 3067,3077 ****
if (func == NULL)
return FALSE;
! *filename_ptr = filename;
! *functionname_ptr = bfd_asymbol_name (func);
! *line_ptr = 0;
return TRUE;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
--- 3057,3119 ----
if (func == NULL)
return FALSE;
! if (filename_ptr)
! *filename_ptr = filename;
! if (functionname_ptr)
! *functionname_ptr = bfd_asymbol_name (func);
return TRUE;
+ }
+
+
+ /* Find the nearest line to a particular section and offset, for error
+ reporting. This code is a duplicate of the code in elf.c, except
+ that it uses arm_elf_find_function. */
+
+ static bfd_boolean
+ elf32_arm_find_nearest_line (bfd * abfd,
+ asection * section,
+ asymbol ** symbols,
+ bfd_vma offset,
+ const char ** filename_ptr,
+ const char ** functionname_ptr,
+ unsigned int * line_ptr)
+ {
+ bfd_boolean found = FALSE;
+
+ /* We skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain uses it. */
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, 0,
+ & elf_tdata (abfd)->dwarf2_find_line_info))
+ {
+ if (!*functionname_ptr)
+ arm_elf_find_function (abfd, section, symbols, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+
+ return TRUE;
+ }
+
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ & found, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->line_info))
+ return FALSE;
+
+ if (found && (*functionname_ptr || *line_ptr))
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ if (! arm_elf_find_function (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr))
+ return FALSE;
+
+ *line_ptr = 0;
+ return TRUE;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
*************** elf32_arm_output_symbol_hook (struct bfd
*** 3987,3997 ****
return TRUE;
/* We only want mapping symbols. */
! if (name == NULL
! || name[0] != '$'
! || (name[1] != 'a'
! && name[1] != 't'
! && name[1] != 'd'))
return TRUE;
mapcount = ++(elf32_arm_section_data (input_sec)->mapcount);
--- 4029,4035 ----
return TRUE;
/* We only want mapping symbols. */
! if (! is_arm_mapping_symbol_name (name))
return TRUE;
mapcount = ++(elf32_arm_section_data (input_sec)->mapcount);
*************** elf32_arm_write_section (bfd *output_bfd
*** 4152,4155 ****
#define elf_backend_got_header_size 12
#include "elf32-target.h"
-
--- 4190,4192 ----