VirtualBox

Changeset 83886 in vbox for trunk


Ignore:
Timestamp:
Apr 21, 2020 11:14:20 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137415
Message:

IPRT: Implement RTStrEnd in assembly & C++, drop the inlining. memchr from VC++ 14.1 cannot deal wtih RTSTR_MAX on unaligned string, it may step into an electric fence page after the end of the string. bugref:8489

Location:
trunk
Files:
12 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mangling.h

    r83837 r83886  
    21132113# define RTStrDupNTag                                   RT_MANGLER(RTStrDupNTag)
    21142114# define RTStrDupTag                                    RT_MANGLER(RTStrDupTag)
     2115# define RTStrEnd                                       RT_MANGLER(RTStrEnd)
     2116# define RTStrEnd_EndProc                               RT_MANGLER(RTStrEnd_EndProc)
    21152117# define RTStrFormat                                    RT_MANGLER(RTStrFormat)
    21162118# define RTStrFormatNumber                              RT_MANGLER(RTStrFormatNumber)
  • trunk/include/iprt/string.h

    r83168 r83886  
    26112611RTDECL(int) RTStrNLenEx(const char *pszString, size_t cchMax, size_t *pcch);
    26122612
    2613 RT_C_DECLS_END
    2614 
    26152613/** The maximum size argument of a memchr call. */
    26162614#define RTSTR_MEMCHR_MAX            ((~(size_t)0 >> 1) - 15)
     
    26252623 * @param   cchMax      The max string length.  RTSTR_MAX is fine.
    26262624 */
    2627 #if defined(__cplusplus) && !defined(DOXYGEN_RUNNING)
    2628 DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
    2629 {
    2630     /* Avoid potential issues with memchr seen in glibc.
    2631      * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
    2632     while (cchMax > RTSTR_MEMCHR_MAX)
    2633     {
    2634         char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
    2635         if (RT_LIKELY(pszRet))
    2636             return pszRet;
    2637         pszString += RTSTR_MEMCHR_MAX;
    2638         cchMax    -= RTSTR_MEMCHR_MAX;
    2639     }
    2640     return (char const *)memchr(pszString, '\0', cchMax);
    2641 }
    2642 
    2643 DECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax)
    2644 #else
    2645 DECLINLINE(char *) RTStrEnd(const char *pszString, size_t cchMax)
    2646 #endif
    2647 {
    2648     /* Avoid potential issues with memchr seen in glibc.
    2649      * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
    2650     while (cchMax > RTSTR_MEMCHR_MAX)
    2651     {
    2652         char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
    2653         if (RT_LIKELY(pszRet))
    2654             return pszRet;
    2655         pszString += RTSTR_MEMCHR_MAX;
    2656         cchMax    -= RTSTR_MEMCHR_MAX;
    2657     }
    2658     return (char *)memchr(pszString, '\0', cchMax);
    2659 }
    2660 
    2661 RT_C_DECLS_BEGIN
     2625RTDECL(char *) RTStrEnd(char const *pszString, size_t cchMax);
    26622626
    26632627/**
     
    26772641    return psz - pszHaystack;
    26782642}
    2679 
    26802643
    26812644/**
  • trunk/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile

    r82968 r83886  
    9090        RTStrCopyEx.c \
    9191        RTStrCopyP.c \
     92        RTStrEnd.c \
    9293        RTStrICmpAscii.c \
    9394        RTStrNICmpAscii.c \
  • trunk/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest

    r82968 r83886  
    126126    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
    127127    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
     128    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrEnd.cpp=>common/string/RTStrEnd.c \
    128129    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrICmpAscii.cpp=>common/string/RTStrICmpAscii.c \
    129130    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNICmpAscii.cpp=>common/string/RTStrNICmpAscii.c \
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile

    r82968 r83886  
    9696        common/string/RTStrCopyEx.o \
    9797        common/string/RTStrCopyP.o \
     98        common/string/RTStrEnd.o \
    9899        common/string/RTStrICmpAscii.o \
    99100        common/string/RTStrNICmpAscii.o \
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest

    r82968 r83886  
    142142    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
    143143    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
     144    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrEnd.cpp=>common/string/RTStrEnd.c \
    144145    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrICmpAscii.cpp=>common/string/RTStrICmpAscii.c \
    145146    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNICmpAscii.cpp=>common/string/RTStrNICmpAscii.c \
  • trunk/src/VBox/HostDrivers/Support/freebsd/Makefile

    r82968 r83886  
    9595        RTStrCopyEx.c \
    9696        RTStrCopyP.c \
     97        RTStrEnd.c \
    9798        strformat.c \
    9899        strformatnum.c \
  • trunk/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv

    r82968 r83886  
    127127    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopy.cpp=>common/string/RTStrCopy.c \
    128128    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
     129    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrEnd.cpp=>common/string/RTStrEnd.c \
    129130    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNCmp.cpp=>common/string/RTStrNCmp.c \
    130131    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNLen.cpp=>common/string/RTStrNLen.c \
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r82968 r83886  
    9393        common/string/RTStrCopyEx.o \
    9494        common/string/RTStrCopyP.o \
     95        common/string/RTStrEnd.o \
    9596        common/string/RTStrNCmp.o \
    9697        common/string/RTStrNLen.o \
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r82968 r83886  
    133133    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
    134134    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
     135    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrEnd.cpp=>common/string/RTStrEnd.c \
    135136    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNCmp.cpp=>common/string/RTStrNCmp.c \
    136137    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNLen.cpp=>common/string/RTStrNLen.c \
  • trunk/src/VBox/Runtime/Makefile.kmk

    r83861 r83886  
    789789        common/dbg/dbgstackdumpself.cpp \
    790790        common/dbg/dbgstackdumpself-amd64-x86.asm \
    791         common/math/bignum-amd64-x86.asm
     791        common/math/bignum-amd64-x86.asm \
     792       common/string/RTStrEnd.asm
    792793RuntimeR3_SOURCES.amd64 += \
    793794        common/asm/ASMCpuIdExSlow.asm \
     
    813814        common/dbg/dbgstackdumpself-amd64-x86.asm \
    814815        common/math/bignum-amd64-x86.asm \
    815         common/math/RTUInt128MulByU64.asm
     816        common/math/RTUInt128MulByU64.asm \
     817       common/string/RTStrEnd.asm
    816818
    817819# Some versions of GCC might require this.
     
    823825        common/asm/ASMAtomicUoReadU64.asm
    824826
     827# Some non-assembly for non-AMD64 / non-x86 targets:
     828RuntimeR3_SOURCES.arm32 += \
     829        common/string/RTStrEnd.cpp
     830RuntimeR3_SOURCES.arm64 += \
     831        common/string/RTStrEnd.cpp
     832RuntimeR3_SOURCES.sparc32 += \
     833        common/string/RTStrEnd.cpp
     834RuntimeR3_SOURCES.sparc64 += \
     835        common/string/RTStrEnd.cpp
    825836
    826837# VBox specific stuff.
     
    18001811        common/string/RTStrCopyEx.cpp \
    18011812        common/string/RTStrCopyP.cpp \
     1813        common/string/RTStrEnd.cpp \
    18021814        common/string/RTStrIStartsWith.cpp \
    18031815        common/string/RTStrNCmp.cpp \
     
    22862298                ,$(PATH_SUB_CURRENT)/r3/win/VBoxRT-openssl-1.1plus.def )\
    22872299                $(if-expr "$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)" == "win.x86" && defined(VBOX_WITH_MORE_NT4_COMPAT_BINARIES)\
    2288                 ,$(PATH_SUB_CURRENT)/r3/win/VBoxRT-msvcr100-win32.def ,) #$(PATH_SUB_CURRENT)/r3/win/VBoxRT-msvcp100-win32.def
     2300                ,$(PATH_SUB_CURRENT)/r3/win/VBoxRT-msvcr100-win32.def ,) \
     2301                | $$(dir $$@) #$(PATH_SUB_CURRENT)/r3/win/VBoxRT-msvcp100-win32.def
    22892302        $(RM) -f -- $@
    22902303        $(REDIRECT) -wto $@ -- $(CAT_EXT) $^
     
    26712684        common/asm/ASMFxRstor.asm \
    26722685        common/asm/ASMRdMsrEx.asm \
    2673         common/asm/ASMWrMsrEx.asm
     2686        common/asm/ASMWrMsrEx.asm \
     2687        common/string/RTStrEnd.asm
    26742688RuntimeR0_SOURCES.amd64 += \
    26752689        common/asm/ASMCpuIdExSlow.asm \
     
    26882702        common/asm/ASMFxRstor.asm \
    26892703        common/asm/ASMRdMsrEx.asm \
    2690         common/asm/ASMWrMsrEx.asm
     2704        common/asm/ASMWrMsrEx.asm \
     2705        common/string/RTStrEnd.asm
     2706RuntimeR0_SOURCES.arm32 += \
     2707        common/string/RTStrEnd.cpp
     2708RuntimeR0_SOURCES.arm64 += \
     2709        common/string/RTStrEnd.cpp
     2710RuntimeR0_SOURCES.sparc32 += \
     2711        common/string/RTStrEnd.cpp
     2712RuntimeR0_SOURCES.sparc64 += \
     2713        common/string/RTStrEnd.cpp
    26912714
    26922715#if1of ($(KBUILD_TARGET_ARCH),amd64 x86)
     
    28492872        common/asm/ASMWrMsrEx.asm \
    28502873        common/math/bignum-amd64-x86.asm \
    2851         common/math/RTUInt128MulByU64.asm
     2874        common/math/RTUInt128MulByU64.asm \
     2875        common/string/RTStrEnd.asm
    28522876RuntimeR0Drv_SOURCES.x86   = \
    28532877        common/asm/ASMCpuIdExSlow.asm \
     
    28552879        common/asm/ASMRdMsrEx.asm \
    28562880        common/asm/ASMWrMsrEx.asm \
    2857         common/math/bignum-amd64-x86.asm
    2858 
     2881        common/math/bignum-amd64-x86.asm \
     2882        common/string/RTStrEnd.asm
     2883RuntimeR0Drv_SOURCES.arm32 += \
     2884        common/string/RTStrEnd.cpp
     2885RuntimeR0Drv_SOURCES.arm64 += \
     2886        common/string/RTStrEnd.cpp
     2887RuntimeR0Drv_SOURCES.sparc32 += \
     2888        common/string/RTStrEnd.cpp
     2889RuntimeR0Drv_SOURCES.sparc64 += \
     2890        common/string/RTStrEnd.cpp
    28592891
    28602892RuntimeR0Drv_SOURCES.linux = \
     
    34913523        common/string/RTStrCopy.cpp \
    34923524        common/string/RTStrCopyEx.cpp \
     3525        common/string/RTStrEnd.asm \
    34933526        common/string/RTStrICmpAscii.cpp \
    34943527        common/table/avllu32.cpp \
  • trunk/src/VBox/Runtime/common/string/RTStrEnd.asm

    r83872 r83886  
    11; $Id$
    22;; @file
    3 ; IPRT - No-CRT memchr - AMD64 & X86.
     3; IPRT - RTStrEnd - AMD64 & X86.
    44;
    55
     
    3030
    3131;;
    32 ; @param    pv      gcc: rdi  msc: ecx  x86:[esp+4]   wcall: eax
    33 ; @param    ch      gcc: esi  msc: edx  x86:[esp+8]   wcall: edx
    34 ; @param    cb      gcc: rdx  msc: r8   x86:[esp+0ch] wcall: ebx
    35 RT_NOCRT_BEGINPROC memchr
     32; @param    pszString   gcc: rdi  msc: rcx  x86:[esp+4]   wcall: eax
     33; @param    cchMax      gcc: rsi  msc: rdx  x86:[esp+8]   wcall: edx
     34;
     35BEGINPROC_EXPORTED RTStrEnd
    3636        cld
    3737%ifdef RT_ARCH_AMD64
    3838 %ifdef ASM_CALL64_MSC
    39         or      r8, r8
     39        or      rdx, rdx
    4040        jz      .not_found_early
    4141
    4242        mov     r9, rdi                 ; save rdi
    43         mov     eax, edx
    4443        mov     rdi, rcx
    45         mov     rcx, r8
     44        mov     rcx, rdx
    4645 %else
    47         mov     rcx, rdx
     46        mov     rcx, rsi
    4847        jrcxz   .not_found_early
    49 
    50         mov     eax, esi
    5148 %endif
    5249
    5350%else
    5451 %ifdef ASM_CALL32_WATCOM
    55         mov     ecx, ebx
     52        mov     ecx, edx
    5653        jecxz   .not_found_early
    57         xchg    eax, edx
    58         xchg    edi, edx                ; load and save edi.
     54        mov     edx, edi                ; save rdi
     55        mov     edi, eax
    5956 %else
    60         mov     ecx, [esp + 0ch]
     57        mov     ecx, [esp + 8]
    6158        jecxz   .not_found_early
    6259        mov     edx, edi                ; save edi
    63         mov     eax, [esp + 8]
    6460        mov     edi, [esp + 4]
    6561 %endif
    6662%endif
     63        xor     eax, eax                ; we're searching for zero
    6764
    6865        ; do the search
     
    9087        xor     eax, eax
    9188        ret
    92 ENDPROC RT_NOCRT(memchr)
     89ENDPROC RTStrEnd
    9390
  • trunk/src/VBox/Runtime/common/string/RTStrEnd.cpp

    r83872 r83886  
    11/* $Id$ */
    22/** @file
    3  * IPRT - CRT Strings, memcpy().
     3 * IPRT - RTStrEnd, C++ version.
    44 */
    55
     
    3232
    3333
    34 /**
    35  * Search a memory block for a character.
    36  *
    37  * @returns Pointer to the first instance of ch in pv.
    38  * @returns NULL if ch wasn't found.
    39  * @param   pv          Pointer to the block to search.
    40  * @param   ch          The character to search for.
    41  * @param   cb          The size of the block.
    42  */
    43 #ifdef _MSC_VER /* Silly 'safeness' from MS. */
    44 # if _MSC_VER >= 1400
    45 _CRTIMP __checkReturn _CONST_RETURN void *  __cdecl memchr( __in_bcount_opt(_MaxCount) const void * pv, __in int ch, __in size_t cb)
    46 # else
    47 void *memchr(const void *pv, int ch, size_t cb)
    48 # endif
    49 #else
    50 void *memchr(const void *pv, int ch, size_t cb)
    51 #endif
     34RTDECL(char *) RTStrEnd(const char *pszString, size_t cchMax)
    5235{
    53     register uint8_t const *pu8 = (uint8_t const *)pv;
    54     register size_t cb2 = cb;
    55     while (cb2-- > 0)
     36    while (cchMax-- > 0)
    5637    {
    57         if (*pu8 == ch)
    58             return (void *)pu8;
    59         pu8++;
     38        if (*pszString)
     39        { }
     40        else
     41            return pszString;
     42        pszString++;
    6043    }
    6144    return NULL;
    6245}
    63 
     46RT_EXPORT_SYMBOL(RTStrEnd);
  • trunk/src/VBox/Runtime/testcase/tstUtf8.cpp

    r82968 r83886  
    10451045        RTTESTI_CHECK(RTStrEnd(s_szEmpty, ~i) == &s_szEmpty[0]);
    10461046
     1047    /* Check the implementation won't ever overshoot the '\0' in the input in
     1048       anyway that may lead to a SIGSEV. (VC++ 14.1 does this) */
     1049    size_t const cchStr = 1023;
     1050    char *pszStr = (char *)RTTestGuardedAllocTail(hTest, cchStr + 1);
     1051    memset(pszStr, ' ', cchStr);
     1052    char * const pszStrEnd = &pszStr[cchStr];
     1053    *pszStrEnd = '\0';
     1054    RTTEST_CHECK_RETV(hTest, strlen(pszStr) == cchStr);
     1055
     1056    for (size_t off = 0; off <= cchStr; off++)
     1057    {
     1058        RTTEST_CHECK(hTest, RTStrEnd(&pszStr[off], cchStr + 1 - off) == pszStrEnd);
     1059        RTTEST_CHECK(hTest, RTStrEnd(&pszStr[off], RTSTR_MAX) == pszStrEnd);
     1060
     1061        RTTEST_CHECK(hTest, memchr(&pszStr[off], '\0', cchStr + 1 - off) == pszStrEnd);
     1062        RTTEST_CHECK(hTest, strchr(&pszStr[off], '\0') == pszStrEnd);
     1063        RTTEST_CHECK(hTest, strchr(&pszStr[off], '?') == NULL);
     1064
     1065        size_t cchMax = 0;
     1066        for (; cchMax <= cchStr - off; cchMax++)
     1067        {
     1068            const char *pszRet = RTStrEnd(&pszStr[off], cchMax);
     1069            if (pszRet != NULL)
     1070            {
     1071                RTTestFailed(hTest, "off=%zu cchMax=%zu: %p, expected NULL\n", off, cchMax, pszRet);
     1072                break;
     1073            }
     1074        }
     1075        for (; cchMax <= _8K; cchMax++)
     1076        {
     1077            const char *pszRet = RTStrEnd(&pszStr[off], cchMax);
     1078            if (pszRet != pszStrEnd)
     1079            {
     1080                RTTestFailed(hTest, "off=%zu cchMax=%zu: off by %p\n", off, cchMax, pszRet);
     1081                break;
     1082            }
     1083        }
     1084    }
     1085    RTTestGuardedFree(hTest, pszStr);
    10471086}
    10481087
     
    14241463    if (rc == VINF_SUCCESS)
    14251464    {
    1426         RTTESTI_CHECK(!strcmp(pszOut, pszTest1));
    14271465        RTTestIPrintf(RTTESTLVL_ALWAYS, "CurrentCP is UTF-8 or similar (LC_ALL=%s LANG=%s LC_CTYPE=%s)\n",
    14281466                      RTEnvGet("LC_ALL"), RTEnvGet("LANG"), RTEnvGet("LC_CTYPE"));
     1467        if (strcmp(pszOut, pszTest1))
     1468            RTTestFailed(hTest, "mismatch\nutf8: %.*Rhxs\n got: %.*Rhxs\n", strlen(pszTest1), pszTest1, strlen(pszOut), pszOut);
    14291469        RTStrFree(pszOut);
    14301470    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette