[Bug target/93146] New: TLS init function not generated on AIX

dje at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Jan 3 16:35:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93146

            Bug ID: 93146
           Summary: TLS init function not generated on AIX
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dje at gcc dot gnu.org
  Target Milestone: ---
            Target: powerpc-ibm-aix*

SYMPTOM:
On AIX, TLS init elicits linker errors such as

TLS init fuction for thread_local_seg_handler

or

__tls_init


An example C++ program is

$ cat a.cc
#include <atomic>
struct Test {std::atomic<int> x; };

thread_local Test t;

$ cat main.cc
#include <atomic>
struct Test {std::atomic<int> x; };

extern thread_local Test t;
int main () {
  return t.x.load();
}

$ g++ -std=c++14 -pthread a.cc main.cc
ld: 0711-317 ERROR: Undefined symbol: __tls_init


BACKGROUND:

AIX XCOFF symbol aliases do not function the same as ELF symbols aliases: XCOFF
generates "hard aliases" (like hard links) with only one definition and the
attributes are shared / overwritten, instead of a "symbolic" reference to the
other definition with its own attributes.  Because of this
gcc/config/rs6000/xcoff.h defines:

/* This is how we tell the assembler to equate two values. 
   The semantic of AIX assembler's .set do not correspond to middle-end
expectat
ions.
   We output aliases as alternative symbols in the front of the definition
   via DECLARE_FUNCTION_NAME and DECLARE_OBJECT_NAME.
   We still need to define this macro to let middle-end know that aliases are
   supported.
 */
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0)

Honza generously provided other AIX-specific code for function aliases that
generate alternative labels in front of the definition.

Because of this, GCC internals consider AIX as TARGET_SUPPORTS_ALIASES.  Note
that the above macro will not output anything for an alias.

AIX also support TLS.

These two features / behaviors collide for TLS init functions.  gcc/cp/decl2.c
get_tls_init_fn() and handle_tls_init() depend upon TARGET_SUPPORTS_ALIASES,
e.g.,

      if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var))
        {
          tree single_init_fn = get_tls_init_fn (var);
          if (single_init_fn == NULL_TREE)
            continue;
          cgraph_node *alias
            = cgraph_node::get_create (fn)->create_same_body_alias
                (single_init_fn, fn);
          gcc_assert (alias != NULL);
        }

Disabling TARGET_SUPPORTS_ALIASES within cp/decl2.c does not generate correct
code (it switches from a mangled TLS init function to __tls_init).

How can G++ be coerced to generate TLS init functions for AIX?


More information about the Gcc-bugs mailing list