diff options
author | John Reiser <jreiser@BitWagon.com> | 2010-10-27 18:59:07 +0800 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-10-29 19:08:54 +0100 |
commit | a2d49358ba9bc93204dc001d5568c5bdb299b77d (patch) | |
tree | a9f70362c6aba75f56ad4a808473ae961cff957b /scripts/recordmcount.h | |
parent | 949e51bea342da838be5295628e4a7ada8bae833 (diff) | |
download | linux-a2d49358ba9bc93204dc001d5568c5bdb299b77d.tar.gz |
ftrace/MIPS: Add MIPS64 support for C version of recordmcount
MIPS64 has 'weird' Elf64_Rel.r_info[1,2], which must be used instead of
the generic Elf64_Rel.r_info, otherwise, the C version of recordmcount
will not work for "segmentation fault".
Usage of "union mips_r_info" and the functions MIPS64_r_sym() and
MIPS64_r_info() written by Maciej W. Rozycki <macro@linux-mips.org>
----
[1] http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
[2] arch/mips/include/asm/module.h
Tested-by: Wu Zhangjin <wuzhangjin@gmail.com>
Signed-off-by: John Reiser <jreiser@BitWagon.com>
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
LKML-Reference: <AANLkTinwXjLAYACUfhLYaocHD_vBbiErLN3NjwN8JqSy@mail.gmail.com>
LKML-Reference: <910dc2d5ae1ed042df4f96815fe4a433078d1c2a.1288176026.git.wuzhangjin@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'scripts/recordmcount.h')
-rw-r--r-- | scripts/recordmcount.h | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 7f39d0943d2d..190fd18dc853 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -31,8 +31,12 @@ #undef Elf_Rela #undef Elf_Sym #undef ELF_R_SYM +#undef Elf_r_sym #undef ELF_R_INFO +#undef Elf_r_info #undef ELF_ST_BIND +#undef fn_ELF_R_SYM +#undef fn_ELF_R_INFO #undef uint_t #undef _w #undef _align @@ -52,8 +56,12 @@ # define Elf_Rela Elf64_Rela # define Elf_Sym Elf64_Sym # define ELF_R_SYM ELF64_R_SYM +# define Elf_r_sym Elf64_r_sym # define ELF_R_INFO ELF64_R_INFO +# define Elf_r_info Elf64_r_info # define ELF_ST_BIND ELF64_ST_BIND +# define fn_ELF_R_SYM fn_ELF64_R_SYM +# define fn_ELF_R_INFO fn_ELF64_R_INFO # define uint_t uint64_t # define _w w8 # define _align 7u @@ -72,14 +80,32 @@ # define Elf_Rela Elf32_Rela # define Elf_Sym Elf32_Sym # define ELF_R_SYM ELF32_R_SYM +# define Elf_r_sym Elf32_r_sym # define ELF_R_INFO ELF32_R_INFO +# define Elf_r_info Elf32_r_info # define ELF_ST_BIND ELF32_ST_BIND +# define fn_ELF_R_SYM fn_ELF32_R_SYM +# define fn_ELF_R_INFO fn_ELF32_R_INFO # define uint_t uint32_t # define _w w # define _align 3u # define _size 4 #endif +/* Functions and pointers that 64-bit EM_MIPS can override. */ +static uint_t fn_ELF_R_SYM(Elf_Rel const *rp) +{ + return ELF_R_SYM(_w(rp->r_info)); +} +static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; + +static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) +{ + rp->r_info = ELF_R_INFO(sym, type); +} +static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; + + /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ static void append_func(Elf_Ehdr *const ehdr, Elf_Shdr *const shstr, @@ -197,22 +223,22 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, for (t = nrel; t; --t) { if (!mcountsym) { Elf_Sym const *const symp = - &sym0[ELF_R_SYM(_w(relp->r_info))]; + &sym0[Elf_r_sym(relp)]; char const *symname = &str0[w(symp->st_name)]; if ('.' == symname[0]) ++symname; /* ppc64 hack */ if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), symname)) - mcountsym = ELF_R_SYM(_w(relp->r_info)); + mcountsym = Elf_r_sym(relp); } - if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { + if (mcountsym == Elf_r_sym(relp)) { uint_t const addend = _w(_w(relp->r_offset) - recval); mrelp->r_offset = _w(offbase + ((void *)mlocp - (void *)mloc0)); - mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); + Elf_r_info(mrelp, recsym, reltype); if (sizeof(Elf_Rela) == rel_entsize) { ((Elf_Rela *)mrelp)->r_addend = addend; *mlocp++ = 0; |