From: John Reiser <jreiser@bitwagon.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>,
wu zhangjin <wuzhangjin@gmail.com>,
David Daney <ddaney@caviumnetworks.com>,
linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>
Subject: patch v2: [RFC 2/2] ftrace/MIPS: Add support for C version of recordmcount
Date: Mon, 25 Oct 2010 09:46:44 -0700 [thread overview]
Message-ID: <4CC5B474.9050503@bitwagon.com> (raw)
In-Reply-To: <alpine.LFD.2.00.1010250435540.15889@eddie.linux-mips.org>
Here's a second try [discard the first] for handling MIPS64 in recordmcount.[ch].
Signed-off-by: John Reiser <jreiser@BitWagon.com
diff --git a/recordmcount.c b/recordmcount.c
index 7f7f718..7337ee8 100644
--- a/recordmcount.c
+++ b/recordmcount.c
@@ -212,11 +212,48 @@ is_mcounted_section_name(char const *const txtname)
0 == strcmp(".text.unlikely", txtname);
}
+
/* 32 bit and 64 bit are very similar */
#include "recordmcount.h"
#define RECORD_MCOUNT_64
#include "recordmcount.h"
+/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
+ * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
+ * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
+ * to imply the order of the members; the spec does not say so.
+ * typedef unsigned char Elf64_Byte;
+ * fails on MIPS64 because their <elf.h> already has it!
+ */
+typedef unsigned char myElf64_byte;
+typedef struct {
+ Elf64_Addr r_offset; /* Address */
+ struct {
+ Elf64_Word r_sym;
+ myElf64_byte r_ssym; /* Special sym: gp-relative, etc. */
+ myElf64_byte r_type3;
+ myElf64_byte r_type2;
+ myElf64_byte r_type;
+ } r_info;
+ Elf64_Sxword r_addend; /* Addend */
+} MIPS64_Rela;
+
+static uint64_t MIPS64_r_sym(Elf64_Rel const *rp)
+{
+ return w(((MIPS64_Rela const *)rp)->r_info.r_sym);
+}
+
+static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type)
+{
+ MIPS64_Rela *const m64rp = (MIPS64_Rela *)rp;
+ m64rp->r_info.r_sym = w(sym);
+ m64rp->r_info.r_ssym = 0;
+ m64rp->r_info.r_type3 = 0;
+ m64rp->r_info.r_type2 = 0;
+ m64rp->r_info.r_type = type;
+}
+
+
static void
do_file(char const *const fname)
{
@@ -268,6 +305,7 @@ do_file(char const *const fname)
case EM_386: reltype = R_386_32; break;
case EM_ARM: reltype = R_ARM_ABS32; break;
case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
+ case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break;
case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
@@ -291,6 +329,8 @@ do_file(char const *const fname)
}
if (EM_S390 == w2(ehdr->e_machine))
reltype = R_390_32;
+ if (EM_MIPS == w2(ehdr->e_machine))
+ reltype = R_MIPS_32;
do32(ehdr, fname, reltype);
} break;
case ELFCLASS64: {
@@ -303,6 +343,11 @@ do_file(char const *const fname)
}
if (EM_S390 == w2(ghdr->e_machine))
reltype = R_390_64;
+ if (EM_MIPS == w2(ghdr->e_machine)) {
+ reltype = R_MIPS_64;
+ Elf64_r_sym = MIPS64_r_sym;
+ Elf64_r_info = MIPS64_r_info;
+ }
do64(ghdr, fname, reltype);
} break;
} /* end switch */
diff --git a/recordmcount.h b/recordmcount.h
index 7f39d09..190fd18 100644
--- a/recordmcount.h
+++ b/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;
--
John Reiser, jreiser@BitWagon.com
next prev parent reply other threads:[~2010-10-25 16:47 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-23 18:53 [RFC 2/2] ftrace/MIPS: Add support for C version of recordmcount wu zhangjin
2010-10-24 8:58 ` Steven Rostedt
2010-10-24 14:25 ` John Reiser
2010-10-24 20:44 ` patch: " John Reiser
2010-10-25 3:59 ` Maciej W. Rozycki
2010-10-25 12:28 ` John Reiser
2010-10-25 16:46 ` John Reiser [this message]
2010-10-25 18:17 ` patch v2: " wu zhangjin
2010-10-25 20:24 ` Steven Rostedt
2010-10-26 18:28 ` wu zhangjin
2010-10-26 13:36 ` Maciej W. Rozycki
2010-10-26 19:57 ` wu zhangjin
2010-10-27 9:31 ` Maciej W. Rozycki
2010-10-27 9:54 ` wu zhangjin
2010-10-26 21:21 ` wu zhangjin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CC5B474.9050503@bitwagon.com \
--to=jreiser@bitwagon.com \
--cc=ddaney@caviumnetworks.com \
--cc=linux-mips@linux-mips.org \
--cc=macro@linux-mips.org \
--cc=ralf@linux-mips.org \
--cc=rostedt@goodmis.org \
--cc=wuzhangjin@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox