diff --git a/CMakeLists.txt b/CMakeLists.txt index c052d611b6..21016e9182 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,13 @@ configure_file(cmake/intree.toolchain.cmake.in cmake/intree.toolchain.cmake @ONL configure_file(cmake/intreeppc.toolchain.cmake.in cmake/intreeppc.toolchain.cmake @ONLY) configure_file(cmake/intreecarbon.toolchain.cmake.in cmake/intreecarbon.toolchain.cmake @ONLY) +file(GLOB ELF_FILES elfutils/libelf/*.c elfutils/libelf/*.h) +add_library(ELF ${ELF_FILES} + ) +target_include_directories(ELF PRIVATE elfutils/libelf) +target_link_libraries(ELF -lz) +target_compile_definitions(ELF PRIVATE HAVE_CONFIG_H) + add_subdirectory(ResourceFiles) add_subdirectory(MakeAPPL) add_subdirectory(Rez) diff --git a/Elf2Mac/CMakeLists.txt b/Elf2Mac/CMakeLists.txt index f55647eb6a..c8d3db922d 100644 --- a/Elf2Mac/CMakeLists.txt +++ b/Elf2Mac/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required(VERSION 3.1) find_package(Boost COMPONENTS REQUIRED) add_executable(Elf2Mac Elf2Mac.h Elf2Mac.cc SegmentMap.cc LdScript.cc) -target_link_libraries(Elf2Mac ResourceFiles ${CMAKE_INSTALL_PREFIX}/lib/libelf.a -lz) +target_link_libraries(Elf2Mac ResourceFiles ELF) target_include_directories(Elf2Mac PRIVATE ${CMAKE_INSTALL_PREFIX}/include) target_include_directories(Elf2Mac PRIVATE ${Boost_INCLUDE_DIR}) diff --git a/elfutils/libelf/config.h b/elfutils/libelf/config.h new file mode 100644 index 0000000000..400cdc6e77 --- /dev/null +++ b/elfutils/libelf/config.h @@ -0,0 +1,190 @@ +/* Configuration definitions. + Copyright (C) 2008, 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef EU_CONFIG_H +#define EU_CONFIG_H 1 + +#ifdef USE_LOCKS +# include +# include +# define rwlock_define(class,name) class pthread_rwlock_t name +# define RWLOCK_CALL(call) \ + ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); }) +# define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL)) +# define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock)) +# define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock)) +# define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock)) +# define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock)) +#else +/* Eventually we will allow multi-threaded applications to use the + libraries. Therefore we will add the necessary locking although + the macros used expand to nothing for now. */ +# define rwlock_define(class,name) class int name +# define rwlock_init(lock) ((void) (lock)) +# define rwlock_fini(lock) ((void) (lock)) +# define rwlock_rdlock(lock) ((void) (lock)) +# define rwlock_wrlock(lock) ((void) (lock)) +# define rwlock_unlock(lock) ((void) (lock)) +#endif /* USE_LOCKS */ + +/* gettext helper macro. */ +#define N_(Str) Str + +/* Compiler-specific definitions. */ +#define strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); + +#ifdef __i386__ +# define internal_function __attribute__ ((regparm (3), stdcall)) +#else +# define internal_function /* nothing */ +#endif + +#define internal_strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function; + +#define attribute_hidden \ + __attribute__ ((visibility ("hidden"))) + +/* Define ALLOW_UNALIGNED if the architecture allows operations on + unaligned memory locations. */ +#define SANITIZE_UNDEFINED 1 +#if (defined __i386__ || defined __x86_64__) && ! CHECK_UNDEFINED +# define ALLOW_UNALIGNED 1 +#else +# define ALLOW_UNALIGNED 0 +#endif + +#if DEBUGPRED +# ifdef __x86_64__ +asm (".section predict_data, \"aw\"; .previous\n" + ".section predict_line, \"a\"; .previous\n" + ".section predict_file, \"a\"; .previous"); +# ifndef PIC +# define debugpred__(e, E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \ + ".section predict_line; .quad %c1\n" \ + ".section predict_file; .quad %c2; .popsection\n" \ + "addq $1,..predictcnt%=(,%0,8)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# endif +# elif defined __i386__ +asm (".section predict_data, \"aw\"; .previous\n" + ".section predict_line, \"a\"; .previous\n" + ".section predict_file, \"a\"; .previous"); +# ifndef PIC +# define debugpred__(e, E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \ + ".section predict_line; .long %c1\n" \ + ".section predict_file; .long %c2; .popsection\n" \ + "incl ..predictcnt%=(,%0,8)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# endif +# endif +# ifdef debugpred__ +# define unlikely(e) debugpred__ (e,0) +# define likely(e) debugpred__ (e,1) +# endif +#endif +#ifndef likely +# define unlikely(expr) __builtin_expect (!!(expr), 0) +# define likely(expr) __builtin_expect (!!(expr), 1) +#endif + +#define obstack_calloc(ob, size) \ + ({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); }) +#define obstack_strdup(ob, str) \ + ({ const char *_s = (str); obstack_copy0 (ob, _s, strlen (_s)); }) +#define obstack_strndup(ob, str, n) \ + ({ const char *_s = (str); obstack_copy0 (ob, _s, strnlen (_s, n)); }) + +#if __STDC_VERSION__ >= 199901L +# define flexarr_size /* empty */ +#else +# define flexarr_size 0 +#endif + +/* Calling conventions. */ +#ifdef __i386__ +# define CALLING_CONVENTION regparm (3), stdcall +# define AND_CALLING_CONVENTION , regparm (3), stdcall +#else +# define CALLING_CONVENTION +# define AND_CALLING_CONVENTION +#endif + +/* Avoid PLT entries. */ +#ifdef PIC +# define INTUSE(name) _INTUSE(name) +# define _INTUSE(name) __##name##_internal +# define INTDEF(name) _INTDEF(name) +# define _INTDEF(name) \ + extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name))); +# define INTDECL(name) _INTDECL(name) +# define _INTDECL(name) \ + extern __typeof__ (name) __##name##_internal attribute_hidden; +#else +# define INTUSE(name) name +# define INTDEF(name) /* empty */ +# define INTDECL(name) /* empty */ +#endif + +/* This macro is used by the tests conditionalize for standalone building. */ +#define ELFUTILS_HEADER(name) + + +#ifdef SYMBOL_VERSIONING +# define OLD_VERSION(name, version) \ + asm (".globl _compat." #version "." #name "\n" \ + "_compat." #version "." #name " = " #name "\n" \ + ".symver _compat." #version "." #name "," #name "@" #version); +# define NEW_VERSION(name, version) \ + asm (".symver " #name "," #name "@@@" #version); +# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ + asm (".symver _compat." #version "." #name "," #name "@" #version); \ + __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \ + asm ("_compat." #version "." #name); +# define COMPAT_VERSION(name, version, prefix) \ + asm (".symver _compat." #version "." #name "," #name "@" #version); \ + __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name); +#else +# define OLD_VERSION(name, version) /* Nothing for static linking. */ +# define NEW_VERSION(name, version) /* Nothing for static linking. */ +# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ + error "should use #ifdef SYMBOL_VERSIONING" +# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING" +#endif + + +#endif /* eu-config.h */ diff --git a/elfutils/libelf/fixedsizehash.h b/elfutils/libelf/fixedsizehash.h new file mode 100644 index 0000000000..dac2a5f559 --- /dev/null +++ b/elfutils/libelf/fixedsizehash.h @@ -0,0 +1,272 @@ +/* Fixed size hash table with internal linking. + Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include +#include + +#include + +#ifdef __CONCAT +#define CONCAT(t1,t2) __CONCAT (t1,t2) +#else +#define STROF(t2) t2 +#define CONCAT_EXPANDED(t1,t2) t1 ## t2 +#define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2) +#endif + +/* Before including this file the following macros must be defined: + + TYPE data type of the hash table entries + HASHFCT name of the hashing function to use + HASHTYPE type used for the hashing value + COMPARE comparison function taking two pointers to TYPE objects + CLASS can be defined to `static' to avoid exporting the functions + PREFIX prefix to be used for function and data type names + STORE_POINTER if defined the table stores a pointer and not an element + of type TYPE + INSERT_HASH if defined alternate insert function which takes a hash + value is defined + NO_FINI_FCT if defined the fini function is not defined +*/ + + +/* Defined separately. */ +extern size_t next_prime (size_t seed); + + +/* Set default values. */ +#ifndef HASHTYPE +# define HASHTYPE size_t +#endif + +#ifndef CLASS +# define CLASS +#endif + +#ifndef PREFIX +# define PREFIX +#endif + + +/* The data structure. */ +struct CONCAT(PREFIX,fshash) +{ + size_t nslots; + struct CONCAT(PREFIX,fshashent) + { + HASHTYPE hval; +#ifdef STORE_POINTER +# define ENTRYP(el) (el).entry + TYPE *entry; +#else +# define ENTRYP(el) &(el).entry + TYPE entry; +#endif + } table[0]; +}; + + +/* Constructor for the hashing table. */ +CLASS struct CONCAT(PREFIX,fshash) * +CONCAT(PREFIX,fshash_init) (size_t nelems) +{ + struct CONCAT(PREFIX,fshash) *result; + /* We choose a size for the hashing table 150% over the number of + entries. This will guarantee short medium search lengths. */ + const size_t max_size_t = ~((size_t) 0); + + if (nelems >= (max_size_t / 3) * 2) + { + errno = EINVAL; + return NULL; + } + + /* Adjust the size to be used for the hashing table. */ + nelems = next_prime (MAX ((nelems * 3) / 2, 10)); + + /* Allocate the data structure for the result. */ + result = (struct CONCAT(PREFIX,fshash) *) + xcalloc (sizeof (struct CONCAT(PREFIX,fshash)) + + (nelems + 1) * sizeof (struct CONCAT(PREFIX,fshashent)), 1); + if (result == NULL) + return NULL; + + result->nslots = nelems; + + return result; +} + + +#ifndef NO_FINI_FCT +CLASS void +CONCAT(PREFIX,fshash_fini) (struct CONCAT(PREFIX,fshash) *htab) +{ + free (htab); +} +#endif + + +static struct CONCAT(PREFIX,fshashent) * +CONCAT(PREFIX,fshash_lookup) (struct CONCAT(PREFIX,fshash) *htab, + HASHTYPE hval, TYPE *data) +{ + size_t idx = 1 + hval % htab->nslots; + + if (htab->table[idx].hval != 0) + { + HASHTYPE hash; + + /* See whether this is the same entry. */ + if (htab->table[idx].hval == hval + && COMPARE (data, ENTRYP (htab->table[idx])) == 0) + return &htab->table[idx]; + + /* Second hash function as suggested in [Knuth]. */ + hash = 1 + hval % (htab->nslots - 2); + + do + { + if (idx <= hash) + idx = htab->nslots + idx - hash; + else + idx -= hash; + + if (htab->table[idx].hval == hval + && COMPARE (data, ENTRYP(htab->table[idx])) == 0) + return &htab->table[idx]; + } + while (htab->table[idx].hval != 0); + } + + return &htab->table[idx]; +} + + +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_insert) (struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + if (slot->hval != 0) + /* We don't want to overwrite the old value. */ + return -1; + + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} + + +#ifdef INSERT_HASH +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_insert_hash) (struct CONCAT(PREFIX,fshash) *htab, + HASHTYPE hval, TYPE *data) +{ + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + if (slot->hval != 0) + /* We don't want to overwrite the old value. */ + return -1; + + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} +#endif + + +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_overwrite) (struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), + TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} + + +CLASS const TYPE * +CONCAT(PREFIX,fshash_find) (const struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) ((struct CONCAT(PREFIX,fshash) *) htab, + hval, data); + if (slot->hval == 0) + /* Not found. */ + return NULL; + + return ENTRYP(*slot); +} + + +/* Unset the macros we expect. */ +#undef TYPE +#undef HASHFCT +#undef HASHTYPE +#undef COMPARE +#undef CLASS +#undef PREFIX +#undef INSERT_HASH +#undef STORE_POINTER +#undef NO_FINI_FCT diff --git a/elfutils/libelf/system.h b/elfutils/libelf/system.h new file mode 100644 index 0000000000..5b6b8dfdfc --- /dev/null +++ b/elfutils/libelf/system.h @@ -0,0 +1,150 @@ +/* Declarations for common convenience functions. + Copyright (C) 2006-2011 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef LIB_SYSTEM_H +#define LIB_SYSTEM_H 1 + +#include +#include +#include +#include +#include +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define LE32(n) (n) +# define LE64(n) (n) +# define BE32(n) bswap_32 (n) +# define BE64(n) bswap_64 (n) +#elif __BYTE_ORDER == __BIG_ENDIAN +# define BE32(n) (n) +# define BE64(n) (n) +# define LE32(n) bswap_32 (n) +# define LE64(n) bswap_64 (n) +#else +# error "Unknown byte order" +#endif + +#ifndef MAX +#define MAX(m, n) ((m) < (n) ? (n) : (m)) +#endif + +#ifndef MIN +#define MIN(m, n) ((m) < (n) ? (m) : (n)) +#endif + +#if !HAVE_DECL_MEMPCPY +#define mempcpy(dest, src, n) \ + ((void *) ((char *) memcpy (dest, src, n) + (size_t) n)) +#endif + +/* A special gettext function we use if the strings are too short. */ +#define sgettext(Str) \ + ({ const char *__res = strrchr (gettext (Str), '|'); \ + __res ? __res + 1 : Str; }) + +#define gettext_noop(Str) Str + +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(expression) \ + ({ ssize_t __res; \ + do \ + __res = expression; \ + while (__res == -1 && errno == EINTR); \ + __res; }) +#endif + +static inline ssize_t __attribute__ ((unused)) +pwrite_retry (int fd, const void *buf, size_t len, off_t off) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd, + off + recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +static inline ssize_t __attribute__ ((unused)) +write_retry (int fd, const void *buf, size_t len) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +static inline ssize_t __attribute__ ((unused)) +pread_retry (int fd, void *buf, size_t len, off_t off) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd, + off + recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +/* The demangler from libstdc++. */ +extern char *__cxa_demangle (const char *mangled_name, char *output_buffer, + size_t *length, int *status); + +/* A static assertion. This will cause a compile-time error if EXPR, + which must be a compile-time constant, is false. */ + +#define eu_static_assert(expr) \ + extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \ + __attribute__ ((unused)) + +#endif /* system.h */