public void ExplictStripOption_ThirdPartyLibrary_AndWarnsIfSo(bool?strip, bool shouldStrip)
        {
            MMPTests.RunMMPTest(tmpDir => {
                string originalLocation   = Path.Combine(Configuration.SourceRoot, "tests", "test-libraries", "libtest-fat.macos.dylib");
                string newLibraryLocation = Path.Combine(tmpDir, "libTest.dylib");
                File.Copy(originalLocation, newLibraryLocation);

                TI.UnifiedTestConfig test = CreateStripTestConfig(strip, tmpDir, $" --native-reference=\"{newLibraryLocation}\"");
                test.Release = true;

                var testResult  = TI.TestUnifiedExecutable(test);
                var bundleDylib = Path.Combine(test.BundlePath, "Contents", "MonoBundle", "libTest.dylib");
                Assert.That(bundleDylib, Does.Exist, "libTest.dylib presence in app bundle");

                var architectures = MachO.GetArchitectures(bundleDylib);
                if (shouldStrip)
                {
                    Assert.AreEqual(1, architectures.Count, "libTest.dylib should only contain 1 architecture");
                    Assert.AreEqual(Abi.x86_64, architectures [0], "libTest.dylib should be x86_64");
                    testResult.Messages.AssertWarning(2108, "libTest.dylib was stripped of architectures except x86_64 to comply with App Store restrictions. This could break existing codesigning signatures. Consider stripping the library with lipo or disabling with --optimize=-trim-architectures");
                }
                else
                {
                    Assert.AreEqual(2, architectures.Count, "libTest.dylib should contain 2+ architectures");
                    Assert.That(architectures, Is.EquivalentTo(new Abi [] { Abi.i386, Abi.x86_64 }), "libTest.dylib should be x86_64 + i386");
                    testResult.Messages.AssertWarningCount(1);                      // dylib ([...]/xamarin-macios/tests/mmptest/bin/Debug/tmp-test-dir/Xamarin.MMP.Tests.MMPTests.RunMMPTest47/bin/Release/UnifiedExample.app/Contents/MonoBundle/libTest.dylib) was built for newer macOS version (10.11) than being linked (10.9)
                }
            });
        }
Beispiel #2
0
        public void FromSwiftLibraryMacOS()
        {
            Stream           lib   = HelloSwiftAsLibrary(null);
            List <MachOFile> macho = MachO.Read(lib, null).ToList();

            Assert.IsNotNull(macho);
            Assert.AreEqual(1, macho.Count);
        }
        public static void MakeInfoPList(string pathToLibrary, string pathToPlistFile)
        {
            using (FileStream stm = new FileStream(pathToLibrary, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                // oh dog, this code is so fragile.
                PLDict dict = MakeDefaultDict(pathToLibrary);

                string os = null;
                MachOFile.MinOSVersion lc = null;
                using (var files = MachO.Read(pathToLibrary, ReadingMode.Deferred)) {
                    foreach (var file in files)
                    {
                        var osmin = file.MinOS;
                        if (osmin == null)
                        {
                            throw new NotSupportedException("dylib files without a minimum supported operating system load command are not supported.");
                        }
                        switch (osmin.Platform)
                        {
                        case MachO.Platform.IOS:
                        case MachO.Platform.IOSSimulator:
                            os = "iphoneos";
                            break;

                        case MachO.Platform.TvOS:
                        case MachO.Platform.TvOSSimulator:
                            os = "appletvos";
                            break;

                        case MachO.Platform.WatchOS:
                        case MachO.Platform.WatchOSSimulator:
                            os = "watchos";
                            break;

                        default:
                            break;
                        }
                        if (os != null)
                        {
                            lc = osmin;
                            break;
                        }
                    }
                }

                if (os != null && lc != null)
                {
                    AddInOSSpecifics(os, lc, dict);
                }

                if (File.Exists(pathToPlistFile))
                {
                    File.Delete(pathToPlistFile);
                }
                using (FileStream pliststm = new FileStream(pathToPlistFile, FileMode.Create)) {
                    dict.ToXml(pliststm);
                }
            }
        }
 public static IEnumerable <FileSymbolPair> Symbols(Stream stm, Func <NListEntry, bool> entryFilter = null,
                                                    Func <MachOFile, bool> fileFilter = null)
 {
     fileFilter  = fileFilter ?? AllFiles;
     entryFilter = entryFilter ?? AllPublic;
     return(from file in MachO.Read(stm) where fileFilter(file)
            from symTab in file.load_commands.OfType <SymTabLoadCommand> ()
            from entry in symTab.nlist where entryFilter(entry)
            select new FileSymbolPair(file, entry.str));
 }
Beispiel #5
0
        public void ContainsASymbolTable()
        {
            Stream           lib   = HelloSwiftAsLibrary(null);
            List <MachOFile> macho = MachO.Read(lib, null).ToList();

            Assert.IsNotNull(macho);
            Assert.AreEqual(1, macho.Count);
            MachOFile file           = macho [0];
            bool      hasSymbolTable = file.load_commands.Exists(lc => lc.cmd == (uint)MachO.LoadCommands.SymTab ||
                                                                 lc.cmd == (uint)MachO.LoadCommands.DySymTab);

            Assert.IsTrue(hasSymbolTable);
        }
Beispiel #6
0
        public static List <string> TargetsFromDylib(Stream stm)
        {
            List <string> targets = new List <string> ();

            foreach (MachOFile file in MachO.Read(stm))
            {
                string arch  = ToArchString(file.Architecture);
                var    osmin = file.MinOS;
                if (osmin == null)
                {
                    throw new NotSupportedException("dylib files without a minimum supported operating system load command are not supported.");
                }
                targets.Add($"{arch}-apple-{osmin.OSName}{osmin.Version.ToString ()}");
            }
            return(targets);
        }
        void AssertStrip(string libPath, bool shouldStrip)
        {
            var archsFound = MachO.GetArchitectures(libPath);

            if (shouldStrip)
            {
                Assert.AreEqual(1, archsFound.Count, "Did not contain one archs");
                Assert.True(archsFound.Contains(Abi.x86_64), "Did not contain x86_64");
            }
            else
            {
                Assert.AreEqual(2, archsFound.Count, "Did not contain two archs");
                Assert.True(archsFound.Contains(Abi.i386), "Did not contain i386");
                Assert.True(archsFound.Contains(Abi.x86_64), "Did not contain x86_64");
            }
        }
        void AssertStrip(string libPath, bool shouldStrip)
        {
            var archsFound = MachO.GetArchitectures(libPath);

            if (shouldStrip)
            {
                Assert.AreEqual(1, archsFound.Count, "Did not contain one archs");
                Assert.True(archsFound.Contains(Abi.x86_64), "Did not contain x86_64");
            }
            else
            {
                Assert.That(archsFound.Count, Is.GreaterThanOrEqualTo(2), "Did not contain two or more archs");
                Assert.True(archsFound.Contains(Abi.i386) || archsFound.Contains(Abi.ARM64), "Did not contain i386 nor arm64");
                Assert.True(archsFound.Contains(Abi.x86_64), "Did not contain x86_64");
            }
        }
Beispiel #9
0
        public void HasOneRealPublicSymbol()
        {
            Stream           lib   = HelloSwiftAsLibrary(null);
            List <MachOFile> macho = MachO.Read(lib, null).ToList();

            Assert.IsNotNull(macho);
            Assert.AreEqual(1, macho.Count);
            MachOFile file = macho [0];
            List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();

            Assert.AreEqual(1, symbols.Count);
            NListEntryType    nlet    = symbols [0].nlist [0].EntryType;
            List <NListEntry> entries = symbols [0].nlist.
                                        Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();

            Assert.AreEqual(1, entries.Count);
        }
Beispiel #10
0
 static bool IsMacOSLib(string pathToLibrary)
 {
     using (FileStream stm = new FileStream(pathToLibrary, FileMode.Open, FileAccess.Read, FileShare.Read)) {
         foreach (MachOFile file in MachO.Read(stm))
         {
             var osmin = file.MinOS;
             if (osmin == null)
             {
                 throw new NotSupportedException("dylib files without a minimum supported operating system load command are not supported.");
             }
             if (osmin.Platform != MachO.Platform.MacOS)
             {
                 return(false);
             }
         }
         return(true);
     }
 }
Beispiel #11
0
        static void TLFunctionsForStream(Stream stm, PlatformName platform, Dictionary <string, string> functions)
        {
            List <NListEntry> entries = null;
            List <MachOFile>  macho   = MachO.Read(stm, null).ToList();
            MachOFile         file    = macho [0];

            List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();
            NListEntryType           nlet    = symbols [0].nlist [0].EntryType;

            entries = symbols [0].nlist.
                      Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();

            bool isOldVersion = IsOldVersion(entries);

            foreach (var entry in entries)
            {
                if (!entry.IsSwiftEntryPoint())
                {
                    continue;
                }
                TLDefinition def = null;
                try {
                    def = Decomposer.Decompose(entry.str, isOldVersion, Offset(entry));
                } catch { }
                if (def != null)
                {
                    // this skips over privatized names
                    var tlf = def as TLFunction;
                    if (tlf != null && tlf.Name != null && tlf.Name.Name.Contains("..."))
                    {
                        continue;
                    }
                    if (tlf?.Name != null)
                    {
                        if (!functions.ContainsKey(tlf.Name.Name))
                        {
                            functions.Add(tlf.Name.Name, tlf.MangledName);
                        }
                    }
                }
            }
        }
        public void TestLipoExecutable()
        {
            var fileA   = Path.Combine(Configuration.RootPath, "tests", "test-libraries", ".libs", "macos", "libtest.arm64.dylib");
            var fileB   = Path.Combine(Configuration.RootPath, "tests", "test-libraries", ".libs", "macos", "libtest.x86_64.dylib");
            var bundles = CreateAppBundles(fileA, fileB, "libtest.dylib");

            var outputBundle = Path.Combine(Cache.CreateTemporaryDirectory(), "Merged.app");
            var task         = CreateTask(outputBundle, bundles);

            Assert.IsTrue(task.Execute(), "Task execution");

            // The bundle should only contain a single file.
            Assert.AreEqual(1, Directory.GetFileSystemEntries(outputBundle).Length, "Files in bundle");

            // The resulting dylib should contain 2 architectures.
            var fatLibrary = Path.Combine(outputBundle, "libtest.dylib");

            Assert.That(fatLibrary, Does.Exist, "Existence");
            var machO = MachO.Read(fatLibrary).ToArray();

            Assert.AreEqual(2, machO.Length, "Architecture Count");
        }
Beispiel #13
0
        FileType GetFileType(string path)
        {
            if (PathUtils.IsSymlink(path))
            {
                return(FileType.Symlink);
            }

            if (Directory.Exists(path))
            {
                return(FileType.Directory);
            }

            if (path.EndsWith(".exe", StringComparison.Ordinal) || path.EndsWith(".dll", StringComparison.Ordinal))
            {
                return(FileType.PEAssembly);
            }

            if (MachO.IsMachOFile(path))
            {
                return(FileType.MachO);
            }

            if (StaticLibrary.IsStaticLibrary(path))
            {
                return(FileType.MachO);
            }

            if (ArchitectureSpecificFiles != null)
            {
                var filename = Path.GetFileName(path);
                if (ArchitectureSpecificFiles.Any(v => v.ItemSpec == filename))
                {
                    return(FileType.ArchitectureSpecific);
                }
            }

            return(FileType.Other);
        }
        public void TestSingleInput()
        {
            var fileA        = Path.Combine(Configuration.RootPath, "tests", "test-libraries", ".libs", "macos", "libtest.arm64.dylib");
            var bundle       = CreateAppBundle(Path.GetDirectoryName(fileA), Path.GetFileName(fileA));
            var outputBundle = Path.Combine(Cache.CreateTemporaryDirectory(), "Merged.app");
            var task         = CreateTask(outputBundle, bundle);

            Assert.IsTrue(task.Execute(), "Task execution");

            // The bundle should only contain a single file.
            Assert.AreEqual(1, Directory.GetFileSystemEntries(outputBundle).Length, "Files in bundle");

            // The resulting dylib should contain 1 architecture.
            var nonFatBinary = Path.Combine(outputBundle, "libtest.arm64.dylib");

            Assert.That(nonFatBinary, Does.Exist, "Existence");
            var machO = MachO.Read(nonFatBinary).ToArray();

            Assert.AreEqual(1, machO.Length, "Architecture Count");

            // and the file size should be the same as the input
            Assert.That(new FileInfo(fileA).Length, Is.EqualTo(new FileInfo(nonFatBinary).Length), "File length");
        }
        public override bool Execute()
        {
            if (FrameworkToPublish is not null && FrameworkToPublish.Length > 0)
            {
                var list = FrameworkToPublish.ToList();
                for (var i = list.Count - 1; i >= 0; i--)
                {
                    var item = list [i];
                    var frameworkExecutablePath = item.ItemSpec;
                    try {
                        if (frameworkExecutablePath.EndsWith(".framework", StringComparison.OrdinalIgnoreCase) && Directory.Exists(frameworkExecutablePath))
                        {
                            frameworkExecutablePath = Path.Combine(frameworkExecutablePath, Path.GetFileNameWithoutExtension(frameworkExecutablePath));
                        }

                        if (MachO.IsDynamicFramework(frameworkExecutablePath))
                        {
                            continue;
                        }
                    } catch (Exception e) {
                        Log.LogError(7091, frameworkExecutablePath, MSBStrings.E7092 /* File '{0}' is not a valid framework: {1} */, frameworkExecutablePath, e.Message);
                        continue;
                    }

                    Log.LogWarning(7091, frameworkExecutablePath, MSBStrings.W7091 /* "The framework {0} is a framework of static libraries, and will not be copied to the app." */, Path.GetDirectoryName(frameworkExecutablePath));
                    list.RemoveAt(i);
                }

                // Copy back the list if anything was removed from it
                if (FrameworkToPublish.Length != list.Count)
                {
                    FrameworkToPublish = list.ToArray();
                }
            }

            return(!Log.HasLoggedErrors);
        }
Beispiel #16
0
        static ModuleInventory FromStreamInto(Stream stm, ModuleInventory inventory,
                                              ErrorHandling errors, string fileName = null)
        {
            Ex.ThrowOnNull(errors, "errors");
            Ex.ThrowOnNull(stm, "stm");
            OffsetStream      osstm   = null;
            List <NListEntry> entries = null;

            try {
                List <MachOFile> macho = MachO.Read(stm, null).ToList();
                MachOFile        file  = macho [0];

                List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();
                NListEntryType           nlet    = symbols [0].nlist [0].EntryType;
                entries = symbols [0].nlist.
                          Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();
                inventory.Architecture = file.Architecture;
                osstm = new OffsetStream(stm, file.StartOffset);
            } catch (Exception e) {
                errors.Add(ErrorHelper.CreateError(ReflectorError.kCantHappenBase + 58, e, "Unable to retrieve functions from {0}: {1}",
                                                   fileName ?? "stream", e.Message));
                return(inventory);
            }

            bool isOldVersion = IsOldVersion(entries);

            foreach (var entry in entries)
            {
                if (!entry.IsSwiftEntryPoint())
                {
                    continue;
                }
                TLDefinition def = null;
                try {
                    def = Decomposer.Decompose(entry.str, isOldVersion, Offset(entry));
                } catch (RuntimeException e) {
                    var except = new RuntimeException(e.Code, false, e, $"error decomposing {entry.str}: {e.Message}, skipping");
                    errors.Add(except);
                }
                catch (Exception e) {
                    var except = new RuntimeException(ReflectorError.kDecomposeBase + 0, false, e, $"unexpected error handling {entry.str}: {e.Message}, skipping.");
                    errors.Add(except);
                }
                if (def != null)
                {
                    // this skips over privatized names
                    var tlf = def as TLFunction;
                    if (tlf != null && tlf.Name != null && tlf.Name.Name.Contains("..."))
                    {
                        continue;
                    }
                    try {
                        inventory.Add(def, osstm);
                    } catch (RuntimeException e) {
                        e = new RuntimeException(e.Code, e.Error, $"error dispensing top level definition of type {def.GetType ().Name} decomposed from {entry.str}: {e.Message}");
                        errors.Add(e);
                    }
                }
                else
                {
                    var ex = ErrorHelper.CreateWarning(ReflectorError.kInventoryBase + 18, $"entry {entry.str} uses an unsupported swift feature, skipping.");
                    errors.Add(ex);
                }
            }

            return(inventory);
        }
    // This is tool very similar to Apple's swift-stdlib-tool, which scans an .app and copies the required swift libraries to the app.
    // Unfortunately Apple's tool has a shortcoming: it scans only executables, not shared libraries / frameworks.
    // So this tool fixes that shortcoming: it scans all both executables and shared libraries / frameworks.
    // As opposed to swift-stdlib-tool, code signing is not supported, since we don't need it (for now at least).
    // swift-stdlib-tool also doesn't update the timestamp of the files it copies, which makes dependency tracking annoying in the MSBuild target files.
    public static int Main(string [] args)
    {
        const string TOOL               = "swift-copy-libs";
        OptionSet    os                 = null;
        int?         exit_code          = null;
        var          action             = Action.None;
        var          scan_executables   = new List <string> ();
        var          scan_folders       = new List <string> ();
        var          platform           = string.Empty;
        var          source_libraries   = string.Empty;
        var          destination        = string.Empty;
        var          resource_libraries = new List <string> ();
        var          verbosity          = 0;
        var          failed             = false;

        os = new OptionSet {
            { "h|help|?", "Show help", (v) =>
              {
                  Console.WriteLine(TOOL + " [OPTIONS]");
                  os.WriteOptionDescriptions(Console.Out);
                  exit_code = 0;
              } },
            { "copy", "Copy required swift libraries to the target location", (v) => action = Action.Copy },
            { "print", "Print required swift libraries", (v) => action = Action.Print },
            { "scan-executable=", "Scan the specified executable", (v) => scan_executables.Add(v) },
            { "scan-folder=", "Scan the specified folder", (v) => scan_folders.Add(v) },
            { "platform=", "The platform to use", (v) => platform = v },
            { "source-libraries=", "The path where to find the swift libraries", (v) => source_libraries = v },
            { "destination=", "The destination path for the swift libraries", (v) => destination = v },
            { "resource-library=", "Additional swift libraries.", (v) => resource_libraries.Add(v) },
            { "v|verbose", "Show verbose output", (v) => { verbosity++; } },
            { "q|quiet", "Show less verbose output", (v) => { verbosity--; } },
            { "strip-bitcode", "Strip bitcode", (v) => {} },
        };

        var left = os.Parse(args);

        if (exit_code.HasValue)
        {
            return(exit_code.Value);
        }

        if (left.Count > 0)
        {
            Console.Error.WriteLine($"{TOOL}: unexpected arguments: {left.First ()}");
            return(1);
        }

        switch (action)
        {
        case Action.Copy:
        case Action.Print:
            break;

        default:
            Console.Error.WriteLine($"{TOOL}: no action specified: pass either --copy or --print.");
            return(1);
        }

        var files = new HashSet <string> ();

        files.UnionWith(scan_executables);
        foreach (var folder in scan_folders)
        {
            if (!Directory.Exists(folder))
            {
                Console.WriteLine($"Could not find the folder {folder}.");
                continue;
            }
            files.UnionWith(Directory.EnumerateFileSystemEntries(folder, "*", SearchOption.AllDirectories));
        }

        // Remove directories from the list.
        files.RemoveWhere(Directory.Exists);

        var process_queue = new Queue <string> (files);
        var processed     = new HashSet <string> ();
        var dependencies  = new HashSet <string> ();

        while (process_queue.Count > 0)
        {
            var file = process_queue.Dequeue();
            if (processed.Contains(file))
            {
                continue;
            }
            processed.Add(file);
            if (!File.Exists(file))
            {
                Console.WriteLine($"Could not find the file {file}.");
                failed = true;
                continue;
            }
            try {
                var macho_file = MachO.Read(file, ReadingMode.Deferred);
                foreach (var slice in macho_file)
                {
                    using (slice) {
                        Console.WriteLine($"{file} [{slice.Architecture}]:");
                        foreach (var lc in slice.load_commands)
                        {
                            var cmd = (MachO.LoadCommands)lc.cmd;
                            if (cmd != MachO.LoadCommands.LoadDylib)
                            {
                                continue;
                            }
                            var ldcmd = (DylibLoadCommand)lc;
                            if (!ldcmd.name.StartsWith("@rpath/libswift", StringComparison.Ordinal))
                            {
                                continue;
                            }
                            var dependency = ldcmd.name.Substring("@rpath/".Length);
                            dependency = Path.Combine(source_libraries, platform, dependency);

                            if (verbosity > 0)
                            {
                                Console.WriteLine($"    {Path.GetFileName (dependency)}");
                            }
                            if (!File.Exists(dependency))
                            {
                                if (verbosity > 0)
                                {
                                    Console.WriteLine($"        Could not find the file {dependency}");
                                }
                            }
                            else
                            {
                                dependencies.Add(dependency);
                                process_queue.Enqueue(dependency);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                if (verbosity > 0)
                {
                    Console.WriteLine($"{file}: not a Mach-O file ({e.Message})");
                }
            }
        }

        var allDependencies = dependencies.Union(resource_libraries.Select((v) => Path.Combine(source_libraries, platform, v))).ToList();

        if (verbosity > 0)
        {
            Console.WriteLine($"Found {allDependencies.Count} dependencies:");
            foreach (var dependency in allDependencies)
            {
                Console.WriteLine($"    {dependency}");
            }
        }

        if (action == Action.Copy)
        {
            foreach (var dependency in allDependencies)
            {
                var src     = dependency;
                var tgt     = Path.Combine(destination, Path.GetFileName(dependency));
                var srcInfo = new FileInfo(src);
                var tgtInfo = new FileInfo(tgt);
                if (!tgtInfo.Exists || srcInfo.Length != tgtInfo.Length || srcInfo.LastWriteTimeUtc > tgtInfo.LastWriteTimeUtc)
                {
                    File.Copy(src, tgt, true);
                }
                else
                {
                    if (verbosity > 0)
                    {
                        Console.WriteLine($"Did not copy {Path.GetFileName (src)} because it's up-to-date.");
                    }
                }

                new FileInfo(tgt).LastWriteTimeUtc = DateTime.Now;
            }
            if (verbosity >= 0)
            {
                Console.WriteLine($"Copied all dependencies ({string.Join (", ", allDependencies.Select (Path.GetFileName))}) to {destination}.");
            }
        }

        return(failed ? 1 : 0);
    }
        protected override bool Init()
        {
            // Detect endianness - default is little-endianness
            MachO magic = (MachO)ReadUInt32();

            if (magic == MachO.MH_CIGAM || magic == MachO.MH_CIGAM_64)
            {
                Endianness = Endianness.Big;
            }
            else if (magic != MachO.MH_MAGIC && magic != MachO.MH_MAGIC_64)
            {
                return(false);
            }

            Console.WriteLine("Endianness: {0}", Endianness);

            Position -= sizeof(uint);
            header    = ReadObject <MachOHeader>();

            // 64-bit files have an extra 4 bytes after the header
            is64 = false;
            if (magic == MachO.MH_MAGIC_64)
            {
                is64 = true;
                ReadUInt32();
            }
            Console.WriteLine("Architecture: {0}-bit", is64 ? 64 : 32);

            // Must be executable file
            if ((MachO)header.FileType != MachO.MH_EXECUTE)
            {
                return(false);
            }

            Console.WriteLine("CPU Type: " + (MachO)header.CPUType);

            MachOLinkEditDataCommand functionStarts = null;

            for (var c = 0; c < header.NumCommands; c++)
            {
                var startPos    = Position;
                var loadCommand = ReadObject <MachOLoadCommand>();

                if ((MachO)loadCommand.Command == MachO.LC_SEGMENT)
                {
                    var segment = ReadObject <MachOSegmentCommand>();
                    if (segment.Name == "__TEXT" || segment.Name == "__DATA")
                    {
                        for (int s = 0; s < segment.NumSections; s++)
                        {
                            var section = ReadObject <MachOSection>();
                            sections.Add(section);
                            if (section.Name == "__text")
                            {
                                GlobalOffset = section.Address - section.ImageOffset;
                            }
                        }
                    }
                }
                else if ((MachO)loadCommand.Command == MachO.LC_SEGMENT_64)
                {
                    var segment = ReadObject <MachOSegmentCommand64>();
                    if (segment.Name == "__TEXT" || segment.Name == "__DATA")
                    {
                        for (int s = 0; s < segment.NumSections; s++)
                        {
                            var section64 = ReadObject <MachOSection64>();
                            sections64.Add(section64);
                            if (section64.Name == "__text")
                            {
                                GlobalOffset = (uint)section64.Address - section64.ImageOffset;
                            }
                        }
                    }
                }

                if ((MachO)loadCommand.Command == MachO.LC_FUNCTION_STARTS)
                {
                    functionStarts = ReadObject <MachOLinkEditDataCommand>();
                }

                // There might be other data after the load command so always use the specified total size to step forwards
                Position = startPos + loadCommand.Size;
            }

            // Must find LC_FUNCTION_STARTS load command
            if (functionStarts == null)
            {
                return(false);
            }

            pFuncTable = functionStarts.Offset;
            sFuncTable = functionStarts.Size;
            return(true);
        }
Beispiel #19
0
 protected override bool checkMagicBE(MachO magic) => magic == MachO.MH_CIGAM_64;
Beispiel #20
0
 protected override bool checkMagicLE(MachO magic) => magic == MachO.MH_MAGIC_64;