diff options
| -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) | |||
| 302 | continue; | 302 | continue; |
| 303 | sym->pfunc = sym->cfunc = sym; | 303 | sym->pfunc = sym->cfunc = sym; |
| 304 | coldstr = strstr(sym->name, ".cold."); | 304 | coldstr = strstr(sym->name, ".cold."); |
| 305 | if (coldstr) { | 305 | if (!coldstr) |
| 306 | coldstr[0] = '\0'; | 306 | continue; |
| 307 | pfunc = find_symbol_by_name(elf, sym->name); | 307 | |
| 308 | coldstr[0] = '.'; | 308 | coldstr[0] = '\0'; |
| 309 | 309 | pfunc = find_symbol_by_name(elf, sym->name); | |
| 310 | if (!pfunc) { | 310 | coldstr[0] = '.'; |
| 311 | WARN("%s(): can't find parent function", | 311 | |
| 312 | sym->name); | 312 | if (!pfunc) { |
| 313 | goto err; | 313 | WARN("%s(): can't find parent function", |
| 314 | } | 314 | sym->name); |
| 315 | 315 | goto err; | |
| 316 | sym->pfunc = pfunc; | 316 | } |
| 317 | pfunc->cfunc = sym; | 317 | |
| 318 | sym->pfunc = pfunc; | ||
| 319 | pfunc->cfunc = sym; | ||
| 320 | |||
| 321 | /* | ||
| 322 | * Unfortunately, -fnoreorder-functions puts the child | ||
| 323 | * inside the parent. Remove the overlap so we can | ||
| 324 | * have sane assumptions. | ||
| 325 | * | ||
| 326 | * Note that pfunc->len now no longer matches | ||
| 327 | * pfunc->sym.st_size. | ||
| 328 | */ | ||
| 329 | if (sym->sec == pfunc->sec && | ||
| 330 | sym->offset >= pfunc->offset && | ||
| 331 | sym->offset + sym->len == pfunc->offset + pfunc->len) { | ||
| 332 | pfunc->len -= sym->len; | ||
| 318 | } | 333 | } |
| 319 | } | 334 | } |
| 320 | } | 335 | } |
