@@ -133,53 +133,77 @@ class MachOParser {
133133 void fillBasicUnwindInfo (const section_64* unwind_section) {
134134 u32 * unwind_info = (u32 *)(_vmaddr_slide + unwind_section->addr );
135135
136- if (*unwind_info != 1 ) {
136+ if (! strstr (_cc-> name (), " libsystem_m.dylib " ) && ! strstr (_cc-> name (), " libjninativestacks.dylib " ) ) {
137137 return ;
138138 }
139139
140- unwind_info++; // version
141- unwind_info++; // global_opcodes_offset
142- unwind_info++; // global_opcodes_len
143- unwind_info++; // personalities_offset
144- unwind_info++; // personalities_len
145-
140+ u32 version = *(unwind_info++);
141+ u32 global_opcodes_offset = *(unwind_info++);
142+ u32 global_opcodes_len = *(unwind_info++);
143+ u32 personalities_offset = *(unwind_info++);
144+ u32 personalities_len = *(unwind_info++);
146145 u32 pages_offset = *(unwind_info++);
147146 u32 pages_len = *(unwind_info++);
148147
149148 u32 * pages = (u32 *)(_vmaddr_slide + unwind_section->addr + pages_offset);
150149 u32 table_size = pages_len;
151- u32 base_index = 0 ;
152150
153- if (*pages) {
154- table_size++;
155- base_index++;
156- }
151+ fprintf (stderr, " ======================================================================\n " );
152+ fprintf (stderr, " Unwind info for %s\n " , _cc->name ());
153+ fprintf (stderr, " Version: %u\n " , version);
157154
158- // initialize unwind table with unwinding of empty frames
159- FrameDesc* unwind_table = (FrameDesc*)calloc (table_size, sizeof (FrameDesc));
160- for (int i = 0 ; i < table_size; i++) {
161- memcpy (&unwind_table[i], &FrameDesc::empty_frame, sizeof (FrameDesc));
155+ u32 * global_opcodes = (u32 *)(global_opcodes_offset + _vmaddr_slide + unwind_section->addr );
156+ for (u32 i = 0 ; i < global_opcodes_len; i++) {
157+ u32 global_opcode = global_opcodes[i];
158+ u32 opcode_kind = (global_opcode & 0x0f000000 ) >> 24 ;
159+ fprintf (stderr, " Global opcode %u: %u\n " , i, opcode_kind);
162160 }
163161
164- // set all symbols that have unwind information to be unwinded using frame pointers
165- for (int i = 0 ; i < pages_len - 1 ; ++i) {
166- memcpy (&unwind_table[i + base_index], &FrameDesc::default_frame, sizeof (FrameDesc));
167- unwind_table[i + base_index].loc = *pages;
162+ for (u32 i = 0 ; i < pages_len; i++) {
163+ u32 * page_root = pages;
168164
169- if (strstr (_cc->name (), " libsystem_m.dylib" ) || strstr (_cc->name (), " libjninativestacks.dylib" )) {
170- fprintf (stderr, " %s ==> PAGE = %d, location = 0x%x\n " , _cc->name (), i, *pages);
171- }
165+ u32 first_address = *(pages++);
166+ u32 second_level_page_offset = *(pages++);
167+ u32 lsda_index_offset = *(pages++);
168+
169+ fprintf (stderr, " Page %u: 0x%x\n " , i, first_address);
170+
171+ u32 * second_level_page = (u32 *)(second_level_page_offset + _vmaddr_slide + unwind_section->addr );
172+ u32 second_page_kind = *second_level_page;
173+
174+ fprintf (stderr, " Second level page kind: %d\n " , second_page_kind);
175+
176+
177+ if (second_page_kind == 3 ) { // compressed page
178+ u16 * data = (u16 *)(second_level_page + 1 );
172179
173- pages++; // address
174- pages++; // second_level_page_offset
175- pages++; // lsda_index_offset
176- } // 0x18e62df80
177- if (strstr (_cc->name (), " libsystem_m.dylib" ) || strstr (_cc->name (), " libjninativestacks.dylib" )) {
178- fprintf (stderr, " %s ==> PAGE = %d, location = 0x%x\n " , _cc->name (), pages_len - 1 , *pages);
180+ u16 entries_offset = *data++;
181+ u16 entries_len = *data++;
182+
183+ u16 local_opcodes_offset = *data++;
184+ u16 local_opcodes_len = *data++;
185+ u32 * local_opcodes = (u32 *)(local_opcodes_offset + (const char *)second_level_page);
186+
187+ fprintf (stderr, " Local Opcode Length = %u\n " , local_opcodes_len);
188+
189+ for (u32 j = 0 ; j < local_opcodes_len; j++) {
190+ u32 local_opcode = local_opcodes[j];
191+ u32 local_opcode_kind = (local_opcode & 0x0f000000 ) >> 24 ;
192+ fprintf (stderr, " Local opcode %u: %u\n " , j, local_opcode_kind);
193+ }
194+
195+ u32 * local_entries = (u32 *)(entries_offset + (const char *)second_level_page);
196+ for (u32 j = 0 ; j < entries_len; j++) {
197+ u32 entry = local_entries[j];
198+ u8 opcode_index = (entry & 0xff000000 ) >> 24 ;
199+ u32 instruction = entry & 0x00ffffff ;
200+
201+ fprintf (stderr, " Instruction 0x%x, Opcode %u\n " , instruction + first_address, opcode_index);
202+ }
203+ }
179204 }
180- unwind_table[pages_len + base_index - 1 ].loc = *pages; // set information of last unwinding
181205
182- _cc-> setDwarfTable (unwind_table, table_size );
206+ fprintf (stderr, " ====================================================================== \n " );
183207 }
184208
185209 public:
0 commit comments