freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] Position Independent Port of FreeType2


From: Mickey Gabel
Subject: Re: [ft-devel] Position Independent Port of FreeType2
Date: Tue, 20 Jan 2009 18:04:15 +0200
User-agent: Thunderbird 2.0.0.19 (Windows/20081209)

address@hidden wrote:
Hi,

On Tue, 20 Jan 2009 15:31:59 +0200
Mickey Gabel <address@hidden> wrote:
  const int x = 0; /* no problem */
  const int* p = &x; /* needs address fixup - can't be used in PIC */
  char  *list1[] = {"zero", "one", "two"}; /* pointers need fixup */
  char  list2[3][5] = {"zero", "one", "two"}; /* OK, no problem */

FT2 uses lots a lot of such constants, such as arrays of pointers to structs and function tables. This is pervasive throughout all parts of FT2.

Hmm, in BREW development,

        int  x = 0;
        int* p = &x;

is bad, but

        int  x = 0;
        int* p;
        ...

        if ( FT_NEW( p ) );
                goto Error;
        else
                p = &x;

        ...

        FT_FREE( p );

is acceptable? Using ft_malloc/ft_free for such purpose for
such purpose should be avoided?

Regards,
mpsuzuki

I must have explained this the wrong way.
The issue I am talking about (position independent code) is unrelated to dynamic memory allocation (which is a different issue, more easily solvable).

What I am talking about is that global/static data must be const, and ALSO cannot contain ANY pointers, because those require relocations.

Let's take a real example from autofit/aflatin.c:

  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
  af_latin_script_class =
  {
    AF_SCRIPT_LATIN,
    af_latin_uniranges,

    sizeof( AF_LatinMetricsRec ),

    (AF_Script_InitMetricsFunc) af_latin_metrics_init,
    (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,
    (AF_Script_DoneMetricsFunc) NULL,

    (AF_Script_InitHintsFunc)   af_latin_hints_init,
    (AF_Script_ApplyHintsFunc)  af_latin_hints_apply
  };

This is a global struct, which although const, contains many pointer, that require relocations. This is impossible on BREW (and other systems were the code must be position independent).
(global non-const variables are a big no as well).

Instead what can be done is something like:
1) Move the struct as a (non-const) member in another struct, for example FT_LibraryRec_. 2) During initialization of autofit module (for example) you would call this function which initializes all members:

  void af_latin_script_class_init(AF_ScriptClassRec* ac)
  {
    ac->script = AF_SCRIPT_LATIN;
    ac->script_uni_ranges = af_latin_uniranges;
    ...
ac->script_hints_apply = (AF_Script_ApplyHintsFunc) af_latin_hints_apply;
  }
3) Now in the code itself, instead of accessing af_latin_script_class directly, it would get to the relevant member (in this example via the library struct).

This of course gets a bit more complicated because there is ANOTHER const table of pointers called af_script_classes which is again forbidden, and needs to be moved to a struct somewhere.

in general, as a static/global variable:

  int x = 0; /* not ok */
  const int x = 0; /* ok */
  const int *px = x; /* NOT ok */
  const struct pnt1_t{ int x; int y; } point = {4,6}; /* probably ok? */
const struct pnt2_t { int x; int* px; } point = {4, &x}; /* definitely NOT ok */

Mickey





reply via email to

[Prev in Thread] Current Thread [Next in Thread]