@@ -1064,6 +1064,9 @@ fn build_task(cfg: &PackageConfig, name: &str) -> Result<()> {
1064
1064
}
1065
1065
1066
1066
fn task_can_overflow ( cfg : & PackageConfig , task_name : & str ) -> Result < bool > {
1067
+ use yaxpeax_arch:: { AddressDisplay , Decoder , Reader , U8Reader } ;
1068
+ use yaxpeax_arm:: armv7:: { DecodeError , InstDecoder , Opcode , Operand } ;
1069
+
1067
1070
// Open the statically-linked ELF file
1068
1071
let f = cfg. dist_file ( format ! ( "{task_name}.tmp" ) ) ;
1069
1072
let data = std:: fs:: read ( f) . context ( "could not open ELF file" ) ?;
@@ -1084,45 +1087,6 @@ fn task_can_overflow(cfg: &PackageConfig, task_name: &str) -> Result<bool> {
1084
1087
let text = crate :: elf:: get_section_by_name ( & elf, ".text" )
1085
1088
. context ( "could not get .text" ) ?;
1086
1089
1087
- pub fn get_calls ( data : & [ u8 ] ) -> Vec < i32 > {
1088
- use yaxpeax_arch:: { AddressDisplay , Decoder , Reader , U8Reader } ;
1089
- use yaxpeax_arm:: armv7:: { DecodeError , InstDecoder , Opcode , Operand } ;
1090
-
1091
- let mut reader = U8Reader :: new ( data) ;
1092
- let mut address: u32 =
1093
- <U8Reader as Reader < u32 , u8 > >:: total_offset ( & mut reader) ;
1094
-
1095
- let decoder = InstDecoder :: default_thumb ( ) ;
1096
- let mut decode_res = decoder. decode ( & mut reader) ;
1097
- let mut targets = vec ! [ ] ;
1098
- loop {
1099
- match decode_res {
1100
- Ok ( ref inst) => {
1101
- match ( inst. opcode , inst. operands [ 0 ] ) {
1102
- ( Opcode :: BL , Operand :: BranchThumbOffset ( i) ) => {
1103
- targets. push ( address as i32 + i * 2 )
1104
- }
1105
- ( Opcode :: BL , v) => println ! ( "cannot decode {v:?}" ) ,
1106
- _ => ( ) ,
1107
- }
1108
-
1109
- decode_res = decoder. decode ( & mut reader) ;
1110
- address = <U8Reader as Reader < u32 , u8 > >:: total_offset (
1111
- & mut reader,
1112
- ) ;
1113
- }
1114
- Err ( DecodeError :: ExhaustedInput | DecodeError :: Incomplete ) => {
1115
- break ;
1116
- }
1117
- Err ( e) => {
1118
- println ! ( "{}: decode error: {}" , address. show( ) , e) ;
1119
- break ;
1120
- }
1121
- }
1122
- }
1123
- targets
1124
- }
1125
-
1126
1090
// Pack everything into a single data structure
1127
1091
#[ derive( Debug ) ]
1128
1092
struct FunctionData {
@@ -1156,10 +1120,46 @@ fn task_can_overflow(cfg: &PackageConfig, task_name: &str) -> Result<bool> {
1156
1120
let offset = ( val - text. sh_addr + text. sh_offset ) as usize ;
1157
1121
let text = & data[ offset..] [ ..sym. st_size as usize ] ;
1158
1122
1159
- let calls = get_calls ( text)
1160
- . into_iter ( )
1161
- . map ( |j| addr. checked_add_signed ( j) . unwrap ( ) )
1162
- . collect :: < Vec < _ > > ( ) ;
1123
+ // Disassemble, looking for BL operations
1124
+ let mut reader = U8Reader :: new ( text) ;
1125
+
1126
+ let decoder = InstDecoder :: default_thumb ( ) ;
1127
+ let mut calls = vec ! [ ] ;
1128
+ loop {
1129
+ let decode_res = decoder. decode ( & mut reader) ;
1130
+ let offset =
1131
+ <U8Reader as Reader < u32 , u8 > >:: total_offset ( & mut reader) ;
1132
+ let addr = addr + offset;
1133
+ match decode_res {
1134
+ Ok ( ref inst) => match ( inst. opcode , inst. operands [ 0 ] ) {
1135
+ ( Opcode :: BL , Operand :: BranchThumbOffset ( i) ) => {
1136
+ let target = addr. checked_add_signed ( i * 2 ) . unwrap ( ) ;
1137
+ calls. push ( target)
1138
+ }
1139
+ ( Opcode :: BL , v) => {
1140
+ println ! (
1141
+ "{}: cannot find call target with offset {v:?}" ,
1142
+ addr. show( )
1143
+ )
1144
+ }
1145
+ _ => ( ) ,
1146
+ } ,
1147
+
1148
+ // These are errors that we see either at the end of the input,
1149
+ // or when it starts trying to decode data words as instructions
1150
+ Err (
1151
+ DecodeError :: ExhaustedInput
1152
+ | DecodeError :: Incomplete
1153
+ | DecodeError :: Undefined ,
1154
+ ) => {
1155
+ break ;
1156
+ }
1157
+ Err ( e) => {
1158
+ println ! ( "{}: decode error: {e}" , addr. show( ) ) ;
1159
+ break ;
1160
+ }
1161
+ }
1162
+ }
1163
1163
1164
1164
fns. insert (
1165
1165
addr,
0 commit comments