| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Josh Poimboeuf <[email protected]>
- Date: Tue, 11 Jul 2017 10:33:43 -0500
- Subject: [PATCH] objtool, x86: Add facility for asm code to provide unwind
- hints
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- CVE-2017-5754
- Some asm (and inline asm) code does special things to the stack which
- objtool can't understand. (Nor can GCC or GNU assembler, for that
- matter.) In such cases we need a facility for the code to provide
- annotations, so the unwinder can unwind through it.
- This provides such a facility, in the form of unwind hints. They're
- similar to the GNU assembler .cfi* directives, but they give more
- information, and are needed in far fewer places, because objtool can
- fill in the blanks by following branches and adjusting the stack pointer
- for pushes and pops.
- Signed-off-by: Josh Poimboeuf <[email protected]>
- Cc: Andy Lutomirski <[email protected]>
- Cc: Borislav Petkov <[email protected]>
- Cc: Brian Gerst <[email protected]>
- Cc: Denys Vlasenko <[email protected]>
- Cc: H. Peter Anvin <[email protected]>
- Cc: Jiri Slaby <[email protected]>
- Cc: Linus Torvalds <[email protected]>
- Cc: Mike Galbraith <[email protected]>
- Cc: Peter Zijlstra <[email protected]>
- Cc: Thomas Gleixner <[email protected]>
- Cc: [email protected]
- Link: http://lkml.kernel.org/r/0f5f3c9104fca559ff4088bece1d14ae3bca52d5.1499786555.git.jpoimboe@redhat.com
- Signed-off-by: Ingo Molnar <[email protected]>
- (cherry picked from commit 39358a033b2e4432052265c1fa0f36f572d8cfb5)
- Signed-off-by: Andy Whitcroft <[email protected]>
- Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
- (cherry picked from commit a1fed2e10e84d48643a09861c2d127968621813e)
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- tools/objtool/Makefile | 3 +
- arch/x86/include/asm/orc_types.h | 107 ++++++++++++++++++++
- arch/x86/include/asm/unwind_hints.h | 103 +++++++++++++++++++
- tools/objtool/check.h | 4 +-
- tools/objtool/orc_types.h | 22 +++++
- tools/objtool/check.c | 191 +++++++++++++++++++++++++++++++++---
- 6 files changed, 417 insertions(+), 13 deletions(-)
- create mode 100644 arch/x86/include/asm/orc_types.h
- create mode 100644 arch/x86/include/asm/unwind_hints.h
- diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
- index 0e2765e243c0..3a6425fefc43 100644
- --- a/tools/objtool/Makefile
- +++ b/tools/objtool/Makefile
- @@ -52,6 +52,9 @@ $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
- diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
- diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
- || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
- + @(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
- + diff ../../arch/x86/include/asm/orc_types.h orc_types.h >/dev/null) \
- + || echo "warning: objtool: orc_types.h differs from kernel" >&2 )) || true
- $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
-
-
- diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
- new file mode 100644
- index 000000000000..7dc777a6cb40
- --- /dev/null
- +++ b/arch/x86/include/asm/orc_types.h
- @@ -0,0 +1,107 @@
- +/*
- + * Copyright (C) 2017 Josh Poimboeuf <[email protected]>
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License
- + * as published by the Free Software Foundation; either version 2
- + * of the License, or (at your option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, see <http://www.gnu.org/licenses/>.
- + */
- +
- +#ifndef _ORC_TYPES_H
- +#define _ORC_TYPES_H
- +
- +#include <linux/types.h>
- +#include <linux/compiler.h>
- +
- +/*
- + * The ORC_REG_* registers are base registers which are used to find other
- + * registers on the stack.
- + *
- + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
- + * address of the previous frame: the caller's SP before it called the current
- + * function.
- + *
- + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
- + * the current frame.
- + *
- + * The most commonly used base registers are SP and BP -- which the previous SP
- + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
- + * usually based on.
- + *
- + * The rest of the base registers are needed for special cases like entry code
- + * and GCC realigned stacks.
- + */
- +#define ORC_REG_UNDEFINED 0
- +#define ORC_REG_PREV_SP 1
- +#define ORC_REG_DX 2
- +#define ORC_REG_DI 3
- +#define ORC_REG_BP 4
- +#define ORC_REG_SP 5
- +#define ORC_REG_R10 6
- +#define ORC_REG_R13 7
- +#define ORC_REG_BP_INDIRECT 8
- +#define ORC_REG_SP_INDIRECT 9
- +#define ORC_REG_MAX 15
- +
- +/*
- + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
- + * caller's SP right before it made the call). Used for all callable
- + * functions, i.e. all C code and all callable asm functions.
- + *
- + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
- + * to a fully populated pt_regs from a syscall, interrupt, or exception.
- + *
- + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
- + * points to the iret return frame.
- + *
- + * The UNWIND_HINT macros are used only for the unwind_hint struct. They
- + * aren't used in struct orc_entry due to size and complexity constraints.
- + * Objtool converts them to real types when it converts the hints to orc
- + * entries.
- + */
- +#define ORC_TYPE_CALL 0
- +#define ORC_TYPE_REGS 1
- +#define ORC_TYPE_REGS_IRET 2
- +#define UNWIND_HINT_TYPE_SAVE 3
- +#define UNWIND_HINT_TYPE_RESTORE 4
- +
- +#ifndef __ASSEMBLY__
- +/*
- + * This struct is more or less a vastly simplified version of the DWARF Call
- + * Frame Information standard. It contains only the necessary parts of DWARF
- + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
- + * unwinder how to find the previous SP and BP (and sometimes entry regs) on
- + * the stack for a given code address. Each instance of the struct corresponds
- + * to one or more code locations.
- + */
- +struct orc_entry {
- + s16 sp_offset;
- + s16 bp_offset;
- + unsigned sp_reg:4;
- + unsigned bp_reg:4;
- + unsigned type:2;
- +};
- +
- +/*
- + * This struct is used by asm and inline asm code to manually annotate the
- + * location of registers on the stack for the ORC unwinder.
- + *
- + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
- + */
- +struct unwind_hint {
- + u32 ip;
- + s16 sp_offset;
- + u8 sp_reg;
- + u8 type;
- +};
- +#endif /* __ASSEMBLY__ */
- +
- +#endif /* _ORC_TYPES_H */
- diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h
- new file mode 100644
- index 000000000000..5e02b11c9b86
- --- /dev/null
- +++ b/arch/x86/include/asm/unwind_hints.h
- @@ -0,0 +1,103 @@
- +#ifndef _ASM_X86_UNWIND_HINTS_H
- +#define _ASM_X86_UNWIND_HINTS_H
- +
- +#include "orc_types.h"
- +
- +#ifdef __ASSEMBLY__
- +
- +/*
- + * In asm, there are two kinds of code: normal C-type callable functions and
- + * the rest. The normal callable functions can be called by other code, and
- + * don't do anything unusual with the stack. Such normal callable functions
- + * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this
- + * category. In this case, no special debugging annotations are needed because
- + * objtool can automatically generate the ORC data for the ORC unwinder to read
- + * at runtime.
- + *
- + * Anything which doesn't fall into the above category, such as syscall and
- + * interrupt handlers, tends to not be called directly by other functions, and
- + * often does unusual non-C-function-type things with the stack pointer. Such
- + * code needs to be annotated such that objtool can understand it. The
- + * following CFI hint macros are for this type of code.
- + *
- + * These macros provide hints to objtool about the state of the stack at each
- + * instruction. Objtool starts from the hints and follows the code flow,
- + * making automatic CFI adjustments when it sees pushes and pops, filling out
- + * the debuginfo as necessary. It will also warn if it sees any
- + * inconsistencies.
- + */
- +.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL
- +#ifdef CONFIG_STACK_VALIDATION
- +.Lunwind_hint_ip_\@:
- + .pushsection .discard.unwind_hints
- + /* struct unwind_hint */
- + .long .Lunwind_hint_ip_\@ - .
- + .short \sp_offset
- + .byte \sp_reg
- + .byte \type
- + .popsection
- +#endif
- +.endm
- +
- +.macro UNWIND_HINT_EMPTY
- + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED
- +.endm
- +
- +.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0
- + .if \base == %rsp && \indirect
- + .set sp_reg, ORC_REG_SP_INDIRECT
- + .elseif \base == %rsp
- + .set sp_reg, ORC_REG_SP
- + .elseif \base == %rbp
- + .set sp_reg, ORC_REG_BP
- + .elseif \base == %rdi
- + .set sp_reg, ORC_REG_DI
- + .elseif \base == %rdx
- + .set sp_reg, ORC_REG_DX
- + .elseif \base == %r10
- + .set sp_reg, ORC_REG_R10
- + .else
- + .error "UNWIND_HINT_REGS: bad base register"
- + .endif
- +
- + .set sp_offset, \offset
- +
- + .if \iret
- + .set type, ORC_TYPE_REGS_IRET
- + .elseif \extra == 0
- + .set type, ORC_TYPE_REGS_IRET
- + .set sp_offset, \offset + (16*8)
- + .else
- + .set type, ORC_TYPE_REGS
- + .endif
- +
- + UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
- +.endm
- +
- +.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
- + UNWIND_HINT_REGS base=\base offset=\offset iret=1
- +.endm
- +
- +.macro UNWIND_HINT_FUNC sp_offset=8
- + UNWIND_HINT sp_offset=\sp_offset
- +.endm
- +
- +#else /* !__ASSEMBLY__ */
- +
- +#define UNWIND_HINT(sp_reg, sp_offset, type) \
- + "987: \n\t" \
- + ".pushsection .discard.unwind_hints\n\t" \
- + /* struct unwind_hint */ \
- + ".long 987b - .\n\t" \
- + ".short " __stringify(sp_offset) "\n\t" \
- + ".byte " __stringify(sp_reg) "\n\t" \
- + ".byte " __stringify(type) "\n\t" \
- + ".popsection\n\t"
- +
- +#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE)
- +
- +#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE)
- +
- +#endif /* __ASSEMBLY__ */
- +
- +#endif /* _ASM_X86_UNWIND_HINTS_H */
- diff --git a/tools/objtool/check.h b/tools/objtool/check.h
- index 046874bbe226..ac3d4b13f17b 100644
- --- a/tools/objtool/check.h
- +++ b/tools/objtool/check.h
- @@ -43,7 +43,7 @@ struct instruction {
- unsigned int len;
- unsigned char type;
- unsigned long immediate;
- - bool alt_group, visited, dead_end, ignore;
- + bool alt_group, visited, dead_end, ignore, hint, save, restore;
- struct symbol *call_dest;
- struct instruction *jump_dest;
- struct list_head alts;
- @@ -58,7 +58,7 @@ struct objtool_file {
- struct list_head insn_list;
- DECLARE_HASHTABLE(insn_hash, 16);
- struct section *rodata, *whitelist;
- - bool ignore_unreachables, c_file;
- + bool ignore_unreachables, c_file, hints;
- };
-
- int check(const char *objname, bool nofp, bool orc);
- diff --git a/tools/objtool/orc_types.h b/tools/objtool/orc_types.h
- index fc5cf6cffd9a..9c9dc579bd7d 100644
- --- a/tools/objtool/orc_types.h
- +++ b/tools/objtool/orc_types.h
- @@ -61,11 +61,19 @@
- *
- * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
- * points to the iret return frame.
- + *
- + * The UNWIND_HINT macros are used only for the unwind_hint struct. They
- + * aren't used in struct orc_entry due to size and complexity constraints.
- + * Objtool converts them to real types when it converts the hints to orc
- + * entries.
- */
- #define ORC_TYPE_CALL 0
- #define ORC_TYPE_REGS 1
- #define ORC_TYPE_REGS_IRET 2
- +#define UNWIND_HINT_TYPE_SAVE 3
- +#define UNWIND_HINT_TYPE_RESTORE 4
-
- +#ifndef __ASSEMBLY__
- /*
- * This struct is more or less a vastly simplified version of the DWARF Call
- * Frame Information standard. It contains only the necessary parts of DWARF
- @@ -82,4 +90,18 @@ struct orc_entry {
- unsigned type:2;
- } __packed;
-
- +/*
- + * This struct is used by asm and inline asm code to manually annotate the
- + * location of registers on the stack for the ORC unwinder.
- + *
- + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
- + */
- +struct unwind_hint {
- + u32 ip;
- + s16 sp_offset;
- + u8 sp_reg;
- + u8 type;
- +};
- +#endif /* __ASSEMBLY__ */
- +
- #endif /* _ORC_TYPES_H */
- diff --git a/tools/objtool/check.c b/tools/objtool/check.c
- index cb57c526ba17..368275de5f23 100644
- --- a/tools/objtool/check.c
- +++ b/tools/objtool/check.c
- @@ -100,7 +100,6 @@ static bool gcov_enabled(struct objtool_file *file)
- static bool ignore_func(struct objtool_file *file, struct symbol *func)
- {
- struct rela *rela;
- - struct instruction *insn;
-
- /* check for STACK_FRAME_NON_STANDARD */
- if (file->whitelist && file->whitelist->rela)
- @@ -113,11 +112,6 @@ static bool ignore_func(struct objtool_file *file, struct symbol *func)
- return true;
- }
-
- - /* check if it has a context switching instruction */
- - func_for_each_insn(file, func, insn)
- - if (insn->type == INSN_CONTEXT_SWITCH)
- - return true;
- -
- return false;
- }
-
- @@ -879,6 +873,99 @@ static int add_switch_table_alts(struct objtool_file *file)
- return 0;
- }
-
- +static int read_unwind_hints(struct objtool_file *file)
- +{
- + struct section *sec, *relasec;
- + struct rela *rela;
- + struct unwind_hint *hint;
- + struct instruction *insn;
- + struct cfi_reg *cfa;
- + int i;
- +
- + sec = find_section_by_name(file->elf, ".discard.unwind_hints");
- + if (!sec)
- + return 0;
- +
- + relasec = sec->rela;
- + if (!relasec) {
- + WARN("missing .rela.discard.unwind_hints section");
- + return -1;
- + }
- +
- + if (sec->len % sizeof(struct unwind_hint)) {
- + WARN("struct unwind_hint size mismatch");
- + return -1;
- + }
- +
- + file->hints = true;
- +
- + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
- + hint = (struct unwind_hint *)sec->data->d_buf + i;
- +
- + rela = find_rela_by_dest(sec, i * sizeof(*hint));
- + if (!rela) {
- + WARN("can't find rela for unwind_hints[%d]", i);
- + return -1;
- + }
- +
- + insn = find_insn(file, rela->sym->sec, rela->addend);
- + if (!insn) {
- + WARN("can't find insn for unwind_hints[%d]", i);
- + return -1;
- + }
- +
- + cfa = &insn->state.cfa;
- +
- + if (hint->type == UNWIND_HINT_TYPE_SAVE) {
- + insn->save = true;
- + continue;
- +
- + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
- + insn->restore = true;
- + insn->hint = true;
- + continue;
- + }
- +
- + insn->hint = true;
- +
- + switch (hint->sp_reg) {
- + case ORC_REG_UNDEFINED:
- + cfa->base = CFI_UNDEFINED;
- + break;
- + case ORC_REG_SP:
- + cfa->base = CFI_SP;
- + break;
- + case ORC_REG_BP:
- + cfa->base = CFI_BP;
- + break;
- + case ORC_REG_SP_INDIRECT:
- + cfa->base = CFI_SP_INDIRECT;
- + break;
- + case ORC_REG_R10:
- + cfa->base = CFI_R10;
- + break;
- + case ORC_REG_R13:
- + cfa->base = CFI_R13;
- + break;
- + case ORC_REG_DI:
- + cfa->base = CFI_DI;
- + break;
- + case ORC_REG_DX:
- + cfa->base = CFI_DX;
- + break;
- + default:
- + WARN_FUNC("unsupported unwind_hint sp base reg %d",
- + insn->sec, insn->offset, hint->sp_reg);
- + return -1;
- + }
- +
- + cfa->offset = hint->sp_offset;
- + insn->state.type = hint->type;
- + }
- +
- + return 0;
- +}
- +
- static int decode_sections(struct objtool_file *file)
- {
- int ret;
- @@ -909,6 +996,10 @@ static int decode_sections(struct objtool_file *file)
- if (ret)
- return ret;
-
- + ret = read_unwind_hints(file);
- + if (ret)
- + return ret;
- +
- return 0;
- }
-
- @@ -1382,7 +1473,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
- struct insn_state state)
- {
- struct alternative *alt;
- - struct instruction *insn;
- + struct instruction *insn, *next_insn;
- struct section *sec;
- struct symbol *func = NULL;
- int ret;
- @@ -1397,6 +1488,8 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
- }
-
- while (1) {
- + next_insn = next_insn_same_sec(file, insn);
- +
- if (file->c_file && insn->func) {
- if (func && func != insn->func) {
- WARN("%s() falls through to next function %s()",
- @@ -1414,13 +1507,54 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
- }
-
- if (insn->visited) {
- - if (!!insn_state_match(insn, &state))
- + if (!insn->hint && !insn_state_match(insn, &state))
- return 1;
-
- return 0;
- }
-
- - insn->state = state;
- + if (insn->hint) {
- + if (insn->restore) {
- + struct instruction *save_insn, *i;
- +
- + i = insn;
- + save_insn = NULL;
- + func_for_each_insn_continue_reverse(file, func, i) {
- + if (i->save) {
- + save_insn = i;
- + break;
- + }
- + }
- +
- + if (!save_insn) {
- + WARN_FUNC("no corresponding CFI save for CFI restore",
- + sec, insn->offset);
- + return 1;
- + }
- +
- + if (!save_insn->visited) {
- + /*
- + * Oops, no state to copy yet.
- + * Hopefully we can reach this
- + * instruction from another branch
- + * after the save insn has been
- + * visited.
- + */
- + if (insn == first)
- + return 0;
- +
- + WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
- + sec, insn->offset);
- + return 1;
- + }
- +
- + insn->state = save_insn->state;
- + }
- +
- + state = insn->state;
- +
- + } else
- + insn->state = state;
-
- insn->visited = true;
-
- @@ -1497,6 +1631,14 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
-
- return 0;
-
- + case INSN_CONTEXT_SWITCH:
- + if (func && (!next_insn || !next_insn->hint)) {
- + WARN_FUNC("unsupported instruction in callable function",
- + sec, insn->offset);
- + return 1;
- + }
- + return 0;
- +
- case INSN_STACK:
- if (update_insn_state(insn, &state))
- return -1;
- @@ -1510,7 +1652,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
- if (insn->dead_end)
- return 0;
-
- - insn = next_insn_same_sec(file, insn);
- + insn = next_insn;
- if (!insn) {
- WARN("%s: unexpected end of section", sec->name);
- return 1;
- @@ -1520,6 +1662,27 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
- return 0;
- }
-
- +static int validate_unwind_hints(struct objtool_file *file)
- +{
- + struct instruction *insn;
- + int ret, warnings = 0;
- + struct insn_state state;
- +
- + if (!file->hints)
- + return 0;
- +
- + clear_insn_state(&state);
- +
- + for_each_insn(file, insn) {
- + if (insn->hint && !insn->visited) {
- + ret = validate_branch(file, insn, state);
- + warnings += ret;
- + }
- + }
- +
- + return warnings;
- +}
- +
- static bool is_kasan_insn(struct instruction *insn)
- {
- return (insn->type == INSN_CALL &&
- @@ -1665,8 +1828,9 @@ int check(const char *_objname, bool _nofp, bool orc)
- hash_init(file.insn_hash);
- file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
- file.rodata = find_section_by_name(file.elf, ".rodata");
- - file.ignore_unreachables = false;
- file.c_file = find_section_by_name(file.elf, ".comment");
- + file.ignore_unreachables = false;
- + file.hints = false;
-
- arch_initial_func_cfi_state(&initial_func_cfi);
-
- @@ -1683,6 +1847,11 @@ int check(const char *_objname, bool _nofp, bool orc)
- goto out;
- warnings += ret;
-
- + ret = validate_unwind_hints(&file);
- + if (ret < 0)
- + goto out;
- + warnings += ret;
- +
- if (!warnings) {
- ret = validate_reachable_instructions(&file);
- if (ret < 0)
- --
- 2.14.2
|