This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld 2.15.94.0.2.2 : prohibited cross reference to a local symbol.
- From: "Etienne Lorrain" <etienne dot lorrain at masroudeau dot com>
- To: binutils at sourceware dot org
- Date: Fri, 23 Sep 2005 11:28:10 +0100 (BST)
- Subject: ld 2.15.94.0.2.2 : prohibited cross reference to a local symbol.
- Reply-to: etienne dot lorrain at masroudeau dot com
Hello,
I have just switched to Fedora FC4 ia32, which contains this version:
[etienne@localhost linux-2.6.14-rc2-3]$ ld -v
GNU ld version 2.15.94.0.2.2 20041220
and I am not sure what happens in my case.
In short, I have a patch for Linux which defines a local symbol
(in one file named realmode.c) called "memcpy". This local symbol
shall never be seen outside of the realmode.o file because it will
not work. Probably Linux has an extern symbol named memcpy.
Here is a source extract of linux-2.6.14-rc2/arch/i386/kernel/realmode.c:
#define CODE __attribute__ ((section (".text16")))
CODE void code16_memcpy (char *dest, const char *src, unsigned nb)
{
while (nb--)
*dest++ = *src++;
}
CODE void code16_memset (char *dest, unsigned val, unsigned nb)
{
while (nb--)
*dest++ = val;
}
asm (
// ".internal memcpy, memset\n"
"memcpy = code16_memcpy \n"
"memset = code16_memset \n"
);
....
And GCC will call symbol memcpy in the last part of the file.
I also have added this to the link file:
NOCROSSREFS(.realmode .text)
Now if I try to compile Linux, I get:
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
arch/i386/kernel/built-in.o(.text+0xf720): In function
`pentium3_get_frequency':
speedstep-lib.c: prohibited cross reference from .text to `memcpy' in
.realmode
make: *** [.tmp_vmlinux1] Error 1
The thing I do not understand is that ld seems to try to use a local
symbol of file realmode.o in another file.
I checked it was local:
$ nm arch/i386/kernel/realmode.o
00000000 T code16_memcpy
00000040 T code16_memset
U _edata16
00000000 r itoa_array.2599
00000cd0 T linux_set_params
00000000 t memcpy
00000040 t memset
00000000 B param
00000011 r root_pattern.2655
U _sdata16
00000460 t vmlinuz_ROOT
00000060 t vmlinuz_VIDEO
and the "t" is not a capitale letter so local.
Note that
$ objdump arch/i386/kernel/realmode.o -t
arch/i386/kernel/realmode.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 realmode.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .init.text16 00000000 .init.text16
00000000 l d .text16 00000000 .text16
00000000 l F .text16 00000035 memcpy
00000040 l F .text16 0000001c memset
00000060 l F .text16 000003f8 vmlinuz_VIDEO
00000000 l d .rodata16 00000000 .rodata16
00000000 l O .rodata16 00000011 itoa_array.2599
00000011 l O .rodata16 0000000c root_pattern.2655
00000460 l F .text16 00000870 vmlinuz_ROOT
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 *UND* 00000000 _sdata16
00000000 *UND* 00000000 _edata16
00000cd0 g F .text16 00000aa7 linux_set_params
00000000 g F .text16 00000035 code16_memcpy
00000040 g F .text16 0000001c code16_memset
00000000 g O .bss 00000004 param
Am I doing something completely wrong, and what means the "F" in front
of memcpy symbol?
Shall I declare the memcpy symbol more local than local?
Thanks for any help,
Etienne.