check.c (951ddecf435659553ed15a9214e153a3af43a9a1) check.c (a149180fbcf336e97ce4eb2cdc13672727feb94d)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
4 */
5
6#include <string.h>
7#include <stdlib.h>
8#include <inttypes.h>

--- 1288 unchanged lines hidden (view full) ---

1297 * Annotated intra-function calls retain the stack_ops but
1298 * are converted to JUMP, see read_intra_function_calls().
1299 */
1300 remove_insn_ops(insn);
1301
1302 annotate_call_site(file, insn, false);
1303}
1304
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
4 */
5
6#include <string.h>
7#include <stdlib.h>
8#include <inttypes.h>

--- 1288 unchanged lines hidden (view full) ---

1297 * Annotated intra-function calls retain the stack_ops but
1298 * are converted to JUMP, see read_intra_function_calls().
1299 */
1300 remove_insn_ops(insn);
1301
1302 annotate_call_site(file, insn, false);
1303}
1304
1305static void add_return_call(struct objtool_file *file, struct instruction *insn)
1305static void add_return_call(struct objtool_file *file, struct instruction *insn, bool add)
1306{
1307 /*
1308 * Return thunk tail calls are really just returns in disguise,
1309 * so convert them accordingly.
1310 */
1311 insn->type = INSN_RETURN;
1312 insn->retpoline_safe = true;
1313
1306{
1307 /*
1308 * Return thunk tail calls are really just returns in disguise,
1309 * so convert them accordingly.
1310 */
1311 insn->type = INSN_RETURN;
1312 insn->retpoline_safe = true;
1313
1314 list_add_tail(&insn->call_node, &file->return_thunk_list);
1314 if (add)
1315 list_add_tail(&insn->call_node, &file->return_thunk_list);
1315}
1316
1317static bool same_function(struct instruction *insn1, struct instruction *insn2)
1318{
1319 return insn1->func->pfunc == insn2->func->pfunc;
1320}
1321
1322static bool is_first_func_insn(struct objtool_file *file, struct instruction *insn)

--- 39 unchanged lines hidden (view full) ---

1362 dest_off = arch_jump_destination(insn);
1363 } else if (reloc->sym->type == STT_SECTION) {
1364 dest_sec = reloc->sym->sec;
1365 dest_off = arch_dest_reloc_offset(reloc->addend);
1366 } else if (reloc->sym->retpoline_thunk) {
1367 add_retpoline_call(file, insn);
1368 continue;
1369 } else if (reloc->sym->return_thunk) {
1316}
1317
1318static bool same_function(struct instruction *insn1, struct instruction *insn2)
1319{
1320 return insn1->func->pfunc == insn2->func->pfunc;
1321}
1322
1323static bool is_first_func_insn(struct objtool_file *file, struct instruction *insn)

--- 39 unchanged lines hidden (view full) ---

1363 dest_off = arch_jump_destination(insn);
1364 } else if (reloc->sym->type == STT_SECTION) {
1365 dest_sec = reloc->sym->sec;
1366 dest_off = arch_dest_reloc_offset(reloc->addend);
1367 } else if (reloc->sym->retpoline_thunk) {
1368 add_retpoline_call(file, insn);
1369 continue;
1370 } else if (reloc->sym->return_thunk) {
1370 add_return_call(file, insn);
1371 add_return_call(file, insn, true);
1371 continue;
1372 } else if (insn->func) {
1373 /*
1374 * External sibling call or internal sibling call with
1375 * STT_FUNC reloc.
1376 */
1377 add_call_dest(file, insn, reloc->sym, true);
1378 continue;
1379 } else if (reloc->sym->sec->idx) {
1380 dest_sec = reloc->sym->sec;
1381 dest_off = reloc->sym->sym.st_value +
1382 arch_dest_reloc_offset(reloc->addend);
1383 } else {
1384 /* non-func asm code jumping to another file */
1385 continue;
1386 }
1387
1388 jump_dest = find_insn(file, dest_sec, dest_off);
1389 if (!jump_dest) {
1372 continue;
1373 } else if (insn->func) {
1374 /*
1375 * External sibling call or internal sibling call with
1376 * STT_FUNC reloc.
1377 */
1378 add_call_dest(file, insn, reloc->sym, true);
1379 continue;
1380 } else if (reloc->sym->sec->idx) {
1381 dest_sec = reloc->sym->sec;
1382 dest_off = reloc->sym->sym.st_value +
1383 arch_dest_reloc_offset(reloc->addend);
1384 } else {
1385 /* non-func asm code jumping to another file */
1386 continue;
1387 }
1388
1389 jump_dest = find_insn(file, dest_sec, dest_off);
1390 if (!jump_dest) {
1391 struct symbol *sym = find_symbol_by_offset(dest_sec, dest_off);
1392
1393 /*
1394 * This is a special case for zen_untrain_ret().
1395 * It jumps to __x86_return_thunk(), but objtool
1396 * can't find the thunk's starting RET
1397 * instruction, because the RET is also in the
1398 * middle of another instruction. Objtool only
1399 * knows about the outer instruction.
1400 */
1401 if (sym && sym->return_thunk) {
1402 add_return_call(file, insn, false);
1403 continue;
1404 }
1405
1390 WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
1391 insn->sec, insn->offset, dest_sec->name,
1392 dest_off);
1393 return -1;
1394 }
1395
1396 /*
1397 * Cross-function jump.

--- 2691 unchanged lines hidden ---
1406 WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
1407 insn->sec, insn->offset, dest_sec->name,
1408 dest_off);
1409 return -1;
1410 }
1411
1412 /*
1413 * Cross-function jump.

--- 2691 unchanged lines hidden ---