This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: LD issue : Problem in NOCROSSREFS overlay check
- From: "Philippe Vandermersch" <philippev at nvidia dot com>
- To: <binutils at sourceware dot org>
- Date: Thu, 15 Feb 2007 15:33:47 -0800
- Subject: RE: LD issue : Problem in NOCROSSREFS overlay check
- References: <FEE662BF3FC168428F3C828EBB8D86DA0CCB74E0@hqemmail05.nvidia.com>
Hi,
I am using binutils-2.17 to link an embedded application using overlays.
Due to technical reasons, we rename the .text section of some object
files before to partial link them together to form a big object file.
Each object file has a different text section name.
The idea is that each section will be an overlay.
I recreated the problem with a small example 2 object files ovl1.o
ovl2.o ( partial linked to form app.o ) and main.o
I got the following error when trying to do the final link :
app.o: In function `_ovl2_main':
(.ovl2+0xb): prohibited cross reference from .ovl2 to `.LL8' in .ovl1
collect2: ld returned 1 exit status
symbol .LL8 is used as relocatable local jump table in overlay2, and is
a simple local symbol in overlay1. There is no cross-reference for 2
reasons :
-because these symbols are local. ( see below the symbols
details )
-because .LL8 should in section .rodata not ovl2
My link script :
ENTRY(_start)
MEMORY
{
CODE (X) : ORIGIN = 0x00000000, LENGTH = 16K
DATA (A) : ORIGIN = 0x10000000, LENGTH = 16K
OVERLAYS : ORIGIN = 0x20000000, LENGTH = 1M
}
PROVIDE (__stack = LENGTH(DATA));
SECTIONS
{
.start : { *(.start) }
.text : { *(EXCLUDE_FILE(*.ovl*.o) .text) }
_Overlay1Base = ALIGN(256);
OVERLAY ALIGN(256) : NOCROSSREFS
{
.ovl1 { *(.ovl1) . = ALIGN(256); }
.ovl2 { *(.ovl2) . = ALIGN(256); }
.ovl3 { *(.ovl3) . = ALIGN(256); }
} >CODE AT >OVERLAYS
.rodata : { *(.rodata ) }
.data : { *(.data ) }
.bss : { *(.bss) *(COMMON) }
}
Ovl1 symbols
U _falc_printf
000000fc t .L*dot0
000000f6 t .LL10
000000e1 t .LL12
000000e9 t .LL2
000000a2 t .LL3
000000b2 t .LL4
000000be t .LL5
000000ca t .LL6
000000d6 t .LL7
000000dd t .LL8
0000006c r .LL9
00000000 r .LLC0
0000000a r .LLC1
00000019 r .LLC2
00000027 r .LLC3
00000035 r .LLC4
00000043 r .LLC5
00000051 r .LLC6
0000005f r .LLC7
00000078 T _ovl1_main
Ovl2 symbols
U _falc_printf
000000aa t .L*dot0
000000ba t .L*dot1
0000009e t .LL2
00000067 t .LL3
00000072 t .LL4
0000007d t .LL5
00000088 t .LL6
00000093 t .LL7
00000038 r .LL8
00000000 r .LLC0
00000008 r .LLC1
00000010 r .LLC2
00000018 r .LLC3
00000020 r .LLC4
00000028 r .LLC5
00000042 r .LLC6
00000050 T _ovl2_main
000000aa T _ovl2_phil
Partial link symbols of app.o
00000010 D _a
00000014 D _b
U _falc_printf
00000022 T _IV0_handler
0000009c t .L*dot0
000000f6 t .L*dot0
00000022 t .L*dot0
00000106 t .L*dot1
00000050 t .L*dot1
000000d6 t .L*dot2
000000fb t .L*dot3
00000096 t .LL10
00000081 t .LL12
00000089 t .LL2
000000ea t .LL2
0000001a t .LL2
00000042 t .LL3
000000b3 t .LL3
0000000f t .LL3
00000052 t .LL4
000000be t .LL4
0000005e t .LL5
000000c9 t .LL5
0000006a t .LL6
000000d4 t .LL6
00000076 t .LL7
000000df t .LL7
0000007d t .LL8
000000b0 r .LL8
0000006c r .LL9
00000091 t .LL9
00000000 r .LLC0
00000078 r .LLC0
000000c8 r .LLC0
0000000a r .LLC1
00000080 r .LLC1
000000cb r .LLC1
00000019 r .LLC2
00000088 r .LLC2
00000027 r .LLC3
00000090 r .LLC3
00000035 r .LLC4
00000098 r .LLC4
00000043 r .LLC5
000000a0 r .LLC5
00000051 r .LLC6
000000ba r .LLC6
0000005f r .LLC7
00000000 T __loadOverlay
U __load_start_ovl1
U __load_start_ovl2
U __load_stop_ovl1
U __load_stop_ovl2
00000050 T _main
U _Overlay1Base
00000018 T _ovl1_main
0000009c T _ovl2_main
000000f6 T _ovl2_phil
00000000 D _string
000000d6 T _timer_interrupt
Readelf of the big object file containing the both overlays in 2
differents section ovl1 and ovl2
l-xterm-31:/home/scratch.philippev_vp2/examples/overlay> readelf -S
app.o
There are 13 section headers, starting at offset 0x360:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg
Lk Inf Al
[ 0] NULL 00000000 000000 000000 00
0 0 0
[ 1] .text PROGBITS 00000000 000034 0000fb 00 AX
0 0 1
[ 2] .rela.text RELA 00000000 000ae0 0000b4 0c
11 1 4
[ 3] .rodata PROGBITS 00000000 000130 0000d7 00 A
0 0 4
[ 4] .rela.rodata RELA 00000000 000b94 000084 0c
11 3 4
[ 5] .data PROGBITS 00000000 000208 000018 00 WA
0 0 4
[ 6] .ovl1 PROGBITS 00000018 000220 000084 00 AX
0 0 1
[ 7] .rela.ovl1 RELA 00000000 000c18 000078 0c
11 6 4
[ 8] .ovl2 PROGBITS 0000009c 0002a4 00006a 00 AX
0 0 1
[ 9] .rela.ovl2 RELA 00000000 000c90 000078 0c
11 8 4
[10] .shstrtab STRTAB 00000000 00030e 00004f 00
0 0 1
[11] .symtab SYMTAB 00000000 000568 000430 10
12 33 4
[12] .strtab STRTAB 00000000 000998 000147 00
0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor
specific)
I located the problem in binutils/ld/ldcref.c.
2 questions :
1) Can somebody explain me the reason for the comment below on green ?
2) What is the test (in pink below) meant for ?
If I comment it out, my link problem is gone.
static void
check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
{
struct check_refs_info *info = iarg;
asection *outsec;
const char *outsecname;
asection *outdefsec;
const char *outdefsecname;
struct lang_nocrossref *ncr;
const char *symname;
bfd_boolean global;
long relsize;
arelent **relpp;
long relcount;
arelent **p, **pend;
outsec = sec->output_section;
outsecname = bfd_get_section_name (outsec->owner, outsec);
outdefsec = info->defsec->output_section;
outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
/* The section where the symbol is defined is permitted. */
if (strcmp (outsecname, outdefsecname) == 0)
return;
for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
if (strcmp (outsecname, ncr->name) == 0)
break;
if (ncr == NULL)
return;
/* This section is one for which cross references are prohibited.
Look through the relocations, and see if any of them are to
INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
against the section symbol. If INFO->GLOBAL is TRUE, the
definition is global, check for relocations against the global
symbols. Otherwise check for relocations against the local and
section symbols. */
symname = info->sym_name;
global = info->global;
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize < 0)
einfo (_("%B%F: could not read relocs: %E\n"), abfd);
if (relsize == 0)
return;
relpp = xmalloc (relsize);
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
if (relcount < 0)
einfo (_("%B%F: could not read relocs: %E\n"), abfd);
p = relpp;
pend = p + relcount;
for (; p < pend && *p != NULL; p++)
{
arelent *q = *p;
if (q->sym_ptr_ptr != NULL
&& *q->sym_ptr_ptr != NULL
&& ((global
&& (bfd_is_und_section (bfd_get_section
(*q->sym_ptr_ptr))
|| bfd_is_com_section (bfd_get_section
(*q->sym_ptr_ptr))
|| ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
| BSF_WEAK)) != 0))
|| (!global
&& ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
| BSF_SECTION_SYM)) !=
0))
&& (symname != NULL
? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) ==
0
: (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
&& bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
{
/* We found a reloc for the symbol. The symbol is defined
in OUTSECNAME. This reloc is from a section which is
mapped into a section from which references to OUTSECNAME
are prohibited. We must report an error. */
einfo (_("%X%C: prohibited cross reference from %s to `%T' in
%s\n"),
abfd, sec, q->address, outsecname,
bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
}
}
free (relpp);
}
Thanks,
Phil.
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
--- Begin Message ---
- From: "Philippe Vandermersch" <philippev at nvidia dot com>
- To: <binutils at sourceware dot org>
- Date: Thu, 15 Feb 2007 15:18:40 -0800
- Subject: LD issue : Problem in NOCROSSREFS overlay check
Hi,
I am using binutils-2.17 to link an embedded application using overlays.
Due to technical reasons, we rename the .text section of some object
files before to partial link them together to form a big object file.
Each object file has a different text section name.
The idea is that each section will be an overlay.
I recreated the problem with a small example 2 object files ovl1.o
ovl2.o ( partial linked to form app.o ) and main.o
I got the following error when trying to do the final link :
app.o: In function `_ovl2_main':
(.ovl2+0xb): prohibited cross reference from .ovl2 to `.LL8' in .ovl1
collect2: ld returned 1 exit status
symbol .LL8 is used as relocatable local jump table in overlay2, and is
a simple local symbol in overlay1. There is no cross-reference for 2
reasons :
-because these symbols are local. ( see below the symbols
details )
-because .LL8 should in section .rodata not ovl2
My link script :
ENTRY(_start)
MEMORY
{
CODE (X) : ORIGIN = 0x00000000, LENGTH = 16K
DATA (A) : ORIGIN = 0x10000000, LENGTH = 16K
OVERLAYS : ORIGIN = 0x20000000, LENGTH = 1M
}
PROVIDE (__stack = LENGTH(DATA));
SECTIONS
{
.start : { *(.start) }
.text : { *(EXCLUDE_FILE(*.ovl*.o) .text) }
_Overlay1Base = ALIGN(256);
OVERLAY ALIGN(256) : NOCROSSREFS
{
.ovl1 { *(.ovl1) . = ALIGN(256); }
.ovl2 { *(.ovl2) . = ALIGN(256); }
.ovl3 { *(.ovl3) . = ALIGN(256); }
} >CODE AT >OVERLAYS
.rodata : { *(.rodata ) }
.data : { *(.data ) }
.bss : { *(.bss) *(COMMON) }
}
Ovl1 symbols
U _falc_printf
000000fc t .L*dot0
000000f6 t .LL10
000000e1 t .LL12
000000e9 t .LL2
000000a2 t .LL3
000000b2 t .LL4
000000be t .LL5
000000ca t .LL6
000000d6 t .LL7
000000dd t .LL8
0000006c r .LL9
00000000 r .LLC0
0000000a r .LLC1
00000019 r .LLC2
00000027 r .LLC3
00000035 r .LLC4
00000043 r .LLC5
00000051 r .LLC6
0000005f r .LLC7
00000078 T _ovl1_main
Ovl2 symbols
U _falc_printf
000000aa t .L*dot0
000000ba t .L*dot1
0000009e t .LL2
00000067 t .LL3
00000072 t .LL4
0000007d t .LL5
00000088 t .LL6
00000093 t .LL7
00000038 r .LL8
00000000 r .LLC0
00000008 r .LLC1
00000010 r .LLC2
00000018 r .LLC3
00000020 r .LLC4
00000028 r .LLC5
00000042 r .LLC6
00000050 T _ovl2_main
000000aa T _ovl2_phil
Partial link symbols of app.o
00000010 D _a
00000014 D _b
U _falc_printf
00000022 T _IV0_handler
0000009c t .L*dot0
000000f6 t .L*dot0
00000022 t .L*dot0
00000106 t .L*dot1
00000050 t .L*dot1
000000d6 t .L*dot2
000000fb t .L*dot3
00000096 t .LL10
00000081 t .LL12
00000089 t .LL2
000000ea t .LL2
0000001a t .LL2
00000042 t .LL3
000000b3 t .LL3
0000000f t .LL3
00000052 t .LL4
000000be t .LL4
0000005e t .LL5
000000c9 t .LL5
0000006a t .LL6
000000d4 t .LL6
00000076 t .LL7
000000df t .LL7
0000007d t .LL8
000000b0 r .LL8
0000006c r .LL9
00000091 t .LL9
00000000 r .LLC0
00000078 r .LLC0
000000c8 r .LLC0
0000000a r .LLC1
00000080 r .LLC1
000000cb r .LLC1
00000019 r .LLC2
00000088 r .LLC2
00000027 r .LLC3
00000090 r .LLC3
00000035 r .LLC4
00000098 r .LLC4
00000043 r .LLC5
000000a0 r .LLC5
00000051 r .LLC6
000000ba r .LLC6
0000005f r .LLC7
00000000 T __loadOverlay
U __load_start_ovl1
U __load_start_ovl2
U __load_stop_ovl1
U __load_stop_ovl2
00000050 T _main
U _Overlay1Base
00000018 T _ovl1_main
0000009c T _ovl2_main
000000f6 T _ovl2_phil
00000000 D _string
000000d6 T _timer_interrupt
Readelf of the big object file containing the both overlays in 2
differents section ovl1 and ovl2
l-xterm-31:/home/scratch.philippev_vp2/examples/overlay> readelf -S
app.o
There are 13 section headers, starting at offset 0x360:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg
Lk Inf Al
[ 0] NULL 00000000 000000 000000 00
0 0 0
[ 1] .text PROGBITS 00000000 000034 0000fb 00 AX
0 0 1
[ 2] .rela.text RELA 00000000 000ae0 0000b4 0c
11 1 4
[ 3] .rodata PROGBITS 00000000 000130 0000d7 00 A
0 0 4
[ 4] .rela.rodata RELA 00000000 000b94 000084 0c
11 3 4
[ 5] .data PROGBITS 00000000 000208 000018 00 WA
0 0 4
[ 6] .ovl1 PROGBITS 00000018 000220 000084 00 AX
0 0 1
[ 7] .rela.ovl1 RELA 00000000 000c18 000078 0c
11 6 4
[ 8] .ovl2 PROGBITS 0000009c 0002a4 00006a 00 AX
0 0 1
[ 9] .rela.ovl2 RELA 00000000 000c90 000078 0c
11 8 4
[10] .shstrtab STRTAB 00000000 00030e 00004f 00
0 0 1
[11] .symtab SYMTAB 00000000 000568 000430 10
12 33 4
[12] .strtab STRTAB 00000000 000998 000147 00
0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor
specific)
I located the problem in binutils/ld/ldcref.c.
2 questions :
1) Can somebody explain me the reason for the comment below on green ?
2) What is the test (in pink below) meant for ?
If I comment it out, my link problem is gone.
static void
check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
{
struct check_refs_info *info = iarg;
asection *outsec;
const char *outsecname;
asection *outdefsec;
const char *outdefsecname;
struct lang_nocrossref *ncr;
const char *symname;
bfd_boolean global;
long relsize;
arelent **relpp;
long relcount;
arelent **p, **pend;
outsec = sec->output_section;
outsecname = bfd_get_section_name (outsec->owner, outsec);
outdefsec = info->defsec->output_section;
outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
/* The section where the symbol is defined is permitted. */
if (strcmp (outsecname, outdefsecname) == 0)
return;
for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
if (strcmp (outsecname, ncr->name) == 0)
break;
if (ncr == NULL)
return;
/* This section is one for which cross references are prohibited.
Look through the relocations, and see if any of them are to
INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
against the section symbol. If INFO->GLOBAL is TRUE, the
definition is global, check for relocations against the global
symbols. Otherwise check for relocations against the local and
section symbols. */
symname = info->sym_name;
global = info->global;
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize < 0)
einfo (_("%B%F: could not read relocs: %E\n"), abfd);
if (relsize == 0)
return;
relpp = xmalloc (relsize);
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
if (relcount < 0)
einfo (_("%B%F: could not read relocs: %E\n"), abfd);
p = relpp;
pend = p + relcount;
for (; p < pend && *p != NULL; p++)
{
arelent *q = *p;
if (q->sym_ptr_ptr != NULL
&& *q->sym_ptr_ptr != NULL
&& ((global
&& (bfd_is_und_section (bfd_get_section
(*q->sym_ptr_ptr))
|| bfd_is_com_section (bfd_get_section
(*q->sym_ptr_ptr))
|| ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
| BSF_WEAK)) != 0))
|| (!global
&& ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
| BSF_SECTION_SYM)) !=
0))
&& (symname != NULL
? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) ==
0
: (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
&& bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
{
/* We found a reloc for the symbol. The symbol is defined
in OUTSECNAME. This reloc is from a section which is
mapped into a section from which references to OUTSECNAME
are prohibited. We must report an error. */
einfo (_("%X%C: prohibited cross reference from %s to `%T' in
%s\n"),
abfd, sec, q->address, outsecname,
bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
}
}
free (relpp);
}
Thanks,
Phil.
--- End Message ---