Commit c89d7d19 by Iain Sandoe Committed by Iain Sandoe

[Darwin, machopic 6/n] Fix for 67183

When we're using the LLVM-based assembler (the default on modern Darwin)
the ordering of stubs and non-lazy symbol pointers is important.

Interleaving the output (current GCC behaviour) leads to crashes which
prevents us from building code with symbol stubs.

To resolve this, we order the output of stubs and symbol indirections:

 1. Any indirections in the data section
 2. Symbol stubs.
 3. Non-lazy symbol pointers.

At present, we still emit LTO sections after these.

gcc/ChangeLog:

2019-10-12  Iain Sandoe  <iain@sandoe.co.uk>

	PR target/67183
	* config/darwin.c (machopic_indirection): New field to flag
	non-lazy-symbol-pointers in the data section.
	(machopic_indirection_name): Compute if an indirection should
	appear in the data section.
	(machopic_output_data_section_indirection): New callback split
	from machopic_output_indirection.
	(machopic_output_stub_indirection): Likewise.
	(machopic_output_indirection): Retain the code for non-lazy
	symbol pointers in their regular section.
	(machopic_finish): Use the new callbacks to order the indirection
	output.

From-SVN: r276926
parent 1aea083d
2019-10-12 Iain Sandoe <iain@sandoe.co.uk>
PR target/67183
* config/darwin.c (machopic_indirection): New field to flag
non-lazy-symbol-pointers in the data section.
(machopic_indirection_name): Compute if an indirection should
appear in the data section.
(machopic_output_data_section_indirection): New callback split
from machopic_output_indirection.
(machopic_output_stub_indirection): Likewise.
(machopic_output_indirection): Retain the code for non-lazy
symbol pointers in their regular section.
(machopic_finish): Use the new callbacks to order the indirection
output.
2019-10-12 Iain Sandoe <iain@sandoe.co.uk>
* config/darwin-protos.h (machopic_finish): Delete.
* config/darwin.c (machopic_finish): Make static.
2019-10-12 Iain Sandoe <iain@sandoe.co.uk>
* config/darwin.c (darwin_file_end): Only emit empty CTOR/DTOR
sections when building kernel extension code.
2019-10-12 Palmer Dabbelt <palmer@sifive.com>
* doc/extend.texi (Alternate Keywords): Change "-std=c11" to "a
......
......@@ -454,6 +454,13 @@ typedef struct GTY ((for_user)) machopic_indirection
bool stub_p;
/* True iff this stub or pointer has been referenced. */
bool used;
/* True iff a non-lazy symbol pointer should be emitted into the .data
section, rather than the non-lazy symbol pointers section. The cases
for which this occurred seem to have been unintentional, and later
toolchains emit all of the indirections to the 'usual' section. We
are keeping this in case it is necessary to preserve compatibility with
older toolchains. */
bool nlsp_in_data_section;
} machopic_indirection;
struct indirection_hasher : ggc_ptr_hash<machopic_indirection>
......@@ -590,6 +597,18 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
p->ptr_name = xstrdup (buffer);
p->stub_p = stub_p;
p->used = false;
/* Here we are undoing a number of causes that placed some indirections
(apparently erroneously) into the .data section. Specifically, some
symbols that are ABI mandated indirections and some hidden symbols
were being placed there - which cause difficulties with later
versions of ld64.
*/
p->nlsp_in_data_section =
! MACHO_SYMBOL_MUST_INDIRECT_P (sym_ref)
&& ! MACHO_SYMBOL_HIDDEN_VIS_P (sym_ref)
&& (machopic_symbol_defined_p (sym_ref)
|| SYMBOL_REF_LOCAL_P (sym_ref))
&& ! indirect_data (sym_ref);
*slot = p;
}
......@@ -1069,32 +1088,52 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
return pic_ref;
}
/* Output the stub or non-lazy pointer in *SLOT, if it has been used.
DATA is the FILE* for assembly output. Called from
htab_traverse. */
/* Callbacks to output the stub or non-lazy pointers.
Each works on the item in *SLOT,if it has been used.
DATA is the FILE* for assembly output.
Called from htab_traverses, invoked from machopic_finish(). */
int
machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
machopic_output_data_section_indirection (machopic_indirection **slot,
FILE *asm_out_file)
{
machopic_indirection *p = *slot;
rtx symbol;
const char *sym_name;
const char *ptr_name;
if (!p->used)
if (!p->used || !p->nlsp_in_data_section)
return 1;
symbol = p->symbol;
sym_name = XSTR (symbol, 0);
ptr_name = p->ptr_name;
rtx symbol = p->symbol;
/* The original symbol name. */
const char *sym_name = XSTR (symbol, 0);
/* The name of the indirection symbol. */
const char *ptr_name = p->ptr_name;
if (p->stub_p)
{
char *sym;
char *stub;
tree id;
switch_to_section (data_section);
assemble_align (GET_MODE_ALIGNMENT (Pmode));
assemble_label (asm_out_file, ptr_name);
assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
GET_MODE_SIZE (Pmode),
GET_MODE_ALIGNMENT (Pmode), 1);
return 1;
}
int
machopic_output_stub_indirection (machopic_indirection **slot,
FILE *asm_out_file)
{
machopic_indirection *p = *slot;
if (!p->used || !p->stub_p)
return 1;
id = maybe_get_identifier (sym_name);
rtx symbol = p->symbol;
/* The original symbol name. */
const char *sym_name = XSTR (symbol, 0);
/* The name of the stub symbol. */
const char *ptr_name = p->ptr_name;
tree id = maybe_get_identifier (sym_name);
if (id)
{
tree id_orig = id;
......@@ -1105,7 +1144,7 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
sym_name = IDENTIFIER_POINTER (id);
}
sym = XALLOCAVEC (char, strlen (sym_name) + 2);
char *sym = XALLOCAVEC (char, strlen (sym_name) + 2);
if (sym_name[0] == '*' || sym_name[0] == '&')
strcpy (sym, sym_name + 1);
else if (sym_name[0] == '-' || sym_name[0] == '+')
......@@ -1113,42 +1152,42 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
else
sprintf (sym, "%s%s", user_label_prefix, sym_name);
stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
char *stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
if (ptr_name[0] == '*' || ptr_name[0] == '&')
strcpy (stub, ptr_name + 1);
else
sprintf (stub, "%s%s", user_label_prefix, ptr_name);
machopic_output_stub (asm_out_file, sym, stub);
}
else if (! indirect_data (symbol)
&& ! MACHO_SYMBOL_MUST_INDIRECT_P (symbol)
&& ! MACHO_SYMBOL_HIDDEN_VIS_P (symbol)
&& (machopic_symbol_defined_p (symbol)
|| SYMBOL_REF_LOCAL_P (symbol)))
{
switch_to_section (data_section);
assemble_align (GET_MODE_ALIGNMENT (Pmode));
assemble_label (asm_out_file, ptr_name);
assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
GET_MODE_SIZE (Pmode),
GET_MODE_ALIGNMENT (Pmode), 1);
}
else
{
rtx init = const0_rtx;
return 1;
}
int
machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
{
machopic_indirection *p = *slot;
if (!p->used || p->stub_p || p->nlsp_in_data_section)
return 1;
rtx symbol = p->symbol;
/* The original symbol name. */
const char *sym_name = XSTR (symbol, 0);
/* The nonlazy-stub symbol name. */
const char *ptr_name = p->ptr_name;
switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
/* Mach-O symbols are passed around in code through indirect
references and the original symbol_ref hasn't passed through
the generic handling and reference-catching in
output_operand, so we need to manually mark weak references
as such. */
/* Mach-O symbols are passed around in code through indirect references and
the original symbol_ref hasn't passed through the generic handling and
reference-catching in output_operand, so we need to manually mark weak
references as such. */
if (SYMBOL_REF_WEAK (symbol))
{
tree decl = SYMBOL_REF_DECL (symbol);
gcc_assert (DECL_P (decl));
gcc_checking_assert (DECL_P (decl));
if (decl != NULL_TREE
&& DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
......@@ -1177,13 +1216,12 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
of the translation unit with the original instance of the
symbol. */
if (MACHO_SYMBOL_STATIC_P (symbol)
&& machopic_symbol_defined_p (symbol))
rtx init = const0_rtx;
if (MACHO_SYMBOL_STATIC_P (symbol) && machopic_symbol_defined_p (symbol))
init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
assemble_integer (init, GET_MODE_SIZE (Pmode),
GET_MODE_ALIGNMENT (Pmode), 1);
}
return 1;
}
......@@ -1191,9 +1229,19 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
static void
machopic_finish (FILE *asm_out_file)
{
if (machopic_indirections)
machopic_indirections
->traverse_noresize<FILE *, machopic_output_indirection> (asm_out_file);
if (!machopic_indirections)
return;
/* First output an symbol indirections that have been placed into .data
(we don't expect these now). */
machopic_indirections->traverse_noresize
<FILE *, machopic_output_data_section_indirection> (asm_out_file);
machopic_indirections->traverse_noresize
<FILE *, machopic_output_stub_indirection> (asm_out_file);
machopic_indirections->traverse_noresize
<FILE *, machopic_output_indirection> (asm_out_file);
}
int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment