@@ -1744,36 +1744,49 @@ static int handle_group_alt(struct objtool_file *file,
1744
1744
struct instruction * orig_insn ,
1745
1745
struct instruction * * new_insn )
1746
1746
{
1747
- struct instruction * last_orig_insn , * last_new_insn = NULL , * insn , * nop = NULL ;
1747
+ struct instruction * last_new_insn = NULL , * insn , * nop = NULL ;
1748
1748
struct alt_group * orig_alt_group , * new_alt_group ;
1749
1749
unsigned long dest_off ;
1750
1750
1751
-
1752
- orig_alt_group = malloc (sizeof (* orig_alt_group ));
1751
+ orig_alt_group = orig_insn -> alt_group ;
1753
1752
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 ;
1763
1754
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
+ }
1769
1766
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 ;
1776
1771
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
+ }
1777
1790
1778
1791
new_alt_group = malloc (sizeof (* new_alt_group ));
1779
1792
if (!new_alt_group ) {
@@ -1848,7 +1861,7 @@ static int handle_group_alt(struct objtool_file *file,
1848
1861
1849
1862
dest_off = arch_jump_destination (insn );
1850
1863
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 );
1852
1865
if (!insn -> jump_dest ) {
1853
1866
WARN_FUNC ("can't find alternative jump destination" ,
1854
1867
insn -> sec , insn -> offset );
@@ -3226,8 +3239,12 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
3226
3239
alt_cfi [group_off ] = insn -> cfi ;
3227
3240
} else {
3228
3241
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 );
3231
3248
return -1 ;
3232
3249
}
3233
3250
}
0 commit comments