OSDev.org
https://forum.osdev.org/

Linker-script writers beware: COMMON Symbols
https://forum.osdev.org/viewtopic.php?f=1&t=21425
Page 1 of 1

Author:  Darwish [ Wed Jan 13, 2010 1:25 pm ]
Post subject:  Linker-script writers beware: COMMON Symbols

So I was writing some memory management test code to find that my kernel panic()s at different places once any of the text, data, or bss sections size exceed something close to 20 kilobytes.

After a day of debugging, I found that the compiler does not put my uninitialized globally-exported symbols under BSS; it marks them as "common symbols" instead. This has lead to disastrous effects cause I use the following innocent-looking segment in the linker script:
Code:
SECTIONS {
          ...
          .bss : {
                  __bss_start = .;
                  *(EXCLUDE_FILE (*head.o *e820.o) .bss)
                  __bss_end = .;
           }
           __kernel_end = .;
}
Which meant that some of the kernel's uninitialized variables was not cleared by my clear_bss() method, leading to unpredictable behavior.

The best explanation of "common symbols" I found was from Ulrich Drepper's paper (archive) on shared libraries, mainly the following part:
Quote:
Common variables are widely used in fortran, but they got used in C and C++ as well to work around mistakes of programmers. Since in the early days people used to drop the 'extern' keyword from variable definitions, in the same way it is possible to drop it from function declaration, the compiler often had multiple definitions of the same variable in different files.

To help the poor and clueless programmer, the C/C++ compiler normally generates common variables for uninitialized definitions such as `int foo;' For common variables, there can be more than one definition, and they all get unified in one location in the output file .. their values does not need to be stored in the ELF file.

There are also further information about those symbols from Ian Lance Taylor's articles series on linkers here (archive), on nm(1) manpage, and on ld(1) about LD's very useful `--warn-common' flag. You can also check some nice historical details from this binutils bugreport (archive). To let your BSS variable boundaries really reflect your entire BSS space, you either need to use GCC's '--no-common' parameter or modify the above script segment to:
Code:
SECTIONS {
          ...
          .bss : {
                  __bss_start = .;
                  *(EXCLUDE_FILE (*head.o *e820.o) .bss)
                  *(EXCLUDE_FILE (*head.o *e820.o) COMMON)
                  __bss_end = .;
           }
           __kernel_end = .;
}

I've noticed that this wasn't mentiond on the WIKI, I'll wait for any corrections or comments, then add it there.
Thanks all :)

Author:  Owen [ Wed Jan 13, 2010 3:04 pm ]
Post subject:  Re: Linker-script writers beware: COMMON Symbols

Please don't use dark red for emphasis; that's what italic or bold are for, and some of us use white on dark themes.

Author:  Darwish [ Fri Jan 15, 2010 10:56 pm ]
Post subject:  Re: Linker-script writers beware: COMMON Symbols

Owen wrote:
Please don't use dark red for emphasis; that's what italic or bold are for, and some of us use white on dark themes.

No problem; fixed.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/