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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html