Re: [PATCH 5/5 V2] kvm tools: Initialize and use VESA and VNC

Paolo Bonzini
2011-05-25T09:15:31Z

On 05/25/2011 10:32 AM, Ingo Molnar wrote:
>
> * Paolo Bonzini<pbonzini@redhat.com> wrote:
>
>>> In that sense ((section)) is way more robust: there's not really that many
>>> ways to screw that up. Fiddling with the ((constructor)) environment on the
>>> other hand ...
>>
>> Sorry, this is textbook FUD.
>
> I specifically cited the problem of static libraries. They *do not work* with
> ((constructor)).

((constructor)) has easily explained semantics: it's the same semantics
as C++ global constructors. If you don't like those, that's another story.

But anyway, I specifically cited the reason why ((section)) is not any
better, AFAIU how you would use it. Now I didn't trust myself and tried it.

f.ld:
SECTIONS {
.paolo : {
PROVIDE(__paolo_start = .);
*(.paolo)
PROVIDE(__paolo_end = .);
}
}

f.c:
int x __attribute__((section(".paolo"))) = 0x12345678;

int main()
{
extern int __paolo_start[];
extern int __paolo_end[];

int *p;
for (p = __paolo_start; p < __paolo_end; p++) {
printf ("%x\n", *p);
}
}

f1.c:
int y __attribute__((section(".paolo"))) = 0x76543210;

compilation with objects:
$ gcc f.c -o f.o -c
$ gcc f1.c -o f1.o -c
$ ld -r f.ld f.o f1.o -o f2.o
$ gcc f2.o -o a.out
$ ./a.out
12345678
76543210

compilation with static libraries:
$ gcc f.c -o f.o -c
$ gcc f1.c -o f1.o -c
$ ar cr f1.a f1.o
$ ld -r f.ld f.o f1.a -o f2.o
$ gcc f2.o -o a.out
$ ./a.out
12345678

Since this is userspace, you do not have complete control on the build
and you still need to use gcc to drive the final link.

So you get exactly the same semantics as ((constructor)), plus one extra
build step that spits out a warning ("ld: warning: f.ld contains output
sections; did you forget -T?").

>>> __attribute__((constructor)) is not particularly portable to begin with:
>>> does the MSVC compiler support it for example?
>>
>> No, but GCC supports it on non-ELF platforms, [...]
>
> So you claim that ((section)) is 'not portable' but concede that it does in
> fact not port to one of the most widely used compilers.

Can you please avoid trimming messages? I said "the differences between
MSVC and GCC can easily be abstracted with a macro". This is not unlike
other differences between the two compilers (e.g. __forceinline vs. the
((always_inline)) attribute), and it is not true of linker scripts.

> Instead you clarify that under 'not portable' you really meant to say that
> ((section)) does not work on non-ELF binary platforms.
>
> That is a pretty inconsistent position and has nothing to do with 'portability'
> in itself but with being portable to what *you* consider important.

My definition of "(reasonably) portable" includes having to write a
5-line macro that works across _all_ GCC targets and _all_ MSVC targets.

Having to change the build process for every compiler target (see the
above "ld -r" step) is a bit more unportable, though not much.
Potentially having to modify the custom linker script for every targeted
architecture (the above doesn't work for mingw32, it needs an extra _ in
front of the start/end symbols) is pretty much my definition of
"unportable".

Paolo