Skip to content

Commit

Permalink
Fix potential memory alignment issues on X86_64.
Browse files Browse the repository at this point in the history
Clang version 4.0 and newer uses SSE instructions that require
16-byte alignment to zero memory allocated using the C++ new operator.
The internal memory allocator does not understand anything larger
than 8-byte alignment.  Modify it to be capable of doing 16-byte
alignment when necessary.

There is also a debug layer beneath the C++ new and delete operators
that is enabled by the --enable-debug configure option.  This layer
adds 8 to the requested size of any allocations before calling the
underlying allocator, adds a known signature to the start of the
memory block, and then adds an 8 byte offset to the pointer before
returning it to the caller.  The delete operator basically does the
reverse, checking for the proper signature.  Modify this code so
that it adds and subtracts a 16-byte offset on X86_64 so that a
properly aligned block from the underlying allocator does not cause
new to return a misaligned pointer.

Modify set_soenv.in so that it always requests 16-byte alignment
on X86_64 so that the ABI is the same independent of the toolchain.



git-svn-id: https://svn.apache.org/repos/asf/openoffice/trunk@1830406 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Don Lewis committed Apr 28, 2018
1 parent 46b6f86 commit 787e113
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 9 deletions.
12 changes: 12 additions & 0 deletions main/sal/cpprt/operators_new_delete.cxx
Expand Up @@ -68,7 +68,11 @@ struct AllocatorTraits
{
n = std::max(n, std::size_t(1));
#if OSL_DEBUG_LEVEL > 0
# ifdef NEED_ALIGN16
n += 2*sizeof(signature_type);
# else
n += sizeof(signature_type);
# endif
#endif /* OSL_DEBUG_LEVEL */
return n;
}
Expand All @@ -77,15 +81,23 @@ struct AllocatorTraits
{
#if OSL_DEBUG_LEVEL > 0
memcpy (p, m_signature, sizeof(signature_type));
# ifdef NEED_ALIGN16
p = static_cast<char*>(p) + 2*sizeof(signature_type);
# else
p = static_cast<char*>(p) + sizeof(signature_type);
# endif
#endif /* OSL_DEBUG_LEVEL */
return p;
}

