Permalink
Browse files

vendor compiler portability to Solaris, AIX, HP-UX

vendor compiler portability to Solaris, AIX, HP-UX
document Makefile flags for Oracle Sun Studio, IBM xlC, HP aCC
(additional work needs to be done on contrib/* modules)
clean up loads of pedantic warnings from HP compiler +w
HP aCC does not appear to support C99 inline functions in headers
xlC does not handle __attribute__((noinline)) following ptr return value
Avoid AIX posix_fallocate(); it is broken for 32-bit, slow for 64-bit
(workaround for Solaris madvise() crash bug handled in prior commit)
  • Loading branch information...
1 parent d2c858e commit cc41e53c68ea308019841c87ff280034bacced7a @gstrauss committed Jan 30, 2012
Showing with 256 additions and 160 deletions.
  1. +55 −13 Makefile
  2. +15 −5 code_attributes.h
  3. +4 −1 contrib/MCDB_File/Makefile.PL
  4. +12 −8 mcdb.c
  5. +3 −4 mcdb.h
  6. +16 −6 mcdb_make.c
  7. +11 −7 mcdb_makefmt.c
  8. +10 −10 mcdbctl.c
  9. +1 −1 nointr.c
  10. +6 −6 nss_mcdb.c
  11. +6 −6 nss_mcdb_acct.c
  12. +6 −6 nss_mcdb_acct_make.c
  13. +2 −2 nss_mcdb_authn_make.c
  14. +15 −6 nss_mcdb_make.c
  15. +18 −15 nss_mcdb_netdb.c
  16. +13 −13 nss_mcdb_netdb_make.c
  17. +4 −3 nss_mcdbctl.c
  18. +4 −1 t/testmcdbrand.c
  19. +27 −25 uint32.c
  20. +28 −22 uint32.h
View
@@ -28,27 +28,28 @@ endif
# 'gmake ABI_BITS=64' for 64-bit build (recommended on all 64-bit platforms)
ifeq (64,$(ABI_BITS))
ifeq ($(OSNAME),Linux)
-ABI_FLAGS=-m64
+ABI_FLAGS?=-m64
endif
ifeq ($(OSNAME),AIX)
AR+=-X64
-ABI_FLAGS=-maix64
+ABI_FLAGS?=-maix64
endif
ifeq ($(OSNAME),HP-UX)
-ABI_FLAGS=-mlp64
+ABI_FLAGS?=-mlp64
endif
ifeq ($(OSNAME),SunOS)
-ABI_FLAGS=-m64
+ABI_FLAGS?=-m64
endif
endif
ifneq (,$(RPM_OPT_FLAGS))
CFLAGS+=$(RPM_OPT_FLAGS)
LDFLAGS+=$(RPM_OPT_FLAGS)
else
- CC=gcc -pipe
+ CC?=gcc -pipe
ANSI?=-ansi
- CFLAGS+=-Wall -Winline -pedantic $(ANSI) -O3 -g $(ABI_FLAGS)
+ WARNING_FLAGS?=-Wall -Winline -pedantic $(ANSI)
+ CFLAGS+=$(WARNING_FLAGS) -O3 -g $(ABI_FLAGS)
LDFLAGS+=$(ABI_FLAGS)
ifneq (,$(filter %clang,$(CC)))
ANSI=
@@ -100,10 +101,51 @@ endif
# heavy handed dependencies
_DEPENDENCIES_ON_ALL_HEADERS_Makefile:= $(wildcard *.h) Makefile
+# C99
+STDC99?=-std=c99
+CFLAGS+=$(STDC99)
+# position independent code (for shared libraries)
+FPIC?=-fpic
+# link shared library
+SHLIB?=-shared
+
# Thread-safety (e.g. for thread-specific errno)
# (vendor compilers might need additional compiler flags, e.g. Sun Studio -mt)
PTHREAD_FLAGS?=-pthread -D_THREAD_SAFE
-CFLAGS+=-std=c99 $(PTHREAD_FLAGS)
+CFLAGS+=$(PTHREAD_FLAGS)
+
+# To use vendor compiler, set CC and the following macros, as appropriate:
+# Oracle Sun Studio
+# CC=cc
+# STDC99=-xc99=all
+# PTHREAD_FLAGS=-mt -D_THREAD_SAFE
+# FPIC=-xcode=pic13
+# SHLIB=-G
+# WARNING_FLAGS=-v
+# IBM Visual Age XL C/C++
+# CC=xlc
+# # use -qsuppress to silence msg: keyword '__attribute__' is non-portable
+# STDC99=-qlanglvl=stdc99 -qsuppress=1506-1108
+# PTHREAD_FLAGS=-qthreaded -D__VACPP_MULTI__ -D_THREAD_SAFE
+# FPIC=-qpic=small
+# SHLIB=-qmkshrobj
+# WARNING_FLAGS=
+# #(64-bit)
+# ABI_FLAGS=-q64
+# #(additionally, xlc needs -qtls to recognized __thread keyword)
+# nss_mcdb.o: CFLAGS+=-qtls=local-dynamic
+# HP aCC
+# CC=cc
+# STDC99=-AC99
+# PTHREAD_FLAGS=-mt -D_THREAD_SAFE
+# FPIC=+z
+# SHLIB=-b
+# #(noisy list of inconsequential warnings)
+# WARNING_FLAGS=+w
+# #(64-bit)
+# ABI_FLAGS=+DD64
+# #(additionally, aCC does not appear to support C99 inline)
+# CFLAGS+=-DNO_C99INLINE
%.o: %.c $(_DEPENDENCIES_ON_ALL_HEADERS_Makefile)
$(CC) -o $@ $(CFLAGS) -c $<
@@ -113,21 +155,21 @@ lib32/nss_mcdb.o: CFLAGS+=-DNSS_MCDB_PATH='"$(PREFIX)/etc/mcdb/"'
PIC_OBJS:= mcdb.o mcdb_make.o mcdb_makefmt.o mcdb_makefn.o nointr.o uint32.o \
nss_mcdb.o nss_mcdb_acct.o nss_mcdb_authn.o nss_mcdb_netdb.o
-$(PIC_OBJS): CFLAGS+= -fpic
+$(PIC_OBJS): CFLAGS+=$(FPIC)
# (nointr.o, uint32.o need not be included when fully inlined; adds 10K to .so)
ifeq ($(OSNAME),Linux)
libnss_mcdb.so.2: LDFLAGS+=-Wl,-soname,$(@F) -Wl,--version-script,nss_mcdb.map
endif
libnss_mcdb.so.2: mcdb.o \
nss_mcdb.o nss_mcdb_acct.o nss_mcdb_authn.o nss_mcdb_netdb.o
- $(CC) -o $@ -shared -fpic $(LDFLAGS) $^
+ $(CC) -o $@ $(SHLIB) $(FPIC) $(LDFLAGS) $^
ifeq ($(OSNAME),Linux)
libmcdb.so: LDFLAGS+=-Wl,-soname,mcdb
endif
libmcdb.so: mcdb.o mcdb_make.o mcdb_makefmt.o mcdb_makefn.o nointr.o uint32.o
- $(CC) -o $@ -shared -fpic $(LDFLAGS) $^
+ $(CC) -o $@ $(SHLIB) $(FPIC) $(LDFLAGS) $^
libmcdb.a: mcdb.o mcdb_error.o mcdb_make.o mcdb_makefmt.o mcdb_makefn.o \
nointr.o uint32.o
@@ -225,7 +267,7 @@ lib32/%.o: %.c $(_DEPENDENCIES_ON_ALL_HEADERS_Makefile)
LIB32_PIC_OBJS:= $(addprefix lib32/,$(PIC_OBJS))
$(LIB32_PIC_OBJS): LIB_BITS=32
$(LIB32_PIC_OBJS): ABI_FLAGS=-m32
-$(LIB32_PIC_OBJS): CFLAGS+= -fpic
+$(LIB32_PIC_OBJS): CFLAGS+= $(FPIC)
ifeq ($(OSNAME),Linux)
lib32/libnss_mcdb.so.2: \
@@ -234,15 +276,15 @@ endif
lib32/libnss_mcdb.so.2: ABI_FLAGS=-m32
lib32/libnss_mcdb.so.2: $(addprefix lib32/, \
mcdb.o nss_mcdb.o nss_mcdb_acct.o nss_mcdb_authn.o nss_mcdb_netdb.o)
- $(CC) -o $@ -shared -fpic $(LDFLAGS) $^
+ $(CC) -o $@ $(SHLIB) $(FPIC) $(LDFLAGS) $^
ifeq ($(OSNAME),Linux)
lib32/libmcdb.so: LDFLAGS+=-Wl,-soname,mcdb
endif
lib32/libmcdb.so: ABI_FLAGS=-m32
lib32/libmcdb.so: $(addprefix lib32/, \
mcdb.o mcdb_make.o mcdb_makefmt.o mcdb_makefn.o nointr.o uint32.o)
- $(CC) -o $@ -shared -fpic $(LDFLAGS) $^
+ $(CC) -o $@ $(SHLIB) $(FPIC) $(LDFLAGS) $^
ifneq ($(PREFIX_USR),$(PREFIX))
$(PREFIX_USR)/lib/libnss_mcdb.so.2: $(PREFIX)/lib/libnss_mcdb.so.2 \
View
@@ -260,7 +260,7 @@ extern "C" {
* (on Power7, might check locality and use __dcbtt() or __dcbstt())*/
#if defined(__xlc__) || defined(__xlC__)
#define __builtin_prefetch(addr,rw,locality) \
- ((rw) ? __dcbst(addr) : __dcbt(addr))
+ ((rw) ? __dcbst((void *)(addr)) : __dcbt((void *)(addr)))
#endif
/* Sun Studio
* http://blogs.oracle.com/solarisdev/entry/new_article_prefetching
@@ -273,13 +273,23 @@ extern "C" {
#endif
/* HP aCC for IA-64 (Itanium)
* Search internet "Inline assembly for Itanium-based HP-UX"
- * _Asm_lfhint competers appear to be reverse those of gcc __builtin_prefetch */
+ * (HP compiler expects to see string _LFHINT_* and not integral constants)*/
#if defined(__ia64) && (defined(__HP_cc) || defined(__HP_aCC))
#include <fenv.h>
#include <machine/sys/inline.h>
-#define __builtin_prefetch(addr,rw,locality) \
- ((rw) ? _Asm_lfetch_excl(_LFTYPE_NONE, -(locality)+3, (addr)) \
- : _Asm_lfetch(_LFTYPE_NONE, -(locality)+3, (addr)))
+#define __builtin_prefetch(addr,rw,locality) \
+ ((rw) ? _Asm_lfetch_excl(_LFTYPE_NONE, \
+ (locality) == 0 ? _LFHINT_NONE : \
+ (locality) == 1 ? _LFHINT_NT1 : \
+ (locality) == 2 ? _LFHINT_NT2 : \
+ _LFHINT_NTA, \
+ (void *)(addr)) \
+ : _Asm_lfetch( _LFTYPE_NONE, \
+ (locality) == 0 ? _LFHINT_NONE : \
+ (locality) == 1 ? _LFHINT_NT1 : \
+ (locality) == 2 ? _LFHINT_NT2 : \
+ _LFHINT_NTA, \
+ (void *)(addr)))
#endif
/* default (do-nothing macros) */
#ifndef __builtin_prefetch
@@ -18,7 +18,10 @@ WriteMakefile(
# compile and link with local, static libmcdb.a
INC => '-I ../../..',
dynamic_lib => {
- OTHERLDFLAGS => '../../libmcdb.a -Wl,--version-script,perlext.map',
+ OTHERLDFLAGS => '../../libmcdb.a'.
+ ( $^O eq 'linux' ? ' -Wl,--version-script,perlext.map'
+ : $^O eq 'solaris' ? ' -lrt'
+ : ''),
},
# compile and link with system libmcdb.so
#LIBS => ['-lmcdb'],
View
20 mcdb.c
@@ -69,6 +69,7 @@
#include <errno.h>
#include <limits.h>
#include <string.h>
+#include <stdint.h> /* SIZE_MAX */
#ifdef _THREAD_SAFE
#include <pthread.h> /* pthread_mutex_t, pthread_mutex_{lock,unlock}() */
@@ -118,7 +119,8 @@ mcdb_findtagstart(struct mcdb * const restrict m,
if (__builtin_expect((!m->hslots), 0))
return false;
/* (size of data in lvl2 hash table element is 16-bytes (shift 4 bits)) */
- m->kpos = m->hpos + (((khash >> MCDB_SLOT_BITS) % m->hslots) << m->map->b);
+ m->kpos = m->hpos
+ +(((uintptr_t)((khash>>MCDB_SLOT_BITS) % m->hslots)) << m->map->b);
ptr = m->map->ptr + m->kpos;
__builtin_prefetch(ptr,0,2); /*prefetch for mcdb_findtagnext()*/
__builtin_prefetch(ptr+64,0,2); /*prefetch for mcdb_findtagnext()*/
@@ -232,7 +234,7 @@ mcdb_validate_slots(struct mcdb * const restrict m)
numrecs += (hslots = uint32_strunpack_bigendian_aligned_macro(ptr+u+8));
if (/* __builtin_expect( (*(uint32_t *)(ptr+u+12)) == 0, 1) && */
__builtin_expect( (hpos == hpos_next), 1)) /*(skip padding == 0)*/
- hpos_next += (hslots << bits);
+ hpos_next += ((uintptr_t)hslots << bits);
else
return false;
} while ((u += 16) < MCDB_HEADER_SZ);
@@ -314,7 +316,8 @@ mcdb_mmap_init(struct mcdb_mmap * const restrict map, int fd)
mcdb_mmap_unmap(map);
if (fstat(fd, &st) != 0) return false;
- x = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (st.st_size >= SIZE_MAX) return (errno = EFBIG, false);
+ x = mmap(0, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (x == MAP_FAILED) return false;
__builtin_prefetch((char *)x+960, 0, 3); /*(touch mem page w/ mcdb header)*/
#if 0 /* disable; does not appear to improve performance */
@@ -324,8 +327,8 @@ mcdb_mmap_init(struct mcdb_mmap * const restrict map, int fd)
/*(addr (x) must be aligned on _SC_PAGESIZE for madvise portability)*/
#endif
map->ptr = (unsigned char *)x;
- map->size = st.st_size;
- map->b = st.st_size < UINT_MAX || *(uint32_t *)x == 0 ? 3 : 4;
+ map->size = (uintptr_t)st.st_size;
+ map->b = st.st_size < UINT_MAX || *(uint32_t *)x == 0 ? 3u : 4u;
map->n = ~0;
map->mtime = st.st_mtime;
map->next = NULL;
@@ -440,7 +443,8 @@ mcdb_mmap_refresh_check(const struct mcdb_mmap * const restrict map)
* mcdb_mmap_create(), fn_free(map) is called, whether or not map or NULL was
* passed as first argument to mcdb_mmap_create().
*/
-struct mcdb_mmap * __attribute_noinline__
+__attribute_noinline__
+struct mcdb_mmap *
mcdb_mmap_create(struct mcdb_mmap * restrict map,
const char * const dname __attribute_unused__,
const char * const fname,
@@ -511,7 +515,7 @@ mcdb_mmap_create(struct mcdb_mmap * restrict map,
bool __attribute_noinline__
mcdb_mmap_thread_registration(struct mcdb_mmap ** const restrict mapptr,
- const enum mcdb_flags flags)
+ const int flags)
{
struct mcdb_mmap *map;
struct mcdb_mmap *next = NULL;
@@ -598,7 +602,7 @@ mcdb_mmap_reopen_threadsafe(struct mcdb_mmap ** const restrict mapptr)
/* else rc = true; (map->next already updated e.g. while obtaining lock) */
if (rc) {
- const enum mcdb_flags mcdb_flags_hold_lock =
+ const int mcdb_flags_hold_lock =
MCDB_REGISTER_USE_INCR
| MCDB_REGISTER_MUTEX_UNLOCK_HOLD
| MCDB_REGISTER_MUTEX_LOCK_HOLD;
View
7 mcdb.h
@@ -189,8 +189,7 @@ enum mcdb_flags {
};
extern bool
-mcdb_mmap_thread_registration(struct mcdb_mmap ** restrict,
- enum mcdb_flags)
+mcdb_mmap_thread_registration(struct mcdb_mmap ** restrict, int)
__attribute_nonnull__;
extern bool
mcdb_mmap_reopen_threadsafe(struct mcdb_mmap ** restrict)
@@ -212,8 +211,8 @@ mcdb_mmap_reopen_threadsafe(struct mcdb_mmap ** restrict)
#define MCDB_SLOTS (1u<<MCDB_SLOT_BITS) /* must be power-of-2 */
#define MCDB_SLOT_MASK (MCDB_SLOTS-1) /* bitmask */
#define MCDB_HEADER_SZ (MCDB_SLOTS<<4) /* MCDB_SLOTS * 16 (256*16=4096) */
-#define MCDB_MMAP_SZ (1<<19) /* 512KB; must be > MCDB_HEADER_SZ */
-#define MCDB_BLOCK_SZ (1<<22) /* 4MB; must be >= MCDB_MMAP_SZ */
+#define MCDB_MMAP_SZ (1u<<19) /* 512KB; must be > MCDB_HEADER_SZ */
+#define MCDB_BLOCK_SZ (1u<<22) /* 4MB; must be >= MCDB_MMAP_SZ */
#define MCDB_PAD_ALIGN 16
#define MCDB_PAD_MASK (MCDB_PAD_ALIGN-1)
View
@@ -177,10 +177,12 @@ mcdb_make_fallocate(const int fd, off_t offset, off_t len)
|| defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) \
|| defined(_LARGE_FILES)
if (len <= LLONG_MAX-(stvfs.f_bsize-1) /* check for integer overflow */
- && ((len+stvfs.f_bsize-1) & ~(stvfs.f_bsize-1)) <= LLONG_MAX-offset)
+ && ((len+stvfs.f_bsize-1) & ~(stvfs.f_bsize-1))
+ <= (unsigned long long)(LLONG_MAX-offset))
#else
if (len <= LONG_MAX-(stvfs.f_bsize-1) /* check for integer overflow */
- && ((len+stvfs.f_bsize-1) & ~(stvfs.f_bsize-1)) <= LONG_MAX-offset)
+ && ((len+stvfs.f_bsize-1) & ~(stvfs.f_bsize-1))
+ <= (unsigned long)(LONG_MAX-offset))
#endif
len += offset;
else
@@ -275,8 +277,16 @@ mcdb_mmap_upsize(struct mcdb_make * const restrict m, const size_t sz,
#if defined(__GLIBC__)/* glibc emulates if not natively supported by fs */
if ((errno = posix_fallocate(m->fd, (off_t)m->osz,
(off_t)(m->fsz-m->osz))) == 0)
- #elif defined(_AIX)/*AIX errno=ENOTSUP if not natively supported by fs*/ \
- || defined(__SunOS_5_11) /*not sure about Solaris 11 emulation*/
+ #elif defined(__SunOS_5_11)/*not sure about Solaris 11; not tested by me*/
+ /* disabled for defined(_AIX) since mcdb_make_fallocate() is faster
+ * and because posix_fallocate() in 32-bit can result in SIGSEGV.
+ * Observed on AIX TL6 SP3: posix_fallocate() fails on initial resize
+ * and mcdb_make_fallocate() succeeds, but then posix_fallocate()
+ * returns 0 on second call to extend file, but later access invalid.
+ * Prior issues others had with posix_fallocate() on AIX:
+ * http://thr3ads.net/dovecot/2009/07/1089409-AIX-and-posix_fallocate
+ * https://www-304.ibm.com/support/docview.wss?uid=isg1IZ46957 */
+ /*defined(_AIX)*//*AIX errno=ENOTSUP if not natively supported by fs*/
if ((errno = posix_fallocate(m->fd, (off_t)m->osz,
(off_t)(m->fsz-m->osz))) == 0
|| (errno != ENOSPC
@@ -475,7 +485,7 @@ mcdb_make_finish(struct mcdb_make * const restrict m)
* (madvise is supposed to be advice, not promise; Solaris crash is bug) */
posix_madvise(m->map, m->msz, POSIX_MADV_NORMAL);
- b = (m->pos < UINT_MAX) ? 3 : 4;
+ b = (m->pos < UINT_MAX) ? 3u : 4u;
for (i = 0; i < MCDB_SLOTS; ++i) {
len = count[i] << 1;
d = m->pos;
@@ -536,7 +546,7 @@ mcdb_make_finish(struct mcdb_make * const restrict m)
}
}
- u = (i == MCDB_SLOTS && mcdb_mmap_commit(m, header));
+ u = (uint32_t)(i == MCDB_SLOTS && mcdb_mmap_commit(m, header));
return (u ? 0 : -1) | mcdb_make_destroy(m);
}
View
@@ -151,11 +151,11 @@ mcdb_bufread_number (struct mcdb_input * const restrict b,
const char * const buf = b->buf;
const size_t datasz = b->datasz;
- while (datasz != pos && ((size_t)(buf[pos]-'0'))<=9uL && num <= 214748363uL)
+ while (datasz != pos && ((uint32_t)(buf[pos]-'0'))<=9u && num <=214748363uL)
num = num * 10 + (buf[pos++]-'0');
*rv = num;
- if (b->pos != pos && (datasz == pos || ((size_t)(buf[pos]-'0')) > 9uL)) {
+ if (b->pos != pos && (datasz == pos || ((uint32_t)(buf[pos]-'0')) > 9u)) {
b->pos = pos;
return true;
}
@@ -347,19 +347,23 @@ mcdb_makefmt_fileintofile (const char * const restrict infile,
if ((fd = nointr_open(infile,O_RDONLY,0)) == -1)
return MCDB_ERROR_READ;
- if (fstat(fd, &st) == -1 || (!S_ISREG(st.st_mode) && (errno = EINVAL))
- || ((x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0)) == MAP_FAILED))
+ if (fstat(fd, &st) == -1
+ || (!S_ISREG(st.st_mode) || st.st_size >= SIZE_MAX ? (errno=EFBIG) : 0)
+ || ((x = mmap(0, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0))
+ == MAP_FAILED))
errsave = errno;
/* close fd after mmap (no longer needed),check mmap succeeded,create mcdb*/
if (nointr_close(fd) == 0 && x != MAP_FAILED) {
- posix_madvise(x, st.st_size, POSIX_MADV_SEQUENTIAL|POSIX_MADV_WILLNEED);
+ posix_madvise(x, (size_t)st.st_size,
+ POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);
/* pass entire map and size as params; fd -1 elides read()/remaps */
- rv = mcdb_makefmt_fdintofile(-1,x,st.st_size,fname,fn_malloc,fn_free);
+ rv = mcdb_makefmt_fdintofile(-1, x, (size_t)st.st_size,
+ fname, fn_malloc, fn_free);
}
if (x != MAP_FAILED)
- munmap(x, st.st_size);
+ munmap(x, (size_t)st.st_size);
else if (errsave != 0)
errno = errsave;
Oops, something went wrong.

0 comments on commit cc41e53

Please sign in to comment.