Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Remove libmachista, promote pkg_elf on all platforms and deprecate pkg_macho
Keve committed 1 year ago
commit bdd5af5aea4514b47c5abf4e89c594be956c4ffe
parent 00c1cab
15 files changed +1005 -1249
modified .gitignore
@@ -63,7 +63,6 @@ scripts/sbin/pkg2ng
/external/libucl/autom4te.cache
/external/yxml/Makefile
/external/liblua/Makefile
-
/external/libmachista/Makefile
/external/libfetch/Makefile
/external/libelf/Makefile
/external/sqlite/Makefile
modified auto.def
@@ -102,7 +102,7 @@ cc-with { -libs { -llzma }} {
	}
}
if {[string match *-freebsd* [get-define host]]} {
-
	define pkg_freebsd
+
	define pkgos_freebsd
	cc-with { -libs { -lmd }} {
		if {![cc-check-functions SHA256_Data]} {
			user-error "Unable to find libmd"
@@ -213,14 +213,6 @@ if {![cc-check-functions dlclose]} {
	}
}

-
if {![cc-check-functions __res_query]} {
-
	cc-with { -libs { -lresolv }} {
-
		if {[cc-check-functions __res_query]} {
-
			define-feature LIBRESOLV
-
		}
-
	}
-
}
-

cc-check-includes link.h machine/endian.h osreldate.h readpassphrase.h \
	sys/procctl.h sys/statfs.h sys/statvfs.h libutil.h

@@ -228,7 +220,7 @@ cc-check-includes link.h machine/endian.h osreldate.h readpassphrase.h \
cc-check-includes dirent.h sys/sockio.h

#endian stuff
-
foreach header [list endian.h sys/endian.h] {
+
foreach header [list endian.h sys/endian.h machine/endian.h] {
	if {[cc-check-includes $header]} {
		cc-with [list -includes $header] {
			cc-check-decls be16dec be16enc be32dec be32enc be64dec be64enc \
@@ -238,9 +230,10 @@ foreach header [list endian.h sys/endian.h] {
}

if {[string match *-darwin* [get-define host]]} {
-
	define libmachista
+
	define pkgos_darwin
	define waflags ""
	define nowaflags ""
+
	define libelf-internal
} else {
# libelf
	define waflags "-Wl,-whole-archive"
@@ -394,7 +387,7 @@ make-template Makefile.autosetup Makefile
foreach dir [list external/blake2 external/picosat \
	external/linenoise external/sqlite \
	external compat libpkg libpkg/repo libpkg/repo/binary src \
-
	external/libucl external/libelf external/libmachista tests docs \
+
	external/libucl external/libelf tests docs \
	external/liblua external/yxml scripts external/libcurl external/libder \
	external/libecc] {
	make-template $dir/Makefile.autosetup $dir/Makefile
modified external/Makefile.autosetup
@@ -1,8 +1,5 @@
include @builddir@/mk/defs.mk
DIRS=	blake2 picosat linenoise sqlite libucl liblua yxml libder libecc
-
@if libmachista
-
DIRS+=	libmachista
-
@endif
@if libelf-internal
DIRS+=	libelf
@endif
deleted external/libmachista/LICENSE
@@ -1,52 +0,0 @@
-
Copyright (c) 2011 Clemens Lang <cal@macports.org>
-
Copyright (c) 2011 - 2014 Landon Fuller <landonf@macports.org>
-
Copyright (c) 2004 - 2014, The MacPorts Project.
-
Copyright (c) 2002 - 2003, Apple Inc.
-
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.
-
3. Neither the name of Apple Inc., The MacPorts Project nor the
-
   names of its contributors may be used to endorse or promote products
-
   derived from this software without specific prior written permission.
-

-
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.
-

-
hashmap.c is subject to the following license:
-

-
Copyright (c) 2011 Christoph Erhardt. 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 CHRISTOPH ERHARDT ``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 CHRISTOPH ERHARDT 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.
deleted external/libmachista/Makefile.autosetup
@@ -1,8 +0,0 @@
-
include @builddir@/mk/defs.mk
-
LIB=	machista
-
SRCS=	libmachista.c \
-
	hashmap.c
-

-
VPATH=	$(top_srcdir)/external/libmachista
-

-
include $(MK)/static-lib.mk
deleted external/libmachista/hashmap.c
@@ -1,295 +0,0 @@
-
/* vim:expandtab:tw=80:ts=2:sts=2:sw=2
-
 */
-
/*-
-
 * Copyright (c) 2011 Christoph Erhardt. 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 CHRISTOPH ERHARDT ``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 CHRISTOPH ERHARDT 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.
-
 */
-
/*-
-
 * Modified by Clemens Lang to accept values of arbitrary type.
-
 */
-

-

-
#ifndef _BSD_SOURCE
-
  #define _BSD_SOURCE
-
#endif
-
#ifndef _CRT_NONSTDC_NO_DEPRECATE
-
  #define _CRT_NONSTDC_NO_DEPRECATE
-
#endif
-

-
#include "hashmap.h"
-
#include <limits.h>
-
#include <stdint.h>
-
#include <string.h>
-

-

-
static const size_t INITIAL_CAPACITY = 16; /* Must be a power of 2 */
-
static const size_t MAXIMUM_CAPACITY = (1U << 31);
-
static const float  LOAD_FACTOR      = 0.75;
-

-

-
typedef struct HashMapEntry {
-
  char                *key;
-
  const void          *value;
-
  struct HashMapEntry *next;
-
  uint32_t             hash;
-
} HashMapEntry;
-

-
struct HashMap {
-
  HashMapEntry **table;
-
  size_t         capacity;
-
  size_t         size;
-
  size_t         threshold;
-
  void         (*freeFunc)(const void *);
-
};
-

-

-
static void setTable(HashMap *map, HashMapEntry **table, size_t capacity) {
-
  map->table     = table;
-
  map->capacity  = capacity;
-
  map->threshold = (size_t) (capacity * LOAD_FACTOR);
-
}
-

-

-
static uint32_t doHash(const char key[]) {
-
  size_t   length;
-
  size_t   i;
-
  uint32_t h = 0;
-
  if (key == NULL)
-
    return 0;
-
  length = strlen(key);
-
  for (i = 0; i < length; ++i) {
-
    h = (31 * h) + key[i];
-
  }
-
  h ^= (h >> 20) ^ (h >> 12);
-
  return h ^ (h >> 7) ^ (h >> 4);
-
}
-

-

-
static size_t indexFor(uint32_t hash, size_t length) {
-
  return hash & (length - 1);
-
}
-

-

-
static int isHit(HashMapEntry *e, const char key[], uint32_t hash) {
-
  return (e->hash == hash
-
          && (e->key == key || (key != NULL && strcmp(e->key, key) == 0)));
-
}
-

-

-
static void copyOrFree(void (*freeFunc)(const void *),
-
                       const void *value, const void **valPtr) {
-
  if (valPtr != NULL)
-
    *valPtr = value;
-
  else
-
    freeFunc(value);
-
}
-

-

-
static int updateValue(HashMap *map, HashMapEntry *e, const void *newVal,
-
                       const void **oldValPtr) {
-
  copyOrFree(map->freeFunc, e->value, oldValPtr);
-
  e->value = newVal;
-
  return 1;
-
}
-

-

-
/* Creates a hash map. */
-
HashMap *hashMapCreate(void (*freeFunc)(const void *)) {
-
  HashMapEntry **table;
-
  HashMap       *map = malloc(sizeof(*map));
-
  if (map == NULL)
-
    return NULL;
-
  table = calloc(INITIAL_CAPACITY, sizeof(*map->table));
-
  if (table == NULL) {
-
    free(map);
-
    return NULL;
-
  }
-
  setTable(map, table, INITIAL_CAPACITY);
-
  map->size = 0;
-
  map->freeFunc = freeFunc;
-
  return map;
-
}
-

-

-
/* Inserts a key-value pair into a hash map. */
-
int hashMapPut(HashMap *map, const char key[], const void * const value,
-
               const void **oldValPtr) {
-

-
  HashMapEntry  *e;
-
  size_t         newCapacity;
-
  HashMapEntry **newTable;
-
  size_t         i;
-

-
  /* If an entry with the same key exists, update it */
-
  uint32_t hash  = doHash(key);
-
  size_t   index = indexFor(hash, map->capacity);
-
  for (e = map->table[index]; e != NULL; e = e->next) {
-
    if (isHit(e, key, hash) == 0)
-
      continue;
-
    return updateValue(map, e, value, oldValPtr);
-
  }
-

-
  /* Create a new entry */
-
  e = calloc(1, sizeof(HashMapEntry)); /* Must be zeroed */
-
  if (e == NULL)
-
    return 0;
-

-
  /* Copy key and value into the entry */
-
  if (key != NULL) {
-
    e->key = strdup(key);
-
    if (e->key == NULL) {
-
      free(e);
-
      return 0;
-
    }
-
  }
-
  if (updateValue(map, e, value, oldValPtr) == 0) {
-
    free(e->key);
-
    free(e);
-
    return 0;
-
  }
-

-
  /* Insert entry into the table */
-
  e->hash = hash;
-
  e->next = map->table[index];
-
  map->table[index] = e;
-
  if (map->size++ < map->threshold)
-
    return 1;
-

-
  /* If the size exceeds the threshold, double the table's capacity */
-
  newCapacity = 2 * map->capacity;
-
  if (map->capacity == MAXIMUM_CAPACITY) {
-
    map->threshold = UINT_MAX;
-
    return 1;
-
  }
-
  newTable = calloc(newCapacity, sizeof(*newTable));
-
  if (newTable == NULL)
-
    return 0;
-

-
  /* Copy entries from the old table into the new one */
-
  for (i = 0; i < map->capacity; ++i) {
-
    HashMapEntry *next;
-
    for (e = map->table[i]; e != NULL; e = next) {
-
      index   = indexFor(e->hash, newCapacity);
-
      next    = e->next;
-
      e->next = newTable[index];
-
      newTable[index] = e;
-
    }
-
  }
-

-
  /* Release the old table and set the new one */
-
  free(map->table);
-
  setTable(map, newTable, newCapacity);
-
  return 1;
-
}
-

-

-
/* Performs a hash map lookup. */
-
const void *hashMapGet(HashMap *map, const char key[]) {
-
  HashMapEntry *e;
-
  uint32_t      hash  = doHash(key);
-
  size_t        index = indexFor(hash, map->capacity);
-
  for (e = map->table[index]; e != NULL; e = e->next) {
-
    if (isHit(e, key, hash))
-
      return e->value;
-
  }
-
  return NULL;
-
}
-

-

-
/* Checks whether a hash map contains an entry with a certain key. */
-
int hashMapContainsKey(HashMap *map, const char key[]) {
-
  HashMapEntry *e;
-
  uint32_t      hash  = doHash(key);
-
  size_t        index = indexFor(hash, map->capacity);
-
  for (e = map->table[index]; e != NULL; e = e->next) {
-
    if (isHit(e, key, hash))
-
      return 1;
-
  }
-
  return 0;
-
}
-

-

-
/* Removes a key-value pair from a hash map. */
-
void hashMapRemove(HashMap *map, const char key[], const void **valPtr) {
-
  uint32_t      hash  = doHash(key);
-
  size_t        index = indexFor(hash, map->capacity);
-
  HashMapEntry *prev  = map->table[index];
-
  HashMapEntry *e     = prev;
-
  while (e != NULL) {
-
    HashMapEntry *next = e->next;
-
    if (isHit(e, key, hash)) {
-
      map->size--;
-
      if (prev == e)
-
        map->table[index] = next;
-
      else
-
        prev->next = next;
-
      break;
-
    }
-
    prev = e;
-
    e    = next;
-
  }
-
  if (e == NULL) {
-
    copyOrFree(map->freeFunc, NULL, valPtr);
-
    return;
-
  }
-
  free(e->key);
-
  copyOrFree(map->freeFunc, e->value, valPtr);
-
  free(e);
-
}
-

-

-
/* Returns the number of elements stored in a hash map. */
-
size_t hashMapSize(const HashMap *map) {
-
  return map->size;
-
}
-

-

-
/* Checks whether a hash map is empty. */
-
int hashMapIsEmpty(const HashMap *map) {
-
  return (map->size == 0);
-
}
-

-

-
/* Removes all entries from a hash map. */
-
void hashMapClear(HashMap *map) {
-
  size_t i;
-
  for (i = 0; i < map->capacity; ++i) {
-
    HashMapEntry *e;
-
    HashMapEntry *next;
-
    for (e = map->table[i]; e != NULL; e = next) {
-
      free(e->key);
-
      map->freeFunc(e->value);
-
      next = e->next;
-
      free(e);
-
    }
-
    map->table[i] = NULL;
-
  }
-
}
-

-

-
/* Destroys a hash map. */
-
void hashMapDestroy(HashMap *map) {
-
  if (map == NULL)
-
    return;
-
  hashMapClear(map);
-
  free(map->table);
-
  free(map);
-
}
deleted external/libmachista/hashmap.h
@@ -1,135 +0,0 @@
-
/* vim:tw=80:expandtab
-
 */
-
/**
-
 * @file  hashmap.h
-
 * @brief A hash map implementation in C.
-
 * @author Christoph Erhardt <erhardt@cs.fau.de>
-
 */
-

-
/*-
-
 * Copyright (c) 2011 Christoph Erhardt. 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 CHRISTOPH ERHARDT ``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 CHRISTOPH ERHARDT 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.
-
 */
-
/*-
-
 * Modified by Clemens Lang to accept values of arbitrary type.
-
 */
-

-

-
#ifndef HASHMAP_H
-
#define HASHMAP_H
-

-

-
#include <stdlib.h>
-

-

-
/** Hash map type. */
-
typedef struct HashMap HashMap;
-

-

-
/**
-
 * @brief Creates a hash map.
-
 *
-
 * The keys and values managed in the map can be arbitrary C strings.
-
 * @param freeFunc Function to call in order to free a stored value
-
 * @return Pointer to the newly created hash map, or @c NULL on error.
-
 */
-
HashMap *hashMapCreate(void (*freeFunc)(const void *));
-

-
/**
-
 * @brief Inserts a key-value pair into a hash map.
-
 *
-
 * Both key and value are copied internally, so the caller can reuse the
-
 * original variables.
-
 * If oldValPtr is @c NULL, the previously stored value corresponding to the key
-
 * is freed. Otherwise it is written into @c *valPtr and the caller is
-
 * responsible for freeing it.
-
 * @param map       Hash map.
-
 * @param key       Key.
-
 * @param value     Value.
-
 * @param oldValPtr Output parameter receiving the previously stored value
-
 *                  corresponding to the key (@c NULL if no mapping existed
-
 *                  before).
-
 * @return Nonzero on success, 0 on error.
-
 */
-
int hashMapPut(HashMap *map, const char key[], const void * const value,
-
               const void **oldValPtr);
-

-
/**
-
 * @brief Performs a hash map lookup.
-
 *
-
 * The returned value must not be freed or otherwise manipulated by the caller.
-
 * @param map Hash map.
-
 * @param key Key.
-
 * @return Value corresponding to the key on success, @c NULL if no matching
-
 *         entry was found.
-
 */
-
const void *hashMapGet(HashMap *map, const char key[]);
-

-
/**
-
 * @brief Checks whether a hash map contains an entry with a certain key.
-
 * @param map Hash map.
-
 * @param key Key.
-
 * @return Nonzero if the map contains an entry with the given key, 0 if it does
-
 *         not.
-
 */
-
int hashMapContainsKey(HashMap *map, const char key[]);
-

-
/**
-
 * @brief Removes a key-value pair from a hash map and frees the stored key.
-
 *
-
 * If @c valPtr is @c NULL, the internally stored value corresponding to the key
-
 * is freed. Otherwise it is written into @c *valPtr and the caller is
-
 * responsible for freeing it.
-
 * @param map    Hash map.
-
 * @param key    Key.
-
 * @param valPtr Output parameter receiving the internally stored value
-
 *               corresponding to the key.
-
 */
-
void hashMapRemove(HashMap *map, const char key[], const void **valPtr);
-

-
/**
-
 * @brief Returns the number of elements stored in a hash map.
-
 * @param map Hash map.
-
 * @return Number of elements stored in the map.
-
 */
-
size_t hashMapSize(const HashMap *map);
-

-
/**
-
 * @brief Checks whether a hash map is empty.
-
 * @param map Hash map.
-
 * @return Nonzero if the map contains no entries, 0 otherwise.
-
 */
-
int hashMapIsEmpty(const HashMap *map);
-

-
/**
-
 * @brief Removes all entries from a hash map.
-
 * @param map Hash map.
-
 */
-
void hashMapClear(HashMap *map);
-

-
/**
-
 * @brief Destroys a hash map.
-
 * @param map Hash map to be destroyed.
-
 */
-
void hashMapDestroy(HashMap *map);
-

-

-
#endif /* HASHMAP_H */
deleted external/libmachista/libmachista.c
@@ -1,569 +0,0 @@
-
/*
-
 * -*- 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: libmachista.c 120067 2014-05-14 22:18:53Z cal@macports.org $
-
 *
-
 * Copyright (c) 2011 The MacPorts Project
-
 * Copyright (c) 2011 Landon Fuller <landonf@macports.org>
-
 * Copyright (c) 2011 Clemens Lang <cal@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.
-
 */
-

-
#ifdef HAVE_CONFIG_H
-
#include <pkg_config.h>
-
#endif
-

-
/* required for asprintf(3) on OS X */
-
#define _DARWIN_C_SOURCE
-
/* required for asprintf(3) on Linux */
-
#define _GNU_SOURCE
-

-
#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 <strings.h>
-

-
#ifdef __MACH__
-
#include <mach-o/fat.h>
-
#include <mach-o/loader.h>
-

-
#include <libkern/OSAtomic.h>
-
#endif
-

-
#include "libmachista.h"
-
#include "hashmap.h"
-

-
#ifdef __MACH__
-
/* Tiger compatibility */
-
#ifndef LC_RPATH
-
#define LC_RPATH       (0x1c | LC_REQ_DYLD)    /* runpath additions */
-
/*
-
 * The rpath_command contains a path which at runtime should be added to
-
 * the current run path used to find @rpath prefixed dylibs.
-
 */
-
struct rpath_command {
-
    uint32_t     cmd;       /* LC_RPATH */
-
    uint32_t     cmdsize;   /* includes string */
-
    union lc_str path;      /* path to add to run path */
-
};
-
#endif
-
#ifndef LC_REEXPORT_DYLIB
-
#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */
-
#endif
-
#endif /* __MACH__ */
-

-
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 {
-
    HashMap *result_map;
-
};
-

-
#ifdef __MACH__
-
/* 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);
-
}
-
#endif
-

-
/* 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) & 0xFFFF, (version >> 8) & 0xFF, version & 0xFF);
-
    return result;
-
}
-

-
#ifdef __MACH__
-
const char *macho_get_arch_name (cpu_type_t cputype) {
-
    const NXArchInfo *archInfo = NXGetArchInfoFromCpuType(cputype, CPU_SUBTYPE_MULTIPLE);	
-
    if (!archInfo) {
-
        return NULL;
-
    }
-
    return archInfo->name;
-
#else
-
const char *macho_get_arch_name (cpu_type_t cputype UNUSED) {
-
    return NULL;
-
#endif
-
}
-

-
#ifdef __MACH__
-
/* 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;
-
}
-
#endif
-

-
/* 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);
-
}
-

-
#ifdef __MACH__
-
/* 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;
-
}
-
#endif
-

-
/* Parse a Mach-O header */
-
#ifdef __MACH__
-
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_cputype = swap32(header->cputype);
-
            mat->mat_cpusubtype = swap32(header->cpusubtype);
-
            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_cputype = swap32(header->cputype);
-
            mat->mat_cpusubtype = swap32(header->cpusubtype);
-
            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_cputype = swap32(header->cputype);
-
    mat->mat_cpusubtype = swap32(header->cpusubtype);
-

-
    /* Parse the Mach-O load commands */
-
    uint32_t ncmds = swap32(header->ncmds);
-

-
    /* Setup to jump over the header on the first pass through instead of the previous command */
-
    const struct load_command *cmd = (void *)header;
-
    uint32_t cmdsize = header_size;
-

-
    /* Iterate over the load commands */
-
    for (uint32_t i = 0; i < ncmds; i++) {
-
        /* Load the next command */
-
        cmd = macho_offset(input, cmd, cmdsize, sizeof(struct load_command));
-
        if (cmd == NULL)
-
            return MACHO_ERANGE;
-

-
        /* Load the full command */
-
        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;
-
        }
-
    }
-

-
    return MACHO_SUCCESS;
-
}
-
#endif
-

-
/* Parse a (possible Mach-O) file. For a more detailed description, see the header */
-
#ifdef __MACH__
-
int macho_parse_file(macho_handle_t *handle, const char *filepath, const macho_t **res) {
-
    int fd;
-
    struct stat st;
-
    void *data;
-
    macho_input_t input_file;
-

-
    /* Check hashmap for precomputed results */
-
    const macho_t *cached_res = hashMapGet(handle->result_map, filepath);
-
    if (cached_res != NULL) {
-
        *res = cached_res;
-
        return MACHO_SUCCESS;
-
    }
-

-
    
-
    /* 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;
-

-
    /* The output parameter *res should be read-only for the user of the lib only, but writable for
-
     * us */
-
    int ret = parse_macho((macho_t *)*res, &input_file);
-
    if (ret == MACHO_SUCCESS) {
-
        /* Insert into hashmap for caching */
-
        if (0 == hashMapPut(handle->result_map, filepath, *res, NULL)) {
-
            free_macho_t((macho_t *)*res);
-
            *res = NULL;
-
            ret = MACHO_EMEM;
-
        }
-
    } else {
-
        /* An error occured, free mt */
-
        free_macho_t((macho_t *)*res);
-
        *res = NULL;
-
    }
-

-
    /* Cleanup */
-
    munmap(data, st.st_size);
-
    close(fd);
-

-
    return ret;
-
#else
-
int macho_parse_file(macho_handle_t *handle UNUSED, const char *filepath UNUSED, const macho_t **res UNUSED) {
-
    return 0;
-
#endif
-
}
-

-
/* 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;
-
    mht->result_map = hashMapCreate((void (*)(const void *))free_macho_t);
-
    if (mht->result_map == NULL) {
-
        free(mht);
-
        return NULL;
-
    }
-
    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;
-
    
-
    hashMapDestroy(handle->result_map);
-

-
    free(handle);
-
}
-

-
/* Returns string representation of the MACHO_* error code constants */
-
const char *macho_strerror(int err) {
-
    int num;
-
#ifdef HAVE_FLS
-
    num = fls(err);
-
#else
-
    /* Tiger compatibility, see #42186 */
-
    num = 0;
-
    while (err > 0) {
-
        err >>= 1;
-
        num++;
-
    }
-
#endif
-

-
    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];
-
}
-

deleted external/libmachista/libmachista.h
@@ -1,150 +0,0 @@
-
/*
-
 * -*- 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 <cal@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.
-
 */
-

-
#ifndef __LIBMACHISTA_H__
-
#define __LIBMACHISTA_H__
-

-
/*
-
 * This is a library to parse Mach-O files in single architecture _and_ universal variant and return
-
 * a list of architectures and their load commands and properties
-
 * The name a pun: machista is the spanish translation of "macho".
-
 */
-

-
#ifdef __MACH__
-
#include <mach-o/arch.h>
-
#else
-
typedef int cpu_type_t;
-
#endif
-
#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_cputype;         /* cpu_type_t describing the CPU this part of the binary is
-
                                       intended for */
-
    cpu_type_t mat_cpusubtype;      /* cpu_subtype_t describing the CPU subtype 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);
-

-
/**
-
 * Returns a readable version of any cpu_type_t constant. Returns a valid pointer to the first
-
 * character in a 0-terminated string or NULL on error. The pointer must not be free()'d after use.
-
 */
-
const char *macho_get_arch_name(cpu_type_t cputype);
-

-
/**
-
 * 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. *res should also never be modified or otherwise
-
 * free()'d.
-
 */
-
int macho_parse_file(macho_handle_t *handle, const char *filepath, const macho_t **res);
-

-
/**
-
 * Returns a string representation of the MACHO_* error code constants
-
 */
-
const char *macho_strerror(int err);
-

-
#endif
-

modified libpkg/Makefile.autosetup
@@ -32,6 +32,8 @@ SRCS= backup_lib.c \
	pkg_jobs_conflicts.c pkg_ports.c \
	pkg_solve.c \
	pkgdb.c \
+
	pkg_elf.c \
+
	binfmt_macho.c \
	ssh.c elfhints.c \
	pkg_arch.c \
	pkg_cudf.c \
@@ -117,22 +119,14 @@ LOCAL_LDFLAGS+= -lfts
@if HAVE_LIBDL
LOCAL_LDFLAGS+= -ldl
@endif
-
@if HAVE_LIBRESOLV
-
LOCAL_LDFLAGS+= -lresolv
-
@endif

-
@if libmachista
-
LOCAL_CFLAGS+= -I$(top_srcdir)/external/libmachista
-
STATIC_LIBS+=	$(top_builddir)/external/libmachista/libmachista.a
-
LOCAL_LDFLAGS+=	-L$(top_builddir)/external/libmachista -lmachista_pic \
-
		-larchive -lresolv
-
SRCS+=		pkg_macho.c
-
@else
-
SRCS+=		pkg_elf.c
-
@if pkg_freebsd
+
@if pkgos_darwin
+
LOCAL_LDFLAGS+=	-lresolv
+
@else 
+
@if pkgos_freebsd
LOCAL_LDFLAGS+=	-Wl,--version-script=$(top_srcdir)/libpkg/libpkg.ver,--undefined-version 
@else
-
# --undefined-version is a FreeBSD ld option
+
### --undefined-version is a FreeBSD ld option
LOCAL_LDFLAGS+=	-Wl,--version-script=$(top_srcdir)/libpkg/libpkg.ver
@endif
@endif
@@ -185,7 +179,7 @@ all: lib$(LIB)_flat.a

lib$(LIB)$(LIBSOEXT): $(STATIC_LIBS)

-
@if libmachista
+
@if pkgos_darwin
lib$(LIB)_flat.a: $(STATIC_LIBS)
	libtool -static -o lib$(LIB)_flat.a $(STATIC_LIBS)
@else
added libpkg/binfmt_macho.c
@@ -0,0 +1,665 @@
+
/*-
+
 * Copyright (c) 2024 Keve Müller <kevemueller@users.github.com>
+
 *
+
 * 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
+
 *    in this position and unchanged.
+
 * 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 AUTHOR(S) ``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 AUTHOR(S) 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 <endian_util.h>
+
#include <errno.h>
+
#include <fcntl.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+
#include <unistd.h>
+

+
#include "private/binfmt_macho.h"
+

+
/**
+
 * Minimal Mach-O binary file parser for both FAT as well as plain binaries with
+
 * sufficient functionality to handle architecture, OS, file type, library
+
 * dependencies.
+
 * As well as utility functions to convert data into different formats.
+
 */
+

+
/**** Readers ****/
+

+
static ssize_t
+
read_fully(const int fd, const size_t len, void *dest)
+
{
+
	unsigned char *p = dest;
+
	size_t n = len;
+
	ssize_t x;
+
	while (n > 0) {
+
		if ((x = read(fd, p, n)) < 0) {
+
			return x;
+
		}
+
		n -= x;
+
		p += x;
+
	}
+
	return len;
+
}
+

+
ssize_t
+
read_u32(const int fd, const bool swap, uint32_t *dest)
+
{
+
	unsigned char buf[4];
+
	ssize_t x;
+
	if ((x = read_fully(fd, sizeof(buf), buf)) < 0) {
+
		return x;
+
	}
+
	if (swap) {
+
		*dest = le32dec(buf);
+
	} else {
+
		*dest = be32dec(buf);
+
	}
+
	return x;
+
}
+

+
static ssize_t
+
read_u64(const int fd, const bool swap, uint64_t *dest)
+
{
+
	unsigned char buf[8];
+
	ssize_t x;
+
	if ((x = read_fully(fd, sizeof(buf), buf)) < 0) {
+
		return x;
+
	}
+
	if (swap) {
+
		*dest = le64dec(buf);
+
	} else {
+
		*dest = be64dec(buf);
+
	}
+
	return x;
+
}
+

+
static ssize_t
+
read_cpu_type(const int fd, const bool swap, cpu_type_subtype_t *dest)
+
{
+
	ssize_t n = 0, x;
+
	uint32_t cputype;
+
	uint32_t cpusubtype;
+

+
	READ(u32, cputype);
+
	READ(u32, cpusubtype);
+
	dest->type = cputype & ~CPU_ARCH_MASK;
+
	dest->type_is64 = (cputype & CPU_ARCH_MASK) == CPU_ARCH_ABI64;
+
	dest->type_is64_32 = (cputype & CPU_ARCH_MASK) == CPU_ARCH_ABI64_32;
+
	dest->subtype_islib64 = (cpusubtype & CPU_SUBTYPE_MASK) ==
+
	    CPU_SUBTYPE_LIB64;
+
	switch (dest->type) {
+
	case CPU_TYPE_ARM:
+
		dest->subtype_arm = cpusubtype & ~CPU_SUBTYPE_MASK;
+
		break;
+
	case CPU_TYPE_X86:
+
		dest->subtype_x86 = cpusubtype & ~CPU_SUBTYPE_MASK;
+
		break;
+
	case CPU_TYPE_POWERPC:
+
		dest->subtype_ppc = cpusubtype & ~CPU_SUBTYPE_MASK;
+
		break;
+
	default:
+
		errno = EINVAL;
+
		return -1;
+
	}
+
	return n;
+
}
+

+
static ssize_t
+
read_fat_arch(const int fd, const uint32_t magic, fat_arch_t *dest)
+
{
+
	ssize_t n = 0, x;
+
	const bool swap = magic == FAT_CIGAM || magic == FAT_CIGAM_64;
+

+
	READ(cpu_type, dest->cpu);
+
	uint32_t align;
+
	uint32_t reserved;
+

+
	switch (magic) {
+
	case FAT_MAGIC:
+
	case FAT_CIGAM:;
+
		uint32_t offset32;
+
		uint32_t size32;
+
		READ(u32, offset32);
+
		READ(u32, size32);
+
		READ(u32, align); // bits
+

+
		dest->offset = offset32;
+
		dest->size = size32;
+
		dest->align = align;
+
		break;
+
	case FAT_MAGIC_64:
+
	case FAT_CIGAM_64:
+
		READ(u64, dest->offset);
+
		READ(u64, dest->size);
+
		READ(u32, align);
+
		READ(u32, reserved);
+
		dest->align = align;
+
		break;
+
	default:
+
		errno = EINVAL;
+
		return -1;
+
	}
+
	return n;
+
}
+

+
static ssize_t
+
read_version(const int fd, const bool swap, macho_version_t *dest)
+
{
+
	ssize_t n = 0, x;
+

+
	uint32_t version;
+
	READ(u32, version);
+
	dest->major = (version >> 16) & 0xffff;
+
	dest->minor = (version >> 8) & 0xff;
+
	dest->patch = version & 0xff;
+
	return n;
+
}
+

+
ssize_t
+
read_min_version(const int fd, const bool swap, const uint32_t loadcmd,
+
    build_version_t **dest)
+
{
+
	ssize_t n = 0, x;
+

+
	*dest = malloc(sizeof(build_version_t));
+
	(*dest)->ntools = 0;
+
	switch (loadcmd) {
+
	case LC_VERSION_MIN_IPHONEOS:
+
		(*dest)->platform = PLATFORM_IOS;
+
		break;
+
	case LC_VERSION_MIN_MACOSX:
+
		(*dest)->platform = PLATFORM_MACOS;
+
		break;
+
	case LC_VERSION_MIN_TVOS:
+
		(*dest)->platform = PLATFORM_TVOS;
+
		break;
+
	case LC_VERSION_MIN_WATCHOS:
+
		(*dest)->platform = PLATFORM_WATCHOS;
+
		break;
+
	default:
+
		return -1;
+
	}
+
	READ(version, (*dest)->minos);
+
	READ(version, (*dest)->sdk);
+
	return n;
+
}
+

+
static ssize_t
+
read_path(const int fd, const bool swap, const uint32_t loadcmdsize,
+
    char **dest)
+
{
+
	ssize_t n = 0, x;
+

+
	uint32_t name_ofs;
+
	READ(u32, name_ofs);
+
	if (-1 == (x = lseek(fd, name_ofs - 12, SEEK_CUR))) {
+
		return x;
+
	}
+
	n += name_ofs - 12;
+
	*dest = malloc(loadcmdsize - name_ofs + 1);
+
	if ((x = read_fully(fd, loadcmdsize - name_ofs, *dest)) < 0) {
+
		free(*dest);
+
		*dest = 0;
+
		return x;
+
	}
+
	n += x;
+
	(*dest)[loadcmdsize - name_ofs] = '\0';
+
	return n;
+
}
+

+
static ssize_t
+
read_dylib(const int fd, const bool swap, const uint32_t loadcmdsize,
+
    dylib_t **dest)
+
{
+
	ssize_t n = 0, x;
+

+
	uint32_t name_ofs;
+
	uint32_t timestamp;
+
	macho_version_t current_version;
+
	macho_version_t compatibility_version;
+

+
	READ(u32, name_ofs);
+
	READ(u32, timestamp);
+
	READ(version, current_version);
+
	READ(version, compatibility_version);
+

+
	if (-1 == (x = lseek(fd, name_ofs - 24, SEEK_CUR))) {
+
		return x;
+
	}
+
	n += name_ofs - 24;
+

+
	*dest = malloc(sizeof(dylib_t) + loadcmdsize - name_ofs + 1);
+
	(*dest)->timestamp = timestamp;
+
	(*dest)->current_version = current_version;
+
	(*dest)->compatibility_version = compatibility_version;
+
	if ((x = read_fully(fd, loadcmdsize - name_ofs, (*dest)->path)) < 0) {
+
		free(*dest);
+
		*dest = 0;
+
		return x;
+
	}
+
	n += x;
+
	(*dest)->path[loadcmdsize - name_ofs] = '\0';
+
	return n;
+
}
+

+
ssize_t
+
read_build_version(const int fd, const bool swap, build_version_t **dest)
+
{
+
	ssize_t n = 0, x;
+

+
	uint32_t platform;
+
	macho_version_t minos;
+
	macho_version_t sdk;
+
	uint32_t ntools;
+

+
	READ(u32, platform);
+
	READ(version, minos);
+
	READ(version, sdk);
+
	READ(u32, ntools);
+

+
	*dest = malloc(
+
	    sizeof(build_version_t) + ntools * sizeof(tool_version_t));
+
	(*dest)->platform = platform;
+
	(*dest)->minos = minos;
+
	(*dest)->sdk = sdk;
+
	(*dest)->ntools = ntools;
+
	tool_version_t *p = (*dest)->tools;
+

+
	for (; ntools-- > 0; p++) {
+
		uint32_t tool;
+
		READ(u32, tool);
+
		p->tool = tool;
+
		READ(version, p->version);
+
	}
+
	return n;
+
}
+

+
ssize_t
+
read_macho_header(const int fd, macho_header_t *dest)
+
{
+
	ssize_t n = 0, x;
+
	uint32_t reserved;
+

+
	if ((x = read_u32(fd, false, &dest->magic) < 0)) {
+
		return x;
+
	}
+
	n += x;
+

+
	const bool swap = dest->swap = dest->magic == MH_CIGAM ||
+
	    dest->magic == MH_CIGAM_64;
+

+
	READ(cpu_type, dest->cpu);
+
	READ(u32, dest->filetype);
+
	READ(u32, dest->ncmds);
+
	READ(u32, dest->sizeofcmds);
+
	READ(u32, dest->flags);
+
	switch (dest->magic) {
+
	case MH_MAGIC_64:
+
	case MH_CIGAM_64:
+
		READ(u32, reserved);
+
		break;
+
	default:
+
		break;
+
	}
+
	return n;
+
}
+

+
ssize_t
+
read_macho_file(const int fd, macho_file_t **dest)
+
{
+
	ssize_t n = 0, x;
+

+
	uint32_t magic;
+
	if ((x = read_u32(fd, false, &magic)) < 0) {
+
		return x;
+
	}
+
	n += x;
+

+
	const bool swap = magic == FAT_CIGAM || magic == FAT_CIGAM_64 ||
+
	    magic == MH_CIGAM || magic == MH_CIGAM_64;
+

+
	uint32_t nfat_arch;
+
	fat_arch_t *p;
+
	switch (magic) {
+
	case FAT_MAGIC:
+
	case FAT_MAGIC_64:
+
	case FAT_CIGAM:
+
	case FAT_CIGAM_64:
+
		READ(u32, nfat_arch);
+
		*dest = malloc(
+
		    sizeof(macho_file_t) + nfat_arch * sizeof(fat_arch_t));
+
		(*dest)->magic = magic;
+
		(*dest)->narch = nfat_arch;
+
		p = (*dest)->arch;
+

+
		while (nfat_arch-- > 0) {
+
			if ((x = read_fat_arch(fd, magic, p)) < 0) {
+
				free(*dest);
+
				*dest = 0;
+
				return x;
+
			}
+
			n += x;
+
			p++;
+
		}
+
		break;
+

+
	case MH_MAGIC:
+
	case MH_MAGIC_64:
+
	case MH_CIGAM:
+
	case MH_CIGAM_64:
+
		nfat_arch = 1;
+
		*dest = malloc(
+
		    sizeof(macho_file_t) + nfat_arch * sizeof(fat_arch_t));
+
		(*dest)->magic = magic;
+
		(*dest)->narch = nfat_arch;
+
		p = (*dest)->arch;
+
		READ(cpu_type, p->cpu);
+
		off_t xo;
+
		if (-1 == (xo = lseek(fd, 0, SEEK_END))) {
+
			free(*dest);
+
			*dest = 0;
+
			return xo;
+
		}
+
		p->offset = 0;
+
		p->size = xo;
+
		p->align = 0; // number of trailing zero bits in size;
+
		n = xo;
+
		break;
+
	default:
+
		errno = EINVAL;
+
		return -1;
+
	}
+
	return n;
+
}
+

+
/**** OS -> Kernel conversion ****/
+

+
static macho_version_t macos_to_darwin[][2] = {
+
	// macOS Sequoia
+
	{ { 15, 2, 0 }, { 24, 2, 0 } },
+
	{ { 15, 1, 0 }, { 24, 1, 0 } },
+
	{ { 15, 0, 0 }, { 24, 0, 0 } },
+
	// macOS Sonoma
+
	{ { 14, 6, 0 }, { 23, 6, 0 } },
+
	{ { 14, 5, 0 }, { 23, 4, 0 } },
+
	{ { 14, 4, 0 }, { 23, 5, 0 } },
+
	{ { 14, 3, 0 }, { 23, 3, 0 } },
+
	{ { 14, 2, 0 }, { 23, 2, 0 } },
+
	{ { 14, 1, 0 }, { 23, 1, 0 } },
+
	{ { 14, 0, 0 }, { 23, 0, 0 } },
+
	// macOS Ventura
+
	{ { 13, 5, 0 }, { 22, 6, 0 } },
+
	{ { 13, 4, 0 }, { 22, 5, 0 } },
+
	{ { 13, 3, 0 }, { 22, 4, 0 } },
+
	{ { 13, 2, 0 }, { 22, 3, 0 } },
+
	{ { 13, 1, 0 }, { 22, 2, 0 } },
+
	{ { 13, 0, 0 }, { 22, 1, 0 } },
+
	// macOS Monterey
+
	{ { 12, 5, 0 }, { 21, 6, 0 } },
+
	{ { 12, 4, 0 }, { 21, 5, 0 } },
+
	{ { 12, 3, 0 }, { 21, 4, 0 } },
+
	{ { 12, 2, 0 }, { 21, 3, 0 } },
+
	{ { 12, 1, 0 }, { 21, 2, 0 } },
+
	{ { 12, 0, 1 }, { 21, 1, 0 } },
+
	{ { 12, 0, 0 }, { 21, 0, 1 } },
+
	// macOS Big Sur
+
	{ { 11, 5, 0 }, { 20, 6, 0 } },
+
	{ { 11, 4, 0 }, { 20, 5, 0 } },
+
	{ { 11, 3, 0 }, { 20, 4, 0 } },
+
	{ { 11, 2, 0 }, { 20, 3, 0 } },
+
	{ { 11, 1, 0 }, { 20, 2, 0 } },
+
	{ { 11, 0, 0 }, { 20, 1, 0 } },
+
	// macOS Catalina
+
	{ { 10, 15, 6 }, { 19, 6, 0 } },
+
	{ { 10, 15, 5 }, { 19, 5, 0 } },
+
	{ { 10, 15, 4 }, { 19, 4, 0 } },
+
	{ { 10, 15, 3 }, { 19, 3, 0 } },
+
	{ { 10, 15, 2 }, { 19, 2, 0 } },
+
	{ { 10, 15, 0 }, { 19, 0, 0 } },
+
	// macOS Mojave
+
	{ { 10, 14, 6 }, { 18, 7, 0 } },
+
	{ { 10, 14, 5 }, { 18, 6, 0 } },
+
	{ { 10, 14, 4 }, { 18, 5, 0 } },
+
	{ { 10, 14, 1 }, { 18, 2, 0 } },
+
	{ { 10, 14, 0 }, { 18, 0, 0 } },
+
	// macOS High Sierra
+
	{ { 10, 13, 6 }, { 17, 7, 0 } },
+
	{ { 10, 13, 5 }, { 17, 6, 0 } },
+
	{ { 10, 13, 4 }, { 17, 5, 0 } },
+
	{ { 10, 13, 3 }, { 17, 4, 0 } },
+
	{ { 10, 13, 2 }, { 17, 3, 0 } },
+
	{ { 10, 13, 1 }, { 17, 2, 0 } },
+
	{ { 10, 13, 0 }, { 17, 0, 0 } },
+
	// macOS Sierra
+
	{ { 10, 12, 6 }, { 16, 7, 0 } },
+
	{ { 10, 12, 5 }, { 16, 6, 0 } },
+
	{ { 10, 12, 4 }, { 16, 5, 0 } },
+
	{ { 10, 12, 3 }, { 16, 4, 0 } },
+
	{ { 10, 12, 2 }, { 16, 3, 0 } },
+
	{ { 10, 12, 1 }, { 16, 1, 0 } },
+
	{ { 10, 12, 0 }, { 16, 0, 0 } },
+
	// OS X El Capitan
+
	{ { 10, 11, 6 }, { 15, 6, 0 } },
+
	{ { 10, 11, 5 }, { 15, 5, 0 } },
+
	{ { 10, 11, 4 }, { 15, 4, 0 } },
+
	{ { 10, 11, 3 }, { 15, 3, 0 } },
+
	{ { 10, 11, 2 }, { 15, 2, 0 } },
+
	{ { 10, 11, 0 }, { 15, 0, 0 } },
+
	// OS X Yosemite
+
	{ { 10, 10, 5 }, { 14, 5, 0 } },
+
	{ { 10, 10, 4 }, { 14, 4, 0 } },
+
	{ { 10, 10, 3 }, { 14, 3, 0 } },
+
	{ { 10, 10, 2 }, { 14, 1, 0 } },
+
	{ { 10, 10, 0 }, { 14, 0, 0 } },
+
	// OS X Mavericks
+
	{ { 10, 9, 5 }, { 13, 4, 0 } },
+
	{ { 10, 9, 4 }, { 13, 3, 0 } },
+
	{ { 10, 9, 3 }, { 13, 2, 0 } },
+
	{ { 10, 9, 2 }, { 13, 1, 0 } },
+
	{ { 10, 9, 0 }, { 13, 0, 0 } },
+
	// OS X Mountain Lion
+
	{ { 10, 8, 5 }, { 12, 5, 0 } }, // Build 12F45 switched to 12.6
+
	{ { 10, 8, 4 }, { 12, 4, 0 } },
+
	{ { 10, 8, 3 }, { 12, 3, 0 } },
+
	{ { 10, 8, 2 }, { 12, 2, 0 } },
+
	{ { 10, 8, 1 }, { 12, 1, 0 } },
+
	{ { 10, 8, 0 }, { 12, 0, 0 } },
+
	// OS X Lion
+
	{ { 10, 7, 5 }, { 11, 4, 2 } },
+
	{ { 10, 7, 4 }, { 11, 4, 0 } },
+
	{ { 10, 7, 3 }, { 11, 3, 0 } },
+
	{ { 10, 7, 2 }, { 11, 2, 0 } },
+
	{ { 10, 7, 1 }, { 11, 1, 0 } },
+
	{ { 10, 7, 0 }, { 11, 0, 0 } },
+
	// Mac OS X Snow Leopard
+
	{ { 10, 6, 8 }, { 10, 8, 0 } },
+
	{ { 10, 6, 7 }, { 10, 7, 0 } },
+
	{ { 10, 6, 6 }, { 10, 6, 0 } },
+
	{ { 10, 6, 5 }, { 10, 5, 0 } },
+
	{ { 10, 6, 4 }, { 10, 4, 0 } },
+
	{ { 10, 6, 3 }, { 10, 3, 0 } },
+
	{ { 10, 6, 2 }, { 10, 2, 0 } },
+
	{ { 10, 6, 1 }, { 10, 1, 0 } },
+
	{ { 10, 6, 0 }, { 10, 0, 0 } },
+
	// Mac OS X Leopard
+
	{ { 10, 5, 8 }, { 9, 8, 0 } },
+
	{ { 10, 5, 7 }, { 9, 7, 0 } },
+
	{ { 10, 5, 6 }, { 9, 6, 0 } },
+
	{ { 10, 5, 5 }, { 9, 5, 0 } },
+
	{ { 10, 5, 4 }, { 9, 4, 0 } },
+
	{ { 10, 5, 3 }, { 9, 3, 0 } },
+
	{ { 10, 5, 2 }, { 9, 2, 0 } },
+
	{ { 10, 5, 1 }, { 9, 1, 0 } }, // Build 9B2117 switched to 9.1.1
+
	{ { 10, 5, 0 }, { 9, 0, 0 } },
+
	// Mac OS X Tiger
+
	{ { 10, 4, 11 }, { 8, 11, 0 } },
+
	{ { 10, 4, 10 }, { 8, 10, 0 } },
+
	{ { 10, 4, 9 }, { 8, 9, 0 } },
+
	{ { 10, 4, 8 }, { 8, 8, 0 } },
+
	{ { 10, 4, 7 }, { 8, 7, 0 } },
+
	{ { 10, 4, 6 }, { 8, 6, 0 } },
+
	{ { 10, 4, 5 }, { 8, 5, 0 } },
+
	{ { 10, 4, 4 }, { 8, 4, 0 } },
+
	{ { 10, 4, 3 }, { 8, 3, 0 } },
+
	{ { 10, 4, 2 }, { 8, 2, 0 } },
+
	{ { 10, 4, 1 }, { 8, 1, 0 } },
+
	{ { 10, 4, 0 }, { 8, 0, 0 } },
+
	// Mac OS X Panther
+
	{ { 10, 3, 9 }, { 7, 9, 0 } },
+
	{ { 10, 3, 8 }, { 7, 8, 0 } },
+
	{ { 10, 3, 7 }, { 7, 7, 0 } },
+
	{ { 10, 3, 6 }, { 7, 6, 0 } },
+
	{ { 10, 3, 5 }, { 7, 5, 0 } },
+
	{ { 10, 3, 4 }, { 7, 4, 0 } },
+
	{ { 10, 3, 3 }, { 7, 3, 0 } },
+
	{ { 10, 3, 2 }, { 7, 2, 0 } },
+
	{ { 10, 3, 1 }, { 7, 1, 0 } },
+
	{ { 10, 3, 0 }, { 7, 0, 0 } },
+
	// Mac OS X Jaguar
+
	{ { 10, 2, 8 }, { 6, 8, 0 } },
+
	{ { 10, 2, 7 }, { 6, 7, 0 } },
+
	{ { 10, 2, 6 }, { 6, 6, 0 } },
+
	{ { 10, 2, 5 }, { 6, 5, 0 } },
+
	{ { 10, 2, 4 }, { 6, 4, 0 } },
+
	{ { 10, 2, 3 }, { 6, 3, 0 } },
+
	{ { 10, 2, 2 }, { 6, 2, 0 } },
+
	{ { 10, 2, 1 }, { 6, 1, 0 } },
+
	{ { 10, 2, 0 }, { 6, 0, 0 } },
+
	// Mac OS X 10.1 Puma
+
	{ { 10, 1, 5 }, { 5, 5, 0 } },
+
	{ { 10, 1, 4 }, { 5, 4, 0 } },
+
	{ { 10, 1, 3 }, { 5, 3, 0 } },
+
	{ { 10, 1, 2 }, { 5, 2, 0 } },
+
	{ { 10, 1, 1 }, { 5, 1, 0 } },
+
	{ { 10, 1, 0 }, { 1, 4, 1 } },
+
	// Mac OS X 10.0 Cheetah
+
	{ { 10, 0, 1 }, { 1, 3, 1 } },
+
	{ { 10, 0, 0 }, { 1, 3, 0 } },
+
	// Mac OS X Public Beta
+
	// {{x,y,z}}, {1,2,1}},
+
	// Mac OS X Server 1.0
+
	{ { 1, 0, 2 }, { 0, 3, 0 } },
+
	{ { 1, 0, 1 }, { 0, 2, 0 } },
+
	{ { 1, 0, 0 }, { 0, 1, 0 } },
+
	// EOA
+
	{ { 0, 0, 0 }, { 0, 0, 0 } },
+
};
+

+
static macho_version_t ios_to_darwin[][2] = {
+
	// iOS 18, iPadOS 18, tvOS 18
+
	{ { 18, 0, 0 }, { 24, 0, 0 } },
+
	// iOS 17, iPadOS 17, tvOS 17
+
	{ { 17, 5, 0 }, { 23, 5, 0 } },
+
	{ { 17, 4, 0 }, { 23, 4, 0 } },
+
	{ { 17, 3, 0 }, { 23, 3, 0 } },
+
	{ { 17, 2, 0 }, { 23, 2, 0 } },
+
	{ { 17, 1, 0 }, { 23, 1, 0 } },
+
	{ { 17, 0, 0 }, { 23, 0, 0 } },
+
	// iOS 16, iPadOS 16, tvOS 16
+
	{ { 16, 6, 0 }, { 22, 6, 0 } },
+
	{ { 16, 5, 0 }, { 22, 5, 0 } },
+
	{ { 16, 4, 0 }, { 22, 4, 0 } },
+
	{ { 16, 3, 0 }, { 22, 3, 0 } },
+
	{ { 16, 2, 0 }, { 22, 2, 0 } },
+
	{ { 16, 1, 0 }, { 22, 1, 0 } },
+
	{ { 16, 0, 0 }, { 22, 0, 0 } },
+
	// iOS 15, iPadOS 15, tvOS 15
+
	{ { 15, 6, 0 }, { 21, 6, 0 } },
+
	{ { 15, 5, 0 }, { 21, 5, 0 } },
+
	{ { 15, 4, 0 }, { 21, 4, 0 } },
+
	{ { 15, 3, 0 }, { 21, 3, 0 } },
+
	{ { 15, 2, 0 }, { 21, 2, 0 } },
+
	{ { 15, 0, 0 }, { 21, 1, 0 } },
+
	// iOS 15.0 beta 1 -> 21.0.0
+
	// iOS 14, iPadOS 14, tvOS 14
+
	{ { 14, 7, 0 }, { 20, 6, 0 } },
+
	{ { 14, 6, 0 }, { 20, 5, 0 } },
+
	{ { 14, 5, 0 }, { 20, 4, 0 } },
+
	{ { 14, 4, 0 }, { 20, 3, 0 } },
+
	{ { 14, 3, 0 }, { 20, 2, 0 } },
+
	{ { 14, 0, 0 }, { 20, 0, 0 } },
+
	// iOS 13
+
	{ { 13, 6, 0 }, { 19, 6, 0 } },
+
	{ { 13, 5, 0 }, { 19, 5, 0 } },
+
	{ { 13, 3, 1 }, { 19, 3, 0 } },
+
	{ { 13, 3, 0 }, { 19, 2, 0 } },
+
	// iOS 12
+
	{ { 12, 1, 0 }, { 18, 2, 0 } },
+
	// iOS 11
+
	{ { 11, 4, 1 }, { 17, 7, 0 } },
+
	// iOS 10
+
	{ { 10, 3, 3 }, { 16, 6, 0 } },
+
	{ { 10, 3, 0 }, { 16, 3, 0 } },
+
	{ { 10, 0, 1 }, { 16, 0, 0 } },
+
	// iOS 9
+
	{ { 9, 3, 3 }, { 15, 6, 0 } },
+
	{ { 9, 0, 0 }, { 15, 0, 0 } },
+
	// iOS 7, iOS 8
+
	{ { 7, 0, 0 }, { 14, 0, 0 } },
+
	// iOS 6
+
	{ { 6, 0, 0 }, { 13, 0, 0 } },
+
	// iOS 4.3
+
	{ { 4, 3, 0 }, { 11, 0, 0 } },
+
	// iPhone OS 3
+
	{ { 3, 0, 0 }, { 10, 0, 0 } },
+
	// iPhone OS 1
+
	{ { 1, 0, 0 }, { 9, 0, 0 } },
+
	// EOA
+
	{ { 0, 0, 0 }, { 0, 0, 0 } },
+
};
+

+
int
+
map_platform_to_darwin(macho_version_t *darwin,
+
    const enum MachoPlatform platform, const macho_version_t version)
+
{
+
	macho_version_t *p;
+
	switch (platform) {
+
	case PLATFORM_MACOS:
+
		p = macos_to_darwin[0];
+
		break;
+

+
	case PLATFORM_IOS:
+
	case PLATFORM_IOSSIMULATOR:
+
	case PLATFORM_TVOS:
+
	case PLATFORM_TVOSSIMULATOR:
+
		p = ios_to_darwin[0];
+
		break;
+

+
	case PLATFORM_WATCHOS:
+
	case PLATFORM_WATCHOSSIMULATOR:
+
		darwin->major = version.major + 13;
+
		darwin->minor = version.minor;
+
		darwin->patch = 0;
+
		return 0;
+

+
	default:
+
		return -1;
+
	}
+
	while (p->major > version.major || p->minor > version.minor ||
+
	    p->patch > version.patch) {
+
		p += 2;
+
	}
+
	p++;
+
	if (0 == p->major && 0 == p->minor && 0 == p->patch) {
+
		return -1;
+
	}
+
	*darwin = *p;
+
	return 0;
+
}
added libpkg/private/binfmt_macho.h
@@ -0,0 +1,324 @@
+
/*-
+
 * Copyright (c) 2024 Keve Müller <kevemueller@users.github.com>
+
 *
+
 * 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
+
 *    in this position and unchanged.
+
 * 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 AUTHOR(S) ``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 AUTHOR(S) 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 _PKG_BINFMT_MACHO_H
+
#define _PKG_BINFMT_MACHO_H
+

+
#include <sys/types.h>
+

+
#include <stdbool.h>
+
#include <stdint.h>
+

+
/**** Magic numbers & constants ****/
+

+
// Constants for magic (big&little endian)
+
#define MH_MAGIC     0xFEEDFACEu
+
#define MH_CIGAM     0xCEFAEDFEu
+
#define MH_MAGIC_64  0xFEEDFACFu
+
#define MH_CIGAM_64  0xCFFAEDFEu
+
#define FAT_MAGIC    0xCAFEBABEu
+
#define FAT_CIGAM    0xBEBAFECAu
+
#define FAT_MAGIC_64 0xCAFEBABFu
+
#define FAT_CIGAM_64 0xBFBAFECAu
+

+
// Masks for CPUType capability bits
+
static const uint32_t CPU_ARCH_MASK = 0xff000000u;
+
static const uint32_t CPU_ARCH_ABI64 = 0x01000000u; // 64 bit ABI
+
static const uint32_t CPU_ARCH_ABI64_32 =
+
    0x02000000u; // ILP32 ABI on 64-bit hardware
+

+
// Masks for the CPUSubType
+
static const uint32_t CPU_SUBTYPE_MASK =
+
    0xff000000u; // Mask for architecture bits
+
static const uint32_t CPU_SUBTYPE_LIB64 = 0x80000000u; // 64 bit libraries
+
// static const uint32_t  CPU_SUBTYPE_MULTIPLE = ~0u;
+

+
// // arm64e uses the capability bits to encode ptrauth ABI information.
+
// // Bit 63 marks the binary as Versioned.
+
// CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK = 0x80000000U,
+
// // Bit 62 marks the binary as using a kernel ABI.
+
// CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK = 0x40000000U,
+
// // Bits [59:56] hold the 4-bit ptrauth ABI version.
+
// CPU_SUBTYPE_ARM64E_PTRAUTH_MASK = 0x0f000000U,
+

+
enum CPUType {
+
	CPU_TYPE_ANY = -1,
+
	CPU_TYPE_VAX = 1,
+
	CPU_TYPE_ROMP,
+
	CPU_TYPE_NS32032 = 4,
+
	CPU_TYPE_NS32332,
+
	CPU_TYPE_MC680x0,
+
	CPU_TYPE_X86,
+
	CPU_TYPE_MIPS,
+
	CPU_TYPE_NS32352,
+
	CPU_TYPE_MC98000,
+
	CPU_TYPE_HPPA,
+
	CPU_TYPE_ARM,
+
	CPU_TYPE_MC88000,
+
	CPU_TYPE_SPARC,
+
	CPU_TYPE_I860BE,
+
	CPU_TYPE_I860LE,
+
	CPU_TYPE_RS6000,
+
	CPU_TYPE_POWERPC
+
};
+

+
enum CPUSubTypeX86 {
+
	CPU_SUBTYPE_X86_INVALID = -1,
+
	CPU_SUBTYPE_X86_ALL = 3,
+
	CPU_SUBTYPE_486 = 4,
+
	CPU_SUBTYPE_486SX = 0x84,
+
	CPU_SUBTYPE_586 = 5,
+
	CPU_SUBTYPE_PENTPRO = 0x16,
+
	CPU_SUBTYPE_PENTII_M3 = 0x36,
+
	CPU_SUBTYPE_PENTII_M5 = 0x56,
+
	CPU_SUBTYPE_CELERON = 0x67,
+
	CPU_SUBTYPE_CELERON_MOBILE = 0x77,
+
	CPU_SUBTYPE_PENTIUM_3 = 0x08,
+
	CPU_SUBTYPE_PENTIUM_3_M = 0x18,
+
	CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
+
	CPU_SUBTYPE_PENTIUM_M = 0x09,
+
	CPU_SUBTYPE_PENTIUM_4 = 0x0a,
+
	CPU_SUBTYPE_PENTIUM_4_M = 0x1a,
+
	CPU_SUBTYPE_ITANIUM = 0x0b,
+
	CPU_SUBTYPE_ITANIUM_2 = 0x1b,
+
	CPU_SUBTYPE_XEON = 0x0c,
+
	CPU_SUBTYPE_XEON_MP = 0x1c
+
};
+

+
enum CPUSubTypeARM {
+
	CPU_SUBTYPE_ARM_INVALID = -1,
+
	CPU_SUBTYPE_ARM_ALL,
+
	CPU_SUBTYPE_ARM64_V8,
+
	CPU_SUBTYPE_ARM64E,
+
	CPU_SUBTYPE_ARM_V4T = 5,
+
	CPU_SUBTYPE_ARM_V6,
+
	CPU_SUBTYPE_ARM_V5,
+
	CPU_SUBTYPE_ARM_V5TEJ = CPU_SUBTYPE_ARM_V5,
+
	CPU_SUBTYPE_ARM_XSCALE,
+
	CPU_SUBTYPE_ARM_V7,
+
	CPU_SUBTYPE_ARM_V7S = 11,
+
	CPU_SUBTYPE_ARM_V7K,
+
	CPU_SUBTYPE_ARM_V6M = 14,
+
	CPU_SUBTYPE_ARM_V7M,
+
	CPU_SUBTYPE_ARM_V7EM
+
};
+

+
enum CPUSubTypePPC {
+
	CPU_SUBTYPE_POWERPC_ALL = 0,
+
	CPU_SUBTYPE_POWERPC_601,
+
	CPU_SUBTYPE_POWERPC_602,
+
	CPU_SUBTYPE_POWERPC_603,
+
	CPU_SUBTYPE_POWERPC_603e,
+
	CPU_SUBTYPE_POWERPC_603ev,
+
	CPU_SUBTYPE_POWERPC_604,
+
	CPU_SUBTYPE_POWERPC_604e,
+
	CPU_SUBTYPE_POWERPC_620,
+
	CPU_SUBTYPE_POWERPC_750,
+
	CPU_SUBTYPE_POWERPC_7400,
+
	CPU_SUBTYPE_POWERPC_7450,
+
	CPU_SUBTYPE_POWERPC_970 = 100,
+

+
	CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL,
+
	CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
+
};
+

+
enum MachOFileType {
+
	MH_OBJECT = 0x1,
+
	MH_EXECUTE = 0x2,
+
	MH_FVMLIB = 0x3,
+
	MH_CORE = 0x4,
+
	MH_PRELOAD = 0x5,
+
	MH_DYLIB = 0x6,
+
	MH_DYLINKER = 0x7,
+
	MH_BUNDLE = 0x8,
+
	MH_DYLIB_STUB = 0x9,
+
	MH_DSYM = 0xA,
+
	MH_KEXT_BUNDLE = 0xB,
+
	MH_FILESET = 0xC
+
};
+

+
static const uint32_t LC_REQ_DYLD = 0x80000000u; // required load command flag
+

+
enum MachOLoadCommand {
+
	LC_SEGMENT = 1,
+
	LC_SYMTAB,
+
	LC_SYMSEG,
+
	LC_THREAD,
+
	LC_UNIXTHREAD,
+
	LC_LOADFVMLIB,
+
	LC_IDFVMLIB,
+
	LC_IDENT,
+
	LC_FVMFILE,
+
	LC_PREPAGE,
+
	LC_DYSYMTAB,
+
	LC_LOAD_DYLIB,
+
	LC_ID_DYLIB,
+
	LC_LOAD_DYLINKER,
+
	LC_ID_DYLINKER,
+
	LC_PREBOUND_DYLIB,
+
	LC_ROUTINES,
+
	LC_SUB_FRAMEWORK,
+
	LC_SUB_UMBRELLA,
+
	LC_SUB_CLIENT,
+
	LC_SUB_LIBRARY,
+
	LC_TWOLEVEL_HINTS,
+
	LC_PREBIND_CKSUM,
+
	LC_LOAD_WEAK_DYLIB,
+
	LC_SEGMENT_64,
+
	LC_ROUTINES_64,
+
	LC_UUID,
+
	LC_RPATH,
+
	LC_CODE_SIGNATURE,
+
	LC_SEGMENT_SPLIT_INFO,
+
	LC_REEXPORT_DYLIB,
+
	LC_LAZY_LOAD_DYLIB,
+
	LC_ENCRYPTION_INFO,
+
	LC_DYLD_INFO,
+
	LC_DYLD_INFO_ONLY = LC_DYLD_INFO,
+
	LC_LOAD_UPWARD_DYLIB,
+
	LC_VERSION_MIN_MACOSX,
+
	LC_VERSION_MIN_IPHONEOS,
+
	LC_FUNCTION_STARTS,
+
	LC_DYLD_ENVIRONMENT,
+
	LC_MAIN,
+
	LC_DATA_IN_CODE,
+
	LC_SOURCE_VERSION,
+
	LC_DYLIB_CODE_SIGN_DRS,
+
	LC_ENCRYPTION_INFO_64,
+
	LC_LINKER_OPTION,
+
	LC_LINKER_OPTIMIZATION_HINT,
+
	LC_VERSION_MIN_TVOS,
+
	LC_VERSION_MIN_WATCHOS,
+
	LC_NOTE,
+
	LC_BUILD_VERSION,
+
	LC_DYLD_EXPORTS_TRIE,
+
	LC_DYLD_CHAINED_FIXUPS,
+
	LC_FILESET_ENTRY,
+
	LC_ATOM_INFO
+
};
+

+
enum MachoPlatform {
+
	PLATFORM_UNKNOWN = 0,
+
	PLATFORM_MACOS,
+
	PLATFORM_IOS,
+
	PLATFORM_TVOS,
+
	PLATFORM_WATCHOS,
+
	PLATFORM_BRIDGEOS,
+
	PLATFORM_MACCATALYST,
+
	PLATFORM_IOSSIMULATOR,
+
	PLATFORM_TVOSSIMULATOR,
+
	PLATFORM_WATCHOSSIMULATOR,
+
	PLATFORM_DRIVERKIT,
+
	PLATFORM_XROS,
+
	PLATFORM_XROS_SIMULATOR
+
};
+

+
enum MachoTool { TOOL_CLANG = 1, TOOL_SWIFT, TOOL_LD, TOOL_LLD };
+

+
/**** Unpacked structures ****/
+

+
typedef struct cpu_type_subtype {
+
	enum CPUType type;
+
	bool type_is64;
+
	bool type_is64_32;
+
	union {
+
		enum CPUSubTypeX86 subtype_x86;
+
		enum CPUSubTypeARM subtype_arm;
+
		enum CPUSubTypePPC subtype_ppc;
+
	};
+
	bool subtype_islib64;
+
} cpu_type_subtype_t;
+

+
typedef struct fat_arch {
+
	struct cpu_type_subtype cpu;
+
	uint64_t offset;
+
	uint64_t size;
+
	uint_fast8_t align;
+
} fat_arch_t;
+

+
typedef struct macho_file {
+
	uint32_t magic;
+
	uint32_t narch;
+
	fat_arch_t arch[];
+
} macho_file_t;
+

+
typedef struct macho_header {
+
	uint32_t magic;
+
	bool swap;
+
	cpu_type_subtype_t cpu;
+
	enum MachOFileType filetype;
+
	uint32_t ncmds;
+
	uint32_t sizeofcmds;
+
	uint32_t flags;
+
} macho_header_t;
+

+
typedef struct macho_version {
+
	uint_fast16_t major;
+
	uint_fast16_t minor;
+
	uint_fast16_t patch;
+
} macho_version_t;
+

+
typedef struct tool_version {
+
	enum MachoTool tool;
+
	macho_version_t version;
+
} tool_version_t;
+

+
typedef struct build_version {
+
	enum MachoPlatform platform;
+
	macho_version_t minos;
+
	macho_version_t sdk;
+
	uint32_t ntools;
+
	tool_version_t tools[];
+
} build_version_t;
+

+
typedef struct dylib {
+
	uint32_t timestamp;
+
	macho_version_t current_version;
+
	macho_version_t compatibility_version;
+
	char path[];
+
} dylib_t;
+

+
/**** Function prototypes ****/
+

+
/* utility */
+
int map_platform_to_darwin(macho_version_t *darwin,
+
    const enum MachoPlatform platform, const macho_version_t version);
+

+
/* readers */
+
ssize_t read_macho_file(const int fd, macho_file_t **dest);
+
ssize_t read_macho_header(const int fd, macho_header_t *dest);
+
ssize_t read_build_version(const int fd, const bool swap,
+
    build_version_t **dest);
+
ssize_t read_min_version(const int fd, const bool swap, const uint32_t loadcmd,
+
    build_version_t **dest);
+

+
#define READ(f, var)                              \
+
	if ((x = read_##f(fd, swap, &var)) < 0) { \
+
		return x;                         \
+
	}                                         \
+
	n += x
+
ssize_t read_u32(const int fd, const bool swap, uint32_t *dest);
+

+
#endif

\ No newline at end of file
modified src/Makefile.autosetup
@@ -69,10 +69,6 @@ OTHER_LIBS+= -lfts
OTHER_LIBS+=	-ldl
@endif

-
@if HAVE_LIBRESOLV
-
OTHER_LIBS+=	-lresolv
-
@endif
-

@if HAVE_LIBMD
OTHER_LIBS+=	-lmd
@endif
@@ -89,7 +85,7 @@ LOCAL_CFLAGS+= @PKG_LIBCURL_CFLAGS@
OTHER_LIBS+=	@PKG_LIBCURL_LDFLAGS@ @PKG_LIBCURL_LIBS@
@endif

-
@if libmachista
+
@if pkgos_darwin
LOCAL_LDFLAGS=	$(LIBPKGFLAT) $(LIBS) $(OTHER_LIBS) -lresolv
STATIC_LDFLAGS=	$(LIBPKGFLAT) $(LIBS) $(OTHER_LIBS) -lresolv
# OSX doesn't support static binaries, sigh
modified tests/Makefile.autosetup
@@ -137,9 +137,6 @@ OTHER_LIBS+= -lfts
@if HAVE_LIBDL
OTHER_LIBS+=	-ldl
@endif
-
@if HAVE_LIBRESOLV
-
OTHER_LIBS+=	-lresolv
-
@endif
@if PKG_LIBCURL_LIBS
CFLAGS+=	@PKG_LIBCURL_CFLAGS@
LIBS+=	@PKG_LIBCURL_LDFLAGS@ @PKG_LIBCURL_LIBS@
@@ -153,7 +150,7 @@ OTHER_LIBS+= -lssl -lcrypto


# Hack to determine we are on osx
-
@if libmachista
+
@if pkgos_darwin
OTHER_LIBS+=	-lresolv
@endif

modified tests/cocci/README.md
@@ -23,7 +23,7 @@ From the pkg's source root (use _libpkg_ or _src_ as `$DIR`):

	% spatch -I . -I /usr/include -I /usr/local/include -I libpkg -I src       \
		-I external/blake2  -I external/yxml      -I external/include     \
-
		-I external/libelf  -I external/libfetch       -I external/libmachista \
+
		-I external/libelf  -I external/libfetch        \
		-I external/libsbuf -I external/libucl/include -I external/linenoise   \
		-I external/picosat -I external/sqlite         \
		-in_place -sp_file ./tests/cocci/$TESTFILE.cocci -dir $DIR