https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80881
--- Comment #79 from LIU Hao <lh_mouse at 126 dot com> --- Created attachment 59639 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59639&action=edit quote symbols for intel syntax This patch is necessary for TLS in Intel syntax to work with GNU AS. Details follow. This is actually a bit more complicated, and lacks a check for assembler support in configure. I will not care about those assemblers; please update the patch as necessary. [00:48:32] <lh_mouse> theshermantanker: am going to bed soon so I would like to provide some details about the GAS parser. [00:49:45] <lh_mouse> for AT&T syntax: Control flow enters `i386_displacement`, where you will find this: gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); if (gotfree_input_line) input_line_pointer = gotfree_input_line; expr_mode = expr_operator_none; exp_seg = expression (exp); [00:50:46] <lh_mouse> `lex_got` might stand for 'lexically parse for GOT` but anyway, it strips `@SECREL32` from the symbol and returns a malloc'd buffer of the symbol without it. [00:51:39] <lh_mouse> this unsuffixed symbol is assigned to `input_line_pointer` (static variable), then `expression` is invoked to parse it as an expression. [00:52:14] <lh_mouse> the `@SECREL32` thing affects what will be stored into `&i.reloc[this_operand]`, the first argument to `lex_got`. [00:52:24] <lh_mouse> -- end AT&T suffix] [00:53:17] <lh_mouse> for Intel syntax: Notice the macro `md_operator` which is only defined for x86. In 'expr.c' there is: if (is_name_beginner (c) || c == '"') /* Here if did not begin with a digit. */ { /* Identifier begins here. This is kludged for speed, so code is repeated. */ isname: -- input_line_pointer; c = get_symbol_name (&name); [00:54:40] <lh_mouse> Control flow enters `md_operand` where you will find a `case '[':`; this is how Intel syntax is parsed; the stuff in [] is parsed as an expression. [00:55:59] <lh_mouse> when an identifier is encountered, in 'expr.c', `get_symbol_name` is used to parse it. but it knows nothing about the `@SECREL32` thing and mistakes it as the symbol name. [00:56:28] <lh_mouse> (note how this path differs from AT&T where `expression` is called on the result of `lex_got`.) [00:57:29] <lh_mouse> so, later `md_operator` will not see the @ character, because it has already mistaken as part of the symbol. [00:58:22] <lh_mouse> this can be worked around for GAS by inserting a space before @; Clang does not accept this workaround, so please only play with it at home. [01:01:14] <lh_mouse> hope you know how to fix it now. :) good night.