This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: ARM crt.. files


I believe I have devised a solution, but I am too lazy to fully implement
it myself.  This would replace my postprocessed-assembly kludge with a
postprocessed-object file kludge, which is probably more portable given GNU
binutils.  

I don't know if this will actually fly on the ARM, it depends on the
relocations working the way I am presuming.  But it seems like a good
direction to investigate.

I have just whipped up a little test case, not actually built this in libc.
I'm pretty sure my example as shown below is not adequate; it needs to make
sure the alignment is fixed up with nops at the ends of the prologues.  But
it should give you the idea.

I've reduced initfini.c to the following cpp-less code.
The only change to the actual code is the section directives.


void __attribute__((section (".init.prologue")))
_init (void)
{
  /* We cannot use the normal constructor mechanism in gcrt1.o because it
     appears before crtbegin.o in the link, so the header elt of .ctors
     would come after the elt for __gmon_start__.  One approach is for
     gcrt1.o to reference a symbol which would be defined by some library
     module which has a constructor; but then user code's constructors
     would come first, and not be profiled.  */
  extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/

  if (__gmon_start__)
    __gmon_start__ ();

  asm (".section .init.epilogue,\"ax\",@progbits");

  /* Now the epilog. */
}


void __attribute__((section (".fini.prologue")))
_fini (void)
{

  asm (".section .garbage,\"ax\",@progbits");
  /* End of the _fini prolog. */

  {
    /* Let GCC know that _fini is not a leaf function by having a dummy
       function call here.  We arrange for this call to be omitted from
       either crt file.  */
    extern void i_am_not_a_leaf (void);
    i_am_not_a_leaf ();
  }

  asm (".section .fini.epilogue,\"ax\",@progbits");
  /* Beginning of the _fini epilog. */
}


I compile this file to a normal object file:

	% cc -c -g0 -fPIC foo.c

I then split it up using magical features of ld and objcopy, to wit:

	% ld -r -T foo.script foo.o -o fooi.o --warn-section-align
	ld: warning: changing start of section .fini by 3 bytes
	ld: warning: changing start of section .data by 1 bytes
	% ld -r -T bar.script foo.o -o foon.o --warn-section-align
	ld: warning: changing start of section .text by 2 bytes
	ld: warning: changing start of section .data by 3 bytes
	% objcopy -R .init.epilogue -R .fini.epilogue -R .garbage fooi.o crti.o
	% objcopy -R .init.prologue -R .fini.prologue -R .garbage foon.o crtn.o

The two linker script files are, foo.script:

	SECTIONS
	{
	  .init :
	    {
	      *(.init.prologue)
	    }
	  .fini :
	    {
	      *(.fini.prologue)
	    }
	}

and bar.script:

	SECTIONS
	{
	  .init :
	    {
	      *(.init.epilogue)
	    }
	  .fini :
	    {
	      *(.fini.epilogue)
	    }
	}

Note that I used --warn-section-align and it complained.  I believe there
needs to be the proper number of nop insns to align the sections properly
or this won't actually work.

The objcopy step is necessary because ld will stick all the unmentioned
sections into the output, and as far as I can tell there is no way to tell
it on the command line or in a linker script to discard sections.

If there are sections such as .rodata or whatnot that actually have
necessary contents on other machines (they are all empty on x86), we might
need some more tweaks to the linker script and/or objcopy commands.

I haven't tried it, but I think that with this approach there is no need to
avoid -g or other normal things when compiling initfini.c.


Hope this helps,
Roland


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]