mirror of
https://github.com/darlinghq/cctools-port.git
synced 2024-11-23 04:09:48 +00:00
cctools: make is_llvm_bitcode() more portable (fixes -flto with multiple -arch flags)
ld64: use faster strlcpy()/strlcat() "helper" implementations ld64: fix qsort_r() helper function fix emulated _NSGetExecutablePath() for FreeBSD fix -luuid linkage issue on FreeBSD 10 Conflicts: cctools/configure.ac
This commit is contained in:
parent
9ae44420dc
commit
3833a7ce54
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
*.lo
|
@ -60,7 +60,7 @@ char **envp)
|
|||||||
_NSGetExecutablePath(p, &bufsize);
|
_NSGetExecutablePath(p, &bufsize);
|
||||||
}
|
}
|
||||||
prefix = realpath(p, resolved_name);
|
prefix = realpath(p, resolved_name);
|
||||||
if(realpath == NULL)
|
if(prefix == NULL)
|
||||||
system_fatal("realpath(3) for %s failed", p);
|
system_fatal("realpath(3) for %s failed", p);
|
||||||
p = rindex(prefix, '/');
|
p = rindex(prefix, '/');
|
||||||
if(p != NULL)
|
if(p != NULL)
|
||||||
|
@ -10,9 +10,9 @@ AC_ARG_PROGRAM
|
|||||||
CC=clang
|
CC=clang
|
||||||
CXX=clang++
|
CXX=clang++
|
||||||
|
|
||||||
CFLAGS="`cat tmp/cflags 2>/dev/null` -O3"
|
CFLAGS="$CFLAGS `cat tmp/cflags 2>/dev/null` -O3"
|
||||||
CXXFLAGS="`cat tmp/libcxx-conf 2>/dev/null || echo -stdlib=libc++` `cat tmp/cxxflags 2>/dev/null` -O3"
|
CXXFLAGS="$CXXFLAGS `cat tmp/libcxx-conf 2>/dev/null || echo -stdlib=libc++` `cat tmp/cxxflags 2>/dev/null` -O3"
|
||||||
LDFLAGS="`cat tmp/ldflags 2>/dev/null`"
|
LDFLAGS="$LDFLAGS `cat tmp/ldflags 2>/dev/null`"
|
||||||
export LD_LIBRARY_PATH="`cat tmp/ldpath 2>/dev/null`"
|
export LD_LIBRARY_PATH="`cat tmp/ldpath 2>/dev/null`"
|
||||||
export C_INCLUDE_PATH="$C_INCLUDE_PATH:/usr/local/include"
|
export C_INCLUDE_PATH="$C_INCLUDE_PATH:/usr/local/include"
|
||||||
|
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
#include <mach/host_info.h>
|
#include <mach/host_info.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
|
||||||
const char ldVersionString[] = "136\n";
|
const char ldVersionString[] = "136\n";
|
||||||
@ -27,22 +32,29 @@ void __assert_rtn(const char *func, const char *file, int line, const char *msg)
|
|||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int _NSGetExecutablePath(char *path, unsigned int *size)
|
int _NSGetExecutablePath(char *path, unsigned int *size)
|
||||||
{
|
{
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
int mib[4];
|
||||||
|
mib[0] = CTL_KERN;
|
||||||
|
mib[1] = KERN_PROC;
|
||||||
|
mib[2] = KERN_PROC_PATHNAME;
|
||||||
|
mib[3] = -1;
|
||||||
|
size_t cb = *size;
|
||||||
|
return sysctl(mib, 4, path, &cb, NULL, 0);
|
||||||
|
#else
|
||||||
int bufsize = *size;
|
int bufsize = *size;
|
||||||
int ret_size;
|
int ret_size;
|
||||||
char *localpath = (char*)malloc(bufsize);
|
ret_size = readlink("/proc/self/exe", path, bufsize-1);
|
||||||
bzero(localpath,bufsize);
|
|
||||||
ret_size = readlink("/proc/self/exe", localpath, bufsize);
|
|
||||||
if (ret_size != -1)
|
if (ret_size != -1)
|
||||||
{
|
{
|
||||||
*size = ret_size;
|
*size = ret_size;
|
||||||
strcpy(path,localpath);
|
path[ret_size]=0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int _dyld_find_unwind_sections(void* i, struct dyld_unwind_sections* sec)
|
int _dyld_find_unwind_sections(void* i, struct dyld_unwind_sections* sec)
|
||||||
|
@ -1,23 +1,429 @@
|
|||||||
#include "qsort_r.h"
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. 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.
|
||||||
|
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define I_AM_QSORT_R
|
||||||
|
#define qsort_r qsort_r_local
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void *_qsort_thunk = NULL;
|
#ifndef __FreeBSD__
|
||||||
int (*_qsort_saved_func)(void *, const void *, const void *) = NULL;
|
/* flsl.c */
|
||||||
|
int
|
||||||
static int _qsort_comparator(const void *a, const void *b);
|
flsl(long mask)
|
||||||
|
|
||||||
static int _qsort_comparator(const void *a, const void *b)
|
|
||||||
{
|
{
|
||||||
return _qsort_saved_func(_qsort_thunk, a, b);
|
int bit;
|
||||||
|
|
||||||
|
if (mask == 0)
|
||||||
|
return (0);
|
||||||
|
for (bit = 1; mask != 1; bit++)
|
||||||
|
mask = (unsigned long)mask >> 1;
|
||||||
|
return (bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsl.c */
|
||||||
|
int
|
||||||
|
fls(int mask)
|
||||||
|
{
|
||||||
|
int bit;
|
||||||
|
if (mask == 0)
|
||||||
|
return (0);
|
||||||
|
for (bit = 1; mask != 1; bit++)
|
||||||
|
mask = (unsigned int)mask >> 1;
|
||||||
|
return (bit);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swap two areas of size number of bytes. Although qsort(3) permits random
|
||||||
|
* blocks of memory to be sorted, sorting pointers is almost certainly the
|
||||||
|
* common case (and, were it not, could easily be made so). Regardless, it
|
||||||
|
* isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
|
||||||
|
* arithmetic gets lost in the time required for comparison function calls.
|
||||||
|
*/
|
||||||
|
#define SWAP(a, b, count, size, tmp) { \
|
||||||
|
count = size; \
|
||||||
|
do { \
|
||||||
|
tmp = *a; \
|
||||||
|
*a++ = *b; \
|
||||||
|
*b++ = tmp; \
|
||||||
|
} while (--count); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy one block of size size to another. */
|
||||||
|
#define COPY(a, b, count, size, tmp1, tmp2) { \
|
||||||
|
count = size; \
|
||||||
|
tmp1 = a; \
|
||||||
|
tmp2 = b; \
|
||||||
|
do { \
|
||||||
|
*tmp1++ = *tmp2++; \
|
||||||
|
} while (--count); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the list into a heap, where a heap is defined such that for
|
||||||
|
* the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
|
||||||
|
*
|
||||||
|
* There two cases. If j == nmemb, select largest of Ki and Kj. If
|
||||||
|
* j < nmemb, select largest of Ki, Kj and Kj+1.
|
||||||
|
*/
|
||||||
|
#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
|
||||||
|
for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
|
||||||
|
par_i = child_i) { \
|
||||||
|
child = base + child_i * size; \
|
||||||
|
if (child_i < nmemb && compar(thunk, child, child + size) < 0) { \
|
||||||
|
child += size; \
|
||||||
|
++child_i; \
|
||||||
|
} \
|
||||||
|
par = base + par_i * size; \
|
||||||
|
if (compar(thunk, child, par) <= 0) \
|
||||||
|
break; \
|
||||||
|
SWAP(par, child, count, size, tmp); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select the top of the heap and 'heapify'. Since by far the most expensive
|
||||||
|
* action is the call to the compar function, a considerable optimization
|
||||||
|
* in the average case can be achieved due to the fact that k, the displaced
|
||||||
|
* elememt, is ususally quite small, so it would be preferable to first
|
||||||
|
* heapify, always maintaining the invariant that the larger child is copied
|
||||||
|
* over its parent's record.
|
||||||
|
*
|
||||||
|
* Then, starting from the *bottom* of the heap, finding k's correct place,
|
||||||
|
* again maintianing the invariant. As a result of the invariant no element
|
||||||
|
* is 'lost' when k is assigned its correct place in the heap.
|
||||||
|
*
|
||||||
|
* The time savings from this optimization are on the order of 15-20% for the
|
||||||
|
* average case. See Knuth, Vol. 3, page 158, problem 18.
|
||||||
|
*
|
||||||
|
* XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
|
||||||
|
*/
|
||||||
|
#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
|
||||||
|
for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
|
||||||
|
child = base + child_i * size; \
|
||||||
|
if (child_i < nmemb && compar(thunk, child, child + size) < 0) { \
|
||||||
|
child += size; \
|
||||||
|
++child_i; \
|
||||||
|
} \
|
||||||
|
par = base + par_i * size; \
|
||||||
|
COPY(par, child, count, size, tmp1, tmp2); \
|
||||||
|
} \
|
||||||
|
for (;;) { \
|
||||||
|
child_i = par_i; \
|
||||||
|
par_i = child_i / 2; \
|
||||||
|
child = base + child_i * size; \
|
||||||
|
par = base + par_i * size; \
|
||||||
|
if (child_i == 1 || compar(thunk, k, par) < 0) { \
|
||||||
|
COPY(child, k, count, size, tmp1, tmp2); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
COPY(child, par, count, size, tmp1, tmp2); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
|
||||||
|
* and worst. While heapsort is faster than the worst case of quicksort,
|
||||||
|
* the BSD quicksort does median selection so that the chance of finding
|
||||||
|
* a data set that will trigger the worst case is nonexistent. Heapsort's
|
||||||
|
* only advantage over quicksort is that it requires little additional memory.
|
||||||
|
*/
|
||||||
|
__private_extern__ int
|
||||||
|
__heapsort_r(vbase, nmemb, size, thunk, compar)
|
||||||
|
void *vbase;
|
||||||
|
size_t nmemb, size;
|
||||||
|
void *thunk;
|
||||||
|
int (*compar)(void *, const void *, const void *);
|
||||||
|
{
|
||||||
|
size_t cnt, i, j, l;
|
||||||
|
char tmp, *tmp1, *tmp2;
|
||||||
|
char *base, *k, *p, *t;
|
||||||
|
|
||||||
|
if (nmemb <= 1)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((k = malloc(size)) == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Items are numbered from 1 to nmemb, so offset from size bytes
|
||||||
|
* below the starting address.
|
||||||
|
*/
|
||||||
|
base = (char *)vbase - size;
|
||||||
|
|
||||||
|
for (l = nmemb / 2 + 1; --l;)
|
||||||
|
CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For each element of the heap, save the largest element into its
|
||||||
|
* final slot, save the displaced element (k), then recreate the
|
||||||
|
* heap.
|
||||||
|
*/
|
||||||
|
while (nmemb > 1) {
|
||||||
|
COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
|
||||||
|
COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
|
||||||
|
--nmemb;
|
||||||
|
SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
|
||||||
|
}
|
||||||
|
free(k);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* qsort.c */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef I_AM_QSORT_R
|
||||||
|
typedef int cmp_t(void *, const void *, const void *);
|
||||||
|
#else
|
||||||
|
typedef int cmp_t(const void *, const void *);
|
||||||
|
#endif
|
||||||
|
#ifdef I_AM_QSORT_B
|
||||||
|
static inline char *med3(char *, char *, char *, cmp_t ^, void *) __attribute__((always_inline));
|
||||||
|
#else
|
||||||
|
static inline char *med3(char *, char *, char *, cmp_t *, void *) __attribute__((always_inline));
|
||||||
|
#endif
|
||||||
|
static inline void swapfunc(char *, char *, int, int) __attribute__((always_inline));
|
||||||
|
|
||||||
|
#define min(a, b) (a) < (b) ? a : b
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
|
||||||
|
*/
|
||||||
|
#define swapcode(TYPE, parmi, parmj, n) { \
|
||||||
|
long i = (n) / sizeof (TYPE); \
|
||||||
|
TYPE *pi = (TYPE *) (parmi); \
|
||||||
|
TYPE *pj = (TYPE *) (parmj); \
|
||||||
|
do { \
|
||||||
|
TYPE t = *pi; \
|
||||||
|
*pi++ = *pj; \
|
||||||
|
*pj++ = t; \
|
||||||
|
} while (--i > 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
|
||||||
|
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
swapfunc(a, b, n, swaptype)
|
||||||
|
char *a, *b;
|
||||||
|
int n, swaptype;
|
||||||
|
{
|
||||||
|
if(swaptype <= 1)
|
||||||
|
swapcode(long, a, b, n)
|
||||||
|
else
|
||||||
|
swapcode(char, a, b, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
#define swap(a, b) \
|
||||||
|
if (swaptype == 0) { \
|
||||||
|
long t = *(long *)(a); \
|
||||||
|
*(long *)(a) = *(long *)(b); \
|
||||||
|
*(long *)(b) = t; \
|
||||||
|
} else \
|
||||||
|
swapfunc(a, b, es, swaptype)
|
||||||
|
|
||||||
|
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
|
||||||
|
|
||||||
|
#ifdef I_AM_QSORT_R
|
||||||
|
#define CMP(t, x, y) (cmp((t), (x), (y)))
|
||||||
|
#else
|
||||||
|
#define CMP(t, x, y) (cmp((x), (y)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
med3(char *a, char *b, char *c,
|
||||||
|
#ifdef I_AM_QSORT_B
|
||||||
|
cmp_t ^cmp,
|
||||||
|
#else
|
||||||
|
cmp_t *cmp,
|
||||||
|
#endif
|
||||||
|
void *thunk
|
||||||
|
#ifndef I_AM_QSORT_R
|
||||||
|
__unused
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return CMP(thunk, a, b) < 0 ?
|
||||||
|
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
|
||||||
|
:(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __LP64__
|
||||||
|
#define DEPTH(x) (2 * (flsl((long)(x)) - 1))
|
||||||
|
#else /* !__LP64__ */
|
||||||
|
#define DEPTH(x) (2 * (fls((int)(x)) - 1))
|
||||||
|
#endif /* __LP64__ */
|
||||||
|
|
||||||
|
#ifdef I_AM_QSORT_R
|
||||||
|
int __heapsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
_qsort(void *a, size_t n, size_t es,
|
||||||
|
#ifdef I_AM_QSORT_R
|
||||||
|
void *thunk,
|
||||||
|
#else
|
||||||
|
#define thunk NULL
|
||||||
|
#endif
|
||||||
|
#ifdef I_AM_QSORT_B
|
||||||
|
cmp_t ^cmp,
|
||||||
|
#else
|
||||||
|
cmp_t *cmp,
|
||||||
|
#endif
|
||||||
|
int depth_limit)
|
||||||
|
{
|
||||||
|
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
||||||
|
size_t d, r;
|
||||||
|
int cmp_result;
|
||||||
|
int swaptype, swap_cnt;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
if (depth_limit-- <= 0) {
|
||||||
|
#ifdef I_AM_QSORT_B
|
||||||
|
heapsort_b(a, n, es, cmp);
|
||||||
|
#elif defined(I_AM_QSORT_R)
|
||||||
|
__heapsort_r(a, n, es, thunk, cmp);
|
||||||
|
#else
|
||||||
|
heapsort(a, n, es, cmp);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SWAPINIT(a, es);
|
||||||
|
swap_cnt = 0;
|
||||||
|
if (n < 7) {
|
||||||
|
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
|
||||||
|
for (pl = pm;
|
||||||
|
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
|
||||||
|
pl -= es)
|
||||||
|
swap(pl, pl - es);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pm = (char *)a + (n / 2) * es;
|
||||||
|
if (n > 7) {
|
||||||
|
pl = a;
|
||||||
|
pn = (char *)a + (n - 1) * es;
|
||||||
|
if (n > 40) {
|
||||||
|
d = (n / 8) * es;
|
||||||
|
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
|
||||||
|
pm = med3(pm - d, pm, pm + d, cmp, thunk);
|
||||||
|
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
|
||||||
|
}
|
||||||
|
pm = med3(pl, pm, pn, cmp, thunk);
|
||||||
|
}
|
||||||
|
swap(a, pm);
|
||||||
|
pa = pb = (char *)a + es;
|
||||||
|
|
||||||
|
pc = pd = (char *)a + (n - 1) * es;
|
||||||
|
for (;;) {
|
||||||
|
while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
|
||||||
|
if (cmp_result == 0) {
|
||||||
|
swap_cnt = 1;
|
||||||
|
swap(pa, pb);
|
||||||
|
pa += es;
|
||||||
|
}
|
||||||
|
pb += es;
|
||||||
|
}
|
||||||
|
while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
|
||||||
|
if (cmp_result == 0) {
|
||||||
|
swap_cnt = 1;
|
||||||
|
swap(pc, pd);
|
||||||
|
pd -= es;
|
||||||
|
}
|
||||||
|
pc -= es;
|
||||||
|
}
|
||||||
|
if (pb > pc)
|
||||||
|
break;
|
||||||
|
swap(pb, pc);
|
||||||
|
swap_cnt = 1;
|
||||||
|
pb += es;
|
||||||
|
pc -= es;
|
||||||
|
}
|
||||||
|
|
||||||
|
pn = (char *)a + n * es;
|
||||||
|
r = min(pa - (char *)a, pb - pa);
|
||||||
|
vecswap(a, pb - r, r);
|
||||||
|
r = min(pd - pc, pn - pd - es);
|
||||||
|
vecswap(pb, pn - r, r);
|
||||||
|
|
||||||
|
if (swap_cnt == 0) { /* Switch to insertion sort */
|
||||||
|
r = 1 + n / 4; /* n >= 7, so r >= 2 */
|
||||||
|
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
|
||||||
|
for (pl = pm;
|
||||||
|
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
|
||||||
|
pl -= es) {
|
||||||
|
swap(pl, pl - es);
|
||||||
|
if (++swap_cnt > r) goto nevermind;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nevermind:
|
||||||
|
if ((r = pb - pa) > es)
|
||||||
|
#ifdef I_AM_QSORT_R
|
||||||
|
_qsort(a, r / es, es, thunk, cmp, depth_limit);
|
||||||
|
#else
|
||||||
|
_qsort(a, r / es, es, cmp, depth_limit);
|
||||||
|
#endif
|
||||||
|
if ((r = pd - pc) > es) {
|
||||||
|
/* Iterate rather than recurse to save stack space */
|
||||||
|
a = pn - r;
|
||||||
|
n = r / es;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
/* qsort(pn - r, r / es, es, cmp);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
qsort_r_local(void *base, size_t nmemb, size_t size, void *thunk,
|
#ifdef I_AM_QSORT_R
|
||||||
int (*compar)(void *, const void *, const void *))
|
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
|
||||||
|
#elif defined(I_AM_QSORT_B)
|
||||||
|
qsort_b(void *a, size_t n, size_t es, cmp_t ^cmp)
|
||||||
|
#else
|
||||||
|
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
_qsort_thunk = thunk;
|
_qsort(a, n, es,
|
||||||
_qsort_saved_func = compar;
|
#ifdef I_AM_QSORT_R
|
||||||
|
thunk,
|
||||||
qsort(base, nmemb, size, _qsort_comparator);
|
#endif
|
||||||
|
cmp, DEPTH(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,30 +1,38 @@
|
|||||||
#include <sys/types.h>
|
/*
|
||||||
|
* Copyright (c) 2011 Apple, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPLE_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* This file contains Original Code and/or Modifications of Original Code
|
||||||
|
* as defined in and that are subject to the Apple Public Source License
|
||||||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||||||
|
* compliance with the License. Please obtain a copy of the License at
|
||||||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The Original Code and all software distributed under the License are
|
||||||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||||
|
* Please see the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPLE_LICENSE_HEADER_END@
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t strlcat(char *dst, const char *src, size_t siz)
|
size_t
|
||||||
{
|
strlcat(char * restrict dst, const char * restrict src, size_t maxlen) {
|
||||||
char *d = dst;
|
const size_t srclen = strlen(src);
|
||||||
const char *s = src;
|
const size_t dstlen = strnlen(dst, maxlen);
|
||||||
size_t n = siz;
|
if (dstlen == maxlen) return maxlen+srclen;
|
||||||
size_t dlen;
|
if (srclen < maxlen-dstlen) {
|
||||||
|
memcpy(dst+dstlen, src, srclen+1);
|
||||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
} else {
|
||||||
while (n-- != 0 && *d != '\0')
|
memcpy(dst+dstlen, src, maxlen-dstlen-1);
|
||||||
d++;
|
dst[maxlen-1] = '\0';
|
||||||
dlen = d - dst;
|
}
|
||||||
n = siz - dlen;
|
return dstlen + srclen;
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
return(dlen + strlen(s));
|
|
||||||
while (*s != '\0') {
|
|
||||||
if (n != 1) {
|
|
||||||
*d++ = *s;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
*d = '\0';
|
|
||||||
|
|
||||||
return(dlen + (s - src)); /* count does not include NUL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,56 +1,37 @@
|
|||||||
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 2011 Apple, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* @APPLE_LICENSE_HEADER_START@
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
*
|
||||||
* copyright notice and this permission notice appear in all copies.
|
* This file contains Original Code and/or Modifications of Original Code
|
||||||
*
|
* as defined in and that are subject to the Apple Public Source License
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
* compliance with the License. Please obtain a copy of the License at
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
* file.
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
*
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* The Original Code and all software distributed under the License are
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||||
|
* Please see the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPLE_LICENSE_HEADER_END@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy src to string dst of size siz. At most siz-1 characters
|
|
||||||
* will be copied. Always NUL terminates (unless siz == 0).
|
|
||||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
|
||||||
*/
|
|
||||||
size_t
|
size_t
|
||||||
strlcpy(char *dst, const char *src, size_t siz)
|
strlcpy(char * restrict dst, const char * restrict src, size_t maxlen) {
|
||||||
{
|
const size_t srclen = strlen(src);
|
||||||
char *d = dst;
|
if (srclen < maxlen) {
|
||||||
const char *s = src;
|
memcpy(dst, src, srclen+1);
|
||||||
size_t n = siz;
|
} else if (maxlen != 0) {
|
||||||
|
memcpy(dst, src, maxlen-1);
|
||||||
/* Copy as many bytes as will fit */
|
dst[maxlen-1] = '\0';
|
||||||
if (n != 0) {
|
}
|
||||||
while (--n != 0) {
|
return srclen;
|
||||||
if ((*d++ = *s++) == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
|
||||||
if (n == 0) {
|
|
||||||
if (siz != 0)
|
|
||||||
*d = '\0'; /* NUL-terminate dst */
|
|
||||||
while (*s++)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(s - src - 1); /* count does not include NUL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#define __LTO_READER_H__
|
#define __LTO_READER_H__
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -14,8 +14,21 @@
|
|||||||
#include <mach/host_info.h>
|
#include <mach/host_info.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int _NSGetExecutablePath(char *path, unsigned int *size)
|
int _NSGetExecutablePath(char *path, unsigned int *size)
|
||||||
{
|
{
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
int mib[4];
|
||||||
|
mib[0] = CTL_KERN;
|
||||||
|
mib[1] = KERN_PROC;
|
||||||
|
mib[2] = KERN_PROC_PATHNAME;
|
||||||
|
mib[3] = -1;
|
||||||
|
size_t cb = *size;
|
||||||
|
return sysctl(mib, 4, path, &cb, NULL, 0);
|
||||||
|
#else
|
||||||
int bufsize = *size;
|
int bufsize = *size;
|
||||||
int ret_size;
|
int ret_size;
|
||||||
ret_size = readlink("/proc/self/exe", path, bufsize-1);
|
ret_size = readlink("/proc/self/exe", path, bufsize-1);
|
||||||
@ -27,6 +40,7 @@ int _NSGetExecutablePath(char *path, unsigned int *size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_return_t mach_timebase_info( mach_timebase_info_t info) {
|
kern_return_t mach_timebase_info( mach_timebase_info_t info) {
|
||||||
|
@ -26,6 +26,79 @@ static uint32_t (*lto_get_num_symbols)(void *mod) = NULL;
|
|||||||
static lto_symbol_attributes (*lto_get_sym_attr)(void *mod, uint32_t n) = NULL;
|
static lto_symbol_attributes (*lto_get_sym_attr)(void *mod, uint32_t n) = NULL;
|
||||||
static char * (*lto_get_sym_name)(void *mod, uint32_t n) = NULL;
|
static char * (*lto_get_sym_name)(void *mod, uint32_t n) = NULL;
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
static char *liblto_dirs[] = {
|
||||||
|
"/usr/lib/llvm/lib",
|
||||||
|
"/usr/lib/llvm-3.5/lib",
|
||||||
|
"/usr/lib/llvm-3.4/lib",
|
||||||
|
"/usr/lib/llvm-3.3/lib",
|
||||||
|
"/usr/lib/llvm-3.2/lib",
|
||||||
|
"/usr/lib/llvm-3.1/lib",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *load_liblto()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Try to load it normally first,
|
||||||
|
* maybe libLTO.so is even in a known place.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *h = dlopen("libLTO.so", RTLD_NOW);
|
||||||
|
char *p, *path;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(h)
|
||||||
|
return h;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now try the hardcoded paths from above.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(i = 0; liblto_dirs[i] != NULL; i++){
|
||||||
|
char liblto[MAXPATHLEN];
|
||||||
|
snprintf(liblto, sizeof(liblto), "%s/libLTO.so", liblto_dirs);
|
||||||
|
|
||||||
|
if((h = dlopen(liblto, RTLD_NOW)))
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locate the path of the clang binary and try to load
|
||||||
|
* <clangpath>/../lib/libLTO.so.
|
||||||
|
*/
|
||||||
|
|
||||||
|
path = getenv("PATH");
|
||||||
|
|
||||||
|
if(!path) return NULL;
|
||||||
|
path = strdup(path);
|
||||||
|
if(!path) return NULL;
|
||||||
|
|
||||||
|
p = strtok(path, ":");
|
||||||
|
|
||||||
|
while(p != NULL){
|
||||||
|
char clangbin[MAXPATHLEN];
|
||||||
|
struct stat st;
|
||||||
|
snprintf(clangbin, sizeof(clangbin), "%s/clang", p);
|
||||||
|
|
||||||
|
if(stat(clangbin, &st) == 0 && access(clangbin, F_OK|X_OK) == 0){
|
||||||
|
char liblto[MAXPATHLEN];
|
||||||
|
snprintf(liblto, sizeof(liblto), "%s/../lib/libLTO.so", p);
|
||||||
|
|
||||||
|
if((h = dlopen(liblto, RTLD_NOW))){
|
||||||
|
free(path);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strtok(NULL, ":");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* ! __APPLE__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is_llvm_bitcode() is passed an ofile struct pointer and a pointer and size
|
* is_llvm_bitcode() is passed an ofile struct pointer and a pointer and size
|
||||||
* of some part of the ofile. If it is an llvm bit code it returns 1 and
|
* of some part of the ofile. If it is an llvm bit code it returns 1 and
|
||||||
@ -106,19 +179,32 @@ void **pmod) /* maybe NULL */
|
|||||||
_NSGetExecutablePath(p, &bufsize);
|
_NSGetExecutablePath(p, &bufsize);
|
||||||
}
|
}
|
||||||
prefix = realpath(p, resolved_name);
|
prefix = realpath(p, resolved_name);
|
||||||
p = rindex(prefix, '/');
|
p = (prefix ? rindex(prefix, '/') : NULL);
|
||||||
if(p != NULL)
|
if(p != NULL)
|
||||||
p[1] = '\0';
|
p[1] = '\0';
|
||||||
lto_path = makestr(prefix, "../lib/libLTO.so", NULL);
|
#ifdef __APPLE__
|
||||||
|
lto_path = makestr(prefix, "../lib/libLTO.dylib", NULL);
|
||||||
|
|
||||||
lto_handle = dlopen(lto_path, RTLD_NOW);
|
lto_handle = dlopen(lto_path, RTLD_NOW);
|
||||||
if(lto_handle == NULL){
|
if(lto_handle == NULL){
|
||||||
free(lto_path);
|
free(lto_path);
|
||||||
lto_path = NULL;
|
lto_path = NULL;
|
||||||
lto_handle = dlopen("/usr/lib/llvm/libLTO.so", RTLD_NOW);
|
lto_handle = dlopen("/Applications/Xcode.app/Contents/"
|
||||||
|
"Developer/Toolchains/XcodeDefault."
|
||||||
|
"xctoolchain/usr/lib/libLTO.dylib",
|
||||||
|
RTLD_NOW);
|
||||||
}
|
}
|
||||||
if(lto_handle == NULL)
|
if(lto_handle == NULL)
|
||||||
return(0);
|
return(0);
|
||||||
|
#else
|
||||||
|
lto_path = NULL;
|
||||||
|
lto_handle = load_liblto();
|
||||||
|
if(lto_handle == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cannot find or load libLTO.so\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
lto_is_object = dlsym(lto_handle,
|
lto_is_object = dlsym(lto_handle,
|
||||||
"lto_module_is_object_file_in_memory");
|
"lto_module_is_object_file_in_memory");
|
||||||
|
Loading…
Reference in New Issue
Block a user