@@ -1744,36 +1744,49 @@ static int handle_group_alt(struct objtool_file *file,
17441744 struct instruction * orig_insn ,
17451745 struct instruction * * new_insn )
17461746{
1747- struct instruction * last_orig_insn , * last_new_insn = NULL , * insn , * nop = NULL ;
1747+ struct instruction * last_new_insn = NULL , * insn , * nop = NULL ;
17481748 struct alt_group * orig_alt_group , * new_alt_group ;
17491749 unsigned long dest_off ;
17501750
1751-
1752- orig_alt_group = malloc (sizeof (* orig_alt_group ));
1751+ orig_alt_group = orig_insn -> alt_group ;
17531752 if (!orig_alt_group ) {
1754- WARN ("malloc failed" );
1755- return -1 ;
1756- }
1757- orig_alt_group -> cfi = calloc (special_alt -> orig_len ,
1758- sizeof (struct cfi_state * ));
1759- if (!orig_alt_group -> cfi ) {
1760- WARN ("calloc failed" );
1761- return -1 ;
1762- }
1753+ struct instruction * last_orig_insn = NULL ;
17631754
1764- last_orig_insn = NULL ;
1765- insn = orig_insn ;
1766- sec_for_each_insn_from (file , insn ) {
1767- if (insn -> offset >= special_alt -> orig_off + special_alt -> orig_len )
1768- break ;
1755+ orig_alt_group = malloc (sizeof (* orig_alt_group ));
1756+ if (!orig_alt_group ) {
1757+ WARN ("malloc failed" );
1758+ return -1 ;
1759+ }
1760+ orig_alt_group -> cfi = calloc (special_alt -> orig_len ,
1761+ sizeof (struct cfi_state * ));
1762+ if (!orig_alt_group -> cfi ) {
1763+ WARN ("calloc failed" );
1764+ return -1 ;
1765+ }
17691766
1770- insn -> alt_group = orig_alt_group ;
1771- last_orig_insn = insn ;
1772- }
1773- orig_alt_group -> orig_group = NULL ;
1774- orig_alt_group -> first_insn = orig_insn ;
1775- orig_alt_group -> last_insn = last_orig_insn ;
1767+ insn = orig_insn ;
1768+ sec_for_each_insn_from (file , insn ) {
1769+ if (insn -> offset >= special_alt -> orig_off + special_alt -> orig_len )
1770+ break ;
17761771
1772+ insn -> alt_group = orig_alt_group ;
1773+ last_orig_insn = insn ;
1774+ }
1775+ orig_alt_group -> orig_group = NULL ;
1776+ orig_alt_group -> first_insn = orig_insn ;
1777+ orig_alt_group -> last_insn = last_orig_insn ;
1778+ } else {
1779+ if (orig_alt_group -> last_insn -> offset + orig_alt_group -> last_insn -> len -
1780+ orig_alt_group -> first_insn -> offset != special_alt -> orig_len ) {
1781+ WARN_FUNC ("weirdly overlapping alternative! %ld != %d" ,
1782+ orig_insn -> sec , orig_insn -> offset ,
1783+ orig_alt_group -> last_insn -> offset +
1784+ orig_alt_group -> last_insn -> len -
1785+ orig_alt_group -> first_insn -> offset ,
1786+ special_alt -> orig_len );
1787+ return -1 ;
1788+ }
1789+ }
17771790
17781791 new_alt_group = malloc (sizeof (* new_alt_group ));
17791792 if (!new_alt_group ) {
@@ -1848,7 +1861,7 @@ static int handle_group_alt(struct objtool_file *file,
18481861
18491862 dest_off = arch_jump_destination (insn );
18501863 if (dest_off == special_alt -> new_off + special_alt -> new_len ) {
1851- insn -> jump_dest = next_insn_same_sec (file , last_orig_insn );
1864+ insn -> jump_dest = next_insn_same_sec (file , orig_alt_group -> last_insn );
18521865 if (!insn -> jump_dest ) {
18531866 WARN_FUNC ("can't find alternative jump destination" ,
18541867 insn -> sec , insn -> offset );
@@ -3226,8 +3239,12 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
32263239 alt_cfi [group_off ] = insn -> cfi ;
32273240 } else {
32283241 if (cficmp (alt_cfi [group_off ], insn -> cfi )) {
3229- WARN_FUNC ("stack layout conflict in alternatives" ,
3230- insn -> sec , insn -> offset );
3242+ struct alt_group * orig_group = insn -> alt_group -> orig_group ?: insn -> alt_group ;
3243+ struct instruction * orig = orig_group -> first_insn ;
3244+ char * where = offstr (insn -> sec , insn -> offset );
3245+ WARN_FUNC ("stack layout conflict in alternatives: %s" ,
3246+ orig -> sec , orig -> offset , where );
3247+ free (where );
32313248 return -1 ;
32323249 }
32333250 }
0 commit comments