Messages in this thread | | | Date | Mon, 1 Jul 1996 21:23:33 -0400 | From | Michael Meissner <> | Subject | Re: Driver optimization. |
| |
| Implementation: | Ideally gcc should grok an #pragma similar to the MSC compiler above. | Otherwise an "asm" statement could be inserted before and after | init routines to switch to a different segement. The problem with | this approach is that a string in the routine causes an | .section .rodata | .LC0: | .string "this is the string | .text | to be emitted just before the function, undoing the simple | asm (".section .init"); | A way around this needs to be found.
Umm, providing you use an ELF gcc compiler, GCC already supports this:
extern void foo() __attribute__((section(".foo"))); void foo(){}
generates the following code:
.file "foo.c" .version "01.01" gcc2_compiled.: .section .foo,"ax",@progbits .align 16 .globl foo .type foo,@function foo: pushl %ebp movl %esp,%ebp movl %ebp,%esp popl %ebp ret .Lfe1: .size foo,.Lfe1-foo .ident "GCC: (GNU) 2.7.2"
There is no way at all an a.out compiler can support section attributes, due to the limited nature of the object format. Also note, that as currently configured, the Alpha and 32-bit mips do not support putting text in any section other than .text (ie, if you use it, you will need to wrap it in macros so that it can be turned off).
Note, that the __attribute__ must appear on the function declaration, not the definition.
| In ELF lots of segments get mapped the same as .text, ".init" is | indeed one of them, so if you don't want to go and edit binutils, you | could just use one of those (I don't know if ".init" is already used).
In some ELF systems, .init contains all of the constructors (actually, the crti.o module contains the function prologue, and each module deposits a call foo into the .init section to call the appropriate construction, and the crtn.o module contains the function epilogue). The crt[01].o then calls the .init section. Static constructors are handled similarly with a section known as .fini.
This of course also assumes that the linker will link the other other sections close enough to the normal callers, since on RISC platforms in general, the call instruction is limited in the range it can call to without loading the address into a pointer and calling indirect through it. If that happens, you either get an abort, or the linker creates a PLT-type call, which uses up a few cycles.
By the way, the technique of putting init code into memory that will be freed up is quite old. I first ran across it in 1976 on CDC Cybers running Kronos. I'm sure it was old even then.
-- Michael Meissner, Cygnus Support (East Coast) Suite 105, 48 Grove Street, Somerville, MA 02144, USA meissner@cygnus.com, 617-629-3016 (office), 617-629-3010 (fax)
| |