Error: LD: symbol not found: '__data_start'

Alexander Tormasov a.tormasov at innopolis.ru
Mon Jun 14 15:22:37 CEST 2021


Hello Christian,
thank you for a prompt respond!


>> in some places of new code appeared after 10.3 gcc I found
>> extern const char __data_start[] __attribute__ ((weak));
>> 
>> where I can add it, in what ld script?
> 
> The following patch adds the symbol right at the beginning of the data
> segment. I'm not certain that this is correct for your use case. Do
> you have any reference to an official documentation or source that
> specifies the use of this symbol?

not sure that this is official, anyway, here https://gcc.gnu.org/wiki/Building_Cross_Toolchains_with_gcc?action=AttachFile&do=get&target=billgatliff-toolchains.pdf
it mentioned as a part of default script:
/* initialized data */ .init : AT (__text_end) { 
__data_start = .; 
*(.data) __data_end = .; 
} > ram

 In general, golang start using it to perform tracing of code for debugging purposes, and add a special component called field track with the following comment:

/* The compiler will track fields that have the tag go:"track".  Any
   function that refers to such a field will call this function with a
   string
       fieldtrack "package.type.field"

   This function does not actually do anything.  Instead, we gather
   the field tracking information by looking for strings of that form
   in the read-only data section.  This is, of course, a horrible
   hack, but it's good enough for now.  We can improve it, e.g., by a
   linker plugin, if this turns out to be useful.  */

together with function to track end of code segment:
// Return the end of the text segment, assumed to come after the
// read-only data section.

uintptr getEtext(void)
  __asm__ (GOSYM_PREFIX "runtime.getEtext»);

uintptr
getEtext(void)
{
  const void *p;

  p = __data_start;
  if (p == nil)
    p = __etext;
  if (p == nil)
    p = _etext;
  return (uintptr)(p);
}

here another reference to ANSI C used in context that etext (another address to be defined) are the part of standard:
https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html

In some cases, it is desirable for a linker script to define a symbol only if it is referenced, and only if it is not defined by any object included in the link. For example, traditional linkers defined the symbol `etext'. However, ANSI C requires that the user be able to use `etext' as a function name without encountering an error. The PROVIDE keyword may be used to define a symbol, such as `etext', only if it is referenced but not defined. The syntax is PROVIDE(symbol = expression).

in general, golang code reference to the following list of addresses related to ld script and position of code/etc:
extern const char __etext[] __attribute__ ((weak));
extern const char __data_start[] __attribute__ ((weak));
extern const char __edata[] __attribute__ ((weak));
extern const char __bss_start[] __attribute__ ((weak));

some useful info I found in old IRIX man page
http://polarhome.com/service/man/?qf=etext&tf=2&of=IRIX&sf=3

while they are obsolete, anyway, such symbols are created and used in modern linux as well.

my opinion that this is necessary component to be present by definition, and could be used for different tools and languages like golang. It is not mandatory (golang do not support it for AIX, while support for other 10 systems where it can run including *bsd, linux, solaris, windows/etc), but good to have them.

may be it worth to modify patch to add all of them, see above?

Sincerely
	Alexander




More information about the users mailing list