In building Xen we observed a build problem when using binutils 2.15 that wasn't visible for those of us using newer binutils versions. However, I believe that we should have seen this in all cases.
Xen gets compiled with -fPIC, and we recently added a global visibility pragma to avoid the cost of going through the GOT for all access to global data objects (PIC isn't really needed here, all we need is sufficient compiler support to get the final image located outside the +/-2Gb ranges, but large model support is neither there in older compilers nor do we really need all of it either). In a kallsyms-like approach, symbol information gets embedded in the final executable, with the first linking stage not having available the respective table symbols. For that reason, they are being attributed weak. After adding the global visibility hidden pragma, even these weak symbols get accessed (or their address calculated) via RIP-relative addressing. While accessing them this way is probably acceptable from the compiler's perspective (given the hidden attribute it may safely assume the symbol is in the same executable image as the accessing code), calculating its address certainly isn't, as the symbol may not be present at all (and after all, comparing the address of the weak object against NULL is the only method I know to check presence of the symbol at runtime). So the questions are: 1) Why does gcc not use a GOT reference when calculating the address of a weak symbol here? 2) Why does the linker silently resolve the (32-bit PC-relative) relocation targeting an undefined weak symbol, yielding at run-time a non-zero address? While I can see the point of assisting the compiler here under the assumption that it has checked the address elsewhere and hence the actual access is supposed to never happen at runtime, detecting the (incorrect) use of the same relocation (access method) in either assembly code or address calculations should be mandatory; to distinguish the two, two distinct relocation types would then be needed (one that keeps the linker silent, and another one that doesn't). Thanks, Jan >>> Keir Fraser <[EMAIL PROTECTED]> 28.09.06 10:56 >>> >On 28/9/06 09:23, "Keir Fraser" <[EMAIL PROTECTED]> wrote: >> On 28/9/06 07:46, "Jan Beulich" <[EMAIL PROTECTED]> wrote: >>>>>> Keir Fraser <[EMAIL PROTECTED]> 27.09.06 20:14 >>> >>>> So it seems that older versions of gcc (before 4.1.1) don't do anything >>>> more >>>> with the pragma than -fvisibility=hidden. So currently the pragma at best >>>> does nothing (extern references still go through GOT) and at worst breaks >>>> the build. :-) >>> >>> That'd be contrary to my observations; I'll check into this. >> >> Thanks. I am using a personal build of vanilla gcc-4.1.1 by the way. > >...and that's the problem. I'm using it with a too-old version of binutils >(version 2.15). Pretty much any newer version seems to relocate the weak >reference to FFFF830000000000 (i.e., I guess rounds down to a 2GB boundary).