Subject: Initial test of ELF tools...

From: Russell King <[email-masked]>
Date: Sun, 7 Dec 1997 20:39:59 +0000 (GMT)

Hi all!

I decided to try out my hacks of gcc-2.7.2.2 and binutils-2.8 on the Linux kernel
(v2.1.71) to see what it would make of it...  However, gcc requires modifications
far beyond the simple backend mods to get it to produce code suitable for compiling
up the kernel with the __initfunc extensions...

The problem is this:
	The Linux kernel puts all functions and data relating to initialisation
	in a separate section - .text.init and .data.init.  This allows the Linux
	kernel to drop it's initialisation code after boot (since it's only
	run once, there's no point in keeping it in memory).

	When GCC compiles this code under ARM, using the following pre-processed
	C code (somewhat cut-down):
		void calibrate_delay(void) __attribute__((__section__(".text.init")));
		void calibrate_delay(void)
		{
			loops_per_sec = (1<<12);

			printk("Calibrating delay loop.. ");
			...
		}
	GCC outputs the following assembler code (cut-down):
		        .global loops_per_sec
		.data
		        .align  0
		        .type    loops_per_sec,#object
		        .size    loops_per_sec,4
		loops_per_sec:
		        .word   4096
		.text
		.LC106:
		        .ascii  "Calibrating delay loop.. \000"
		.section        .text.init,"ax",@progbits
		        .align  0
		.LC105:
		        .word   loops_per_sec
		        .align  0
		        .global calibrate_delay
		        .type    calibrate_delay,#function
		calibrate_delay:
		        @ args = 0, pretend = 0, frame = 0
		        @ frame_needed = 1, current_function_anonymous_args = 0
		        @ pic_reg_used = 0
		        mov     ip, sp
		        stmfd   sp!, {r4, r5, r6, r7, r8, fp, ip, lr, pc}
			...
		        sub     r0, pc, #(8 + . -.LC106)
		        sub     fp, ip, #4
		        bl      printk

	Unfortunately, the simple code generated for the printk doesn't work -
	the value of (8+.-.LC106) is not known becuase the location of .LC106
	is not in the current section, and the text strings are written to the
	file *before* the constant pool (I've moved the section selection as
	early as I can with the current way GCC works).

	As far as I can see, we have the following options:
	a) Add an entry into the constant pool, but this will require an extra
	   load, and an extra 4 bytes in the constant pool.
	b) Output the strings into the same section as the function (this
	   would be the best solution, but it may not be easy to do with
	   gcc).
	c) Add relocations for sub instructions etc, and get the binutils
	   to do relaxing (requires a lot of work).

If anyone would like to have a go at GCC, my replacement config/arm directory
will be available next weekend.  (Sorry, can't upload it this weekend - someone's
successfully launched a denial of service attack against the FTP server).  I'd
like to be able (at some point) to make use of this feature that the Linux kernel
offers.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email-masked]       --- ---
  | | | |     http://www.arm.uk.linux.org/~rmk/home.html     /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]