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

Paolo Bonzini
2011-05-25T08:21:51Z

On 05/24/2011 09:40 PM, Ingo Molnar wrote:
> > Ah, forgot about this. Given_why_ this happens (for static libraries, the
> > linker omits object modules that are not required to fulfill undefined
> > references in previous objects), I'd be surprised if explicit section tricks
> > do not have the same limitation. [...]
>
> Since we create an actual array (data)

Are you? I figured it was like this example from Linux:

.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
__x86_cpu_dev_start = .;
*(.x86_cpu_dev.init)
__x86_cpu_dev_end = .;
}

extern const struct cpu_dev *const __x86_cpu_dev_start[],
*const __x86_cpu_dev_end[];

for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {

This is pretty much the same as the linker script for ELF:

.init_array : {
__init_array_start = .;
*(.init_array)
*(SORT(.init_array$*))
__init_array_end = .;
}

extern void (*__init_array_start []) (int, char **, char **)
attribute_hidden;
extern void (*__init_array_end []) (int, char **, char **)
attribute_hidden;

const size_t size = __init_array_end - __init_array_start;
for (size_t i = 0; i < size; i++)
(*__init_array_start [i]) (argc, argv, envp);

> ((constructor)) has showstopper properties:
>
> - We don't have access to the program arguments
>
> - stdio is probably not set up yet (this is undefined AFAICS)

As I said, you can do this even better by doing only minimal work in the
constructor. Create a struct with several callbacks (pre_init,
late_init, destroy, reset, whatever) and possibly other information (a
human-readable device name and command-line argument to access it, for
example). In the constructor you just build a linked list of said
structs, and then you can walk it whenever you see fit: do comparisons,
call a function, whatever. This is similar to the cpudev example from
the kernel above.

A simple example from QEMU:

static void virtio_pci_register_devices(void)
{
pci_qdev_register_many(virtio_info);
}

/* This macro wraps ((constructor)). */
device_init(virtio_pci_register_devices)

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

> __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, where you would need a
similar but different linker script. (Also, the differences between
MSVC and GCC can easily be abstracted with a macro).

More practically, is your linker script supported by gold?

Paolo