[80151] branches/gsoc11-rev-upgrade/base/src
cal at macports.org
cal at macports.org
Tue Jul 5 08:46:53 PDT 2011
Revision: 80151
http://trac.macports.org/changeset/80151
Author: cal at macports.org
Date: 2011-07-05 08:46:53 -0700 (Tue, 05 Jul 2011)
Log Message:
-----------
rev-upgrade: Library to parse Mach-O binaries (thanks to Landon J Fuller)
Added Paths:
-----------
branches/gsoc11-rev-upgrade/base/src/libmachista1.0/
branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.c
branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.h
Added: branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.c (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.c 2011-07-05 15:46:53 UTC (rev 80151)
@@ -0,0 +1,494 @@
+/*
+ * -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=c:et:sw=4:ts=4:sts=4:tw=100
+ * libmachista.c
+ * $Id$
+ *
+ * Copyright (c) 2011 The MacPorts Project
+ * Copyright (c) 2011 Landon Fuller <landonf at macports.org>
+ * Copyright (c) 2011 Clemens Lang <cal at macports.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <err.h>
+#include <string.h>
+
+#include <mach-o/fat.h>
+#include <mach-o/loader.h>
+
+#include <libkern/OSAtomic.h>
+
+#include "libmachista.h"
+
+typedef struct macho_input {
+ const void *data;
+ size_t length;
+} macho_input_t;
+
+/* This is macho_handle_t. The corresponding typedef is in the header */
+struct macho_handle {
+ /* this isn't handled as a linked list on purpose, because the mht_results are given out to the
+ * user and should not have a next pointer (as it doesn't make any sense in that context */
+ size_t mht_result_count;
+ macho_t **mht_results;
+};
+
+/* Verify that the given range is within bounds. */
+static const void *macho_read (macho_input_t *input, const void *address, size_t length) {
+ if ((((uint8_t *) address) - ((uint8_t *) input->data)) + length > input->length) {
+ // warnx("Short read parsing Mach-O input");
+ return NULL;
+ }
+
+ return address;
+}
+
+/* Verify that address + offset + length is within bounds. */
+static const void *macho_offset (macho_input_t *input, const void *address, size_t offset, size_t length) {
+ void *result = ((uint8_t *) address) + offset;
+ return macho_read(input, result, length);
+}
+
+/* return a human readable formatted version number. the result must be free()'d. */
+char *macho_format_dylib_version (uint32_t version) {
+ char *result;
+ asprintf(&result, "%"PRIu32".%"PRIu32".%"PRIu32, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return result;
+}
+
+/* Some byteswap wrappers */
+static uint32_t macho_swap32 (uint32_t input) {
+ return OSSwapInt32(input);
+}
+
+static uint32_t macho_nswap32(uint32_t input) {
+ return input;
+}
+
+/* Creates a new macho_t.
+ * Returns NULL on failure or a pointer to a 0-initialized macho_t on success */
+static macho_t *create_macho_t (void) {
+ macho_t *mt = malloc(sizeof(macho_t));
+ if (mt == NULL)
+ return NULL;
+
+ memset(mt, 0, sizeof(macho_t));
+ return mt;
+}
+
+/* Creates a new macho_arch_t.
+ * Returns NULL on failure or a pointer to a 0-initialized macho_arch_t on success */
+static macho_arch_t *create_macho_arch_t (void) {
+ macho_arch_t *mat = malloc(sizeof(macho_arch_t));
+ if (mat == NULL)
+ return NULL;
+
+ memset(mat, 0, sizeof(macho_arch_t));
+ return mat;
+}
+
+/* Creates a new macho_loadcmd_t.
+ * Returns NULL on failure or a pointer to a 0-initialized macho_loadcmd_t on success */
+static macho_loadcmd_t *create_macho_loadcmd_t (void) {
+ macho_loadcmd_t *mlt = malloc(sizeof(macho_loadcmd_t));
+ if (mlt == NULL)
+ return NULL;
+
+ memset(mlt, 0, sizeof(macho_loadcmd_t));
+ return mlt;
+}
+
+/* Frees a previously allocated macho_loadcmd_t and all it's associated resources */
+static void free_macho_loadcmd_t (macho_loadcmd_t *mlt) {
+ if (mlt == NULL)
+ return;
+
+ free(mlt->mlt_install_name);
+ free(mlt);
+}
+
+/* Frees a previously allocated macho_arch_t and all it's associated resources */
+static void free_macho_arch_t (macho_arch_t *mat) {
+ if (mat == NULL)
+ return;
+
+ macho_loadcmd_t *current = mat->mat_loadcmds;
+ while (current != NULL) {
+ macho_loadcmd_t *freeme = current;
+ current = current->next;
+ free_macho_loadcmd_t(freeme);
+ }
+
+ free(mat->mat_install_name);
+ free(mat->mat_rpath);
+ free(mat);
+}
+
+/* Frees a previously allocated macho_t and all it's associated resources */
+static void free_macho_t (macho_t *mt) {
+ if (mt == NULL)
+ return;
+
+ macho_arch_t *current = mt->mt_archs;
+ while (current != NULL) {
+ macho_arch_t *freeme = current;
+ current = current->next;
+ free_macho_arch_t(freeme);
+ }
+
+ free(mt);
+}
+
+/* Creates a new element in the architecture list of a macho_t (mt_archs), increases the counter of
+ * architectures (mt_arch_count) and returns a pointer to the newly allocated element or NULL on
+ * error */
+static macho_arch_t *macho_archlist_append (macho_t *mt) {
+ macho_arch_t *old_head = mt->mt_archs;
+
+ macho_arch_t *new_head = create_macho_arch_t();
+ if (new_head == NULL)
+ return NULL;
+ new_head->next = old_head;
+ mt->mt_archs = new_head;
+
+ return mt->mt_archs;
+}
+
+/* Creates a new element in the load command list of a macho_arch_t (mat_loadcmds), increases the
+ * counter of load commands (mat_loadcmd_count) and returns a pointer to the newly allocated element
+ * or NULL on error */
+static macho_loadcmd_t *macho_loadcmdlist_append (macho_arch_t *mat) {
+ macho_loadcmd_t *old_head = mat->mat_loadcmds;
+
+ macho_loadcmd_t *new_head = create_macho_loadcmd_t();
+ if (new_head == NULL)
+ return NULL;
+ new_head->next = old_head;
+ mat->mat_loadcmds = new_head;
+
+ return mat->mat_loadcmds;
+}
+
+/* Parse a Mach-O header */
+static int parse_macho (macho_t *mt, macho_input_t *input) {
+ /* Read the file type. */
+ const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t));
+ if (magic == NULL)
+ return MACHO_ERANGE;
+
+ /* Parse the Mach-O header */
+ bool universal = false;
+ uint32_t (*swap32)(uint32_t) = macho_nswap32;
+
+ const struct mach_header *header;
+ const struct mach_header_64 *header64;
+ size_t header_size;
+ const struct fat_header *fat_header;
+
+ macho_arch_t *mat = NULL;
+ switch (*magic) {
+ case MH_CIGAM:
+ swap32 = macho_swap32;
+ // Fall-through
+
+ case MH_MAGIC:
+
+ header_size = sizeof(*header);
+ header = macho_read(input, input->data, header_size);
+ if (header == NULL)
+ return MACHO_ERANGE;
+ mat = macho_archlist_append(mt);
+ if (mat == NULL)
+ return MACHO_EMEM;
+
+ /* 32-bit Mach-O */
+ mat->mat_arch = header->cputype;
+ break;
+
+
+ case MH_CIGAM_64:
+ swap32 = macho_swap32;
+ // Fall-through
+
+ case MH_MAGIC_64:
+ header_size = sizeof(*header64);
+ header64 = macho_read(input, input->data, sizeof(*header64));
+ if (header64 == NULL)
+ return MACHO_ERANGE;
+ mat = macho_archlist_append(mt);
+ if (mat == NULL)
+ return MACHO_EMEM;
+
+ /* The 64-bit header is a direct superset of the 32-bit header */
+ header = (struct mach_header *) header64;
+
+ /* 64-bit Macho-O */
+ mat->mat_arch = header->cputype;
+ break;
+
+ case FAT_CIGAM:
+ case FAT_MAGIC:
+ fat_header = macho_read(input, input->data, sizeof(*fat_header));
+ universal = true;
+ /* Universal binary */
+ break;
+
+ default:
+ /* Unknown binary type */
+ //warnx("Unknown Mach-O magic: 0x%" PRIx32 "", *magic);
+ return MACHO_EMAGIC;
+ }
+
+ /* Parse universal file. */
+ if (universal) {
+ uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
+ const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
+ if (archs == NULL)
+ return MACHO_ERANGE;
+
+ for (uint32_t i = 0; i < nfat; i++) { // foreach architecture
+ const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch));
+ if (arch == NULL)
+ return MACHO_ERANGE;
+
+ /* Fetch a pointer to the architecture's Mach-O header. */
+ macho_input_t arch_input;
+ arch_input.length = OSSwapBigToHostInt32(arch->size);
+ arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
+ if (arch_input.data == NULL)
+ return MACHO_ERANGE;
+
+ /* Parse the architecture's Mach-O header */
+ int res = parse_macho(mt, &arch_input);
+ if (res != MACHO_SUCCESS)
+ return res;
+ }
+
+ return MACHO_SUCCESS;
+ }
+
+ /* Copy the architecture */
+ mat->mat_arch = header->cputype;
+
+ /* Parse the Mach-O load commands */
+ const struct load_command *cmd = macho_offset(input, header, header_size, sizeof(struct load_command));
+ if (cmd == NULL)
+ return MACHO_ERANGE;
+ uint32_t ncmds = swap32(header->ncmds);
+
+ /* Iterate over the load commands */
+ for (uint32_t i = 0; i < ncmds; i++) {
+ /* Load the full command */
+ uint32_t cmdsize = swap32(cmd->cmdsize);
+ cmd = macho_read(input, cmd, cmdsize);
+ if (cmd == NULL)
+ return MACHO_ERANGE;
+
+ /* Handle known types */
+ uint32_t cmd_type = swap32(cmd->cmd);
+ switch (cmd_type) {
+ case LC_RPATH: {
+ /* Copy the rpath */
+ if (cmdsize < sizeof(struct rpath_command)) {
+ //warnx("Incorrect cmd size");
+ return MACHO_ERANGE;
+ }
+
+ size_t pathlen = cmdsize - sizeof(struct rpath_command);
+ const void *pathptr = macho_offset(input, cmd, sizeof(struct rpath_command), pathlen);
+ if (pathptr == NULL)
+ return MACHO_ERANGE;
+
+ mat->mat_rpath = malloc(pathlen);
+ if (mat->mat_rpath == NULL)
+ return MACHO_EMEM;
+ strlcpy(mat->mat_rpath, pathptr, pathlen);
+ break;
+ }
+
+ case LC_ID_DYLIB:
+ case LC_LOAD_WEAK_DYLIB:
+ case LC_REEXPORT_DYLIB:
+ case LC_LOAD_DYLIB: {
+ const struct dylib_command *dylib_cmd = (const struct dylib_command *) cmd;
+
+ /* Extract the install name */
+ if (cmdsize < sizeof(struct dylib_command)) {
+ //warnx("Incorrect name size");
+ return MACHO_ERANGE;
+ }
+
+ size_t namelen = cmdsize - sizeof(struct dylib_command);
+ const void *nameptr = macho_offset(input, cmd, sizeof(struct dylib_command), namelen);
+ if (nameptr == NULL)
+ return MACHO_ERANGE;
+
+ if (cmd_type == LC_ID_DYLIB) {
+ /* Copy install name */
+ mat->mat_install_name = malloc(namelen);
+ if (mat->mat_install_name == NULL)
+ return MACHO_EMEM;
+ strlcpy(mat->mat_install_name, nameptr, namelen);
+
+ /* Copy version numbers (raw, for easier comparison) */
+ mat->mat_version = swap32(dylib_cmd->dylib.current_version);
+ mat->mat_comp_version = swap32(dylib_cmd->dylib.compatibility_version);
+ } else {
+ /* Append loadcmd to list of loadcommands */
+ macho_loadcmd_t *mlt = macho_loadcmdlist_append(mat);
+ if (mlt == NULL)
+ return MACHO_EMEM;
+
+ /* Copy install name */
+ mlt->mlt_install_name = malloc(namelen);
+ if (mlt->mlt_install_name == NULL)
+ return MACHO_EMEM;
+ strlcpy(mlt->mlt_install_name, nameptr, namelen);
+
+ /* Copy version numbers (raw, for easier comparison) */
+ mlt->mlt_version = swap32(dylib_cmd->dylib.current_version);
+ mlt->mlt_comp_version = swap32(dylib_cmd->dylib.compatibility_version);
+
+ /* Copy command type */
+ mlt->mlt_type = cmd_type;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ /* Load the next command */
+ cmd = macho_offset(input, cmd, cmdsize, sizeof(struct load_command));
+ if (cmd == NULL)
+ return MACHO_ERANGE;
+ }
+
+ return MACHO_SUCCESS;
+}
+
+/* Parse a (possible Mach-O) file. For a more detailed description, see the header */
+int macho_parse_file(macho_handle_t *handle, const char *filepath, macho_t **res) {
+ int fd;
+ struct stat st;
+ void *data;
+ macho_input_t input_file;
+
+ /* Open input file */
+ if ((fd = open(filepath, O_RDONLY)) < 0) {
+ return MACHO_EFILE;
+ }
+
+ /* Get file length */
+ if (fstat(fd, &st) != 0) {
+ close(fd);
+ return MACHO_EFILE;
+ }
+
+ /* Map file into address space */
+ if ((data = mmap(NULL, st.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
+ close(fd);
+ return MACHO_EMMAP;
+ }
+
+ /* Parse file */
+ input_file.data = data;
+ input_file.length = st.st_size;
+
+ *res = create_macho_t();
+ if (*res == NULL)
+ return MACHO_EMEM;
+
+ int ret = parse_macho(*res, &input_file);
+ if (ret == MACHO_SUCCESS) {
+ /* TODO: Insert into hashmap for caching */
+ macho_t **handle_list = realloc(handle->mht_results, (handle->mht_result_count + 1) * sizeof(*handle->mht_results));
+ if (handle_list == NULL) {
+ free_macho_t(*res);
+ *res = NULL;
+ ret = MACHO_EMEM;
+ } else {
+ handle->mht_results = handle_list;
+ handle->mht_result_count++;
+ handle->mht_results[handle->mht_result_count - 1] = *res;
+ }
+ } else {
+ /* An error occured, free mt */
+ free_macho_t(*res);
+ *res = NULL;
+ }
+
+ /* Cleanup */
+ munmap(data, st.st_size);
+ close(fd);
+
+ return ret;
+}
+
+/* Create a new macho_handle_t. More information on this function is available in the header */
+macho_handle_t *macho_create_handle (void) {
+ macho_handle_t *mht = malloc(sizeof(macho_handle_t));
+ if (mht == NULL)
+ return NULL;
+ memset(mht, 0, sizeof(mht));
+ return mht;
+}
+
+/* Release a macho_handle_t. For more documentation, see the header */
+void macho_destroy_handle(macho_handle_t *handle) {
+ if (handle == NULL)
+ return;
+
+ for (size_t i = 0; i < handle->mht_result_count; ++i)
+ free_macho_t(handle->mht_results[i]);
+ free(handle->mht_results);
+
+ free(handle);
+}
+
+/* Returns string representation of the MACHO_* error code constants */
+char *macho_strerror(int errno) {
+ int num = 0;
+ while ((errno >>= 1) > 0)
+ num++;
+ static char *errors[] = {
+ /* 0x00 */ "Success",
+ /* 0x01 */ "Error opening or reading file",
+ /* 0x02 */ "Error mapping file into memory",
+ /* 0x04 */ "Error allocating memory",
+ /* 0x08 */ "Premature end of data, possibly corrupt file",
+ /* 0x10 */ "Not a Mach-O file",
+ };
+ return errors[num];
+}
+
Property changes on: branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.c
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Added: branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.h (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/libmachista1.0/libmachista.h 2011-07-05 15:46:53 UTC (rev 80151)
@@ -0,0 +1,137 @@
+/*
+ * -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=c:et:sw=4:ts=4:sts=4:tw=100
+ * libmachista.h
+ * $Id$
+ *
+ * Copyright (c) 2011 The MacPorts Project
+ * Copyright (c) 2011 Clemens Lang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LIBMACHISTA_H__
+#define __LIBMACHISTA_H__
+
+/*
+ * This is a library to parse Mach-O files in single architecture _and_ universal varaint and return
+ * a list of architectures and their load commands and properties
+ * The name a pun: machista is the spanish translation of "macho".
+ */
+
+#include <mach-o/arch.h>
+#include <inttypes.h>
+
+#define MACHO_SUCCESS (0x00)
+#define MACHO_EFILE (0x01)
+#define MACHO_EMMAP (0x02)
+#define MACHO_EMEM (0x04)
+#define MACHO_ERANGE (0x08)
+#define MACHO_EMAGIC (0x10)
+
+/* Blind structure; this essentially contains the hash map used to cache
+ * entries, but users should not have to look into this structure. struct
+ * macho_handle is defined in libmachista.c */
+typedef struct macho_handle macho_handle_t;
+
+/** Structure describing a load command within a Mach-O file */
+typedef struct macho_loadcmd {
+ char *mlt_install_name; /* install name of the library to be loaded by this load command */
+ uint32_t mlt_type; /* type of the load command; see mach-o/loader.h for possible
+ values */
+ uint32_t mlt_comp_version; /* compatibility version of the file to be loaded by this
+ command (at build time of this file) */
+ uint32_t mlt_version; /* version of the library to be loaded by this command (at build
+ time of this file) */
+ struct macho_loadcmd *next; /* pointer to the next entry in the linked list of
+ macho_loadcmd_t's (NULL if there's no further element) */
+} macho_loadcmd_t;
+
+/** Stucture describing an architecture within a Mach-O file */
+typedef struct macho_arch {
+ char *mat_install_name; /* install name of the library or NULL if none */
+ char *mat_rpath; /* rpath of the binary of NULL if none */
+ cpu_type_t mat_arch; /* cpu_type_t describing the CPU this part of the binary is
+ intended for */
+ uint32_t mat_comp_version; /* compatibility version of this part of the binary */
+ uint32_t mat_version; /* current version of this part of the binary */
+ macho_loadcmd_t *mat_loadcmds; /* array of macho_loadcmd_t's describing the different load
+ commands */
+ struct macho_arch *next; /* pointer to the next entry in the linked list of
+ macho_arch_t's (NULL if there's no further element) */
+} macho_arch_t;
+
+/** Structure describing a Mach-O file */
+typedef struct macho {
+ macho_arch_t *mt_archs; /* linked list of macho_arch_t's describing the different
+ architectures */
+} macho_t;
+
+/**
+ * Creates and returns a macho_handle_t to be passed to subsequent calls to macho_parse_file. No
+ * assumptions should be made about the contents of a macho_handle_t; it is declared to be a blind
+ * structure.
+ *
+ * Returns either a pointer to a valid macho_handle_t or NULL on failure. errno will be set on
+ * failure. The resources associated with a macho_handle_t must be freed by passing it to
+ * macho_destroy_handle.
+ */
+macho_handle_t *macho_create_handle(void);
+
+/**
+ * Frees resources associated with a macho_handle_t and invalidates all results returned by
+ * macho_parse_file called with this handle.
+ */
+void macho_destroy_handle(macho_handle_t *handle);
+
+/**
+ * Formats a dylib version number given by an uint32_t into a human-readable format and returns a
+ * Pointer to the beginning of that string. The result is either a valid pointer or NULL on error
+ * (in which case the errno is set to indicate the error). The pointer must be free()'d after use.
+ */
+char *macho_format_dylib_version(uint32_t version);
+
+/**
+ * Parses the Mach-O file indicated by filepath and writes a pointer to a macho_t describing the
+ * Mach-O file into the location idicated by res. Returns MACHO_SUCCESS on success or any of the
+ * following error codes on error:
+ *
+ * code description errno set?
+ * MACHO_EFILE error stat()'ing, opening or reading the file yes
+ * MACHO_EMMAP error mmap()'ing the file yes
+ * MACHO_EMEM error allocating memory yes
+ * MACHO_ERANGE unexpected end of file no
+ * MACHO_EMAGIC unknown magic number/not a Mach-O file no
+ *
+ * On error, the contents of res are undefined and should not be used. The memory associated with
+ * the result *res will be free()'d and should thus not be used after calling macho_destroy_handle
+ * on the macho_handle_t used for the call.
+ */
+int macho_parse_file(macho_handle_t *handle, const char *filepath, macho_t **res);
+
+/**
+ * Returns a string representation of the MACHO_* error code constants
+ */
+char *macho_strerror(int errno);
+
+#endif
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110705/2dd9fc19/attachment-0001.html>
More information about the macports-changes
mailing list