From a71741e62aa0d296bdbfdaa8ca77ea8030d9ea0b Mon Sep 17 00:00:00 2001 From: Yongkui Han Date: Thu, 17 Dec 2020 21:35:59 -0500 Subject: [PATCH] Add func-level OSC-METRICS for GNU fortify-source compiling --- README.md | 68 + VERSION | 2 +- configure | 20 +- include/openosc.h | 32 +- include/openosc_extern.h | 2 + include/openosc_fortify.h | 4 - include/openosc_fortify_extern.h | 2 + include/openosc_fortify_redefine_map.h | 4 + include/openosc_fortify_redefine_nomap.h | 4 + include/openosc_fortify_redirect_map.h | 4 + include/openosc_fortify_redirect_nomap.h | 4 + include/openosc_map_metric.h | 12 - include/openosc_metric_only.h | 472 +++++ include/openosc_metric_only2.h | 2007 ++++++++++++++++++++++ include/openosc_nomap_metric.h | 6 + include/openosc_redefine_nomap.h | 3 - include/openosc_redirect_nomap.h | 3 - test/openosc_fortify_test.c | 14 + test/openosc_test.c | 73 +- tools/oscmetrics.py | 27 +- 20 files changed, 2682 insertions(+), 81 deletions(-) create mode 100644 include/openosc_metric_only.h create mode 100644 include/openosc_metric_only2.h diff --git a/README.md b/README.md index 00e10af..553f116 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Table of Contents * [Overview](#Overview) * [Design Considerations](#Design-Considerations) * [Relationship to FORTIFY_SOURCE](#Relationship-to-FORTIFY_SOURCE) +* [Metric-only Mode for FORTIFY_SOURCE](#Metric-only-Mode-for-FORTIFY_SOURCE) * [How to Build OpenOSC Library](#How-to-Build-OpenOSC-Library) * [How to Build Packages with OpenOSC Library](#How-to-Build-Packages-with-OpenOSC-Library) * [Tested Platforms](#Tested-Platforms) @@ -177,6 +178,68 @@ Here is a comparison summary table: | Logging | No syslog | Syslog/Configurable | | Cover new routine | Not easy | Easy | +Metric-only Mode for FORTIFY_SOURCE +------------------------------ +The OpenOSC OSC-METRICS feature has been enhanced to work with FORTIFY_SOURCE +feature enabled. + +It is enabled by adding `-DOPENOSC_METRIC_ONLY_MODE` option to CFLAGS. + + CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -D_FORTIFY_SOURCE=2" + +This does not turn on OSC-METRICS for objsize/copylen. If you want it, add the +OPENOSC_METRIC_OBJSIZE_ENABLED flag. + + CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -DOPENOSC_METRIC_OBJSIZE_ENABLED -D_FORTIFY_SOURCE=2" + +This will generate the same OSC-METRICS watermarks for the compiled binary +file with the OPENOSC_METRIC_FEATURE_ENABLED flag. And you can use the same +tools/oscmetrics.py script to decode the OSC-METRICS watermarks. + +With this OPENOSC_METRIC_ONLY_MODE flag, the memory/string functions will +always be mapped to itself, except for the addition of OSC-METRICS. The +generated assembly/binary code should also be the same as before, except for +the addition of OSC-METRICS. Of course, out-of-order generation of some assembly +instructions are expected, and still considered the same code. + +The nice thing about this metric-only mode is that you don't need to build the +libopenosc.so library. You don't need to change your linking LDFLAGS, since you +don't link with any additional library. The only change required is CFLAGS. + +Note this Metric-only mode also works without FORTIFY_SOURCE feature. It will +map all functions to themselves, except for the addition of OSC-METRICS. There +is no need to change LDFLAGS and no need to build the libopenosc.so library. + + CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -U_FORTIFY_SOURCE" + +There are multiple flags to control the set of memory/string functions to +cover. For example, defining OPENOSC_DISABLE_SOCKET_H_FUNCS will not cover +all functions declared in the sys/socket.h header file, and defining the +OPENOSC_DISABLE_STDIO_H_FUNCS flag will not cover all functions in the stdio.h +header file. Defining OPENOSC_POLL_DISABLE will not cover the poll function. + +You can also control the level of OSC-METRICS details. For example, you +can define OPENOSC_NOMAP_METRIC_ONLY to always map all functions to CASE0, +i.e., the NOMAP case, instead of more detailed CASE1/CASE2/CASE3/CASE4, +which correnspond to Safe/Overflow/Runtime-protection/Unknown cases, +respectively. This can help quickly find the occurrences of all function +invocations in your code. By default, source buffer overread feature is ON, +but you can define the OPENOSC_SRC_OVERREAD_DISABLE flag to turn if off. + +One disadvantage of this Metric-only mode is: it can suppress some +compile-time warning messages that are defined by function attributes +of the OpenOSC covered functions, for example, the warn-unused-result +or nonnull function attribute. + +The clang compiler seems to implement its fortify-source buffer-overflow warning +messages with function attributes, thus the buffer-overflow warnings messages +are also suppressed with the Metric-only mode in clang. If clang can also check +the warning condition in the optimization phase, in addition to the front-end +(pre-optimization phase), then this issue can be fixed. + +The gcc and icc compiler have no such issue, and are able to report compile-time +buffer-overflow warning messages, with Metric-only mode. + How to Build OpenOSC Library ---------------------------- The build system for the OpenOSC library is the well known GNU build system, @@ -319,6 +382,11 @@ Known Issues However, OPENOSC_METRIC_OBJSIZE_ENABLED impacts the compilation performance significantly, especially for Clang. +3. OPENOSC_METRIC_ONLY_MODE suppresses some compile-time warning messages that +are implemented by function attributes of the covered functions, like +-Wunused-result. Fortify-source buffer-overflow warnings are suppressed for +clang, but not for gcc/icc. + References ---------- - [1] OpenOSC: Open Source Object Size Checking Library With Built-in diff --git a/VERSION b/VERSION index ee90284..90a27f9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.4 +1.0.5 diff --git a/configure b/configure index 68c9896..a2c9396 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for openosc 1.0.4. +# Generated by GNU Autoconf 2.69 for openosc 1.0.5. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='openosc' PACKAGE_TARNAME='openosc' -PACKAGE_VERSION='1.0.4' -PACKAGE_STRING='openosc 1.0.4' +PACKAGE_VERSION='1.0.5' +PACKAGE_STRING='openosc 1.0.5' PACKAGE_BUGREPORT='yonhan@cisco.com' PACKAGE_URL='' @@ -1329,7 +1329,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures openosc 1.0.4 to adapt to many kinds of systems. +\`configure' configures openosc 1.0.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1399,7 +1399,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of openosc 1.0.4:";; + short | recursive ) echo "Configuration of openosc 1.0.5:";; esac cat <<\_ACEOF @@ -1508,7 +1508,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -openosc configure 1.0.4 +openosc configure 1.0.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1998,7 +1998,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by openosc $as_me 1.0.4, which was +It was created by openosc $as_me 1.0.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2861,7 +2861,7 @@ fi # Define the identity of the package. PACKAGE='openosc' - VERSION='1.0.4' + VERSION='1.0.5' cat >>confdefs.h <<_ACEOF @@ -16738,7 +16738,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by openosc $as_me 1.0.4, which was +This file was extended by openosc $as_me 1.0.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16804,7 +16804,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -openosc config.status 1.0.4 +openosc config.status 1.0.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/include/openosc.h b/include/openosc.h index 6efd8ae..c403886 100644 --- a/include/openosc.h +++ b/include/openosc.h @@ -13,6 +13,19 @@ #include "openosc_header_metric.h" +/* define the object size checking type in builtin function */ +#define OSC_OBJECT_SIZE_CHECK_0 0 +#define OSC_OBJECT_SIZE_CHECK_1 1 + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* Source over-read is enabled by default, but can be disabled */ +#ifndef OPENOSC_SRC_OVERREAD_DISABLE +#define _OPENOSC_SRC_OVERREAD_ENABLED +#endif + /* * There are two methods to remap a function to openosc_* function: * 1. The function redirect via ASM-label mechanism. @@ -40,10 +53,25 @@ #define NO_OBJECT_SIZE_CHECKING #endif +#ifdef OPENOSC_SKIP_CSTRING_HEADER +#ifdef __cplusplus +#if OPENOSC_MAPPING_METHOD == OPENOSC_FUNC_MACRO_REDEFINE_METHOD || defined OPENOSC_METRIC_ONLY_MODE +/* define the below macro to avoid including header, which #undef >10 memcpy/strcpy functions */ +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 2 +#endif +#endif +#endif +#endif + + #ifdef NO_OBJECT_SIZE_CHECKING #pragma message ("OSC-WARN-DISABLED: OpenOSC disabled due to NO_OBJECT_SIZE_CHECKING, contact OpenOSC package owner for guidance") #elif defined __ASSEMBLER__ #pragma message ("OSC-WARN-ASM: OpenOSC disabled due to __ASSEMBLER__, contact OpenOSC package owner for guidance") +#elif defined OPENOSC_METRIC_ONLY_MODE +#pragma message ("OSC-WARN-METRICONLY: OpenOSC disabled due to METRIC_ONLY_MODE, contact OpenOSC package owner for guidance") +#include "openosc_metric_only.h" #elif !defined __OPTIMIZE__ /* #error "OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance" */ #pragma message ("OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance") @@ -148,10 +176,6 @@ ********************************************************************************** **********************************************************************************/ -/* define the object size checking type in builtin function */ -#define OSC_OBJECT_SIZE_CHECK_0 0 -#define OSC_OBJECT_SIZE_CHECK_1 1 - #include "openosc_map.h" #ifdef HAS_SAFEC diff --git a/include/openosc_extern.h b/include/openosc_extern.h index c45619b..beb6b2f 100644 --- a/include/openosc_extern.h +++ b/include/openosc_extern.h @@ -20,11 +20,13 @@ typedef __builtin_va_list va_list; #endif +#ifndef OSC_THROW #ifdef __cplusplus #define OSC_THROW __THROW #else #define OSC_THROW #endif +#endif /* libC APIs */ extern void *memcpy(void *dst, const void *src, size_t len) OSC_THROW; diff --git a/include/openosc_fortify.h b/include/openosc_fortify.h index b396458..c7469fd 100644 --- a/include/openosc_fortify.h +++ b/include/openosc_fortify.h @@ -207,10 +207,6 @@ #endif -/* Source over-read is enabled by default, but can be disabled */ -#ifndef OPENOSC_SRC_OVERREAD_DISABLE -#define _OPENOSC_SRC_OVERREAD_ENABLED -#endif /* Errors are reported at compile-time unless you disable it explicitly */ #ifndef OPENOSC_OVERFLOW_ERROR_OUT_DISABLE /* Do we want to error out at compile-time when detecting overflow/overread */ diff --git a/include/openosc_fortify_extern.h b/include/openosc_fortify_extern.h index ceb56d5..5f9e17b 100644 --- a/include/openosc_fortify_extern.h +++ b/include/openosc_fortify_extern.h @@ -19,11 +19,13 @@ typedef __builtin_va_list va_list; #endif +#ifndef OSC_THROW #ifdef __cplusplus #define OSC_THROW __THROW #else #define OSC_THROW #endif +#endif /* The below data type forward declarations are required */ diff --git a/include/openosc_fortify_redefine_map.h b/include/openosc_fortify_redefine_map.h index 5f51ca9..8ba2c4a 100644 --- a/include/openosc_fortify_redefine_map.h +++ b/include/openosc_fortify_redefine_map.h @@ -1099,6 +1099,8 @@ openosc_gethostname (char *name, size_t len) #define gethostname(name, len) openosc_gethostname(name, len) +#ifndef OPENOSC_GETS_DISABLE + #ifndef __cplusplus /* Mapping for gets */ @@ -1123,6 +1125,8 @@ openosc_gets (char *s) #define gets(s) openosc_gets(s) #endif /* __cplusplus */ +#endif /* OPENOSC_GETS_DISABLE */ + /* Mapping for getwd */ diff --git a/include/openosc_fortify_redefine_nomap.h b/include/openosc_fortify_redefine_nomap.h index 2f59948..bb1ca83 100644 --- a/include/openosc_fortify_redefine_nomap.h +++ b/include/openosc_fortify_redefine_nomap.h @@ -306,6 +306,8 @@ openosc_gethostname (char *name, size_t len) #define gethostname(name, len) openosc_gethostname(name, len) +#ifndef OPENOSC_GETS_DISABLE + /* Mapping for gets */ static inline __attribute__ ((always_inline)) @@ -318,6 +320,8 @@ openosc_gets (char *s) #undef gets #define gets(s) openosc_gets(s) +#endif /* OPENOSC_GETS_DISABLE */ + /* Mapping for getwd */ diff --git a/include/openosc_fortify_redirect_map.h b/include/openosc_fortify_redirect_map.h index c75e37d..741908b 100644 --- a/include/openosc_fortify_redirect_map.h +++ b/include/openosc_fortify_redirect_map.h @@ -706,6 +706,8 @@ __clang_warn_or_error_if(__size_too_small (__bos1, name, len), __dst_overflow_ms } +#ifndef OPENOSC_GETS_DISABLE + /* Mapping for gets */ extern char * @@ -727,6 +729,8 @@ gets (char * __pass_objsize1 s) #endif } +#endif /* OPENOSC_GETS_DISABLE */ + /* Mapping for getwd */ diff --git a/include/openosc_fortify_redirect_nomap.h b/include/openosc_fortify_redirect_nomap.h index 63f418d..3ba17c9 100644 --- a/include/openosc_fortify_redirect_nomap.h +++ b/include/openosc_fortify_redirect_nomap.h @@ -276,6 +276,8 @@ __NTH (gethostname(char *name, size_t len)) } +#ifndef OPENOSC_GETS_DISABLE + /* Mapping for gets */ extern char * __REDIRECT (__openosc_gets_alias, @@ -287,6 +289,8 @@ gets(char *s) return (GETS_NOMAP_CASE __openosc_gets_alias(s)); } +#endif /* OPENOSC_GETS_DISABLE */ + /* Mapping for getwd */ diff --git a/include/openosc_map_metric.h b/include/openosc_map_metric.h index 425fa18..66e1f02 100644 --- a/include/openosc_map_metric.h +++ b/include/openosc_map_metric.h @@ -10,18 +10,6 @@ #ifndef __OPENOSC_MAP_METRIC_H__ #define __OPENOSC_MAP_METRIC_H__ -#ifdef OPENOSC_HEADER_METRIC_FEATURE_ENABLED - -/* always insert a magic word if osc_map.h is included */ -#if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define MAGIC_OSC_MAP_H_INCLUDED 0x80818d8f80818d8e -#else -#define MAGIC_OSC_MAP_H_INCLUDED 0x8e8d81808f8d8180 -#endif -long long int __attribute__((weak)) rtd_osc_map_h_included_int = MAGIC_OSC_MAP_H_INCLUDED; - -#endif /* OPENOSC_HEADER_METRIC_FEATURE_ENABLED */ - #ifdef OPENOSC_METRIC_FEATURE_ENABLED #include "openosc_metric_objsize.h" diff --git a/include/openosc_metric_only.h b/include/openosc_metric_only.h new file mode 100644 index 0000000..978b450 --- /dev/null +++ b/include/openosc_metric_only.h @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2020, Cisco Systems, Inc. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/cisco/openosc/LICENSE + */ + +#ifndef __OPENOSC_METRIC_ONLY_H__ +#define __OPENOSC_METRIC_ONLY_H__ + +/* if OSC metric feature is disabled, we can completely exclude this header */ +#ifdef OPENOSC_METRIC_FEATURE_ENABLED + +#if !defined __OPTIMIZE__ +#ifndef OPENOSC_NOMAP_METRIC_ONLY +#define OPENOSC_NOMAP_METRIC_ONLY +#endif +#endif + +#ifdef _FORTIFY_SOURCE +#if __clang__ +#warning "The OSC-METRICS feature suppresses fortify-source buffer-overflow warnings for clang" +#else +#warning "The OSC-METRICS feature suppresses some function-attribute warnings, like -Wunused-result/-Wnonnull" +#endif +#endif + + +#ifdef __cplusplus +#include +extern "C" +{ +#endif + + +#include "openosc_extern.h" +#include "openosc_fortify.h" + +#include "openosc_nomap_metric.h" +#include "openosc_map_metric.h" + +#ifndef OPENOSC_NOT_GNU_SOURCE +/* by default, extra GNU functions are supported */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifndef OPENOSC_DISABLE_STRING_H_FUNCS +#include "string.h" +#endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STRING_H_FUNCS + +/* Mapping for memcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) void * +openosc_memcpy (void *dst, const void *src, size_t len) + OSC_THROW +{ + return (MEMCPY_NOMAP_CASE memcpy(dst, src, len)); +} + +#else + +static inline __attribute__ ((always_inline)) void * +openosc_memcpy (void *dst, const void *src, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); + size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); +#ifdef _OPENOSC_SRC_OVERREAD_ENABLED + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? ((_src_sz != (size_t) -1) + ? ((_src_sz >= len) + ? (MEMCPY_CASE7 memcpy(dst, src, len)) + : (MEMCPY_CASE8 memcpy(dst, src, len))) + : (MEMCPY_CASE1 memcpy(dst, src, len))) + : (MEMCPY_CASE2 memcpy(dst, src, len))) + : (MEMCPY_CASE3 memcpy(dst, src, len))) + : ((_src_sz != (size_t) -1) + ? (is_len_constant + ? ((_src_sz >= len) + ? (MEMCPY_CASEa memcpy(dst, src, len)) + : (MEMCPY_CASEb memcpy(dst, src, len))) + : (MEMCPY_CASE9 memcpy(dst, src, len))) + : (MEMCPY_CASE4 memcpy(dst, src, len)))); +#else + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (MEMCPY_CASE1 memcpy(dst, src, len)) + : (MEMCPY_CASE2 memcpy(dst, src, len))) + : (MEMCPY_CASE3 memcpy(dst, src, len))) + : (MEMCPY_CASE4 memcpy(dst, src, len))); +#endif +} +#endif + +#undef memcpy +#define memcpy(dest, src, len) \ + openosc_memcpy(dest, src, len) + + +/* Mapping for memmove */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) void * +openosc_memmove (void *dst, const void *src, size_t len) + OSC_THROW +{ + return (MEMMOVE_NOMAP_CASE memmove(dst, src, len)); +} + +#else + +static inline __attribute__ ((always_inline)) void * +openosc_memmove (void *dst, const void *src, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); + size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); +#ifdef _OPENOSC_SRC_OVERREAD_ENABLED + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? ((_src_sz != (size_t) -1) + ? ((_src_sz >= len) + ? (MEMMOVE_CASE7 memmove(dst, src, len)) + : (MEMMOVE_CASE8 memmove(dst, src, len))) + : (MEMMOVE_CASE1 memmove(dst, src, len))) + : (MEMMOVE_CASE2 memmove(dst, src, len))) + : (MEMMOVE_CASE3 memmove(dst, src, len))) + : ((_src_sz != (size_t) -1) + ? (is_len_constant + ? ((_src_sz >= len) + ? (MEMMOVE_CASEa memmove(dst, src, len)) + : (MEMMOVE_CASEb memmove(dst, src, len))) + : (MEMMOVE_CASE9 memmove(dst, src, len))) + : (MEMMOVE_CASE4 memmove(dst, src, len)))); +#else + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (MEMMOVE_CASE1 memmove(dst, src, len)) + : (MEMMOVE_CASE2 memmove(dst, src, len))) + : (MEMMOVE_CASE3 memmove(dst, src, len))) + : (MEMMOVE_CASE4 memmove(dst, src, len))); +#endif +} +#endif + +#undef memmove +#define memmove(dest, src, len) \ + openosc_memmove(dest, src, len) + +/* Mapping for memset */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) void * +openosc_memset (void *dst, int c, size_t len) + OSC_THROW +{ + return (MEMSET_NOMAP_CASE memset(dst, c, len)); +} + +#else + +static inline __attribute__ ((always_inline)) void * +openosc_memset (void *dst, int c, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (MEMSET_CASE1 memset(dst, c, len)) + : (MEMSET_CASE2 memset(dst, c, len))) + : (MEMSET_CASE3 memset(dst, c, len))) + : (MEMSET_CASE4 memset(dst, c, len))); +} +#endif + +#undef memset +#define memset(dst, c, len) \ + openosc_memset(dst, c, len) + + +/* Mapping for bcopy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) void +openosc_bcopy (const void *src, void *dst, size_t len) + OSC_THROW +{ + return (BCOPY_NOMAP_CASE bcopy(src, dst, len)); +} + +#else + +static inline __attribute__ ((always_inline)) void +openosc_bcopy (const void *src, void *dst, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); + size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); +#ifdef _OPENOSC_SRC_OVERREAD_ENABLED + ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? ((_src_sz != (size_t) -1) + ? ((_src_sz >= len) + ? (BCOPY_CASE7 bcopy(src, dst, len)) + : (BCOPY_CASE8 bcopy(src, dst, len))) + : (BCOPY_CASE1 bcopy(src, dst, len))) + : (BCOPY_CASE2 bcopy(src, dst, len))) + : (BCOPY_CASE3 bcopy(src, dst, len))) + : ((_src_sz != (size_t) -1) + ? (is_len_constant + ? ((_src_sz >= len) + ? (BCOPY_CASEa bcopy(src, dst, len)) + : (BCOPY_CASEb bcopy(src, dst, len))) + : (BCOPY_CASE9 bcopy(src, dst, len))) + : (BCOPY_CASE4 bcopy(src, dst, len)))); +#else + ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (BCOPY_CASE1 bcopy(src, dst, len)) + : (BCOPY_CASE2 bcopy(src, dst, len))) + : (BCOPY_CASE3 bcopy(src, dst, len))) + : (BCOPY_CASE4 bcopy(src, dst, len))); +#endif +} +#endif + +#undef bcopy +#define bcopy(src, dst, len) \ + openosc_bcopy(src, dst, len) + +/* Mapping for bzero */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) void +openosc_bzero (void *dst, size_t len) + OSC_THROW +{ + return (BZERO_NOMAP_CASE bzero(dst, len)); +} + +#else + +static inline __attribute__ ((always_inline)) void +openosc_bzero (void *dst, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); + ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (BZERO_CASE1 bzero(dst, len)) + : (BZERO_CASE2 bzero(dst, len))) + : (BZERO_CASE3 bzero(dst, len))) + : (BZERO_CASE4 bzero(dst, len))); +} +#endif + +#undef bzero +#define bzero(dst, len) \ + openosc_bzero(dst, len) + + +/* Mapping for strcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) char * +openosc_strcpy (char *dst, const char *src) + OSC_THROW +{ + return (STRCPY_NOMAP_CASE strcpy(dst, src)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_strcpy (char *dst, const char *src) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(strlen(src)); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz > strlen(src)) + ? (STRCPY_CASE1 strcpy(dst, src)) + : (STRCPY_CASE2 strcpy(dst, src))) + : (STRCPY_CASE3 strcpy(dst, src))) + : (STRCPY_CASE4 strcpy(dst, src))); +} +#endif + +#undef strcpy +#define strcpy(dst, src) \ + openosc_strcpy(dst, src) + + +/* Mapping for strncpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) char * +openosc_strncpy (char *dst, const char *src, size_t len) + OSC_THROW +{ + return (STRNCPY_NOMAP_CASE strncpy(dst, src, len)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_strncpy (char *dst, const char *src, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (STRNCPY_CASE1 strncpy(dst, src, len)) + : (STRNCPY_CASE2 strncpy(dst, src, len))) + : (STRNCPY_CASE3 strncpy(dst, src, len))) + : (STRNCPY_CASE4 strncpy(dst, src, len))); +} +#endif + +#undef strncpy +#define strncpy(dest, src, len) \ + openosc_strncpy(dest, src, len) + +/* Mapping for strcat */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) char * +openosc_strcat (char *dst, const char *src) + OSC_THROW +{ + return (STRCAT_NOMAP_CASE strcat(dst, src)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_strcat (char *dst, const char *src) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(strlen(src)); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz > strlen(src)) + ? (STRCAT_CASE1 strcat(dst, src)) + : (STRCAT_CASE2 strcat(dst, src))) + : (STRCAT_CASE3 strcat(dst, src))) + : (STRCAT_CASE4 strcat(dst, src))); +} +#endif + +#undef strcat +#define strcat(dst, src) \ + openosc_strcat(dst, src) + +/* Mapping for strncat */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) char * +openosc_strncat (char *dst, const char *src, size_t len) + OSC_THROW +{ + return (STRNCAT_NOMAP_CASE strncat(dst, src, len)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_strncat (char *dst, const char *src, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz > len) + ? (STRNCAT_CASE1 strncat(dst, src, len)) + : (STRNCAT_CASE2 strncat(dst, src, len))) + : (STRNCAT_CASE3 strncat(dst, src, len))) + : (STRNCAT_CASE4 strncat(dst, src, len))); +} +#endif + +#undef strncat +#define strncat(dst, src, len) \ + openosc_strncat(dst, src, len) + +/* Mapping for strnlen */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) size_t +openosc_strnlen (const char *s, size_t maxlen) + OSC_THROW +{ + return (STRNLEN_NOMAP_CASE strnlen(s, maxlen)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_strnlen (const char *s, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (STRNLEN_CASE1 strnlen(s, len)) + : (STRNLEN_CASE2 strnlen(s, len))) + : (STRNLEN_CASE3 strnlen(s, len))) + : (STRNLEN_CASE4 strnlen(s, len))); +} +#endif + +#undef strnlen +#define strnlen(s, maxlen) \ + openosc_strnlen(s, maxlen) + +#endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ + +#ifdef HAS_SAFEC +#include "openosc_safec_nomap.h" +#endif + +#ifndef OPENOSC_FORTIFY_FUNCTIONS_DISABLE +#include "openosc_metric_only2.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* OPENOSC_METRIC_FEATURE_ENABLED */ + +#endif /* __OPENOSC_METRIC_ONLY_H__ */ + diff --git a/include/openosc_metric_only2.h b/include/openosc_metric_only2.h new file mode 100644 index 0000000..96db6db --- /dev/null +++ b/include/openosc_metric_only2.h @@ -0,0 +1,2007 @@ +/* + * Copyright (c) 2020, Cisco Systems, Inc. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/cisco/openosc/LICENSE + */ + +#ifndef __OPENOSC_METRIC_ONLY2_H__ +#define __OPENOSC_METRIC_ONLY2_H__ + +/* if OSC metric feature is disabled, we can completely exclude this header */ +#ifdef OPENOSC_METRIC_FEATURE_ENABLED + +#ifndef _FORTIFY_SOURCE +#include "openosc_fortify_extern.h" +#endif +#include "openosc_fortify_nomap_metric.h" +#include "openosc_fortify_map_metric.h" + +#ifndef OPENOSC_NOT_GNU_SOURCE +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS +#include +#endif +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS +#include +#endif +#ifndef OPENOSC_DISABLE_UNISTD_H_FUNCS +#include +#endif +#ifndef OPENOSC_DISABLE_STDLIB_H_FUNCS +#include +#endif +#ifndef OPENOSC_DISABLE_POLL_H_FUNCS +#include +#endif +#ifndef OPENOSC_DISABLE_SOCKET_H_FUNCS +#include +#include +#endif + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS +#ifndef OPENOSC_VALIST_NOSUPPORT + +#ifdef __va_arg_pack + +#ifndef OPENOSC_ASPRINTF_DISABLE + +/* Mapping for asprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_asprintf (char **strp, const char *fmt, ...) +{ + return (ASPRINTF_NOMAP_CASE asprintf(strp, fmt, __va_arg_pack ())); +} + +#undef asprintf +#define asprintf openosc_asprintf + +#endif /* OPENOSC_ASPRINTF_DISABLE */ + + +/* Mapping for dprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_dprintf (int fd, const char *format, ...) +{ + return (DPRINTF_NOMAP_CASE dprintf(fd, format, __va_arg_pack ())); +} + +#undef dprintf +#define dprintf openosc_dprintf + + +/* Mapping for fprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_fprintf (FILE *stream, const char *format, ...) +{ + return (FPRINTF_NOMAP_CASE fprintf(stream, format, __va_arg_pack ())); +} + +#undef fprintf +#define fprintf openosc_fprintf + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for fwprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_fwprintf (FILE *stream, const wchar_t *format, ...) +{ + return (FWPRINTF_NOMAP_CASE fwprintf(stream, format, __va_arg_pack ())); +} + +#undef fwprintf +#define fwprintf openosc_fwprintf + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + + +/* Mapping for printf */ + +static inline __attribute__ ((always_inline)) +int +openosc_printf (const char *format, ...) +{ + return (PRINTF_NOMAP_CASE printf(format, __va_arg_pack ())); +} + +#undef printf +#define printf openosc_printf + + +/* Mapping for snprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_snprintf (char *str, size_t size, const char *format, ...) +{ + return (SNPRINTF_NOMAP_CASE snprintf(str, size, format, __va_arg_pack ())); +} + +#else + +static inline __attribute__ ((always_inline)) +int +openosc_snprintf (char *s, size_t maxlen, const char *format, ...) +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(maxlen); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= maxlen) + ? (SNPRINTF_CASE1 snprintf(s, maxlen, format, __va_arg_pack ())) + : (SNPRINTF_CASE2 snprintf(s, maxlen, format, __va_arg_pack ()))) + : (SNPRINTF_CASE3 snprintf(s, maxlen, format, __va_arg_pack ()))) + : (SNPRINTF_CASE4 snprintf(s, maxlen, format, __va_arg_pack ()))); +} +#endif + +#undef snprintf +#define snprintf openosc_snprintf + + +/* Mapping for sprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_sprintf (char *str, const char *format, ...) +{ + return (SPRINTF_NOMAP_CASE sprintf(str, format, __va_arg_pack ())); +} + +#else + +static inline __attribute__ ((always_inline)) +int +openosc_sprintf (char *s, const char *format, ...) +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (SPRINTF_CASE3 sprintf(s, format, __va_arg_pack ())) + : (SPRINTF_CASE4 sprintf(s, format, __va_arg_pack ()))); +} +#endif + +#undef sprintf +#define sprintf openosc_sprintf + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for swprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_swprintf (wchar_t *wcs, size_t maxlen, const wchar_t *format, ...) + OSC_THROW +{ + return (SWPRINTF_NOMAP_CASE swprintf(wcs, maxlen, format, __va_arg_pack ())); +} + +#else + +static inline __attribute__ ((always_inline)) +int +openosc_swprintf (wchar_t *s, size_t n, const wchar_t *format, ...) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (SWPRINTF_CASE1 swprintf(s, n, format, __va_arg_pack ())) + : (SWPRINTF_CASE2 swprintf(s, n, format, __va_arg_pack ()))) + : (SWPRINTF_CASE3 swprintf(s, n, format, __va_arg_pack ()))) + : (SWPRINTF_CASE4 swprintf(s, n, format, __va_arg_pack ()))); +} +#endif + +#undef swprintf +#define swprintf openosc_swprintf + + +/* Mapping for wprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_wprintf (const wchar_t *format, ...) +{ + return (WPRINTF_NOMAP_CASE wprintf(format, __va_arg_pack ())); +} + +#undef wprintf +#define wprintf openosc_wprintf + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + +#endif /* __va_arg_pack */ + +#endif /* OPENOSC_VALIST_NOSUPPORT */ +#endif /* OPENOSC_DISABLE_STDIO_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_UNISTD_H_FUNCS + +/* Mapping for confstr */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_confstr (int name, char *buf, size_t len) + OSC_THROW +{ + return (CONFSTR_NOMAP_CASE confstr(name, buf, len)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_confstr (int name, char *buf, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (CONFSTR_CASE1 confstr(name, buf, len)) + : (CONFSTR_CASE2 confstr(name, buf, len))) + : (CONFSTR_CASE3 confstr(name, buf, len))) + : (CONFSTR_CASE4 confstr(name, buf, len))); +} +#endif + +#undef confstr +#define confstr(name, buf, len) openosc_confstr(name, buf, len) + +#endif /* OPENOSC_DISABLE_UNISTD_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS +#ifndef OPENOSC_FGETS_DISABLE + +/* Mapping for fgets */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_fgets (char *s, int size, FILE *stream) +{ + return (FGETS_NOMAP_CASE fgets(s, size, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_fgets (char *s, int size, FILE *stream) +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(size); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((size>0 && _sz >= (size_t)size) + ? (FGETS_CASE1 fgets(s, size, stream)) + : (FGETS_CASE2 fgets(s, size, stream))) + : (FGETS_CASE3 fgets(s, size, stream))) + : (FGETS_CASE4 fgets(s, size, stream))); +} +#endif + +#undef fgets +#define fgets(s, size, stream) openosc_fgets(s, size, stream) + +#endif /* OPENOSC_FGETS_DISABLE */ + + +/* Mapping for fgets_unlocked */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_fgets_unlocked (char *s, int n, FILE *stream) +{ + return (FGETS_UNLOCKED_NOMAP_CASE fgets_unlocked(s, n, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_fgets_unlocked (char *s, int n, FILE *stream) +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(n); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((n>0 && _sz >= (size_t)n) + ? (FGETS_UNLOCKED_CASE1 fgets_unlocked(s, n, stream)) + : (FGETS_UNLOCKED_CASE2 fgets_unlocked(s, n, stream))) + : (FGETS_UNLOCKED_CASE3 fgets_unlocked(s, n, stream))) + : (FGETS_UNLOCKED_CASE4 fgets_unlocked(s, n, stream))); +} +#endif + +#undef fgets_unlocked +#define fgets_unlocked(s, n, stream) openosc_fgets_unlocked(s, n, stream) + +#endif /* OPENOSC_DISABLE_STDIO_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for fgetws */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_fgetws (wchar_t *ws, int n, FILE *stream) +{ + return (FGETWS_NOMAP_CASE fgetws(ws, n, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_fgetws (wchar_t *ws, int n, FILE *stream) +{ + size_t _sz_bytes = __builtin_object_size(ws, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((n>0 && _sz >= (size_t)n) + ? (FGETWS_CASE1 fgetws(ws, n, stream)) + : (FGETWS_CASE2 fgetws(ws, n, stream))) + : (FGETWS_CASE3 fgetws(ws, n, stream))) + : (FGETWS_CASE4 fgetws(ws, n, stream))); +} +#endif + +#undef fgetws +#define fgetws(ws, n, stream) openosc_fgetws(ws, n, stream) + + +/* Mapping for fgetws_unlocked */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_fgetws_unlocked (wchar_t *ws, int n, FILE *stream) +{ + return (FGETWS_UNLOCKED_NOMAP_CASE fgetws_unlocked(ws, n, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_fgetws_unlocked (wchar_t *ws, int n, FILE *stream) +{ + size_t _sz_bytes = __builtin_object_size(ws, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((n>0 && _sz >= (size_t)n) + ? (FGETWS_UNLOCKED_CASE1 fgetws_unlocked(ws, n, stream)) + : (FGETWS_UNLOCKED_CASE2 fgetws_unlocked(ws, n, stream))) + : (FGETWS_UNLOCKED_CASE3 fgetws_unlocked(ws, n, stream))) + : (FGETWS_UNLOCKED_CASE4 fgetws_unlocked(ws, n, stream))); +} +#endif + +#undef fgetws_unlocked +#define fgetws_unlocked(ws, n, stream) openosc_fgetws_unlocked(ws, n, stream) + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS + +/* Mapping for fread */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_fread (void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + return (FREAD_NOMAP_CASE fread(ptr, size, nmemb, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_fread (void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t _sz = __builtin_object_size(ptr, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(size); + return ((_sz != (size_t) -1) + ? (is_len_constant && __builtin_constant_p(nmemb) + ? ((_sz >= size * nmemb) + ? (FREAD_CASE1 fread(ptr, size, nmemb, stream)) + : (FREAD_CASE2 fread(ptr, size, nmemb, stream))) + : (FREAD_CASE3 fread(ptr, size, nmemb, stream))) + : (FREAD_CASE4 fread(ptr, size, nmemb, stream))); +} +#endif + +#undef fread +#define fread(ptr, size, nmemb, stream) openosc_fread(ptr, size, nmemb, stream) + + +#ifndef fread_unlocked + +/* Mapping for fread_unlocked */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_fread_unlocked (void *ptr, size_t size, size_t n, FILE *stream) +{ + return (FREAD_UNLOCKED_NOMAP_CASE fread_unlocked(ptr, size, n, stream)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_fread_unlocked (void *ptr, size_t size, size_t n, FILE *stream) +{ + size_t _sz = __builtin_object_size(ptr, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(n); + return ((_sz != (size_t) -1) + ? (is_len_constant && __builtin_constant_p(size) + ? ((_sz >= n * size) + ? (FREAD_UNLOCKED_CASE1 fread_unlocked(ptr, size, n, stream)) + : (FREAD_UNLOCKED_CASE2 fread_unlocked(ptr, size, n, stream))) + : (FREAD_UNLOCKED_CASE3 fread_unlocked(ptr, size, n, stream))) + : (FREAD_UNLOCKED_CASE4 fread_unlocked(ptr, size, n, stream))); +} +#endif + +#undef fread_unlocked +#define fread_unlocked(ptr, size, n, stream) openosc_fread_unlocked(ptr, size, n, stream) + +#endif /* fread_unlocked */ + +#endif /* OPENOSC_DISABLE_STDIO_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_UNISTD_H_FUNCS + +#ifndef OPENOSC_GETCWD_DISABLE + +/* Mapping for getcwd */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_getcwd (char *buf, size_t size) + OSC_THROW +{ + return (GETCWD_NOMAP_CASE getcwd(buf, size)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_getcwd (char *buf, size_t size) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(size); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= size) + ? (GETCWD_CASE1 getcwd(buf, size)) + : (GETCWD_CASE2 getcwd(buf, size))) + : (GETCWD_CASE3 getcwd(buf, size))) + : (GETCWD_CASE4 getcwd(buf, size))); +} +#endif + +#undef getcwd +#define getcwd(buf, size) openosc_getcwd(buf, size) + +#endif /* OPENOSC_GETCWD_DISABLE */ + + +/* Mapping for getdomainname */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_getdomainname (char *name, size_t len) + OSC_THROW +{ + return (GETDOMAINNAME_NOMAP_CASE getdomainname(name, len)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_getdomainname (char *name, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(name, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (GETDOMAINNAME_CASE1 getdomainname(name, len)) + : (GETDOMAINNAME_CASE2 getdomainname(name, len))) + : (GETDOMAINNAME_CASE3 getdomainname(name, len))) + : (GETDOMAINNAME_CASE4 getdomainname(name, len))); +} +#endif + +#undef getdomainname +#define getdomainname(name, len) openosc_getdomainname(name, len) + + +/* Mapping for getgroups */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_getgroups (int size, gid_t list[]) + OSC_THROW +{ + return (GETGROUPS_NOMAP_CASE getgroups(size, list)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_getgroups (int size, gid_t list[]) + OSC_THROW +{ + size_t _sz = __builtin_object_size(list, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(size); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? (((int)(_sz/sizeof(gid_t)) >= size || size == 0) /* size can be 0, which is valid */ + ? (GETGROUPS_CASE1 getgroups(size, list)) + : (GETGROUPS_CASE2 getgroups(size, list))) + : (GETGROUPS_CASE3 getgroups(size, list))) + : (GETGROUPS_CASE4 getgroups(size, list))); +} +#endif + +#undef getgroups +#define getgroups(size, list) openosc_getgroups(size, list) + + +/* Mapping for gethostname */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_gethostname (char *name, size_t len) + OSC_THROW +{ + return (GETHOSTNAME_NOMAP_CASE gethostname(name, len)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_gethostname (char *name, size_t len) + OSC_THROW +{ + size_t _sz = __builtin_object_size(name, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (GETHOSTNAME_CASE1 gethostname(name, len)) + : (GETHOSTNAME_CASE2 gethostname(name, len))) + : (GETHOSTNAME_CASE3 gethostname(name, len))) + : (GETHOSTNAME_CASE4 gethostname(name, len))); +} +#endif + +#undef gethostname +#define gethostname(name, len) openosc_gethostname(name, len) + +#endif /* OPENOSC_DISABLE_UNISTD_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS +#ifndef OPENOSC_GETS_DISABLE + +#ifndef __cplusplus +/* Mapping for gets */ + +extern char *gets(char *s); + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_gets (char *s) +{ + return (GETS_NOMAP_CASE gets(s)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_gets (char *s) +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (GETS_CASE3 gets(s)) + : (GETS_CASE4 gets(s))); +} +#endif + +#undef gets +#define gets(s) openosc_gets(s) + +#endif +#endif /* OPENOSC_GETS_DISABLE */ +#endif /* OPENOSC_DISABLE_STDIO_H_FUNCS */ + + +#ifdef OPENOSC_COVER_DEPRECATED_FUNCS +/* getwd has been deprecated */ + +/* Mapping for getwd */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_getwd (char *buf) + OSC_THROW +{ + return (GETWD_NOMAP_CASE getwd(buf)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_getwd (char *buf) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (GETWD_CASE3 getwd(buf)) + : (GETWD_CASE4 getwd(buf))); +} +#endif + +#undef getwd +#define getwd(buf) openosc_getwd(buf) + +#endif /* OPENOSC_COVER_DEPRECATED_FUNCS */ + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for mbsnrtowcs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_mbsnrtowcs (wchar_t *dest, const char **src, size_t nms, size_t len, mbstate_t *ps) + OSC_THROW +{ + return (MBSNRTOWCS_NOMAP_CASE mbsnrtowcs(dest, src, nms, len, ps)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_mbsnrtowcs (wchar_t *dest, const char **src, size_t nms, size_t len, mbstate_t *ps) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(len); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (MBSNRTOWCS_CASE1 mbsnrtowcs(dest, src, nms, len, ps)) + : (MBSNRTOWCS_CASE2 mbsnrtowcs(dest, src, nms, len, ps))) + : (MBSNRTOWCS_CASE3 mbsnrtowcs(dest, src, nms, len, ps))) + : (MBSNRTOWCS_CASE4 mbsnrtowcs(dest, src, nms, len, ps))); +} +#endif + +#undef mbsnrtowcs +#define mbsnrtowcs(dest, src, nms, len, ps) openosc_mbsnrtowcs(dest, src, nms, len, ps) + + +/* Mapping for mbsrtowcs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_mbsrtowcs (wchar_t *dest, const char **src, size_t len, mbstate_t *ps) + OSC_THROW +{ + return (MBSRTOWCS_NOMAP_CASE mbsrtowcs(dest, src, len, ps)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_mbsrtowcs (wchar_t *dest, const char **src, size_t len, mbstate_t *ps) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(len); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (MBSRTOWCS_CASE1 mbsrtowcs(dest, src, len, ps)) + : (MBSRTOWCS_CASE2 mbsrtowcs(dest, src, len, ps))) + : (MBSRTOWCS_CASE3 mbsrtowcs(dest, src, len, ps))) + : (MBSRTOWCS_CASE4 mbsrtowcs(dest, src, len, ps))); +} +#endif + +#undef mbsrtowcs +#define mbsrtowcs(dest, src, len, ps) openosc_mbsrtowcs(dest, src, len, ps) + + +#ifndef OPENOSC_DISABLE_STDLIB_H_FUNCS + +/* Mapping for mbstowcs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_mbstowcs (wchar_t *dest, const char *src, size_t n) + OSC_THROW +{ + return (MBSTOWCS_NOMAP_CASE mbstowcs(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_mbstowcs (wchar_t *dest, const char *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (MBSTOWCS_CASE1 mbstowcs(dest, src, n)) + : (MBSTOWCS_CASE2 mbstowcs(dest, src, n))) + : (MBSTOWCS_CASE3 mbstowcs(dest, src, n))) + : (MBSTOWCS_CASE4 mbstowcs(dest, src, n))); +} +#endif + +#undef mbstowcs +#define mbstowcs(dest, src, n) openosc_mbstowcs(dest, src, n) + +#endif /* OPENOSC_DISABLE_STDLIB_H_FUNCS */ +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STRING_H_FUNCS +#ifndef OPENOSC_MEMPCPY_DISABLE + +/* Mapping for mempcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +void * +openosc_mempcpy (void *dest, const void *src, size_t n) + OSC_THROW +{ + return (MEMPCPY_NOMAP_CASE mempcpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) void * +openosc_mempcpy (void *dest, const void *src, size_t n) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(n); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (MEMPCPY_CASE1 mempcpy(dest, src, n)) + : (MEMPCPY_CASE2 mempcpy(dest, src, n))) + : (MEMPCPY_CASE3 mempcpy(dest, src, n))) + : (MEMPCPY_CASE4 mempcpy(dest, src, n))); +} +#endif + +#undef mempcpy +#define mempcpy(dest, src, n) openosc_mempcpy(dest, src, n) + +#endif /* OPENOSC_MEMPCPY_DISABLE */ +#endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_POLL_H_FUNCS +#ifndef OPENOSC_POLL_DISABLE + +/* Mapping for poll */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_poll (struct pollfd *fds, nfds_t nfds, int timeout) +{ + return (POLL_NOMAP_CASE poll(fds, nfds, timeout)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_poll (struct pollfd *fds, nfds_t nfds, int timeout) +{ + size_t _sz = __builtin_object_size(fds, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(nfds); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= nfds * (sizeof(int) + sizeof(short) + sizeof(short))) + ? (POLL_CASE1 poll(fds, nfds, timeout)) + : (POLL_CASE2 poll(fds, nfds, timeout))) + : (POLL_CASE3 poll(fds, nfds, timeout))) + : (POLL_CASE4 poll(fds, nfds, timeout))); +} +#endif + +#undef poll +#define poll(fds, nfds, timeout) openosc_poll(fds, nfds, timeout) + +#endif /* OPENOSC_POLL_DISABLE */ + + +#ifndef OPENOSC_PPOLL_DISABLE + +/* Mapping for ppoll */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) +{ + return (PPOLL_NOMAP_CASE ppoll(fds, nfds, timeout_ts, sigmask)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) +{ + size_t _sz = __builtin_object_size(fds, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(nfds); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= nfds * (sizeof(int) + sizeof(short) + sizeof(short))) + ? (PPOLL_CASE1 ppoll(fds, nfds, timeout_ts, sigmask)) + : (PPOLL_CASE2 ppoll(fds, nfds, timeout_ts, sigmask))) + : (PPOLL_CASE3 ppoll(fds, nfds, timeout_ts, sigmask))) + : (PPOLL_CASE4 ppoll(fds, nfds, timeout_ts, sigmask))); +} +#endif + +#undef ppoll +#define ppoll(fds, nfds, timeout_ts, sigmask) openosc_ppoll(fds, nfds, timeout_ts, sigmask) + +#endif /* OPENOSC_PPOLL_DISABLE */ +#endif /* OPENOSC_DISABLE_POLL_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_UNISTD_H_FUNCS +#ifndef OPENOSC_PREAD_DISABLE + +/* Mapping for pread */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_pread (int fd, void *buf, size_t count, off_t offset) +{ + return (PREAD_NOMAP_CASE pread(fd, buf, count, offset)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_pread (int fd, void *buf, size_t count, off_t offset) +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(count); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= count) + ? (PREAD_CASE1 pread(fd, buf, count, offset)) + : (PREAD_CASE2 pread(fd, buf, count, offset))) + : (PREAD_CASE3 pread(fd, buf, count, offset))) + : (PREAD_CASE4 pread(fd, buf, count, offset))); +} +#endif + +#undef pread +#define pread(fd, buf, count, offset) openosc_pread(fd, buf, count, offset) + +#endif /* OPENOSC_PREAD_DISABLE */ + + +#ifndef OPENOSC_READ_DISABLE + +#ifndef __cplusplus +/* Mapping for read */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_read (int fd, void *buf, size_t count) +{ + return (READ_NOMAP_CASE read(fd, buf, count)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_read (int fd, void *buf, size_t count) +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(count); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= count) + ? (READ_CASE1 read(fd, buf, count)) + : (READ_CASE2 read(fd, buf, count))) + : (READ_CASE3 read(fd, buf, count))) + : (READ_CASE4 read(fd, buf, count))); +} +#endif + +#undef read +#define read(fd, buf, count) openosc_read(fd, buf, count) +#endif /* __cplusplus */ + +#endif /* OPENOSC_READ_DISABLE */ + + +/* Mapping for readlinkat */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_readlinkat (int dirfd, const char *pathname, char *buf, size_t bufsiz) + OSC_THROW +{ + return (READLINKAT_NOMAP_CASE readlinkat(dirfd, pathname, buf, bufsiz)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_readlinkat (int dirfd, const char *pathname, char *buf, size_t bufsiz) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(bufsiz); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= bufsiz) + ? (READLINKAT_CASE1 readlinkat(dirfd, pathname, buf, bufsiz)) + : (READLINKAT_CASE2 readlinkat(dirfd, pathname, buf, bufsiz))) + : (READLINKAT_CASE3 readlinkat(dirfd, pathname, buf, bufsiz))) + : (READLINKAT_CASE4 readlinkat(dirfd, pathname, buf, bufsiz))); +} +#endif + +#undef readlinkat +#define readlinkat(dirfd, pathname, buf, bufsiz) openosc_readlinkat(dirfd, pathname, buf, bufsiz) + + +/* Mapping for readlink */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_readlink (const char *path, char *buf, size_t bufsiz) + OSC_THROW +{ + return (READLINK_NOMAP_CASE readlink(path, buf, bufsiz)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_readlink (const char *path, char *buf, size_t bufsiz) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(bufsiz); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= bufsiz) + ? (READLINK_CASE1 readlink(path, buf, bufsiz)) + : (READLINK_CASE2 readlink(path, buf, bufsiz))) + : (READLINK_CASE3 readlink(path, buf, bufsiz))) + : (READLINK_CASE4 readlink(path, buf, bufsiz))); +} +#endif + +#undef readlink +#define readlink(path, buf, bufsiz) openosc_readlink(path, buf, bufsiz) + +#endif /* OPENOSC_DISABLE_UNISTD_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STDLIB_H_FUNCS + +/* Mapping for realpath */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_realpath (const char *path, char *resolved_path) + OSC_THROW +{ + return (REALPATH_NOMAP_CASE realpath(path, resolved_path)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_realpath (const char *path, char *resolved_path) + OSC_THROW +{ + size_t _sz = __builtin_object_size(resolved_path, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (REALPATH_CASE3 realpath(path, resolved_path)) + : (REALPATH_CASE4 realpath(path, resolved_path))); +} +#endif + +#undef realpath +#define realpath(path, resolved_path) openosc_realpath(path, resolved_path) + +#endif /* OPENOSC_DISABLE_STDLIB_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_SOCKET_H_FUNCS +#ifndef OPENOSC_RECV_DISABLE + +/* Mapping for recv */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_recv (int sockfd, void *buf, size_t len, int flags) +{ + return (RECV_NOMAP_CASE recv(sockfd, buf, len, flags)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_recv (int sockfd, void *buf, size_t len, int flags) +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (RECV_CASE1 recv(sockfd, buf, len, flags)) + : (RECV_CASE2 recv(sockfd, buf, len, flags))) + : (RECV_CASE3 recv(sockfd, buf, len, flags))) + : (RECV_CASE4 recv(sockfd, buf, len, flags))); +} +#endif + +#undef recv +#define recv(sockfd, buf, len, flags) openosc_recv(sockfd, buf, len, flags) + +#endif /* OPENOSC_RECV_DISABLE */ + + +#ifndef OPENOSC_RECVFROM_DISABLE + +/* Mapping for recvfrom */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +ssize_t +openosc_recvfrom (int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) +{ + return (RECVFROM_NOMAP_CASE recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); +} + +#else + +static inline __attribute__ ((always_inline)) ssize_t +openosc_recvfrom (int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_0); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (RECVFROM_CASE1 recvfrom(sockfd, buf, len, flags, src_addr, addrlen)) + : (RECVFROM_CASE2 recvfrom(sockfd, buf, len, flags, src_addr, addrlen))) + : (RECVFROM_CASE3 recvfrom(sockfd, buf, len, flags, src_addr, addrlen))) + : (RECVFROM_CASE4 recvfrom(sockfd, buf, len, flags, src_addr, addrlen))); +} +#endif + +#undef recvfrom +#define recvfrom(sockfd, buf, len, flags, src_addr, addrlen) openosc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen) + +#endif /* OPENOSC_RECVFROM_DISABLE */ +#endif /* OPENOSC_DISABLE_SOCKET_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STRING_H_FUNCS + +/* Mapping for stpcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_stpcpy (char *dest, const char *src) + OSC_THROW +{ + return (STPCPY_NOMAP_CASE stpcpy(dest, src)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_stpcpy (char *dest, const char *src) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (STPCPY_CASE3 stpcpy(dest, src)) + : (STPCPY_CASE4 stpcpy(dest, src))); +} +#endif + +#undef stpcpy +#define stpcpy(dest, src) openosc_stpcpy(dest, src) + + +/* Mapping for stpncpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +char * +openosc_stpncpy (char *dest, const char *src, size_t n) + OSC_THROW +{ + return (STPNCPY_NOMAP_CASE stpncpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) char * +openosc_stpncpy (char *dest, const char *src, size_t n) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(n); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (STPNCPY_CASE1 stpncpy(dest, src, n)) + : (STPNCPY_CASE2 stpncpy(dest, src, n))) + : (STPNCPY_CASE3 stpncpy(dest, src, n))) + : (STPNCPY_CASE4 stpncpy(dest, src, n))); +} +#endif + +#undef stpncpy +#define stpncpy(dest, src, n) openosc_stpncpy(dest, src, n) + +#endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_UNISTD_H_FUNCS + +/* Mapping for ttyname_r */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_ttyname_r (int fd, char *buf, size_t buflen) + OSC_THROW +{ + return (TTYNAME_R_NOMAP_CASE ttyname_r(fd, buf, buflen)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_ttyname_r (int fd, char *buf, size_t buflen) + OSC_THROW +{ + size_t _sz = __builtin_object_size(buf, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(buflen); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= buflen) + ? (TTYNAME_R_CASE1 ttyname_r(fd, buf, buflen)) + : (TTYNAME_R_CASE2 ttyname_r(fd, buf, buflen))) + : (TTYNAME_R_CASE3 ttyname_r(fd, buf, buflen))) + : (TTYNAME_R_CASE4 ttyname_r(fd, buf, buflen))); +} +#endif + +#undef ttyname_r +#define ttyname_r(fd, buf, buflen) openosc_ttyname_r(fd, buf, buflen) + +#endif /* OPENOSC_DISABLE_UNISTD_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_STDIO_H_FUNCS +#ifndef OPENOSC_VALIST_NOSUPPORT + +/* Mapping for vasprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vasprintf (char **strp, const char *fmt, va_list ap) + OSC_THROW +{ + return (VASPRINTF_NOMAP_CASE vasprintf(strp, fmt, ap)); +} + +#undef vasprintf +#define vasprintf(strp, fmt, ap) openosc_vasprintf(strp, fmt, ap) + + +/* Mapping for vdprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vdprintf (int fd, const char *format, va_list ap) +{ + return (VDPRINTF_NOMAP_CASE vdprintf(fd, format, ap)); +} + +#undef vdprintf +#define vdprintf(fd, format, ap) openosc_vdprintf(fd, format, ap) + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for vfwprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vfwprintf (FILE *stream, const wchar_t *format, va_list args) +{ + return (VFWPRINTF_NOMAP_CASE vfwprintf(stream, format, args)); +} + +#undef vfwprintf +#define vfwprintf(stream, format, args) openosc_vfwprintf(stream, format, args) + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + + +/* bits/stdio.h:36 has a define for vprintf, causing redefinition error */ +#ifndef __USE_EXTERN_INLINES + +#ifndef OPENOSC_VPRINTF_DISABLE + +/* Mapping for vprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vprintf (const char *format, va_list ap) +{ + return (VPRINTF_NOMAP_CASE vprintf(format, ap)); +} + +#undef vprintf +#define vprintf(format, ap) openosc_vprintf(format, ap) + +#endif /* OPENOSC_VPRINTF_DISABLE */ + + +/* Mapping for vfprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vfprintf (FILE *stream, const char *format, va_list ap) +{ + return (VFPRINTF_NOMAP_CASE vfprintf(stream, format, ap)); +} + +#undef vfprintf +#define vfprintf(stream, format, ap) openosc_vfprintf(stream, format, ap) + +#endif /* __USE_EXTERN_INLINES */ + + +/* Mapping for vsnprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) int +openosc_vsnprintf (char *str, size_t len, + const char *fmt, va_list ap) + OSC_THROW +{ + return (VSNPRINTF_NOMAP_CASE vsnprintf(str, len, fmt, ap)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_vsnprintf (char *str, size_t len, + const char *fmt, va_list ap) + OSC_THROW +{ + size_t _sz = __builtin_object_size(str, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (VSNPRINTF_CASE1 vsnprintf(str, len, fmt, ap)) + : (VSNPRINTF_CASE2 vsnprintf(str, len, fmt, ap))) + : (VSNPRINTF_CASE3 vsnprintf(str, len, fmt, ap))) + : (VSNPRINTF_CASE4 vsnprintf(str, len, fmt, ap))); +} +#endif + +#undef vsnprintf +#define vsnprintf(str, len, format, ap) \ + openosc_vsnprintf(str, len, format, ap) + +/* avoid redefinition */ +//#define HAVE_VSNPRINTF 1 + + +/* Mapping for vsprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_vsprintf (char *str, const char *format, va_list ap) + OSC_THROW +{ + return (VSPRINTF_NOMAP_CASE vsprintf(str, format, ap)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_vsprintf (char *str, const char *format, va_list ap) + OSC_THROW +{ + size_t _sz = __builtin_object_size(str, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (VSPRINTF_CASE3 vsprintf(str, format, ap)) + : (VSPRINTF_CASE4 vsprintf(str, format, ap))); +} +#endif + +#undef vsprintf +#define vsprintf(str, format, ap) openosc_vsprintf(str, format, ap) + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for vswprintf */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_vswprintf (wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args) + OSC_THROW +{ + return (VSWPRINTF_NOMAP_CASE vswprintf(wcs, maxlen, format, args)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_vswprintf (wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(wcs, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(maxlen); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= maxlen) + ? (VSWPRINTF_CASE1 vswprintf(wcs, maxlen, format, args)) + : (VSWPRINTF_CASE2 vswprintf(wcs, maxlen, format, args))) + : (VSWPRINTF_CASE3 vswprintf(wcs, maxlen, format, args))) + : (VSWPRINTF_CASE4 vswprintf(wcs, maxlen, format, args))); +} +#endif + +#undef vswprintf +#define vswprintf(wcs, maxlen, format, args) openosc_vswprintf(wcs, maxlen, format, args) + + +/* Mapping for vwprintf */ + +static inline __attribute__ ((always_inline)) +int +openosc_vwprintf (const wchar_t *format, va_list args) +{ + return (VWPRINTF_NOMAP_CASE vwprintf(format, args)); +} + +#undef vwprintf +#define vwprintf(format, args) openosc_vwprintf(format, args) + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + +#endif /* OPENOSC_VALIST_NOSUPPORT */ +#endif /* OPENOSC_DISABLE_STDIO_H_FUNCS */ + + +#ifndef OPENOSC_DISABLE_WCHAR_H_FUNCS + +/* Mapping for wcpcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcpcpy (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + return (WCPCPY_NOMAP_CASE wcpcpy(dest, src)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcpcpy (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + return ((_sz_bytes != (size_t) -1) + ? (WCPCPY_CASE3 wcpcpy(dest, src)) + : (WCPCPY_CASE4 wcpcpy(dest, src))); +} +#endif + +#undef wcpcpy +#define wcpcpy(dest, src) openosc_wcpcpy(dest, src) + + +/* Mapping for wcpncpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcpncpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WCPNCPY_NOMAP_CASE wcpncpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcpncpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WCPNCPY_CASE1 wcpncpy(dest, src, n)) + : (WCPNCPY_CASE2 wcpncpy(dest, src, n))) + : (WCPNCPY_CASE3 wcpncpy(dest, src, n))) + : (WCPNCPY_CASE4 wcpncpy(dest, src, n))); +} +#endif + +#undef wcpncpy +#define wcpncpy(dest, src, n) openosc_wcpncpy(dest, src, n) + + +/* Mapping for wcrtomb */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_wcrtomb (char *s, wchar_t wc, mbstate_t *ps) + OSC_THROW +{ + return (WCRTOMB_NOMAP_CASE wcrtomb(s, wc, ps)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_wcrtomb (char *s, wchar_t wc, mbstate_t *ps) + OSC_THROW +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (WCRTOMB_CASE3 wcrtomb(s, wc, ps)) + : (WCRTOMB_CASE4 wcrtomb(s, wc, ps))); +} +#endif + +#undef wcrtomb +#define wcrtomb(s, wc, ps) openosc_wcrtomb(s, wc, ps) + + +/* Mapping for wcscat */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcscat (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + return (WCSCAT_NOMAP_CASE wcscat(dest, src)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcscat (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + return ((_sz_bytes != (size_t) -1) + ? (WCSCAT_CASE3 wcscat(dest, src)) + : (WCSCAT_CASE4 wcscat(dest, src))); +} +#endif + +#undef wcscat +#define wcscat(dest, src) openosc_wcscat(dest, src) + + +#ifndef OPENOSC_WCSCPY_DISABLE + +/* Mapping for wcscpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcscpy (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + return (WCSCPY_NOMAP_CASE wcscpy(dest, src)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcscpy (wchar_t *dest, const wchar_t *src) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + return ((_sz_bytes != (size_t) -1) + ? (WCSCPY_CASE3 wcscpy(dest, src)) + : (WCSCPY_CASE4 wcscpy(dest, src))); +} +#endif + +#undef wcscpy +#define wcscpy(dest, src) openosc_wcscpy(dest, src) + +#endif /* OPENOSC_WCSCPY_DISABLE */ + + +/* Mapping for wcsncat */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcsncat (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WCSNCAT_NOMAP_CASE wcsncat(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcsncat (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WCSNCAT_CASE1 wcsncat(dest, src, n)) + : (WCSNCAT_CASE2 wcsncat(dest, src, n))) + : (WCSNCAT_CASE3 wcsncat(dest, src, n))) + : (WCSNCAT_CASE4 wcsncat(dest, src, n))); +} +#endif + +#undef wcsncat +#define wcsncat(dest, src, n) openosc_wcsncat(dest, src, n) + + +/* Mapping for wcsncpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wcsncpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WCSNCPY_NOMAP_CASE wcsncpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wcsncpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WCSNCPY_CASE1 wcsncpy(dest, src, n)) + : (WCSNCPY_CASE2 wcsncpy(dest, src, n))) + : (WCSNCPY_CASE3 wcsncpy(dest, src, n))) + : (WCSNCPY_CASE4 wcsncpy(dest, src, n))); +} +#endif + +#undef wcsncpy +#define wcsncpy(dest, src, n) openosc_wcsncpy(dest, src, n) + + +/* Mapping for wcsnrtombs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_wcsnrtombs (char *dest, const wchar_t **src, size_t nwc, size_t len, mbstate_t *ps) + OSC_THROW +{ + return (WCSNRTOMBS_NOMAP_CASE wcsnrtombs(dest, src, nwc, len, ps)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_wcsnrtombs (char *dest, const wchar_t **src, size_t nwc, size_t len, mbstate_t *ps) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (WCSNRTOMBS_CASE1 wcsnrtombs(dest, src, nwc, len, ps)) + : (WCSNRTOMBS_CASE2 wcsnrtombs(dest, src, nwc, len, ps))) + : (WCSNRTOMBS_CASE3 wcsnrtombs(dest, src, nwc, len, ps))) + : (WCSNRTOMBS_CASE4 wcsnrtombs(dest, src, nwc, len, ps))); +} +#endif + +#undef wcsnrtombs +#define wcsnrtombs(dest, src, nwc, len, ps) openosc_wcsnrtombs(dest, src, nwc, len, ps) + + +/* Mapping for wcsrtombs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_wcsrtombs (char *dest, const wchar_t **src, size_t len, mbstate_t *ps) + OSC_THROW +{ + return (WCSRTOMBS_NOMAP_CASE wcsrtombs(dest, src, len, ps)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_wcsrtombs (char *dest, const wchar_t **src, size_t len, mbstate_t *ps) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(len); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= len) + ? (WCSRTOMBS_CASE1 wcsrtombs(dest, src, len, ps)) + : (WCSRTOMBS_CASE2 wcsrtombs(dest, src, len, ps))) + : (WCSRTOMBS_CASE3 wcsrtombs(dest, src, len, ps))) + : (WCSRTOMBS_CASE4 wcsrtombs(dest, src, len, ps))); +} +#endif + +#undef wcsrtombs +#define wcsrtombs(dest, src, len, ps) openosc_wcsrtombs(dest, src, len, ps) + + +#ifndef OPENOSC_DISABLE_STDLIB_H_FUNCS + +/* Mapping for wcstombs */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +size_t +openosc_wcstombs (char *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WCSTOMBS_NOMAP_CASE wcstombs(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) size_t +openosc_wcstombs (char *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_1); + int is_len_constant = __builtin_constant_p(n); + return ((_sz != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WCSTOMBS_CASE1 wcstombs(dest, src, n)) + : (WCSTOMBS_CASE2 wcstombs(dest, src, n))) + : (WCSTOMBS_CASE3 wcstombs(dest, src, n))) + : (WCSTOMBS_CASE4 wcstombs(dest, src, n))); +} +#endif + +#undef wcstombs +#define wcstombs(dest, src, n) openosc_wcstombs(dest, src, n) + + +/* Mapping for wctomb */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +int +openosc_wctomb (char *s, wchar_t wc) + OSC_THROW +{ + return (WCTOMB_NOMAP_CASE wctomb(s, wc)); +} + +#else + +static inline __attribute__ ((always_inline)) int +openosc_wctomb (char *s, wchar_t wc) + OSC_THROW +{ + size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); + return ((_sz != (size_t) -1) + ? (WCTOMB_CASE3 wctomb(s, wc)) + : (WCTOMB_CASE4 wctomb(s, wc))); +} +#endif + +#undef wctomb +#define wctomb(s, wc) openosc_wctomb(s, wc) + +#endif /* OPENOSC_DISABLE_STDLIB_H_FUNCS */ + + +/* Mapping for wmemcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wmemcpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WMEMCPY_NOMAP_CASE wmemcpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wmemcpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_0); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WMEMCPY_CASE1 wmemcpy(dest, src, n)) + : (WMEMCPY_CASE2 wmemcpy(dest, src, n))) + : (WMEMCPY_CASE3 wmemcpy(dest, src, n))) + : (WMEMCPY_CASE4 wmemcpy(dest, src, n))); +} +#endif + +#undef wmemcpy +#define wmemcpy(dest, src, n) openosc_wmemcpy(dest, src, n) + + +/* Mapping for wmemmove */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wmemmove (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WMEMMOVE_NOMAP_CASE wmemmove(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wmemmove (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_0); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WMEMMOVE_CASE1 wmemmove(dest, src, n)) + : (WMEMMOVE_CASE2 wmemmove(dest, src, n))) + : (WMEMMOVE_CASE3 wmemmove(dest, src, n))) + : (WMEMMOVE_CASE4 wmemmove(dest, src, n))); +} +#endif + +#undef wmemmove +#define wmemmove(dest, src, n) openosc_wmemmove(dest, src, n) + + +/* Mapping for wmempcpy */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wmempcpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + return (WMEMPCPY_NOMAP_CASE wmempcpy(dest, src, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wmempcpy (wchar_t *dest, const wchar_t *src, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(dest, OSC_OBJECT_SIZE_CHECK_0); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WMEMPCPY_CASE1 wmempcpy(dest, src, n)) + : (WMEMPCPY_CASE2 wmempcpy(dest, src, n))) + : (WMEMPCPY_CASE3 wmempcpy(dest, src, n))) + : (WMEMPCPY_CASE4 wmempcpy(dest, src, n))); +} +#endif + +#undef wmempcpy +#define wmempcpy(dest, src, n) openosc_wmempcpy(dest, src, n) + + +/* Mapping for wmemset */ + +#ifdef OPENOSC_NOMAP_METRIC_ONLY + +static inline __attribute__ ((always_inline)) +wchar_t * +openosc_wmemset (wchar_t *wcs, wchar_t wc, size_t n) + OSC_THROW +{ + return (WMEMSET_NOMAP_CASE wmemset(wcs, wc, n)); +} + +#else + +static inline __attribute__ ((always_inline)) wchar_t * +openosc_wmemset (wchar_t *wcs, wchar_t wc, size_t n) + OSC_THROW +{ + size_t _sz_bytes = __builtin_object_size(wcs, OSC_OBJECT_SIZE_CHECK_0); + size_t _sz = _sz_bytes / sizeof(wchar_t); + int is_len_constant = __builtin_constant_p(n); + return ((_sz_bytes != (size_t) -1) + ? (is_len_constant + ? ((_sz >= n) + ? (WMEMSET_CASE1 wmemset(wcs, wc, n)) + : (WMEMSET_CASE2 wmemset(wcs, wc, n))) + : (WMEMSET_CASE3 wmemset(wcs, wc, n))) + : (WMEMSET_CASE4 wmemset(wcs, wc, n))); +} +#endif + +#undef wmemset +#define wmemset(wcs, wc, n) openosc_wmemset(wcs, wc, n) + +#endif /* OPENOSC_DISABLE_WCHAR_H_FUNCS */ + +#endif /* OPENOSC_METRIC_FEATURE_ENABLED */ + +#endif /* __OPENOSC_METRIC_ONLY2_H__ */ diff --git a/include/openosc_nomap_metric.h b/include/openosc_nomap_metric.h index 951f0e2..a1a0b4f 100644 --- a/include/openosc_nomap_metric.h +++ b/include/openosc_nomap_metric.h @@ -38,6 +38,12 @@ long long int __attribute__((weak)) rtd_osc_nomap_h_included_int = MAGIC_OSC_NOM #else #define MAGIC_OSC_NOMAP_H_REASON 0x038d81808e8d8180 #endif +#elif defined OPENOSC_METRIC_ONLY_MODE +#if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d06 +#else +#define MAGIC_OSC_NOMAP_H_REASON 0x068d81808e8d8180 +#endif #elif defined OSC_ASM #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d04 diff --git a/include/openosc_redefine_nomap.h b/include/openosc_redefine_nomap.h index 9cfa3bf..ec65d21 100644 --- a/include/openosc_redefine_nomap.h +++ b/include/openosc_redefine_nomap.h @@ -24,9 +24,6 @@ extern "C" #include "openosc_extern.h" -#ifndef NULL -#define NULL ((void *)0) -#endif /* Mapping for memcpy */ diff --git a/include/openosc_redirect_nomap.h b/include/openosc_redirect_nomap.h index e53e1e0..d94f17f 100644 --- a/include/openosc_redirect_nomap.h +++ b/include/openosc_redirect_nomap.h @@ -25,9 +25,6 @@ extern "C" #include "openosc_extern.h" -#ifndef NULL -#define NULL ((void *)0) -#endif /* Mapping for memcpy */ diff --git a/test/openosc_fortify_test.c b/test/openosc_fortify_test.c index c27078b..bf29dc9 100644 --- a/test/openosc_fortify_test.c +++ b/test/openosc_fortify_test.c @@ -738,6 +738,20 @@ int openosc_test_vprintf(void) { } +int openosc_test_vsnprintf(void) { + int mylen = 8; + char mydstbuf[15 * sizeof(char)]; + char **pmydstbuf = (char **)(&mydstbuf); + const char mysrcbuf[20] = "I am the source"; + const char **pmysrcbuf = (const char **)(&mysrcbuf); + va_list myap; + printf("Line %d, func %s, mylen is: %d\n", __LINE__, __FUNCTION__, mylen); + vsnprintf((char *) mydstbuf , mylen, " ", myap); /* function invocation */ + printf("End of testing vsnprintf\n"); + return 0; +} + + int openosc_test_vsprintf(void) { int mylen = 8; char mydstbuf[15 * sizeof(char)]; diff --git a/test/openosc_test.c b/test/openosc_test.c index 03c0f44..cf757db 100644 --- a/test/openosc_test.c +++ b/test/openosc_test.c @@ -9,68 +9,63 @@ //#include "../include/openosc.h" #include +#include #include +#include /* Testing OpenOSC public header for all 4 mapping cases. */ -static void openosc_test_strcpy(void) { - char dst4[20] = "dst4"; char src4[15] = "src4"; - //memcpy(dst4, src4, 22); /* overflow */ - //memcpy(dst4, src4, 18); /* overread */ - strncpy(dst4, src4, 4); - strcpy(dst4, src4); - printf("Line %d, func %s, dst4 is: %s\n", __LINE__, __FUNCTION__, dst4); - strncat(dst4, src4, 4); - printf("Line %d, func %s, dst4 is: %s\n", __LINE__, __FUNCTION__, dst4); - strncpy(dst4, src4, strnlen(dst4, 5)); -} - -int openosc_test_memcpy(void) { +int openosc_test_memcpy(char *buf) { /* volatile so the compiler can’t know the value */ volatile int len = 8; char dst[5]; char src[20] = "I am the source"; -#if 0 -/* comment out to avoid compile-time error */ - char dst2[30]; - volatile char *mydst = dst2; - memcpy(dst2, src, 25); /* src over-read CASE 2 */ - printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - len = 26; - memcpy(dst2, src, len); /* src over-read CASE 3 */ - printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy((void *)(&len+2), src, len); /* src over-read CASE 3 */ - printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy(dst, src, 7); /* case 2 */ + memcpy(dst, (void *)(&len+2), 4); /* case 1, actually src over-read CASE8 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy(dst, src, 8); /* case 2 */ + memcpy(dst, src, 4); /* case 1, actually src over-read CASE1 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy((void *)(&len+2), src, 21); /* case 4, actually src over-read CASE2 ???? */ +#if 0 + void *ret = memcpy(dst, src, 14); /* case 2 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); #endif - memcpy(dst, (void *)(&len+2), 4); /* case 1 */ - printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy(dst, src, 4); /* case 1, actually src over-read CASE1 */ - printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - len = (dst[3]-dst[2])/20 ; + len = time(NULL)%7; memcpy(dst, src, len); /* case 3 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - len = (dst[3]-dst[2])/5 + 5 ; - memcpy(dst, src, len); /* case 3 */ + memcpy(buf, src, 10); /* case 4 */ + printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); + memcpy(buf, src, 21); /* case 4, actually src over-read CASEb */ + printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); + printf("End of testing memcpy!\n"); + return 0; +} + +int openosc_test_strncpy(char *buf) { + /* volatile so the compiler can’t know the value */ + volatile int len = 8; + char dst[5]; + char src[20] = "I am the source"; + strncpy(dst, (void *)(&len+2), 4); /* case 1 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); -#if 0 - memcpy((void *)(&len+2), (void *)(&len+3), 1); /* case 4 */ + strncpy(dst, src, 4); /* case 1, actually src over-read CASE1 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); - memcpy((void *)(&len+2), src, 1); /* case 4, actually src over-read CASE1 ???? */ +#if 0 + strncpy(dst, src, 14); /* case 2 */ printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); #endif + len = time(NULL)%5; + strncpy(dst, src, len); /* case 3 */ + printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); + strncpy(buf, src, 21); /* case 4 */ + printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); printf("End of testing memcpy!\n"); return 0; } int main(void) { - openosc_test_strcpy(); - return openosc_test_memcpy(); + srand(time(NULL)); + char *buf = malloc(25); + (void)openosc_test_memcpy(buf); + return openosc_test_strncpy(buf); } diff --git a/tools/oscmetrics.py b/tools/oscmetrics.py index 680f867..5d65d5e 100755 --- a/tools/oscmetrics.py +++ b/tools/oscmetrics.py @@ -70,6 +70,7 @@ '80818d8e80818d03': 'MAGIC_OSC_NOMAP_H_REASON_FORTIFY_SOURCE', '80818d8e80818d04': 'MAGIC_OSC_NOMAP_H_REASON_ASM', '80818d8e80818d05': 'MAGIC_OSC_NOMAP_H_REASON_STRICT_ANSI', + '80818d8e80818d06': 'MAGIC_OSC_NOMAP_H_REASON_METRIC_ONLY', '97cfa25a9fb39d01': 'MAGIC_OSC_COMPILER_ICC', '97cfa25a9fb39d02': 'MAGIC_OSC_COMPILER_CLANG', '97cfa25a9fb39d03': 'MAGIC_OSC_COMPILER_GCC', @@ -1085,6 +1086,7 @@ def get_file_hexdump(afile): 'MAGIC_OSC_NOMAP_H_REASON_FORTIFY_SOURCE' : 'nomap_reason_fortify_source', 'MAGIC_OSC_NOMAP_H_REASON_ASM' : 'nomap_reason_asm', 'MAGIC_OSC_NOMAP_H_REASON_STRICT_ANSI' : 'nomap_reason_strict_ansi', + 'MAGIC_OSC_NOMAP_H_REASON_METRIC_ONLY' : 'nomap_reason_metric_only', 'MAGIC_OSC_HEADER_INCLUDED': 'osc_header_included', 'MAGIC_OSC_COMPILER_ICC': 'osc_compiler_icc', 'MAGIC_OSC_COMPILER_CLANG': 'osc_compiler_clang', @@ -1114,6 +1116,7 @@ def get_file_hexdump(afile): '80818d8e80818d03': 'MAGIC_OSC_NOMAP_H_REASON_FORTIFY_SOURCE', '80818d8e80818d04': 'MAGIC_OSC_NOMAP_H_REASON_ASM', '80818d8e80818d05': 'MAGIC_OSC_NOMAP_H_REASON_STRICT_ANSI', + '80818d8e80818d06': 'MAGIC_OSC_NOMAP_H_REASON_METRIC_ONLY', '97cfa25a9fb39d01': 'MAGIC_OSC_COMPILER_ICC', '97cfa25a9fb39d02': 'MAGIC_OSC_COMPILER_CLANG', '97cfa25a9fb39d03': 'MAGIC_OSC_COMPILER_GCC', @@ -1964,8 +1967,14 @@ def get_func_srcline_from_addr2line_decode_line_pretty(line): line = line.strip() tokens = line.split() if "(inlined by) " in line and len(tokens) > 4: + tokens2 = line.split(" at ") + if len(tokens2) > 1: + return (tokens[2], tokens2[1]) return (tokens[2], tokens[4]) elif len(tokens) > 2: + tokens2 = line.split(" at ") + if len(tokens2) > 1: + return (tokens[0], tokens2[1]) return (tokens[0], tokens[2]) if len(tokens) > 1: return (tokens[0], tokens[1]) @@ -1994,7 +2003,10 @@ def pick_addr2line_decode_entry(lines): if len(lines) > 2: for line in lines: if "(inlined by) " in line: - return get_func_srcline_from_addr2line_decode_line_pretty(line) + (func, srcline) = get_func_srcline_from_addr2line_decode_line_pretty(line) + tokens = srcline.split(":") + if tokens[0][-2:].lower() != '.h': + return (func, srcline) if len(lines) > 0: return get_func_srcline_from_addr2line_decode_line_pretty(lines[-1]) return (func, srcline) @@ -2057,7 +2069,8 @@ def get_addr2line_info(afile, pc): lines = output.splitlines() (func, srcline) = pick_addr2line_decode_entry(lines) #(func, srcline) = pick_addr2line_decode_entry_nopretty(lines) - return (output, func, srcline) + return (cmd, lines, func, srcline) + #return (cmd, output, func, srcline) def get_text_section_info(afile): @@ -2217,7 +2230,7 @@ def scan_text_section_from_file(afile, magics): hex_pc = hex(pc) verbose("offset: " + str(i//2) + " magic: " + word + " vma: " + hex(vma) + " pc: " + hex_pc + " " + str(match), LEVEL_1) i += 16 - (output, srcfunc, srcline) = get_addr2line_info(afile, hex_pc) + (cmd, output, srcfunc, srcline) = get_addr2line_info(afile, hex_pc) d = dict() d['PC'] = hex_pc d['offset'] = i//2 @@ -2228,6 +2241,8 @@ def scan_text_section_from_file(afile, magics): #d['addr2line_cmd'] = 'addr2line -f -i -e ' + cmd_quote(os.path.basename(afile)) + ' ' + hex_pc d['srcfunc'] = srcfunc d['srcline'] = srcline + d['addr2line_cmd'] = cmd + d['addr2line_output'] = output # try to see if __builtin_object_size of dst buffer is embedded too dst_objsize_hexstr = get_dst_len_objsize(text[i:i+96]) d['dstsize_hexstr'] = dst_objsize_hexstr @@ -2433,7 +2448,7 @@ def print_watermarkpc_summary_table(rdict, wsdirs=[]): row_list.append(" NOTFOUND") #row_list.append(pc_entry['dstsize_hexstr']) if run_addr2line: - (output, srcfunc, srcline) = get_addr2line_info(match, pc_entry['PC']) + (cmd, output, srcfunc, srcline) = get_addr2line_info(match, pc_entry['PC']) row_list.append(' ' + srcfunc) row_list.append(' ' + srcline) else: @@ -3382,7 +3397,7 @@ def scan_debug_lines_from_file(afile, magics): stack.append(line) continue hex_pc = pc - (output, srcfunc, srcline) = get_addr2line_info(afile, hex_pc) + (cmd, output, srcfunc, srcline) = get_addr2line_info(afile, hex_pc) d = dict() d['PC'] = hex_pc d['magic'] = line @@ -3390,6 +3405,8 @@ def scan_debug_lines_from_file(afile, magics): d['caseno'] = match[1] d['srcfunc'] = srcfunc d['srcline'] = srcline + d['addr2line_cmd'] = cmd + d['addr2line_output'] = output d['offset'] = 0 magic_list.append(d) prev_pc = pc