Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mono/mini/main.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/mono/mini/main.c b/mono/mini/main.c
index b857ec3ca4d..7cc3fecfa17 100644
--- a/mono/mini/main.c
+++ b/mono/mini/main.c
@@ -35,6 +35,9 @@
# include "buildver-boehm.h"
# endif
#endif
+#ifdef TARGET_OSX
+#include <mach-o/loader.h>
+#endif
//#define TEST_ICALL_SYMBOL_MAP 1
@@ -179,8 +182,68 @@ probe_embedded (const char *program, int *ref_argc, char **ref_argv [])
goto doclose;
if (read (fd, sigbuffer, sizeof (sigbuffer)) == -1)
goto doclose;
- if (memcmp (sigbuffer+sizeof(uint64_t), "xmonkeysloveplay", 16) != 0)
- goto doclose;
+ // First, see if "xmonkeysloveplay" is at the end of file
+ if (memcmp (sigbuffer + sizeof (uint64_t), "xmonkeysloveplay", 16) == 0)
+ goto found;
+
+#ifdef TARGET_OSX
+ {
+ /*
+ * If "xmonkeysloveplay" is not at the end of file,
+ * on Mac OS X, we try a little harder, by actually
+ * reading the binary's header structure, to see
+ * if it is located at the end of a LC_SYMTAB section.
+ *
+ * This is because Apple code-signing appends a
+ * LC_CODE_SIGNATURE section to the binary, so
+ * for a signed binary, "xmonkeysloveplay" is no
+ * longer at the end of file.
+ *
+ * The rest is sanity-checks for the header and section structures.
+ */
+ struct mach_header_64 bin_header;
+ if ((sigstart = lseek (fd, 0, SEEK_SET)) == -1)
+ goto doclose;
+ // Find and check binary header
+ if (read (fd, &bin_header, sizeof (bin_header)) == -1)
+ goto doclose;
+ if (bin_header.magic != MH_MAGIC_64)
+ goto doclose;
+
+ off_t total = bin_header.sizeofcmds;
+ uint32_t count = bin_header.ncmds;
+ while (total > 0 && count > 0) {
+ struct load_command lc;
+ off_t sig_stored = lseek (fd, 0, SEEK_CUR); // get current offset
+ if (read (fd, &lc, sizeof (lc)) == -1)
+ goto doclose;
+ if (lc.cmd == LC_SYMTAB) {
+ struct symtab_command stc;
+ if ((sigstart = lseek (fd, -sizeof (lc), SEEK_CUR)) == -1)
+ goto doclose;
+ if (read (fd, &stc, sizeof (stc)) == -1)
+ goto doclose;
+
+ // Check the end of the LC_SYMTAB section for "xmonkeysloveplay"
+ if ((sigstart = lseek (fd, -(16 + sizeof (uint64_t)) + stc.stroff + stc.strsize, SEEK_SET)) == -1)
+ goto doclose;
+ if (read (fd, sigbuffer, sizeof (sigbuffer)) == -1)
+ goto doclose;
+ if (memcmp (sigbuffer + sizeof (uint64_t), "xmonkeysloveplay", 16) == 0)
+ goto found;
+ }
+ if ((sigstart = lseek (fd, sig_stored + lc.cmdsize, SEEK_SET)) == -1)
+ goto doclose;
+ total -= sizeof (lc.cmdsize);
+ count--;
+ }
+ }
+#endif
+
+ // did not find "xmonkeysloveplay" at end of file or end of LC_SYMTAB section
+ goto doclose;
+
+found:
directory_location = GUINT64_FROM_LE ((*(uint64_t *) &sigbuffer [0]));
if (lseek (fd, directory_location, SEEK_SET) == -1)
goto doclose;