This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
OK, I know this is lame, but I'd like to add a hook to force swap_out_syms() to name local section symbols. Besides the obvious file bloat, is there any reason why this would be a bad thing? The reason I need the hook is to work around a bug in the MIPSpro linker. If you use MIPSpro to build the attached test case: as got-disp-2.s -o got-disp-2.o ld /usr/lib32/crt1.o got-disp-2.o -lc /usr/lib32/crtn.o ./a.out then it works OK. Use gas instead, and you get: Trace/BPT/RangeErr/DivZero/Ovflow trap (core dumped) The crucial difference is that MIPSpro names the section symbols: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 SECTION LOCAL DEFAULT 4 .text 2: 00000000 0 SECTION LOCAL DEFAULT 5 .data but bfd doesn't. For some reason, if the symbols for .text and .data don't have names, then the MIPSpro linker will resolve both of the following relocations to .data: lw $4,%got_disp(.data)($gp) lw $25,%got_disp(.text)($gp) jalr $25 The program ends up jumping there rather than to .text. Note that got-disp-2.s is just the explicit-reloc version of what gas produces for got-disp-1.s. This is the cause of many gcc testsuite failures when using gas with the native linker, see: http://gcc.gnu.org/ml/gcc-testresults/2004-02/msg00250.html for the full horror. Patch tested by bootstrapping & regression testing gcc on IRIX with the combination of gas and the native linker. Fixes many testsuite failures and the got-disp-* ones below. OK to install? Thanks to Rainer for the heads-up about this. Richard * bfd-elf.h (elf_backend_name_local_section_symbols): New hook. * elf.c (swap_out_syms): Use it to decide whether local section symbols should be named. * elfxx-target.h (elf_backend_name_local_section_symbols): New macro. * elfxx-mips.h (_bfd_mips_elf_name_local_section_symbols): Declare. (elf_backend_name_local_section_symbols): Define. * elfxx-mips.c (_bfd_mips_elf_name_local_section_symbols): New. Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.124 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.124 elf-bfd.h *** bfd/elf-bfd.h 8 Dec 2003 13:05:09 -0000 1.124 --- bfd/elf-bfd.h 8 Feb 2004 13:28:06 -0000 *************** struct elf_backend_data *** 576,581 **** --- 576,586 ---- int (*elf_backend_get_symbol_type) (Elf_Internal_Sym *, int); + /* Return true if local section symbols should have a non-null st_name. + NULL implies false. */ + bfd_boolean (*elf_backend_name_local_section_symbols) + (bfd *); + /* A function to do additional processing on the ELF section header just before writing it out. This is used to set the flags and type fields for some sections, or to actually write out data for Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.215 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.215 elf.c *** bfd/elf.c 11 Dec 2003 18:10:19 -0000 1.215 --- bfd/elf.c 8 Feb 2004 13:28:08 -0000 *************** swap_out_syms (bfd *abfd, *** 5261,5266 **** --- 5261,5267 ---- char *outbound_shndx; int idx; bfd_size_type amt; + bfd_boolean name_local_sections; if (!elf_map_symbols (abfd)) return FALSE; *************** swap_out_syms (bfd *abfd, *** 5326,5331 **** --- 5327,5336 ---- outbound_shndx += sizeof (Elf_External_Sym_Shndx); } + name_local_sections + = (bed->elf_backend_name_local_section_symbols + && bed->elf_backend_name_local_section_symbols (abfd)); + syms = bfd_get_outsymbols (abfd); for (idx = 0; idx < symcount; idx++) { *************** swap_out_syms (bfd *abfd, *** 5335,5341 **** flagword flags = syms[idx]->flags; int type; ! if ((flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) { /* Local section symbols have no name. */ sym.st_name = 0; --- 5340,5347 ---- flagword flags = syms[idx]->flags; int type; ! if (!name_local_sections ! && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) { /* Local section symbols have no name. */ sym.st_name = 0; Index: bfd/elfxx-target.h =================================================================== RCS file: /cvs/src/src/bfd/elfxx-target.h,v retrieving revision 1.58 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.58 elfxx-target.h *** bfd/elfxx-target.h 3 Nov 2003 15:17:40 -0000 1.58 --- bfd/elfxx-target.h 8 Feb 2004 13:28:08 -0000 *************** #define elf_backend_symbol_table_process *** 274,279 **** --- 274,282 ---- #ifndef elf_backend_get_symbol_type #define elf_backend_get_symbol_type 0 #endif + #ifndef elf_backend_name_local_section_symbols + #define elf_backend_name_local_section_symbols 0 + #endif #ifndef elf_backend_section_processing #define elf_backend_section_processing 0 #endif *************** static const struct elf_backend_data elf *** 456,461 **** --- 459,465 ---- elf_backend_symbol_processing, elf_backend_symbol_table_processing, elf_backend_get_symbol_type, + elf_backend_name_local_section_symbols, elf_backend_section_processing, elf_backend_section_from_shdr, elf_backend_section_flags, Index: bfd/elfxx-mips.h =================================================================== RCS file: /cvs/src/src/bfd/elfxx-mips.h,v retrieving revision 1.17 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.17 elfxx-mips.h *** bfd/elfxx-mips.h 18 Dec 2003 10:23:07 -0000 1.17 --- bfd/elfxx-mips.h 8 Feb 2004 13:28:08 -0000 *************** extern bfd_boolean _bfd_mips_elf_new_sec *** 24,29 **** --- 24,31 ---- (bfd *, asection *); extern void _bfd_mips_elf_symbol_processing (bfd *, asymbol *); + extern bfd_boolean _bfd_mips_elf_name_local_section_symbols + (bfd *); extern bfd_boolean _bfd_mips_elf_section_processing (bfd *, Elf_Internal_Shdr *); extern bfd_boolean _bfd_mips_elf_section_from_shdr *************** extern bfd_vma _bfd_mips_elf_sign_extend *** 119,122 **** --- 121,126 ---- (bfd_vma, int); extern struct bfd_elf_special_section const _bfd_mips_elf_special_sections[]; + #define elf_backend_name_local_section_symbols \ + _bfd_mips_elf_name_local_section_symbols #define elf_backend_special_sections _bfd_mips_elf_special_sections Index: bfd/elfxx-mips.c =================================================================== RCS file: /cvs/src/src/bfd/elfxx-mips.c,v retrieving revision 1.88 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.88 elfxx-mips.c *** bfd/elfxx-mips.c 18 Dec 2003 10:23:07 -0000 1.88 --- bfd/elfxx-mips.c 8 Feb 2004 13:28:10 -0000 *************** _bfd_mips_elf_symbol_processing (bfd *ab *** 4271,4276 **** --- 4271,4296 ---- } } + /* There appears to be a bug in the MIPSpro linker that causes GOT_DISP + relocations against two unnamed section symbols to resolve to the + same address. For example, if we have code like: + + lw $4,%got_disp(.data)($gp) + lw $25,%got_disp(.text)($gp) + jalr $25 + + then the linker will resolve both relocations to .data and the program + will jump there rather than to .text. + + We can work around this problem by giving names to local section symbols. + This is also what the MIPSpro tools do. */ + + bfd_boolean + _bfd_mips_elf_name_local_section_symbols (bfd *abfd) + { + return SGI_COMPAT (abfd); + } + /* Work over a section just before writing it out. This routine is used by both the 32-bit and the 64-bit ABI. FIXME: We recognize sections that need the SHF_MIPS_GPREL flag by name; there has to be
Attachment:
got-disp-1.s
Description: Text document
Attachment:
got-disp-2.s
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |