Skip to contentSkip to conversation

recordmcount: Fix handling of elf64 big-endian objects.

PATCH In review David Daney 3 participants 8 messages Dec 20, 2011 – Jan 8, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 recordmcount: Fix handling of elf64 big-endian objects.

From: David Daney <[email protected]>

In ELF64, the sh_flags field is 64-bits wide. recordmcount was erroneously treating it as a 32-bit wide field. For little endian objects this works because the flags of interest (SHF_EXECINSTR) reside in the lower 32 bits of the word, and you get the same result with either a 32-bit or 64-bit read. Big endian objects on the other hand do not work at all with this error.

The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects.

The symptom I observed was that my __start_mcount_loc..__stop_mcount_loc was empty even though ftrace function tracing was enabled.

---
 scripts/recordmcount.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
scripts/recordmcount.h +1 -1
index f40a6af6..54e35c1 100644
@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr,  /* is SHT_REL or SHT_RELA */
 		succeed_file();
 	}
 	if (w(txthdr->sh_type) != SHT_PROGBITS ||
-	    !(w(txthdr->sh_flags) & SHF_EXECINSTR))
+	    !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
 		return NULL;
 	return txtname;
 }
Signature · 1 line
1.7.2.3
#1 lore raw
Quoted 9 lines · David Daney

From: David Daney <[email protected]>

In ELF64, the sh_flags field is 64-bits wide. recordmcount was erroneously treating it as a 32-bit wide field. For little endian objects this works because the flags of interest (SHF_EXECINSTR) reside in the lower 32 bits of the word, and you get the same result with either a 32-bit or 64-bit read. Big endian objects on the other hand do not work at all with this error.

Quoted 6 lines

The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects.

The symptom I observed was that my __start_mcount_loc..__stop_mcount_loc was empty even though ftrace function tracing was enabled.

OUCH!

This looks like something that needs to go to stable. Let me play with this on my PPC64 tomorrow.

Thanks!

-- Steve

Quoted 18 lines
---
 scripts/recordmcount.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
scripts/recordmcount.h +1 -1
index f40a6af6..54e35c1 100644
@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr,  /* is SHT_REL or SHT_RELA */
 		succeed_file();
 	}
 	if (w(txthdr->sh_type) != SHT_PROGBITS ||
-	    !(w(txthdr->sh_flags) & SHF_EXECINSTR))
+	    !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
 		return NULL;
 	return txtname;
 }
#2 lore raw
Quoted 17 lines · Steven Rostedt
Quoted 9 lines · David Daney

From: David Daney<[email protected]>

In ELF64, the sh_flags field is 64-bits wide. recordmcount was erroneously treating it as a 32-bit wide field. For little endian objects this works because the flags of interest (SHF_EXECINSTR) reside in the lower 32 bits of the word, and you get the same result with either a 32-bit or 64-bit read. Big endian objects on the other hand do not work at all with this error.

Quoted 6 lines

The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects.

The symptom I observed was that my __start_mcount_loc..__stop_mcount_loc was empty even though ftrace function tracing was enabled.

Quoted 5 lines

OUCH!

This looks like something that needs to go to stable. Let me play with this on my PPC64 tomorrow.

Hi Steven,

Any more feedback on this patch? Should I look for it to appear in 3.3?

Thanks,
David Daney

Quoted 24 lines

Thanks!

-- Steve

Quoted 18 lines
---
  scripts/recordmcount.h |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
scripts/recordmcount.h +1 -1
index f40a6af6..54e35c1 100644
@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr,  /* is SHT_REL or SHT_RELA */
  		succeed_file();
  	}
  	if (w(txthdr->sh_type) != SHT_PROGBITS ||
-	    !(w(txthdr->sh_flags)&  SHF_EXECINSTR))
+	    !(_w(txthdr->sh_flags)&  SHF_EXECINSTR))
  		return NULL;
  	return txtname;
  }
#3 lore raw
Quoted 1 line · David Daney

Any more feedback on this patch? Should I look for it to appear in 3.3?

Crap, I started testing this, and then got sidetracked on some fires I had to put out, and then x-mas came and I got drunk and forget everything before that ;) (not to mention the drugs I was on for my recent hip surgery)

Let me boot up my PPC64 box and test it out now.

Thanks for the reminder. After I get this done, then I'll push this through my "urgent" branch, which will go into the rc releases, and I'll probably add a "stable" tag to it as well.

-- Steve

#4 lore raw
In reply to David Daney
Quoted 1 line · David Daney

Any more feedback on this patch? Should I look for it to appear in 3.3?

OK, I tested it and then I noticed that mainline doesn't have "HAVE_C_RECORDMCOUNT" set. Is that going in the PPC tree? I added that to arch/powerpc/Kconfig, and did see the bug you saw. After adding your patch, I did a diff of the available_filter_functions and had this:

Quoted 4 lines

.elf_core_extra_phdrs
.elf_core_write_extra_phdrs
.elf_core_write_extra_data
.elf_core_extra_data_size

These 4 functions were added after doing the change. Weird.

Anyway, I'll run the change through my normal tests and then push it out.

Thanks!

-- Steve

#5 lore raw
Quoted 6 lines · Steven Rostedt
Quoted 1 line · David Daney

Any more feedback on this patch? Should I look for it to appear in 3.3?

OK, I tested it and then I noticed that mainline doesn't have "HAVE_C_RECORDMCOUNT" set. Is that going in the PPC tree?

I have no idea, I'm a MIPS guy at the moment.

Quoted 9 lines

I added that
to arch/powerpc/Kconfig, and did see the bug you saw. After adding your patch, I did a diff of the available_filter_functions and had this:

Quoted 4 lines

.elf_core_extra_phdrs
.elf_core_write_extra_phdrs
.elf_core_write_extra_data
.elf_core_extra_data_size

Quoted 5 lines

These 4 functions were added after doing the change. Weird.

Anyway, I'll run the change through my normal tests and then push it out.

Thanks,
David Daney

#6 lore raw
Quoted 10 lines · David Daney
Quoted 6 lines · Steven Rostedt
Quoted 1 line · David Daney

Any more feedback on this patch? Should I look for it to appear in 3.3?

OK, I tested it and then I noticed that mainline doesn't have "HAVE_C_RECORDMCOUNT" set. Is that going in the PPC tree?

I have no idea, I'm a MIPS guy at the moment.

Ah, I forgot about that. Sorry ;)

-- Steve

#7 lore raw
In reply to David Daney
Commit-ID:  2e885057b7f75035f0b85e02f737891482815a81
Gitweb:     http://git.kernel.org/tip/2e885057b7f75035f0b85e02f737891482815a81
Author:     David Daney <[email protected]>
AuthorDate: Mon, 19 Dec 2011 17:42:42 -0800
Committer:  Steven Rostedt <[email protected]>
CommitDate: Fri, 6 Jan 2012 17:06:42 -0500

recordmcount: Fix handling of elf64 big-endian objects.

In ELF64, the sh_flags field is 64-bits wide. recordmcount was erroneously treating it as a 32-bit wide field. For little endian objects this works because the flags of interest (SHF_EXECINSTR) reside in the lower 32 bits of the word, and you get the same result with either a 32-bit or 64-bit read. Big endian objects on the other hand do not work at all with this error.

The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects.

The symptom I observed was that my __start_mcount_loc..__stop_mcount_loc was empty even though ftrace function tracing was enabled.

---
 scripts/recordmcount.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
scripts/recordmcount.h +1 -1
index f40a6af6..54e35c1 100644
@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr,  /* is SHT_REL or SHT_RELA */
 		succeed_file();
 	}
 	if (w(txthdr->sh_type) != SHT_PROGBITS ||
-	    !(w(txthdr->sh_flags) & SHF_EXECINSTR))
+	    !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
 		return NULL;
 	return txtname;
 }