@@ -75,7 +75,7 @@ struct macho_header_64
75
75
76
76
struct macho_header_fat
77
77
{
78
- uint32_t magic ; /* Magic number (MACH_O_MH_MAGIC_FAT ) */
78
+ uint32_t magic ; /* Magic number (MACH_O_MH_(MAGIC|CIGAM)_FAT(_64)? ) */
79
79
uint32_t nfat_arch ; /* Number of components */
80
80
};
81
81
@@ -85,6 +85,8 @@ struct macho_header_fat
85
85
#define MACH_O_MH_MAGIC_64 0xfeedfacf
86
86
#define MACH_O_MH_MAGIC_FAT 0xcafebabe
87
87
#define MACH_O_MH_CIGAM_FAT 0xbebafeca
88
+ #define MACH_O_MH_MAGIC_FAT_64 0xcafebabf
89
+ #define MACH_O_MH_CIGAM_FAT_64 0xbfbafeca
88
90
89
91
/* Value for the header filetype field. */
90
92
@@ -105,6 +107,20 @@ struct macho_fat_arch
105
107
uint32_t align ; /* Alignment of this entry */
106
108
};
107
109
110
+ /* A component of a 64-bit fat file. This is used if the magic field
111
+ is MAGIC_FAT_64. This is only used when some file size or file
112
+ offset is too large to represent in the 32-bit format. */
113
+
114
+ struct macho_fat_arch_64
115
+ {
116
+ uint32_t cputype ; /* CPU type */
117
+ uint32_t cpusubtype ; /* CPU subtype */
118
+ uint64_t offset ; /* File offset of this entry */
119
+ uint64_t size ; /* Size of this entry */
120
+ uint32_t align ; /* Alignment of this entry */
121
+ uint32_t reserved ; /* Reserved */
122
+ };
123
+
108
124
/* Values for the fat_arch cputype field (and the header cputype
109
125
field). */
110
126
@@ -740,14 +756,14 @@ static int
740
756
macho_add_fat (struct backtrace_state * state , const char * filename ,
741
757
int descriptor , int swapped , off_t offset ,
742
758
const unsigned char * match_uuid , uintptr_t base_address ,
743
- int skip_symtab , uint32_t nfat_arch ,
759
+ int skip_symtab , uint32_t nfat_arch , int is_64 ,
744
760
backtrace_error_callback error_callback , void * data ,
745
761
fileline * fileline_fn , int * found_sym )
746
762
{
747
763
int arch_view_valid ;
748
764
unsigned int cputype ;
765
+ size_t arch_size ;
749
766
struct backtrace_view arch_view ;
750
- size_t archoffset ;
751
767
unsigned int i ;
752
768
753
769
arch_view_valid = 0 ;
@@ -765,41 +781,57 @@ macho_add_fat (struct backtrace_state *state, const char *filename,
765
781
goto fail ;
766
782
#endif
767
783
784
+ if (is_64 )
785
+ arch_size = sizeof (struct macho_fat_arch_64 );
786
+ else
787
+ arch_size = sizeof (struct macho_fat_arch );
788
+
768
789
if (!backtrace_get_view (state , descriptor , offset ,
769
- nfat_arch * sizeof ( struct macho_fat_arch ) ,
790
+ nfat_arch * arch_size ,
770
791
error_callback , data , & arch_view ))
771
792
goto fail ;
772
793
773
- archoffset = 0 ;
774
794
for (i = 0 ; i < nfat_arch ; ++ i )
775
795
{
776
- struct macho_fat_arch fat_arch ;
796
+ struct macho_fat_arch_64 fat_arch ;
777
797
uint32_t fcputype ;
778
798
779
- memcpy (& fat_arch ,
780
- ((const char * ) arch_view .data
781
- + i * sizeof (struct macho_fat_arch )),
782
- sizeof fat_arch );
799
+ if (is_64 )
800
+ memcpy (& fat_arch ,
801
+ (const char * ) arch_view .data + i * arch_size ,
802
+ arch_size );
803
+ else
804
+ {
805
+ struct macho_fat_arch fat_arch_32 ;
806
+
807
+ memcpy (& fat_arch_32 ,
808
+ (const char * ) arch_view .data + i * arch_size ,
809
+ arch_size );
810
+ fat_arch .cputype = fat_arch_32 .cputype ;
811
+ fat_arch .cpusubtype = fat_arch_32 .cpusubtype ;
812
+ fat_arch .offset = (uint64_t ) fat_arch_32 .offset ;
813
+ fat_arch .size = (uint64_t ) fat_arch_32 .size ;
814
+ fat_arch .align = fat_arch_32 .align ;
815
+ fat_arch .reserved = 0 ;
816
+ }
783
817
784
818
fcputype = fat_arch .cputype ;
785
819
if (swapped )
786
820
fcputype = __builtin_bswap32 (fcputype );
787
821
788
822
if (fcputype == cputype )
789
823
{
790
- uint32_t foffset ;
824
+ uint64_t foffset ;
791
825
792
826
/* FIXME: What about cpusubtype? */
793
827
foffset = fat_arch .offset ;
794
828
if (swapped )
795
- foffset = __builtin_bswap32 (foffset );
829
+ foffset = __builtin_bswap64 (foffset );
796
830
backtrace_release_view (state , & arch_view , error_callback , data );
797
831
return macho_add (state , filename , descriptor , foffset , match_uuid ,
798
832
base_address , skip_symtab , error_callback , data ,
799
833
fileline_fn , found_sym );
800
834
}
801
-
802
- archoffset += sizeof (struct macho_fat_arch );
803
835
}
804
836
805
837
error_callback (data , "could not find executable in fat file" , 0 );
@@ -980,17 +1012,20 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
980
1012
hdroffset = offset + sizeof (struct macho_header_64 );
981
1013
break ;
982
1014
case MACH_O_MH_MAGIC_FAT :
1015
+ case MACH_O_MH_MAGIC_FAT_64 :
983
1016
{
984
1017
struct macho_header_fat fat_header ;
985
1018
986
1019
hdroffset = offset + sizeof (struct macho_header_fat );
987
1020
memcpy (& fat_header , & header , sizeof fat_header );
988
1021
return macho_add_fat (state , filename , descriptor , 0 , hdroffset ,
989
1022
match_uuid , base_address , skip_symtab ,
990
- fat_header .nfat_arch , error_callback , data ,
991
- fileline_fn , found_sym );
1023
+ fat_header .nfat_arch ,
1024
+ header .magic == MACH_O_MH_MAGIC_FAT_64 ,
1025
+ error_callback , data , fileline_fn , found_sym );
992
1026
}
993
1027
case MACH_O_MH_CIGAM_FAT :
1028
+ case MACH_O_MH_CIGAM_FAT_64 :
994
1029
{
995
1030
struct macho_header_fat fat_header ;
996
1031
uint32_t nfat_arch ;
@@ -1000,8 +1035,9 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
1000
1035
nfat_arch = __builtin_bswap32 (fat_header .nfat_arch );
1001
1036
return macho_add_fat (state , filename , descriptor , 1 , hdroffset ,
1002
1037
match_uuid , base_address , skip_symtab ,
1003
- nfat_arch , error_callback , data ,
1004
- fileline_fn , found_sym );
1038
+ nfat_arch ,
1039
+ header .magic == MACH_O_MH_CIGAM_FAT_64 ,
1040
+ error_callback , data , fileline_fn , found_sym );
1005
1041
}
1006
1042
default :
1007
1043
error_callback (data , "executable file is not in Mach-O format" , 0 );
0 commit comments