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 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html