diff --git a/ChangeLog b/ChangeLog index e1e33ef..f2b0ec2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2005-11-16 Patrick Lam + * 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 + 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 * fc-lang/fc-lang.c: * src/fccharset.c: diff --git a/src/fccache.c b/src/fccache.c index 69bb385..af8a318 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -30,9 +30,10 @@ #include #include #include "fcint.h" +#include #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); @@ -417,7 +418,6 @@ FcGlobalCacheSave (FcGlobalCache *cache, return FcFalse; } -#define PAGESIZE 8192 /* * Find the next presumably-mmapable offset after the supplied file * position. @@ -425,10 +425,13 @@ FcGlobalCacheSave (FcGlobalCache *cache, 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, @@ -801,7 +804,8 @@ FcDirCacheProduce (FcFontSet *set, FcCache *metadata) memset (metadata, 0, sizeof(FcCache)); FcFontSetNewBank(); - metadata->count = FcFontSetNeededBytes (set); + metadata->count = FcFontSetNeededBytes (set) + + FcFontSetNeededBytesAlign (); metadata->magic = FC_CACHE_MAGIC; metadata->bank = bank; @@ -943,12 +947,12 @@ static char * 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 *), @@ -968,7 +972,8 @@ FcCacheMachineSignature () (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; } diff --git a/src/fccharset.c b/src/fccharset.c index 9fa0e6b..790d78f 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -1331,6 +1331,13 @@ FcCharSetNeededBytes (const FcCharSet *c) sizeof (FcChar16) * c->num; /* number */ } +int +FcCharSetNeededBytesAlign (void) +{ + return __alignof__ (FcCharSet) + __alignof__ (int) + + __alignof__ (FcCharLeaf) + __alignof__ (FcChar16); +} + static FcBool FcCharSetEnsureBank (int bi) { @@ -1373,15 +1380,19 @@ FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr) 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)); diff --git a/src/fcfs.c b/src/fcfs.c index 3ba5674..0788a6f 100644 --- a/src/fcfs.c +++ b/src/fcfs.c @@ -108,9 +108,19 @@ FcFontSetNeededBytes (FcFontSet *s) 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, diff --git a/src/fcint.h b/src/fcint.h index 00ded26..4dbb7b4 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -415,6 +416,8 @@ typedef struct _FcFileTime { typedef struct _FcCharMap FcCharMap; +#define ALIGN(v,type) ((__typeof__(v))(((uintptr_t)(v) + __alignof__(type) - 1) & ~(__alignof__(type) - 1))) + /* fcblanks.c */ /* fccache.c */ @@ -550,6 +553,9 @@ FcCharSetNewBank (void); int FcCharSetNeededBytes (const FcCharSet *c); +int +FcCharSetNeededBytesAlign (void); + void * FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr); @@ -646,6 +652,9 @@ FcFontSetNewBank (void); int FcFontSetNeededBytes (FcFontSet *s); +int +FcFontSetNeededBytesAlign (void); + void * FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr); @@ -741,6 +750,9 @@ FcLangSetNewBank (void); int FcLangSetNeededBytes (const FcLangSet *l); +int +FcLangSetNeededBytesAlign (void); + void * FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr); @@ -774,6 +786,9 @@ FcObjectToPtr (const char * si); int FcObjectNeededBytes (void); +int +FcObjectNeededBytesAlign (void); + void * FcObjectUnserialize (FcCache metadata, void *block_ptr); @@ -837,6 +852,9 @@ FcPatternNewBank (void); int FcPatternNeededBytes (FcPattern *p); +int +FcPatternNeededBytesAlign (void); + void * FcPatternDistributeBytes (FcCache * metadata, void * block_ptr); diff --git a/src/fclang.c b/src/fclang.c index b1c7c3f..5518821 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -721,6 +721,12 @@ FcLangSetNeededBytes (const FcLangSet *l) return sizeof (FcLangSet); } +int +FcLangSetNeededBytesAlign (void) +{ + return __alignof__ (FcLangSet); +} + static FcBool FcLangSetEnsureBank (int bi) { @@ -749,6 +755,7 @@ FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr) 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)); @@ -778,6 +785,7 @@ FcLangSetUnserialize (FcCache metadata, void *block_ptr) 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)); diff --git a/src/fcname.c b/src/fcname.c index 0767e11..6ca4f1a 100644 --- a/src/fcname.c +++ b/src/fcname.c @@ -332,12 +332,20 @@ FcObjectNeededBytes () 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; } diff --git a/src/fcpat.c b/src/fcpat.c index ca75f90..bb922fe 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -1430,6 +1430,8 @@ static void FcStrNewBank (void); static int FcStrNeededBytes (const FcChar8 * s); +static int +FcStrNeededBytesAlign (void); static void * FcStrDistributeBytes (FcCache * metadata, void * block_ptr); static const FcChar8 * @@ -1441,6 +1443,8 @@ static void FcValueListNewBank (void); static int FcValueListNeededBytes (FcValueList * vl); +static int +FcValueListNeededBytesAlign (void); static void * FcValueListDistributeBytes (FcCache * metadata, void *block_ptr); static FcValueListPtr @@ -1479,6 +1483,13 @@ FcPatternNeededBytes (FcPattern * p) return cum + sizeof (FcPattern) + sizeof(FcPatternElt)*p->num; } +int +FcPatternNeededBytesAlign (void) +{ + return __alignof__ (FcPattern) + __alignof__ (FcPatternElt) + + FcValueListNeededBytesAlign (); +} + static FcBool FcPatternEnsureBank (int bi) { @@ -1525,12 +1536,14 @@ FcPatternDistributeBytes (FcCache * metadata, void * block_ptr) 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)); @@ -1603,12 +1616,14 @@ FcPatternUnserialize (FcCache metadata, void *block_ptr) 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)); @@ -1660,6 +1675,13 @@ FcValueListNeededBytes (FcValueList *p) return cum; } +static int +FcValueListNeededBytesAlign (void) +{ + return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() + + FcStrNeededBytesAlign() + __alignof__ (FcValueList); +} + static FcBool FcValueListEnsureBank (int bi) { @@ -1694,6 +1716,7 @@ FcValueListDistributeBytes (FcCache * metadata, void *block_ptr) 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)); @@ -1774,6 +1797,7 @@ FcValueListUnserialize (FcCache metadata, void *block_ptr) 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)); @@ -1850,6 +1874,11 @@ FcStrNeededBytes (const FcChar8 * s) 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; @@ -1857,6 +1886,12 @@ FcStrNeededBytes (const FcChar8 * s) return strlen((char *)s) + 1; } +static int +FcStrNeededBytesAlign (void) +{ + return __alignof__ (char); +} + static FcBool FcStrEnsureBank (int bi) { @@ -1887,6 +1922,7 @@ FcStrDistributeBytes (FcCache * metadata, void * block_ptr) 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;