Hello,

Suppose a user builds a non-PIC shared object for x86 target with gcc by
passing -shared but not -fPIC.  This works, but internally GCC will not set
flag_shlib (as flag_shlib == flag_pic && !flag_pie).  

Suppose further the user loads that shared object at runtime with dlopen.  For
that to work reliably, any TLS data there must be allocated with local-dynamic
or global-dynamic model.  However, since flag_shlib was not set,
varasm.c:decl_default_tls_model will choose local-exec or initial-exec.

The documentation for -ftls-model option promises that the user can override
the choice from command line:

-ftls-model=model
  Alter the thread-local storage model to be used.  The model argument should
  be one of "global-dynamic", "local-dynamic", "initial-exec" or "local-exec".

However the implementation does not allow arbitrary overriding:

decl_default_tls_model (const_tree decl)
{ 
  if (!flag_shlib)
    kind = is_local ? TLS_MODEL_LOCAL_EXEC : TLS_MODEL_INITIAL_EXEC;
  else
    kind = is_local ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;

  if (kind < flag_tls_default)
    kind = flag_tls_default;

  return kind;
} 

(code edited by hand for brevity; actual source:
http://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/varasm.c#l5985 ).

The TLS_* values are such that TLS_MODEL_GLOBAL_DYNAMIC < TLS_MODEL_LOCAL_EXEC.

Thus, the implementation of -ftls-model allows to clamp storage to faster,
less general models, but does not allow to force slower, more general models.
This prevents building safely dlopen'able non-PIC shared objects without
resorting to using attributes to mark TLS data explicitely as global-dynamic.
This behavior is from day one as far as I could trace it:
http://gcc.gnu.org/ml/gcc-patches/2002-05/msg01912.html

It follows that the documentation is wrong or incomplete.  I also think the
implementation should be changed to allow what the documentation promises.
I can fix either, but I need to know which.  Please advise.

I'll also appreciate comments on whether the inability to set flag_shlib
without -fPIC is entirely intended and WONTFIX.

Thanks.
Alexander

Reply via email to