On Fri, 2021-05-07 at 12:19 +0930, Alan Modra via Gcc-patches wrote:
> On PowerPC64 ELFv1 function symbols are defined on function
> descriptors in an .opd section rather than in the function code.
> .opd is not split up by the PowerPC64 backend for comdat groups or
> other situations where per-function sections are required. Thus
> SECTION_LINK_ORDER can't use the function name to reference a
> suitable
> section for ordering: The .opd section might contain many other
> function descriptors and they may be in a different order to the
> final
> function code placement. This patch arranges to use a code label
> instead of the function name symbol.
>
> I chose to emit the label inside default_elf_asm_named_section,
> immediately before the .section directive using the label, and in
> case
> someone uses .previous or the like, need to save and restore the
> current section when switching to the function code section to emit
> the label. That requires a tweak to switch_to_section in order to
> get
> the current section. I checked all the TARGET_ASM_NAMED_SECTION
> functions and unnamed.callback functions and it appears none will be
> affected by that tweak.
Hi,
good description. thanks :-)
>
> PR target/98125
> * varasm.c (default_elf_asm_named_section): Use a function
> code label rather than the function symbol as the "o" argument.
> (switch_to_section): Don't set in_section until section
> directive has been emitted.
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index 97c1e6fff25..5f95f8cfa75 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6866,6 +6866,26 @@ default_elf_asm_named_section (const char
> *name, unsigned int flags,
> *f = '\0';
> }
>
> + char func_label[256];
> + if (flags & SECTION_LINK_ORDER)
> + {
> + static int recur;
> + if (recur)
> + gcc_unreachable ();
Interesting.. Is there any anticipation of re-entry or parallel runs
through this function that requires the recur lock/protection?
> + else
> + {
> + ++recur;
> + section *save_section = in_section;
> + static int func_code_labelno;
> + switch_to_section (function_section (decl));
> + ++func_code_labelno;
> + ASM_GENERATE_INTERNAL_LABEL (func_label, "LPFC",
> func_code_labelno);
> + ASM_OUTPUT_LABEL (asm_out_file, func_label);
> + switch_to_section (save_section);
> + --recur;
> + }
> + }
ok
> +
> fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
>
> /* default_section_type_flags (above) knows which flags need
> special
> @@ -6893,11 +6913,8 @@ default_elf_asm_named_section (const char
> *name, unsigned int flags,
> fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
> if (flags & SECTION_LINK_ORDER)
> {
> - tree id = DECL_ASSEMBLER_NAME (decl);
> - ultimate_transparent_alias_target (&id);
> - const char *name = IDENTIFIER_POINTER (id);
> - name = targetm.strip_name_encoding (name);
> - fprintf (asm_out_file, ",%s", name);
> + fputc (',', asm_out_file);
> + assemble_name_raw (asm_out_file, func_label);
ok as far as I can tell :-) assemble_name_raw is an if/else that
outputs 'name' or a LABELREF based on the file & name. It's not an
obvious analog to the untimate_transparent_alias_target() and name
processing that is being replaced, but seems to fit the changes as
described.
> }
> if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> {
> @@ -7821,11 +7838,6 @@ switch_to_section (section *new_section, tree
> decl)
> else if (in_section == new_section)
> return;
>
> - if (new_section->common.flags & SECTION_FORGET)
> - in_section = NULL;
> - else
> - in_section = new_section;
> -
> switch (SECTION_STYLE (new_section))
> {
> case SECTION_NAMED:
> @@ -7843,6 +7855,11 @@ switch_to_section (section *new_section, tree
> decl)
> break;
> }
>
> + if (new_section->common.flags & SECTION_FORGET)
> + in_section = NULL;
> + else
> + in_section = new_section;
> +
> new_section->common.flags |= SECTION_DECLARED;
OK.
lgtm, thx
-Will
> }
>