@@ -297,6 +297,7 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
297
297
Options.LinkOpts .Update = Args.hasArg (OPT_update);
298
298
Options.LinkOpts .Verbose = Args.hasArg (OPT_verbose);
299
299
Options.LinkOpts .Statistics = Args.hasArg (OPT_statistics);
300
+ Options.LinkOpts .Fat64 = Args.hasArg (OPT_fat64);
300
301
Options.LinkOpts .KeepFunctionForStatic =
301
302
Args.hasArg (OPT_keep_func_for_static);
302
303
@@ -775,40 +776,47 @@ int dsymutil_main(int argc, char **argv) {
775
776
return EXIT_FAILURE;
776
777
777
778
if (NeedsTempFiles) {
778
- // Universal Mach-O files can't have an archicture slice that starts
779
- // beyond the 4GB boundary. "lipo" can creeate a 64 bit universal header,
780
- // but not all tools can parse these files so we want to return an error
781
- // if the file can't be encoded as a file with a 32 bit universal header.
782
- // To detect this, we check the size of each architecture's skinny Mach-O
783
- // file and add up the offsets. If they exceed 4GB, then we return an
784
- // error.
785
-
786
- // First we compute the right offset where the first architecture will fit
787
- // followin the 32 bit universal header. The 32 bit universal header
788
- // starts with a uint32_t magic and a uint32_t number of architecture
789
- // infos. Then it is followed by 5 uint32_t values for each architecture.
790
- // So we set the start offset to the right value so we can calculate the
791
- // exact offset that the first architecture slice can start at.
792
- constexpr uint64_t MagicAndCountSize = 2 * 4 ;
793
- constexpr uint64_t UniversalArchInfoSize = 5 * 4 ;
794
- uint64_t FileOffset = MagicAndCountSize +
795
- UniversalArchInfoSize * TempFiles.size ();
796
- for (const auto &File: TempFiles) {
797
- ErrorOr<vfs::Status> stat = Options.LinkOpts .VFS ->status (File.path ());
798
- if (!stat)
799
- break ;
800
- if (FileOffset > UINT32_MAX) {
801
- WithColor::error () << formatv (
802
- " the universal binary has a slice with a starting offset ({0:x}) "
803
- " that exceeds 4GB and will produce an invalid Mach-O file." ,
804
- FileOffset);
805
- return EXIT_FAILURE;
779
+ const bool Fat64 = Options.LinkOpts .Fat64 ;
780
+ if (!Fat64) {
781
+ // Universal Mach-O files can't have an archicture slice that starts
782
+ // beyond the 4GB boundary. "lipo" can create a 64 bit universal
783
+ // header, but not all tools can parse these files so we want to return
784
+ // an error if the file can't be encoded as a file with a 32 bit
785
+ // universal header. To detect this, we check the size of each
786
+ // architecture's skinny Mach-O file and add up the offsets. If they
787
+ // exceed 4GB, then we return an error.
788
+
789
+ // First we compute the right offset where the first architecture will
790
+ // fit followin the 32 bit universal header. The 32 bit universal header
791
+ // starts with a uint32_t magic and a uint32_t number of architecture
792
+ // infos. Then it is followed by 5 uint32_t values for each
793
+ // architecture. So we set the start offset to the right value so we can
794
+ // calculate the exact offset that the first architecture slice can
795
+ // start at.
796
+ constexpr uint64_t MagicAndCountSize = 2 * 4 ;
797
+ constexpr uint64_t UniversalArchInfoSize = 5 * 4 ;
798
+ uint64_t FileOffset =
799
+ MagicAndCountSize + UniversalArchInfoSize * TempFiles.size ();
800
+ for (const auto &File : TempFiles) {
801
+ ErrorOr<vfs::Status> stat = Options.LinkOpts .VFS ->status (File.path ());
802
+ if (!stat)
803
+ break ;
804
+ if (FileOffset > UINT32_MAX) {
805
+ WithColor::error ()
806
+ << formatv (" the universal binary has a slice with a starting "
807
+ " offset ({0:x}) that exceeds 4GB and will produce "
808
+ " an invalid Mach-O file. Use the -fat64 flag to "
809
+ " generate a universal binary with a 64-bit header "
810
+ " but note that not all tools support this format." ,
811
+ FileOffset);
812
+ return EXIT_FAILURE;
813
+ }
814
+ FileOffset += stat->getSize ();
806
815
}
807
- FileOffset += stat->getSize ();
808
816
}
809
- if (!MachOUtils::generateUniversalBinary (TempFiles,
810
- OutputLocationOrErr->DWARFFile ,
811
- Options. LinkOpts , SDKPath ))
817
+ if (!MachOUtils::generateUniversalBinary (
818
+ TempFiles, OutputLocationOrErr->DWARFFile , Options. LinkOpts ,
819
+ SDKPath, Fat64 ))
812
820
return EXIT_FAILURE;
813
821
}
814
822
}
0 commit comments