void* fini (void * p) const SAL_THROW(())
{
#if OSL_DEBUG_LEVEL > 0
# ifdef NEED_ALIGN16
p = static_cast<char*>(p) - 2*sizeof(signature_type);
# else
p = static_cast<char*>(p) - sizeof(signature_type);
# endif
if (memcmp (p, m_signature, sizeof(signature_type)) != 0)
{
OSL_ENSURE(0, "operator delete mismatch");
Expand Down
6 changes: 6 additions & 0 deletions main/sal/rtl/source/alloc_cache.c
Expand Up @@ -894,7 +894,13 @@ rtl_cache_activate (
if (objalign == 0)
{
/* determine default alignment */
#ifdef NEED_ALIGN16
if (objsize >= RTL_MEMORY_ALIGNMENT_16)
objalign = RTL_MEMORY_ALIGNMENT_16;
else if (objsize >= RTL_MEMORY_ALIGNMENT_8)
#else
if (objsize >= RTL_MEMORY_ALIGNMENT_8)
#endif
objalign = RTL_MEMORY_ALIGNMENT_8;
else
objalign = RTL_MEMORY_ALIGNMENT_4;
Expand Down
5 changes: 5 additions & 0 deletions main/sal/rtl/source/alloc_global.c
Expand Up @@ -75,8 +75,13 @@ static rtl_cache_type * g_alloc_caches[RTL_MEMORY_CACHED_SIZES] =
0,
};

#ifdef NEED_ALIGN16
#define RTL_MEMALIGN 16
#define RTL_MEMALIGN_SHIFT 4
#else
#define RTL_MEMALIGN 8
#define RTL_MEMALIGN_SHIFT 3
#endif

static rtl_cache_type * g_alloc_table[RTL_MEMORY_CACHED_LIMIT >> RTL_MEMALIGN_SHIFT] =
{
Expand Down
6 changes: 6 additions & 0 deletions main/sal/rtl/source/alloc_impl.h
Expand Up @@ -45,6 +45,12 @@ extern "C" {
#define RTL_MEMORY_ALIGNMENT_8 sizeof(void*)
#endif /* SAL_TYPES_ALIGNMENT8 */

#if defined(SAL_TYPES_ALIGNMENT16) && SAL_TYPES_ALIGNMENT16 > 1
#define RTL_MEMORY_ALIGNMENT_16 SAL_TYPES_ALIGNMENT16
#else
#define RTL_MEMORY_ALIGNMENT_16 16
#endif /* SAL_TYPES_ALIGNMENT16 */

#if 0 /* @@@ */
#define RTL_MEMORY_ALIGNMENT_1 8
#define RTL_MEMORY_ALIGNMENT_2 (sizeof(void*) * 2)
Expand Down
11 changes: 10 additions & 1 deletion main/set_soenv.in
Expand Up @@ -74,7 +74,7 @@ my ( $CALL_CDECL, $COMMON_OUTDIR, $BMP_WRITES_FLAG,
$BUILD_SOSL_RELEASE, $RSC_ONCE );
#
# Platform dependent constant values.
my ( $BIG_SVX, $ARCH, $CPU, $CPUNAME, $CVER, $GLIBC, $GUI, $GUIBASE,
my ( $BIG_SVX, $ALIGN, $ARCH, $CPU, $CPUNAME, $CVER, $GLIBC, $GUI, $GUIBASE,
$GVER, $OS, $OSVERSION, $OUTPATH, $INPATH, $PATH_SEPERATOR,
$DYNAMIC_CRT, $SET_EXCEPTIONS, $use_shl_versions, $CDPATHx, $JRELIBDIR,
$JRETOOLKITDIR, $JRETHREADDIR,
Expand Down Expand Up @@ -850,6 +850,14 @@ else {
print "For $platform.\n";
exit 1;
}

if ( $CPUNAME eq "X86_64") {
$ALIGN = "NEED_ALIGN16";
}
else {
$ALIGN = "NEED_ALIGN8";
}

print "done\n";

#
Expand Down Expand Up @@ -1727,6 +1735,7 @@ ToFile( "CCVER", "@CCVER@", "e" );
ToFile( "CXX_X64_BINARY", $CXX_X64_BINARY, "e" );
ToFile( "LINK_X64_BINARY", $LINK_X64_BINARY, "e" );
ToFile( "LIBMGR_X64_BINARY", $LIBMGR_X64_BINARY, "e" );
ToFile( "ALIGN", $ALIGN, "e" );
ToFile( "CPU", $CPU, "e" );
ToFile( "CPUNAME", $CPUNAME, "e" );
ToFile( "CVER", $CVER, "e" );
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/freebsd.mk
Expand Up @@ -61,7 +61,7 @@ gb_COMPILERDEFS := \
-DHAVE_GCC_VISIBILITY_FEATURE \
-DCPPU_ENV=$(COMNAME) \

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
ifeq ($(CPUNAME),INTEL)
gb_CPUDEFS += -DX86
endif
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/linux.mk
Expand Up @@ -58,7 +58,7 @@ gb_COMPILERDEFS := \
-DHAVE_GCC_VISIBILITY_FEATURE \
-DCPPU_ENV=$(COMNAME) \

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
ifeq ($(CPUNAME),INTEL)
gb_CPUDEFS += -DX86
endif
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/macosx.mk
Expand Up @@ -59,7 +59,7 @@ gb_COMPILERDEFS := \
-DHAVE_GCC_VISIBILITY_FEATURE \
-DCPPU_ENV=$(COMNAME) \

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
ifeq ($(CPUNAME),POWERPC)
gb_CPUDEFS += -DPOWERPC -DPPC
else ifeq ($(CPUNAME),INTEL)
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/os2.mk
Expand Up @@ -60,7 +60,7 @@ gb_COMPILERDEFS := \
-DHAVE_GCC_VISIBILITY_FEATURE \
-DCPPU_ENV=$(COMNAME) \

gb_CPUDEFS := -DINTEL -D_X86_=1 -DX86
gb_CPUDEFS := -D$(ALIGN) -DINTEL -D_X86_=1 -DX86

gb_RCDEFS := \
-DOS2 \
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/solaris.mk
Expand Up @@ -57,7 +57,7 @@ gb_COMPILERDEFS := \
-D$(COM) \
-DCPPU_ENV=$(COMNAME) \

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
ifeq ($(CPUNAME),SPARC)
gb_CPUDEFS += -D__sparcv8plus
endif
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/windows.mk
Expand Up @@ -63,7 +63,7 @@ gb_COMPILERDEFS := \
-DFULL_DESK \
-DM1500 \

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
ifeq ($(CPUNAME),INTEL)
gb_CPUDEFS += -D_X86_=1
endif
Expand Down
2 changes: 1 addition & 1 deletion main/solenv/gbuild/platform/winmingw.mk
Expand Up @@ -87,7 +87,7 @@ ifeq ($(USE_MINGW),cygwin-w64-mingw32)
gb_COMPILERDEFS +=-D_declspec=__declspec
endif

gb_CPUDEFS := -D$(CPUNAME)
gb_CPUDEFS := -D$(ALIGN) -D$(CPUNAME)
gb_CPUDEFS += \
-D_M_IX86 \

Expand Down
2 changes: 1 addition & 1 deletion main/solenv/inc/settings.mk
Expand Up @@ -878,7 +878,7 @@ UNOIDLDEPFLAGS=-Mdepend=$(SOLARVER)

UNOIDLINC+=-I. -I.. -I$(PRJ) -I$(PRJ)/inc -I$(PRJ)/$(INPATH)/idl -I$(OUT)/inc -I$(SOLARIDLDIR) -I$(SOLARINCDIR)

CDEFS= -D$(OS) -D$(GUI) -D$(GVER) -D$(COM) -D$(CVER) -D$(CPUNAME) -DCPPU_ENV=$(COMNAME)
CDEFS= -D$(OS) -D$(GUI) -D$(GVER) -D$(COM) -D$(CVER) -D$(ALIGN) -D$(CPUNAME) -DCPPU_ENV=$(COMNAME)

.IF "$(USE_STLP_DEBUG)" != "" && "$(GUI)"!="OS2"
CDEFS+=-D_STLP_DEBUG
Expand Down

0 comments on commit 787e113

Please sign in to comment.