diff options
| author | Rabin Vincent <rabin@rab.in> | 2011-05-11 13:23:51 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2011-05-25 19:56:33 -0400 |
| commit | 9905ce8ad7b79dddd23c7b4753d0b2cdb65bde3c (patch) | |
| tree | 72f06d11cf99b20d7e91a1bb65be8a7f20756c65 /scripts | |
| parent | 4d7a2fa876d1a615649761dc465708d0a062249a (diff) | |
ftrace/recordmcount: Avoid STT_FUNC symbols as base on ARM
While find_secsym_ndx often finds the unamed local STT_SECTION, if a
section has only one function in it, the ARM toolchain generates the
STT_FUNC symbol before the STT_SECTION, and recordmcount finds this
instead.
This is problematic on ARM because in ARM ELFs, "if a [STT_FUNC] symbol
addresses a Thumb instruction, its value is the address of the
instruction with bit zero set (in a relocatable object, the section
offset with bit zero set)". This leads to incorrect mcount addresses
being recorded.
Fix this by not using STT_FUNC symbols as the base on ARM.
Signed-off-by: Rabin Vincent <rabin@rab.in>
Link: http://lkml.kernel.org/r/1305134631-31617-1-git-send-email-rabin@rab.in
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/recordmcount.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 4be60364a40..f40a6af6bf4 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #undef ELF_R_INFO | 43 | #undef ELF_R_INFO |
| 44 | #undef Elf_r_info | 44 | #undef Elf_r_info |
| 45 | #undef ELF_ST_BIND | 45 | #undef ELF_ST_BIND |
| 46 | #undef ELF_ST_TYPE | ||
| 46 | #undef fn_ELF_R_SYM | 47 | #undef fn_ELF_R_SYM |
| 47 | #undef fn_ELF_R_INFO | 48 | #undef fn_ELF_R_INFO |
| 48 | #undef uint_t | 49 | #undef uint_t |
| @@ -76,6 +77,7 @@ | |||
| 76 | # define ELF_R_INFO ELF64_R_INFO | 77 | # define ELF_R_INFO ELF64_R_INFO |
| 77 | # define Elf_r_info Elf64_r_info | 78 | # define Elf_r_info Elf64_r_info |
| 78 | # define ELF_ST_BIND ELF64_ST_BIND | 79 | # define ELF_ST_BIND ELF64_ST_BIND |
| 80 | # define ELF_ST_TYPE ELF64_ST_TYPE | ||
| 79 | # define fn_ELF_R_SYM fn_ELF64_R_SYM | 81 | # define fn_ELF_R_SYM fn_ELF64_R_SYM |
| 80 | # define fn_ELF_R_INFO fn_ELF64_R_INFO | 82 | # define fn_ELF_R_INFO fn_ELF64_R_INFO |
| 81 | # define uint_t uint64_t | 83 | # define uint_t uint64_t |
| @@ -108,6 +110,7 @@ | |||
| 108 | # define ELF_R_INFO ELF32_R_INFO | 110 | # define ELF_R_INFO ELF32_R_INFO |
| 109 | # define Elf_r_info Elf32_r_info | 111 | # define Elf_r_info Elf32_r_info |
| 110 | # define ELF_ST_BIND ELF32_ST_BIND | 112 | # define ELF_ST_BIND ELF32_ST_BIND |
| 113 | # define ELF_ST_TYPE ELF32_ST_TYPE | ||
| 111 | # define fn_ELF_R_SYM fn_ELF32_R_SYM | 114 | # define fn_ELF_R_SYM fn_ELF32_R_SYM |
| 112 | # define fn_ELF_R_INFO fn_ELF32_R_INFO | 115 | # define fn_ELF_R_INFO fn_ELF32_R_INFO |
| 113 | # define uint_t uint32_t | 116 | # define uint_t uint32_t |
| @@ -427,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx, | |||
| 427 | if (txtndx == w2(symp->st_shndx) | 430 | if (txtndx == w2(symp->st_shndx) |
| 428 | /* avoid STB_WEAK */ | 431 | /* avoid STB_WEAK */ |
| 429 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { | 432 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { |
| 433 | /* function symbols on ARM have quirks, avoid them */ | ||
| 434 | if (w2(ehdr->e_machine) == EM_ARM | ||
| 435 | && ELF_ST_TYPE(symp->st_info) == STT_FUNC) | ||
| 436 | continue; | ||
| 437 | |||
| 430 | *recvalp = _w(symp->st_value); | 438 | *recvalp = _w(symp->st_value); |
| 431 | return symp - sym0; | 439 | return symp - sym0; |
| 432 | } | 440 | } |
