This is the mail archive of the binutils@sourceware.org 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]

RE: 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.


-----------------------------------------------------------------------------------
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 ---
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 ---

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]