[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