@@ -150,6 +150,15 @@ static inline struct reloc *insn_jump_table(struct instruction *insn)
150150 return NULL ;
151151}
152152
153+ static inline unsigned long insn_jump_table_size (struct instruction * insn )
154+ {
155+ if (insn -> type == INSN_JUMP_DYNAMIC ||
156+ insn -> type == INSN_CALL_DYNAMIC )
157+ return insn -> _jump_table_size ;
158+
159+ return 0 ;
160+ }
161+
153162static bool is_jump_table_jump (struct instruction * insn )
154163{
155164 struct alt_group * alt_group = insn -> alt_group ;
@@ -1937,6 +1946,7 @@ static int add_special_section_alts(struct objtool_file *file)
19371946static int add_jump_table (struct objtool_file * file , struct instruction * insn ,
19381947 struct reloc * next_table )
19391948{
1949+ unsigned long table_size = insn_jump_table_size (insn );
19401950 struct symbol * pfunc = insn_func (insn )-> pfunc ;
19411951 struct reloc * table = insn_jump_table (insn );
19421952 struct instruction * dest_insn ;
@@ -1951,6 +1961,8 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
19511961 for_each_reloc_from (table -> sec , reloc ) {
19521962
19531963 /* Check for the end of the table: */
1964+ if (table_size && reloc_offset (reloc ) - reloc_offset (table ) >= table_size )
1965+ break ;
19541966 if (reloc != table && reloc == next_table )
19551967 break ;
19561968
@@ -1995,12 +2007,12 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
19952007 * find_jump_table() - Given a dynamic jump, find the switch jump table
19962008 * associated with it.
19972009 */
1998- static struct reloc * find_jump_table (struct objtool_file * file ,
1999- struct symbol * func ,
2000- struct instruction * insn )
2010+ static void find_jump_table (struct objtool_file * file , struct symbol * func ,
2011+ struct instruction * insn )
20012012{
20022013 struct reloc * table_reloc ;
20032014 struct instruction * dest_insn , * orig_insn = insn ;
2015+ unsigned long table_size ;
20042016
20052017 /*
20062018 * Backward search using the @first_jump_src links, these help avoid
@@ -2021,17 +2033,17 @@ static struct reloc *find_jump_table(struct objtool_file *file,
20212033 insn -> jump_dest -> offset > orig_insn -> offset ))
20222034 break ;
20232035
2024- table_reloc = arch_find_switch_table (file , insn );
2036+ table_reloc = arch_find_switch_table (file , insn , & table_size );
20252037 if (!table_reloc )
20262038 continue ;
20272039 dest_insn = find_insn (file , table_reloc -> sym -> sec , reloc_addend (table_reloc ));
20282040 if (!dest_insn || !insn_func (dest_insn ) || insn_func (dest_insn )-> pfunc != func )
20292041 continue ;
20302042
2031- return table_reloc ;
2043+ orig_insn -> _jump_table = table_reloc ;
2044+ orig_insn -> _jump_table_size = table_size ;
2045+ break ;
20322046 }
2033-
2034- return NULL ;
20352047}
20362048
20372049/*
@@ -2042,7 +2054,6 @@ static void mark_func_jump_tables(struct objtool_file *file,
20422054 struct symbol * func )
20432055{
20442056 struct instruction * insn , * last = NULL ;
2045- struct reloc * reloc ;
20462057
20472058 func_for_each_insn (file , func , insn ) {
20482059 if (!last )
@@ -2065,9 +2076,7 @@ static void mark_func_jump_tables(struct objtool_file *file,
20652076 if (insn -> type != INSN_JUMP_DYNAMIC )
20662077 continue ;
20672078
2068- reloc = find_jump_table (file , func , insn );
2069- if (reloc )
2070- insn -> _jump_table = reloc ;
2079+ find_jump_table (file , func , insn );
20712080 }
20722081}
20732082
0 commit comments