@@ -98,7 +98,7 @@ cleanup_proc_handle(proc_handle_t *handle) {
9898
9999#if defined(__APPLE__ ) && TARGET_OS_OSX
100100static uintptr_t
101- return_section_address (
101+ return_section_address64 (
102102 const char * section ,
103103 mach_port_t proc_ref ,
104104 uintptr_t base ,
@@ -161,6 +161,134 @@ return_section_address(
161161 return 0 ;
162162}
163163
164+ static uintptr_t
165+ return_section_address32 (
166+ const char * section ,
167+ mach_port_t proc_ref ,
168+ uintptr_t base ,
169+ void * map
170+ ) {
171+ struct mach_header * hdr = (struct mach_header * )map ;
172+ int ncmds = hdr -> ncmds ;
173+
174+ int cmd_cnt = 0 ;
175+ struct segment_command * cmd = map + sizeof (struct mach_header );
176+
177+ mach_vm_size_t size = 0 ;
178+ mach_msg_type_number_t count = sizeof (vm_region_basic_info_data_t );
179+ mach_vm_address_t address = (mach_vm_address_t )base ;
180+ vm_region_basic_info_data_t r_info ;
181+ mach_port_t object_name ;
182+ uintptr_t vmaddr = 0 ;
183+
184+ for (int i = 0 ; cmd_cnt < 2 && i < ncmds ; i ++ ) {
185+ if (cmd -> cmd == LC_SEGMENT && strcmp (cmd -> segname , "__TEXT" ) == 0 ) {
186+ vmaddr = cmd -> vmaddr ;
187+ }
188+ if (cmd -> cmd == LC_SEGMENT && strcmp (cmd -> segname , "__DATA" ) == 0 ) {
189+ while (cmd -> filesize != size ) {
190+ address += size ;
191+ kern_return_t ret = mach_vm_region (
192+ proc_ref ,
193+ & address ,
194+ & size ,
195+ VM_REGION_BASIC_INFO ,
196+ (vm_region_info_t )& r_info , // cppcheck-suppress [uninitvar]
197+ & count ,
198+ & object_name
199+ );
200+ if (ret != KERN_SUCCESS ) {
201+ PyErr_SetString (
202+ PyExc_RuntimeError , "Cannot get any more VM maps.\n" );
203+ return 0 ;
204+ }
205+ }
206+
207+ int nsects = cmd -> nsects ;
208+ struct section * sec = (struct section * )(
209+ (void * )cmd + sizeof (struct segment_command )
210+ );
211+ for (int j = 0 ; j < nsects ; j ++ ) {
212+ if (strcmp (sec [j ].sectname , section ) == 0 ) {
213+ return base + sec [j ].addr - vmaddr ;
214+ }
215+ }
216+ cmd_cnt ++ ;
217+ }
218+
219+ cmd = (struct segment_command * )((void * )cmd + cmd -> cmdsize );
220+ }
221+
222+ // We should not be here, but if we are there, we should say about this
223+ PyErr_SetString (
224+ PyExc_RuntimeError , "Cannot find section address.\n" );
225+ return 0 ;
226+ }
227+
228+ static uintptr_t
229+ return_section_address32 (
230+ const char * section ,
231+ mach_port_t proc_ref ,
232+ uintptr_t base ,
233+ void * map
234+ ) {
235+ struct mach_header * hdr = (struct mach_header * )map ;
236+ int ncmds = hdr -> ncmds ;
237+
238+ int cmd_cnt = 0 ;
239+ struct segment_command * cmd = map + sizeof (struct mach_header );
240+
241+ mach_vm_size_t size = 0 ;
242+ mach_msg_type_number_t count = sizeof (vm_region_basic_info_data_t );
243+ mach_vm_address_t address = (mach_vm_address_t )base ;
244+ vm_region_basic_info_data_t r_info ;
245+ mach_port_t object_name ;
246+ uintptr_t vmaddr = 0 ;
247+
248+ for (int i = 0 ; cmd_cnt < 2 && i < ncmds ; i ++ ) {
249+ if (cmd -> cmd == LC_SEGMENT && strcmp (cmd -> segname , "__TEXT" ) == 0 ) {
250+ vmaddr = cmd -> vmaddr ;
251+ }
252+ if (cmd -> cmd == LC_SEGMENT && strcmp (cmd -> segname , "__DATA" ) == 0 ) {
253+ while (cmd -> filesize != size ) {
254+ address += size ;
255+ kern_return_t ret = mach_vm_region (
256+ proc_ref ,
257+ & address ,
258+ & size ,
259+ VM_REGION_BASIC_INFO ,
260+ (vm_region_info_t )& r_info , // cppcheck-suppress [uninitvar]
261+ & count ,
262+ & object_name
263+ );
264+ if (ret != KERN_SUCCESS ) {
265+ PyErr_SetString (
266+ PyExc_RuntimeError , "Cannot get any more VM maps.\n" );
267+ return 0 ;
268+ }
269+ }
270+
271+ int nsects = cmd -> nsects ;
272+ struct section * sec = (struct section * )(
273+ (void * )cmd + sizeof (struct segment_command )
274+ );
275+ for (int j = 0 ; j < nsects ; j ++ ) {
276+ if (strcmp (sec [j ].sectname , section ) == 0 ) {
277+ return base + sec [j ].addr - vmaddr ;
278+ }
279+ }
280+ cmd_cnt ++ ;
281+ }
282+
283+ cmd = (struct segment_command * )((void * )cmd + cmd -> cmdsize );
284+ }
285+
286+ // We should not be here, but if we are there, we should say about this
287+ PyErr_SetString (
288+ PyExc_RuntimeError , "Cannot find section address.\n" );
289+ return 0 ;
290+ }
291+
164292static uintptr_t
165293search_section_in_file (const char * secname , char * path , uintptr_t base , mach_vm_size_t size , mach_port_t proc_ref )
166294{
@@ -185,18 +313,20 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
185313 }
186314
187315 uintptr_t result = 0 ;
316+ uint32_t magic = * (uint32_t * )map ;
188317
189- struct mach_header_64 * hdr = (struct mach_header_64 * )map ;
190- switch (hdr -> magic ) {
318+ switch (magic ) {
191319 case MH_MAGIC :
192320 case MH_CIGAM :
193- case FAT_MAGIC :
194- case FAT_CIGAM :
195- PyErr_SetString (PyExc_RuntimeError , "32-bit Mach-O binaries are not supported" );
321+ result = return_section_address32 (secname , proc_ref , base , map );
196322 break ;
197323 case MH_MAGIC_64 :
198324 case MH_CIGAM_64 :
199- result = return_section_address (secname , proc_ref , base , map );
325+ result = return_section_address64 (secname , proc_ref , base , map );
326+ break ;
327+ case FAT_MAGIC :
328+ case FAT_CIGAM :
329+ result = return_section_address_fat (secname , proc_ref , base , map );
200330 break ;
201331 default :
202332 PyErr_SetString (PyExc_RuntimeError , "Unknown Mach-O magic" );
0 commit comments