On Mon, Apr 17, 2006 at 09:00:39PM +0900, Atsushi Nemoto wrote:
> 64bit mips has different r_info layout. This patch fixes modpost
> segfault for 64bit little endian mips kernel.
>
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
>
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index cd00e9f..7846600 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -712,7 +712,13 @@ static void check_sec_ref(struct module
> r.r_offset = TO_NATIVE(rela->r_offset);
> r.r_info = TO_NATIVE(rela->r_info);
> r.r_addend = TO_NATIVE(rela->r_addend);
> +#if KERNEL_ELFCLASS == ELFCLASS64 && KERNEL_ELFDATA == ELFDATA2LSB
> + sym = elf->symtab_start +
> + (hdr->e_machine == EM_MIPS ?
> + (Elf32_Word)r.r_info : ELF_R_SYM(r.r_info));
> +#else
> sym = elf->symtab_start + ELF_R_SYM(r.r_info);
> +#endif
> /* Skip special sections */
> if (sym->st_shndx >= SHN_LORESERVE)
> continue;
Hi Atsushi
So with 64bit mips with the above we read r.r_info with no
modifications. But the elf.h I have on my system looks like this:
/* How to extract and insert information held in the r_info field. */
#define ELF32_R_SYM(val) ((val) >> 8)
#define ELF32_R_TYPE(val) ((val) & 0xff)
#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
So the difference between 64bit and 32bit is only the number of right
shifts.
Maybe we need to do some simple range check also so it becomes:
if ((sym->st_shndx >= SHN_LORESERVE) || (sym > elf->symtab_stop))
continue;
Could you try this - and if you still see the SEGVAL then try to print
out the value of all members in 'r'.
You can also try to add '-g' to HOSTCFLAGS in toplevel makefile.
Then use make V=1 to see what arguments modpost is caleld with and call
it from the commandline or from a debugger.
Sam
|