[Fontconfig] relocations, readonly data

Patrick Lam plam at MIT.EDU
Fri Nov 4 11:33:35 PST 2005


Matthias Clasen wrote:
> Another interesting bug in this area is 2878, which complains that
> all the FcCharSets in fcLangCharSets are stored in .data and cause
> relocations, although they are not modified at runtime. It seems to me
> that it should be possible to fix this by generating the charsets
> in the form in which fc-cache stores them in the mmap cache, but I have
> not been able to work out the details.

I've committed the attached patch to the branch subsequent to tagging
2.3.92 (release announcement for that will follow once I get home and
type in my gpg password).  However, I'm also sending it to the list for
comments: I'm not entirely sure that this patch is correct, as I don't
know how to test it.  Keith and Matthias, can you take a look?  It does
seem to work, for what that's worth.

pat
-------------- next part --------------
? blacklisting.patch
? charset-diffs
? fc-list-patch
? fclang-static.diff
? plam-blacklist-patch.diff
Index: fc-lang/fc-lang.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fc-lang/fc-lang.c,v
retrieving revision 1.11.4.6
diff -u -r1.11.4.6 fc-lang.c
--- fc-lang/fc-lang.c	23 Sep 2005 01:48:33 -0000	1.11.4.6
+++ fc-lang/fc-lang.c	4 Nov 2005 06:00:40 -0000
@@ -37,6 +37,10 @@
  * functions are also needed in slightly modified form
  */
 
+const FcChar16 *langBankNumbers = 0;
+const FcCharLeaf	*langBankLeaves = 0;
+const int *langBankLeafIdx = 0;
+
 void
 FcMemAlloc (int kind, int size)
 {
@@ -232,6 +236,7 @@
     int		argi;
     FcCharLeaf	**leaves;
     int		total_leaves = 0;
+    int		leafidx_count = 0, numbers_count = 0, numbers_ptr = 0;
     int		l, sl, tl;
     int		c;
     char	line[1024];
@@ -306,7 +311,7 @@
     /*
      * Dump leaves
      */
-    printf ("static const FcCharLeaf	leaves[%d] = {\n", tl);
+    printf ("const FcCharLeaf	langBankLeaves[%d] = {\n", tl);
     for (l = 0; l < tl; l++)
     {
 	printf ("    { { /* %d */", l);
@@ -319,7 +324,6 @@
 	printf ("\n    } },\n");
     }
     printf ("};\n\n");
-    printf ("#define L(n) ((FcCharLeaf *) &leaves[n])\n\n");
 
     /*
      * Find duplicate charsets
@@ -362,8 +366,27 @@
 	
 	if (duplicate[i] >= 0)
 	    continue;
-	printf ("static const FcCharLeaf *leaves_%s[%d] = {\n",
-		names[i], sets[i]->num);
+
+	for (n = 0; n < sets[i]->num; n++)
+	{
+	    for (l = 0; l < tl; l++)
+		if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
+		    break;
+	    if (l == tl)
+		fatal (names[i], 0, "can't find leaf");
+            leafidx_count++;
+            numbers_count += sets[i]->num;
+	}
+    }
+
+    printf ("const int langBankLeafIdx[%d] = {\n",
+	    leafidx_count);
+    for (i = 0; sets[i]; i++)
+    {
+	int n;
+	
+	if (duplicate[i] >= 0)
+	    continue;
 	for (n = 0; n < sets[i]->num; n++)
 	{
 	    if (n % 8 == 0)
@@ -373,17 +396,21 @@
 		    break;
 	    if (l == tl)
 		fatal (names[i], 0, "can't find leaf");
-	    printf (" L(%3d),", l);
+	    printf (" %3d,", l);
 	    if (n % 8 == 7)
 		printf ("\n");
 	}
 	if (n % 8 != 0)
 	    printf ("\n");
-	printf ("};\n\n");
-	
+    }
+    printf ("};\n\n");
 
-	printf ("static const FcChar16 numbers_%s[%d] = {\n",
-		names[i], sets[i]->num);
+    printf ("const FcChar16 langBankNumbers[%d] = {\n",
+	    numbers_count);
+
+    for (i = 0; sets[i]; i++)
+    {
+	int n;
 	for (n = 0; n < sets[i]->num; n++)
 	{
 	    if (n % 8 == 0)
@@ -394,27 +421,27 @@
 	}
 	if (n % 8 != 0)
 	    printf ("\n");
-	printf ("};\n\n");
     }
-    printf ("#undef L\n\n");
+    printf ("};\n\n");
     
     /*
      * Dump sets
      */
 
-    printf ("static const FcLangCharSet  fcLangCharSets[] = {\n");
+    printf ("const FcLangCharSet  fcLangCharSets[] = {\n");
     for (i = 0; sets[i]; i++)
     {
 	int	j = duplicate[i];
 
 	if (j < 0)
 	    j = i;
+
 	printf ("    { (FcChar8 *) \"%s\",\n"
-		"      { FC_REF_CONSTANT, %d, FC_BANK_DYNAMIC, "
-		"{ { (FcCharLeaf **) leaves_%s, "
-		"(FcChar16 *) numbers_%s } } } },\n",
+		"      { FC_REF_CONSTANT, %d, FC_BANK_LANGS, "
+		"{ .stat = { %d, %d } } } },\n",
 		langs[i],
-		sets[j]->num, names[j], names[j]);
+		sets[j]->num, j, numbers_ptr);
+        numbers_ptr += sets[i]->num;
     }
     printf ("};\n\n");
     printf ("#define NUM_LANG_CHAR_SET	%d\n", i);
