On Thu, 2022-04-28 at 13:27 +0200, Jakub Jelinek wrote:
> On Thu, Apr 28, 2022 at 01:03:26PM +0200, Ilya Leoshkevich wrote:
> > This is determined by default_elf_select_rtx_section ().  If we
> > don't
> > want to mix non-reloc and reloc constants, we need to define a
> > special
> > section there.
> > 
> > It seems to me, however, that this all would be made purely for the
> > sake of .LASANPC, which is quite special: it's local, but at the
> > same
> > time it might need to be comdat.  I don't think anything like this
> > can
> > appear from compiling C/C++ code.
> > 
> > Therefore I wonder if we could just drop it altogether like this?
> > 
> > @@ -1928,22 +1919,7 @@ asan_emit_stack_protection (rtx base, rtx
> > pbase,
> > unsigned int alignb,
> > ...
> > -  emit_move_insn (mem, expand_normal (build_fold_addr_expr
> > (decl)));
> > +  emit_move_insn (mem, expand_normal (build_fold_addr_expr
> > (current_function_decl)));
> > ...
> > 
> > That's what LLVM is already doing.  This will also solve the
> > alignment
> > problem I referred to earlier.
> 
> LLVM is doing a wrong thing here.  The global symbol can be
> overridden by
> a symbol in another shared library, that is definitely not what we
> want,
> because the ASAN record is for the particular implementation, not the
> other
> one which could be quite different.

I see; this must be relevant when the overriding library calls
the original one through dlsym (RTLD_NEXT).

> I think the right fix would be:
> --- gcc/varasm.cc.jj    2022-03-07 15:00:17.255592497 +0100
> +++ gcc/varasm.cc       2022-04-28 13:22:44.463147066 +0200
> @@ -7326,6 +7326,9 @@ default_elf_select_rtx_section (machine_
>         return get_named_section (NULL, ".data.rel.ro", 3);
>      }
>  
> +  if (reloc)
> +    return readonly_data_section;
> +
>    return mergeable_constant_section (mode, align, 0);
>  }
>  
> which matches what we do in categorize_decl_for_section:
>       else if (reloc & targetm.asm_out.reloc_rw_mask ())
>         ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL :
> SECCAT_DATA_REL_RO;
>       else if (reloc || flag_merge_constants < 2
> ...
>         /* C and C++ don't allow different variables to share the
> same
>            location.  -fmerge-all-constants allows even that (at the
>            expense of not conforming).  */
>         ret = SECCAT_RODATA;
>       else if (DECL_INITIAL (decl)
>                && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
>         ret = SECCAT_RODATA_MERGE_STR_INIT;
>       else
>         ret = SECCAT_RODATA_MERGE_CONST;
> i.e. if reloc is true, it goes into .data.rel.ro* for -fpic and
> .rodata
> for non-pic, and mergeable sections are only used if there are no
> relocations.

This doesn't resolve the problem, unfortunately, because
references to discarded comdat symbols are still kept in .rodata:

`.text._ZN7testing15AssertionResultlsIPKcEERS0_RKT_' referenced in
section `.rodata' of ../lib/libgtest.a(gtest-all.cc.o): defined in
discarded section
`.text._ZN7testing15AssertionResultlsIPKcEERS0_RKT_[_ZN7testing15Assert
ionResultlsIPKcEERS0_RKT_]' of ../lib/libgtest.a(gtest-all.cc.o)

(That's from building zlib-ng with ASan and your patch on s390).

So I was rather thinking about adding a reloc parameter to
mergeable_constant_section () and slightly changing the section
name when it's nonzero, e.g. from .cst to .cstrel.

> Anyway, I'd feel much safer to change it only in GCC 13, at least
> initially.

That's fine with me.

> Or are some linkers (say lld or mold, fod ld.bfd I'm pretty sure it
> doesn't,
> for gold no idea but unlikely) able to merge even constants with
> relocations against them?

I'm not sure, but putting constants with relocations into a separate
mergeable section shouldn't hurt too much.  And if such a linker is
implemented some day, there would be no need to tweak gcc.

Reply via email to