aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/recordmcount.h
diff options
context:
space:
mode:
authorJohn Reiser <jreiser@BitWagon.com>2010-10-27 06:59:07 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-10-29 14:08:54 -0400
commita2d49358ba9bc93204dc001d5568c5bdb299b77d (patch)
treea9f70362c6aba75f56ad4a808473ae961cff957b /scripts/recordmcount.h
parent949e51bea342da838be5295628e4a7ada8bae833 (diff)
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.h34
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 @@
31#undef Elf_Rela 31#undef Elf_Rela
32#undef Elf_Sym 32#undef Elf_Sym
33#undef ELF_R_SYM 33#undef ELF_R_SYM
34#undef Elf_r_sym
34#undef ELF_R_INFO 35#undef ELF_R_INFO
36#undef Elf_r_info
35#undef ELF_ST_BIND 37#undef ELF_ST_BIND
38#undef fn_ELF_R_SYM
39#undef fn_ELF_R_INFO
36#undef uint_t 40#undef uint_t
37#undef _w 41#undef _w
38#undef _align 42#undef _align
@@ -52,8 +56,12 @@
52# define Elf_Rela Elf64_Rela 56# define Elf_Rela Elf64_Rela
53# define Elf_Sym Elf64_Sym 57# define Elf_Sym Elf64_Sym
54# define ELF_R_SYM ELF64_R_SYM 58# define ELF_R_SYM ELF64_R_SYM
59# define Elf_r_sym Elf64_r_sym
55# define ELF_R_INFO ELF64_R_INFO 60# define ELF_R_INFO ELF64_R_INFO
61# define Elf_r_info Elf64_r_info
56# define ELF_ST_BIND ELF64_ST_BIND 62# define ELF_ST_BIND ELF64_ST_BIND
63# define fn_ELF_R_SYM fn_ELF64_R_SYM
64# define fn_ELF_R_INFO fn_ELF64_R_INFO
57# define uint_t uint64_t 65# define uint_t uint64_t
58# define _w w8 66# define _w w8
59# define _align 7u 67# define _align 7u
@@ -72,14 +80,32 @@
72# define Elf_Rela Elf32_Rela 80# define Elf_Rela Elf32_Rela
73# define Elf_Sym Elf32_Sym 81# define Elf_Sym Elf32_Sym
74# define ELF_R_SYM ELF32_R_SYM 82# define ELF_R_SYM ELF32_R_SYM
83# define Elf_r_sym Elf32_r_sym
75# define ELF_R_INFO ELF32_R_INFO 84# define ELF_R_INFO ELF32_R_INFO
85# define Elf_r_info Elf32_r_info
76# define ELF_ST_BIND ELF32_ST_BIND 86# define ELF_ST_BIND ELF32_ST_BIND
87# define fn_ELF_R_SYM fn_ELF32_R_SYM
88# define fn_ELF_R_INFO fn_ELF32_R_INFO
77# define uint_t uint32_t 89# define uint_t uint32_t
78# define _w w 90# define _w w
79# define _align 3u 91# define _align 3u
80# define _size 4 92# define _size 4
81#endif 93#endif
82 94
95/* Functions and pointers that 64-bit EM_MIPS can override. */
96static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
97{
98 return ELF_R_SYM(_w(rp->r_info));
99}
100static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
101
102static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
103{
104 rp->r_info = ELF_R_INFO(sym, type);
105}
106static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
107
108
83/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ 109/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
84static void append_func(Elf_Ehdr *const ehdr, 110static void append_func(Elf_Ehdr *const ehdr,
85 Elf_Shdr *const shstr, 111 Elf_Shdr *const shstr,
@@ -197,22 +223,22 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
197 for (t = nrel; t; --t) { 223 for (t = nrel; t; --t) {
198 if (!mcountsym) { 224 if (!mcountsym) {
199 Elf_Sym const *const symp = 225 Elf_Sym const *const symp =
200 &sym0[ELF_R_SYM(_w(relp->r_info))]; 226 &sym0[Elf_r_sym(relp)];
201 char const *symname = &str0[w(symp->st_name)]; 227 char const *symname = &str0[w(symp->st_name)];
202 228
203 if ('.' == symname[0]) 229 if ('.' == symname[0])
204 ++symname; /* ppc64 hack */ 230 ++symname; /* ppc64 hack */
205 if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), 231 if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"),
206 symname)) 232 symname))
207 mcountsym = ELF_R_SYM(_w(relp->r_info)); 233 mcountsym = Elf_r_sym(relp);
208 } 234 }
209 235
210 if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { 236 if (mcountsym == Elf_r_sym(relp)) {
211 uint_t const addend = _w(_w(relp->r_offset) - recval); 237 uint_t const addend = _w(_w(relp->r_offset) - recval);
212 238
213 mrelp->r_offset = _w(offbase 239 mrelp->r_offset = _w(offbase
214 + ((void *)mlocp - (void *)mloc0)); 240 + ((void *)mlocp - (void *)mloc0));
215 mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); 241 Elf_r_info(mrelp, recsym, reltype);
216 if (sizeof(Elf_Rela) == rel_entsize) { 242 if (sizeof(Elf_Rela) == rel_entsize) {
217 ((Elf_Rela *)mrelp)->r_addend = addend; 243 ((Elf_Rela *)mrelp)->r_addend = addend;
218 *mlocp++ = 0; 244 *mlocp++ = 0;