Index: src/fccharset.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fccharset.c,v
retrieving revision 1.25.4.4
diff -u -r1.25.4.4 fccharset.c
--- src/fccharset.c	22 Sep 2005 23:45:53 -0000	1.25.4.4
+++ src/fccharset.c	4 Nov 2005 06:00:40 -0000
@@ -38,6 +38,24 @@
 static int ** leaf_idx = 0;
 static int charset_leaf_idx_ptr, charset_leaf_idx_count;
 
+extern const FcChar16 *langBankNumbers;
+extern const FcCharLeaf	*langBankLeaves;
+extern const int *langBankLeafIdx;
+
+static FcBool
+FcCharSetEnsureBank (int bi);
+
+void
+FcLangCharSetPopulate (void)
+{
+    int bi = FcCacheBankToIndex (FC_BANK_LANGS);
+    FcCharSetEnsureBank (bi);
+    charsets[bi] = 0;
+    numbers[bi] = (FcChar16 *)&langBankNumbers;
+    leaves[bi] = (FcCharLeaf *)&langBankLeaves;
+    leaf_idx[bi] = (int *)&langBankLeafIdx;
+}
+
 FcCharSet *
 FcCharSetCreate (void)
 {
Index: src/fcint.h
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcint.h,v
retrieving revision 1.47.4.18
diff -u -r1.47.4.18 fcint.h
--- src/fcint.h	2 Nov 2005 06:29:14 -0000	1.47.4.18
+++ src/fcint.h	4 Nov 2005 06:00:40 -0000
@@ -99,6 +99,8 @@
 
 #define FC_MEM_NUM	    30
 
+#define FC_BANK_LANGS	    0xfcfcfcfc
+
 typedef enum _FcValueBinding {
     FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
 } FcValueBinding;
@@ -524,6 +526,9 @@
 FcConfigModifiedTime (FcConfig *config);
 
 /* fccharset.c */
+void
+FcLangCharSetPopulate (void);
+
 FcCharSet *
 FcCharSetFreeze (FcCharSet *cs);
 
Index: src/fclang.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fclang.c,v
retrieving revision 1.14.4.4
diff -u -r1.14.4.4 fclang.c
--- src/fclang.c	14 Oct 2005 21:02:31 -0000	1.14.4.4
+++ src/fclang.c	4 Nov 2005 06:00:40 -0000
@@ -44,6 +44,8 @@
 #define FcLangSetBitSet(ls, id)	((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
 #define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
 
+static FcBool langsets_populated = FcFalse;
+
 FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
 		   const FcChar8    *exclusiveLang)
@@ -52,7 +54,12 @@
     FcChar32	    missing;
     const FcCharSet *exclusiveCharset = 0;
     FcLangSet	    *ls;
-    
+
+    if (!langsets_populated)
+    {
+        FcLangCharSetPopulate ();
+        langsets_populated = FcTrue;
+    }
 
     if (exclusiveLang)
 	exclusiveCharset = FcCharSetForLang (exclusiveLang);
@@ -188,6 +195,13 @@
 {
     int		i;
     int		country = -1;
+
+    if (!langsets_populated)
+    {
+        FcLangCharSetPopulate ();
+        langsets_populated = FcTrue;
+    }
+
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
 	switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {


More information about the Fontconfig mailing list