From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH 5/5 V2] kvm tools: Initialize and use VESA and VNC Date: Wed, 25 May 2011 10:21:28 +0200 Message-ID: <4DDCBC08.3030507@redhat.com> References: <1306149553-26793-1-git-send-email-levinsasha928@gmail.com> <1306149553-26793-5-git-send-email-levinsasha928@gmail.com> <20110523113824.GE4042@elte.hu> <4DDB6E55.8080408@redhat.com> <20110524085024.GA31453@elte.hu> <4DDB77E5.4080306@redhat.com> <20110524194019.GA27634@elte.hu> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Sasha Levin , penberg@kernel.org, john@jfloren.net, kvm@vger.kernel.org, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com To: Ingo Molnar Return-path: Received: from mx1.redhat.com ([209.132.183.28]:8381 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932489Ab1EYIVv (ORCPT ); Wed, 25 May 2011 04:21:51 -0400 In-Reply-To: <20110524194019.GA27634@elte.hu> Sender: kvm-owner@vger.kernel.org List-ID: 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