diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-08 21:57:40 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-08 21:57:40 +0300 |
commit | f5c926b99e421db13d2056bc99a624499a2be19e (patch) | |
tree | 753cdfb33e567751a750feb316e8b0dd7d77fdf8 /tools | |
parent | 124b99fb8018a7ac45558d8ab249ed758e14e618 (diff) | |
parent | 08b393d01c88aff27347ed2b1b354eb4db2f1532 (diff) | |
download | linux-f5c926b99e421db13d2056bc99a624499a2be19e.tar.xz |
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool fix from Thomas Gleixner:
"A single fix for objtool to address a bug in handling the cold
subfunction detection for aliased functions which was added recently.
The bug causes objtool to enter an infinite loop"
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
objtool: Support GCC 8 '-fnoreorder-functions'
Diffstat (limited to 'tools')
-rw-r--r-- | tools/objtool/elf.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 4e60e105583e..0d1acb704f64 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -302,19 +302,34 @@ static int read_symbols(struct elf *elf) continue; sym->pfunc = sym->cfunc = sym; coldstr = strstr(sym->name, ".cold."); - if (coldstr) { - coldstr[0] = '\0'; - pfunc = find_symbol_by_name(elf, sym->name); - coldstr[0] = '.'; - - if (!pfunc) { - WARN("%s(): can't find parent function", - sym->name); - goto err; - } - - sym->pfunc = pfunc; - pfunc->cfunc = sym; + if (!coldstr) + continue; + + coldstr[0] = '\0'; + pfunc = find_symbol_by_name(elf, sym->name); + coldstr[0] = '.'; + + if (!pfunc) { + WARN("%s(): can't find parent function", + sym->name); + goto err; + } + + sym->pfunc = pfunc; + pfunc->cfunc = sym; + + /* + * Unfortunately, -fnoreorder-functions puts the child + * inside the parent. Remove the overlap so we can + * have sane assumptions. + * + * Note that pfunc->len now no longer matches + * pfunc->sym.st_size. + */ + if (sym->sec == pfunc->sec && + sym->offset >= pfunc->offset && + sym->offset + sym->len == pfunc->offset + pfunc->len) { + pfunc->len -= sym->len; } } } |