aboutsummaryrefslogtreecommitdiff
path: root/contrib/xz/src/liblzma/common/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/xz/src/liblzma/common/common.h')
-rw-r--r--contrib/xz/src/liblzma/common/common.h123
1 files changed, 111 insertions, 12 deletions
diff --git a/contrib/xz/src/liblzma/common/common.h b/contrib/xz/src/liblzma/common/common.h
index b3d3b7a059b1..378923e4012b 100644
--- a/contrib/xz/src/liblzma/common/common.h
+++ b/contrib/xz/src/liblzma/common/common.h
@@ -17,23 +17,104 @@
#include "mythread.h"
#include "tuklib_integer.h"
+// LZMA_API_EXPORT is used to mark the exported API functions.
+// It's used to define the LZMA_API macro.
+//
+// lzma_attr_visibility_hidden is used for marking *declarations* of extern
+// variables that are internal to liblzma (-fvisibility=hidden alone is
+// enough to hide the *definitions*). Such markings allow slightly more
+// efficient code to accesses those variables in ELF shared libraries.
#if defined(_WIN32) || defined(__CYGWIN__)
# ifdef DLL_EXPORT
# define LZMA_API_EXPORT __declspec(dllexport)
# else
# define LZMA_API_EXPORT
# endif
+# define lzma_attr_visibility_hidden
// Don't use ifdef or defined() below.
#elif HAVE_VISIBILITY
# define LZMA_API_EXPORT __attribute__((__visibility__("default")))
+# define lzma_attr_visibility_hidden \
+ __attribute__((__visibility__("hidden")))
#else
# define LZMA_API_EXPORT
+# define lzma_attr_visibility_hidden
#endif
#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
#include "lzma.h"
+// This is for detecting modern GCC and Clang attributes
+// like __symver__ in GCC >= 10.
+#ifdef __has_attribute
+# define lzma_has_attribute(attr) __has_attribute(attr)
+#else
+# define lzma_has_attribute(attr) 0
+#endif
+
+// The extra symbol versioning in the C files may only be used when
+// building a shared library. If HAVE_SYMBOL_VERSIONS_LINUX is defined
+// to 2 then symbol versioning is done only if also PIC is defined.
+// By default Libtool defines PIC when building a shared library and
+// doesn't define it when building a static library but it can be
+// overridden with --with-pic and --without-pic. configure let's rely
+// on PIC if neither --with-pic or --without-pic was used.
+#if defined(HAVE_SYMBOL_VERSIONS_LINUX) \
+ && (HAVE_SYMBOL_VERSIONS_LINUX == 2 && !defined(PIC))
+# undef HAVE_SYMBOL_VERSIONS_LINUX
+#endif
+
+#ifdef HAVE_SYMBOL_VERSIONS_LINUX
+// To keep link-time optimization (LTO, -flto) working with GCC,
+// the __symver__ attribute must be used instead of __asm__(".symver ...").
+// Otherwise the symbol versions may be lost, resulting in broken liblzma
+// that has wrong default versions in the exported symbol list!
+// The attribute was added in GCC 10; LTO with older GCC is not supported.
+//
+// To keep -Wmissing-prototypes happy, use LZMA_SYMVER_API only with function
+// declarations (including those with __alias__ attribute) and LZMA_API with
+// the function definitions. This means a little bit of silly copy-and-paste
+// between declarations and definitions though.
+//
+// As of GCC 12.2, the __symver__ attribute supports only @ and @@ but the
+// very convenient @@@ isn't supported (it's supported by GNU assembler
+// since 2000). When using @@ instead of @@@, the internal name must not be
+// the same as the external name to avoid problems in some situations. This
+// is why "#define foo_52 foo" is needed for the default symbol versions.
+//
+// __has_attribute is supported before GCC 10 and it is supported in Clang 14
+// too (which doesn't support __symver__) so use it to detect if __symver__
+// is available. This should be far more reliable than looking at compiler
+// version macros as nowadays especially __GNUC__ is defined by many compilers.
+# if lzma_has_attribute(__symver__)
+# define LZMA_SYMVER_API(extnamever, type, intname) \
+ extern __attribute__((__symver__(extnamever))) \
+ LZMA_API(type) intname
+# else
+# define LZMA_SYMVER_API(extnamever, type, intname) \
+ __asm__(".symver " #intname "," extnamever); \
+ extern LZMA_API(type) intname
+# endif
+#endif
+
+// MSVC has __forceinline which shouldn't be combined with the inline keyword
+// (results in a warning).
+//
+// GCC 3.1 added always_inline attribute so we don't need to check
+// for __GNUC__ version. Similarly, all relevant Clang versions
+// support it (at least Clang 3.0.0 does already).
+// Other compilers might support too which also support __has_attribute
+// (Solaris Studio) so do that check too.
+#if defined(_MSC_VER)
+# define lzma_always_inline __forceinline
+#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) \
+ || lzma_has_attribute(__always_inline__)
+# define lzma_always_inline inline __attribute__((__always_inline__))
+#else
+# define lzma_always_inline inline
+#endif
+
// These allow helping the compiler in some often-executed branches, whose
// result is almost always the same.
#ifdef __GNUC__
@@ -67,14 +148,15 @@
#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
-/// Supported flags that can be passed to lzma_stream_decoder()
-/// or lzma_auto_decoder().
+/// Supported flags that can be passed to lzma_stream_decoder(),
+/// lzma_auto_decoder(), or lzma_stream_decoder_mt().
#define LZMA_SUPPORTED_FLAGS \
( LZMA_TELL_NO_CHECK \
| LZMA_TELL_UNSUPPORTED_CHECK \
| LZMA_TELL_ANY_CHECK \
| LZMA_IGNORE_CHECK \
- | LZMA_CONCATENATED )
+ | LZMA_CONCATENATED \
+ | LZMA_FAIL_FAST )
/// Largest valid lzma_action value as unsigned integer.
@@ -83,9 +165,12 @@
/// Special return value (lzma_ret) to indicate that a timeout was reached
/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
-/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
-/// there's no need to have it in the public API.
-#define LZMA_TIMED_OUT 32
+/// LZMA_OK in lzma_code().
+#define LZMA_TIMED_OUT LZMA_RET_INTERNAL1
+
+/// Special return value (lzma_ret) for use in stream_decoder_mt.c to
+/// indicate Index was detected instead of a Block Header.
+#define LZMA_INDEX_DETECTED LZMA_RET_INTERNAL2
typedef struct lzma_next_coder_s lzma_next_coder;
@@ -118,8 +203,11 @@ typedef void (*lzma_end_function)(
/// an array of lzma_filter_info structures. This array is used with
/// lzma_next_filter_init to initialize the filter chain.
struct lzma_filter_info_s {
- /// Filter ID. This is used only by the encoder
- /// with lzma_filters_update().
+ /// Filter ID. This can be used to share the same initiazation
+ /// function *and* data structures with different Filter IDs
+ /// (LZMA_FILTER_LZMA1EXT does it), and also by the encoder
+ /// with lzma_filters_update() if filter chain is updated
+ /// in the middle of a raw stream or Block (LZMA_SYNC_FLUSH).
lzma_vli id;
/// Pointer to function used to initialize the filter.
@@ -173,6 +261,16 @@ struct lzma_next_coder_s {
lzma_ret (*update)(void *coder, const lzma_allocator *allocator,
const lzma_filter *filters,
const lzma_filter *reversed_filters);
+
+ /// Set how many bytes of output this coder may produce at maximum.
+ /// On success LZMA_OK must be returned.
+ /// If the filter chain as a whole cannot support this feature,
+ /// this must return LZMA_OPTIONS_ERROR.
+ /// If no input has been given to the coder and the requested limit
+ /// is too small, this must return LZMA_BUF_ERROR. If input has been
+ /// seen, LZMA_OK is allowed too.
+ lzma_ret (*set_out_limit)(void *coder, uint64_t *uncomp_size,
+ uint64_t out_limit);
};
@@ -188,6 +286,7 @@ struct lzma_next_coder_s {
.get_check = NULL, \
.memconfig = NULL, \
.update = NULL, \
+ .set_out_limit = NULL, \
}
@@ -226,14 +325,14 @@ struct lzma_internal_s {
/// Allocates memory
-extern void *lzma_alloc(size_t size, const lzma_allocator *allocator)
- lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
+lzma_attr_alloc_size(1)
+extern void *lzma_alloc(size_t size, const lzma_allocator *allocator);
/// Allocates memory and zeroes it (like calloc()). This can be faster
/// than lzma_alloc() + memzero() while being backward compatible with
/// custom allocators.
-extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
- lzma_alloc_zero(size_t size, const lzma_allocator *allocator);
+lzma_attr_alloc_size(1)
+extern void *lzma_alloc_zero(size_t size, const lzma_allocator *allocator);
/// Frees memory
extern void lzma_free(void *ptr, const lzma_allocator *allocator);