+2005-11-16 Patrick Lam <plam@mit.edu>
+ * src/fccache.c (FcDirCacheProduce):
+ * src/fccharset.c (FcCharSetDistributeBytes):
+ * src/fcfs.c (FcFontSetDistributeBytes):
+ * src/fcint.h:
+ * src/fclang.c (FcLangSetDistributeBytes):
+ * src/fcname.c (FcObjectDistributeBytes):
+ * src/fcpat.c (FcPatternNeededBytes, FcValueListNeededBytes,
+ FcStrNeededBytes):
+
+ Add *NeededBytesAlign(), which overestimates the padding which is
+ later added by the new ALIGN macro. Fix alignment problems on
+ ia64 and s390 by bumping up block_ptr appropriately. (Earlier
+ version by Andreas Schwab).
+
+2005-11-16 Stephan Kulow <coolo@kde.org>
+ reviewed by: plam
+
+ * src/fccache.c:
+
+ Use sysconf to determine proper PAGESIZE value; this
+ appears to be POSIX-compliant. (reported by Andreas Schwab)
+
2005-11-04 Patrick Lam <plam@mit.edu>
* fc-lang/fc-lang.c:
* src/fccharset.c:
#include <sys/types.h>
#include <unistd.h>
#include "fcint.h"
+#include <unistd.h>
#define ENDIAN_TEST 0x12345678
-#define MACHINE_SIGNATURE_SIZE 9 + 5*19 + 1
+#define MACHINE_SIGNATURE_SIZE 9 + 5*20 + 1
static off_t
FcCacheSkipToArch (int fd, const char * arch);
return FcFalse;
}
-#define PAGESIZE 8192
/*
* Find the next presumably-mmapable offset after the supplied file
* position.
static int
FcCacheNextOffset(off_t w)
{
- if (w % PAGESIZE == 0)
+ static long pagesize = -1;
+ if (pagesize == -1)
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (w % pagesize == 0)
return w;
else
- return ((w / PAGESIZE)+1)*PAGESIZE;
+ return ((w / pagesize)+1)*pagesize;
}
/* return the address of the segment for the provided arch,
memset (metadata, 0, sizeof(FcCache));
FcFontSetNewBank();
- metadata->count = FcFontSetNeededBytes (set);
+ metadata->count = FcFontSetNeededBytes (set) +
+ FcFontSetNeededBytesAlign ();
metadata->magic = FC_CACHE_MAGIC;
metadata->bank = bank;
FcCacheMachineSignature ()
{
static char buf[MACHINE_SIGNATURE_SIZE];
- int magic = ENDIAN_TEST;
+ int32_t magic = ENDIAN_TEST;
char * m = (char *)&magic;
sprintf (buf, "%2x%2x%2x%2x "
"%4x %4x %4x %4x %4x %4x %4x %4x %4x %4x %4x %4x "
- "%4x %4x %4x %4x %4x %4x %4x\n",
+ "%4x %4x %4x %4x %4x %4x %4x %4x\n",
m[0], m[1], m[2], m[3],
(unsigned int)sizeof (char),
(unsigned int)sizeof (char *),
(unsigned int)sizeof (FcChar16),
(unsigned int)sizeof (FcCharLeaf),
(unsigned int)sizeof (FcChar32),
- (unsigned int)sizeof (FcCache));
+ (unsigned int)sizeof (FcCache),
+ (unsigned int)sysconf(_SC_PAGESIZE));
return buf;
}
sizeof (FcChar16) * c->num; /* number */
}
+int
+FcCharSetNeededBytesAlign (void)
+{
+ return __alignof__ (FcCharSet) + __alignof__ (int) +
+ __alignof__ (FcCharLeaf) + __alignof__ (FcChar16);
+}
+
static FcBool
FcCharSetEnsureBank (int bi)
{
return 0;
charsets[bi] = (FcCharSet *)block_ptr;
+ block_ptr = ALIGN (block_ptr, FcCharSet);
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcCharSet) * charset_count));
numbers[bi] = (FcChar16 *)block_ptr;
+ block_ptr = ALIGN (block_ptr, FcChar16);
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcChar16) * charset_numbers_count));
leaves[bi] = (FcCharLeaf *)block_ptr;
+ block_ptr = ALIGN (block_ptr, FcCharLeaf);
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcCharLeaf) * charset_leaf_count));
leaf_idx[bi] = (int *)block_ptr;
+ block_ptr = ALIGN (block_ptr, int);
block_ptr = (void *)((char *)block_ptr +
(sizeof(int) * charset_leaf_idx_count));
return 0;
}
+/* Returns an overestimate of the number of bytes that
+ * might later get eaten up by padding in the ALIGN macro. */
+int
+FcFontSetNeededBytesAlign (void)
+{
+ return __alignof__(int) +
+ FcPatternNeededBytesAlign () + FcObjectNeededBytesAlign ();
+}
+
void *
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr)
{
+ block_ptr = ALIGN (block_ptr, int);
fcfs_pat_count = (int *)block_ptr;
block_ptr = (int *)block_ptr + 1;
// we don't consume any bytes for the fontset itself,
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
typedef struct _FcCharMap FcCharMap;
+#define ALIGN(v,type) ((__typeof__(v))(((uintptr_t)(v) + __alignof__(type) - 1) & ~(__alignof__(type) - 1)))
+
/* fcblanks.c */
/* fccache.c */
int
FcCharSetNeededBytes (const FcCharSet *c);
+int
+FcCharSetNeededBytesAlign (void);
+
void *
FcCharSetDistributeBytes (FcCache * metadata,
void * block_ptr);
int
FcFontSetNeededBytes (FcFontSet *s);
+int
+FcFontSetNeededBytesAlign (void);
+
void *
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr);
int
FcLangSetNeededBytes (const FcLangSet *l);
+int
+FcLangSetNeededBytesAlign (void);
+
void *
FcLangSetDistributeBytes (FcCache * metadata,
void * block_ptr);
int
FcObjectNeededBytes (void);
+int
+FcObjectNeededBytesAlign (void);
+
void *
FcObjectUnserialize (FcCache metadata, void *block_ptr);
int
FcPatternNeededBytes (FcPattern *p);
+int
+FcPatternNeededBytesAlign (void);
+
void *
FcPatternDistributeBytes (FcCache * metadata, void * block_ptr);
return sizeof (FcLangSet);
}
+int
+FcLangSetNeededBytesAlign (void)
+{
+ return __alignof__ (FcLangSet);
+}
+
static FcBool
FcLangSetEnsureBank (int bi)
{
if (!FcLangSetEnsureBank(bi))
return 0;
+ block_ptr = ALIGN(block_ptr, FcLangSet);
langsets[bi] = block_ptr;
block_ptr = (void *)((char *)block_ptr +
langset_count * sizeof(FcLangSet));
return 0;
FcMemAlloc (FC_MEM_LANGSET, metadata.langset_count * sizeof(FcLangSet));
+ block_ptr = ALIGN(block_ptr, FcLangSet);
langsets[bi] = (FcLangSet *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
metadata.langset_count * sizeof(FcLangSet));
return num + sizeof(int);
}
+int
+FcObjectNeededBytesAlign (void)
+{
+ return __alignof__ (int) + __alignof__ (char);
+}
+
void *
FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
{
*(int *)block_ptr = biggest_known_ntypes;
+ block_ptr = ALIGN (block_ptr, int);
block_ptr = (int *) block_ptr + 1;
biggest_ptr = block_ptr;
+ block_ptr = ALIGN (block_ptr, char);
block_ptr = (char *) block_ptr + biggest_known_count;
return block_ptr;
}
FcStrNewBank (void);
static int
FcStrNeededBytes (const FcChar8 * s);
+static int
+FcStrNeededBytesAlign (void);
static void *
FcStrDistributeBytes (FcCache * metadata, void * block_ptr);
static const FcChar8 *
FcValueListNewBank (void);
static int
FcValueListNeededBytes (FcValueList * vl);
+static int
+FcValueListNeededBytesAlign (void);
static void *
FcValueListDistributeBytes (FcCache * metadata, void *block_ptr);
static FcValueListPtr
return cum + sizeof (FcPattern) + sizeof(FcPatternElt)*p->num;
}
+int
+FcPatternNeededBytesAlign (void)
+{
+ return __alignof__ (FcPattern) + __alignof__ (FcPatternElt) +
+ FcValueListNeededBytesAlign ();
+}
+
static FcBool
FcPatternEnsureBank (int bi)
{
return 0;
fcpattern_ptr = 0;
+ block_ptr = ALIGN(block_ptr, FcPattern);
fcpatterns[bi] = (FcPattern *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcPattern) * fcpattern_count));
FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt) * fcpatternelt_count);
fcpatternelt_ptr = 0;
+ block_ptr = ALIGN(block_ptr, FcPatternElt);
fcpatternelts[bi] = (FcPatternElt *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcPatternElt) * fcpatternelt_count));
return FcFalse;
FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * metadata.pattern_count);
+ block_ptr = ALIGN(block_ptr, FcPattern);
fcpatterns[bi] = (FcPattern *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcPattern) * metadata.pattern_count));
FcMemAlloc (FC_MEM_PATELT,
sizeof (FcPatternElt) * metadata.patternelt_count);
+ block_ptr = ALIGN(block_ptr, FcPatternElt);
fcpatternelts[bi] = (FcPatternElt *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcPatternElt) * metadata.patternelt_count));
return cum;
}
+static int
+FcValueListNeededBytesAlign (void)
+{
+ return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() +
+ FcStrNeededBytesAlign() + __alignof__ (FcValueList);
+}
+
static FcBool
FcValueListEnsureBank (int bi)
{
FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList) * fcvaluelist_count);
fcvaluelist_ptr = 0;
+ block_ptr = ALIGN(block_ptr, FcValueList);
fcvaluelists[bi] = (FcValueList *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcValueList) * fcvaluelist_count));
FcMemAlloc (FC_MEM_VALLIST,
sizeof (FcValueList) * metadata.valuelist_count);
+ block_ptr = ALIGN(block_ptr, FcValueList);
fcvaluelists[bi] = (FcValueList *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcValueList) * metadata.valuelist_count));
b->next = 0;
b->hash = hash;
strcpy ((char *) (b + 1), (char *)s);
+
+ /* Yes, the following line is convoluted. However, it is
+ * incorrect to replace the with a memset, because the C
+ * specification doesn't guarantee that the null pointer is
+ * the same as the zero bit pattern. */
*(char **)((char *) (b + 1) + strlen((char *)s) + 1) = 0;
*p = b;
return strlen((char *)s) + 1;
}
+static int
+FcStrNeededBytesAlign (void)
+{
+ return __alignof__ (char);
+}
+
static FcBool
FcStrEnsureBank (int bi)
{
return 0;
FcMemAlloc (FC_MEM_STRING, sizeof (char) * fcstr_count);
+ block_ptr = ALIGN (block_ptr, FcChar8);
static_strs[bi] = (FcChar8 *)block_ptr;
block_ptr = (void *)((char *)block_ptr + (sizeof (char) * fcstr_count));
metadata->str_count = fcstr_count;