On Tue, Nov 23, 2010 at 2:46 AM, Arnaud Lacombe <lacombar@gmail.com> wrote:
> Hi,
>
> On Mon, Nov 22, 2010 at 9:57 AM, wu zhangjin <wuzhangjin@gmail.com> wrote:
>> Hi,
>>
>> The cause should be the endian problem, I guess you were cross-compiling it?
>>
> yes.
>
>> If we compile the kernel for (32bit + big endian) target on an x86
>> machine(little endian) or reversely, then, it will fail.
>>
>> Since the scripts/recordmcount is compiled with the local toolchain,
>> the data structs will be explained according to the local
>> configuration(endian...).
>>
> will it ? recordmcount.c does not switch endianness based on the host,
> but based on format of the object file, see the switch
> (ehdr->e_ident[EI_DATA]) { ... } in do_file(), the result does also
> depend a runtime endianness check.
Yes ;-)
>
>> So, we may need to custom our own elf.h for recordmcount according to
>> the target type(endian here) of the kernel image:
>>
>> At first, pass the target information to recordmcount(only a demo
>> here, we may need to clear it carefully):
>>
>> diff --git a/scripts/Makefile b/scripts/Makefile
>> index 2e08810..151fe3e 100644
>> --- a/scripts/Makefile
>> +++ b/scripts/Makefile
>> @@ -11,6 +11,9 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms
>> hostprogs-$(CONFIG_LOGO) += pnmtologo
>> hostprogs-$(CONFIG_VT) += conmakehash
>> hostprogs-$(CONFIG_IKCONFIG) += bin2c
>> +HOSTCFLAGS_recordmcount.o += -DARCH=__$(ARCH)__ \
>> + -DBIT=__$(if $(CONFIG_64BIT),64,32)__ \
>> + -DENDIAN=__$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)__
>> hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
>>
>> always := $(hostprogs-y) $(hostprogs-m)
>>
> hum,
>
> % grep "BIT\|ENDIAN" scripts/recordmcount.*
> scripts/recordmcount.h: mcsec.sh_type = w(SHT_PROGBITS);
> scripts/recordmcount.h: if (SHT_PROGBITS != w(txthdr->sh_type) ||
>
> so none these macro are not checked explicitly, and headers included
> should not either.
John have already abstracted w, w2, w8 to handle the endianess
problem, I just forgot looking to them, sorry ;-)
BTW,
1. But check the endianess and ARCH before compiling the
scripts/recordmcount.c may speedup it a lot for after issuing "make
ARCH=XXX", everything including the endianess and ARCH of the object
files are definite, so, we may don't need to check them at runtime. of
course, check them at runtime can avoid compiling it for different
ARCHs but who will use this for different ARCHs at the same time ;-)
2. In the long run, we may be possible to add a new option(with -pg)
to gcc and ask it to create a __mcount_loc section for us, then, we
will be able to use it in kernel directly. I think gcc will be easier
to put the _mcount calling sites into a section because it adds them
and therefore knows 'more'(where, endianess, type... are definite)
about them, but in kernel, we need extra/complex search, check and
relocation...
Thanks & Regards,
Wu Zhangjin