[lld] Wrong references for C++ COMDAT groups

Hi,

Checking the llvm test-suite SingleSource/Regression/C++/EH/class_hierarchy
testcase on aarch64 I noted something strange:

Dump of assembler code for function _Z4funcj:
   0x0000000000400650 <+0>: stp x22, x21, [sp,#-48]!
   0x0000000000400654 <+4>: stp x20, x19, [sp,#16]
   0x0000000000400658 <+8>: stp x29, x30, [sp,#32]
   0x000000000040065c <+12>: add x29, sp, #0x20
=> 0x0000000000400660 <+16>: .inst 0x2bfffff7 ; undefined

Where it should be:

0000000000000000 <_Z4funcj>:
   0: a9bd57f6 stp x22, x21, [sp,#-48]!
   4: a9014ff4 stp x20, x19, [sp,#16]
   8: a9027bfd stp x29, x30, [sp,#32]
   c: 910083fd add x29, sp, #0x20
  10: 2a0003f3 mov w19, w0

And there is no relocation (static or dynamic) point to the faulty instruction.
It exist, however, a group section relocation with same offset, but for a
different text segments (the exception handler stub create by clang):

Relocation section '.rela.text' at offset 0xed8 contains 2 entries:
  Offset Info Type Sym. Value Sym. Name + Addend
000000000010 00480000011b R_AARCH64_CALL26 0000000000000000 _ZNSt9exceptionD2Ev + 0
000000000020 004d0000011a R_AARCH64_JUMP26 0000000000000000 _ZdlPv + 0

Relocation section '.rela.text' at offset 0xf08 contains 2 entries:
  Offset Info Type Sym. Value Sym. Name + Addend
000000000010 00480000011b R_AARCH64_CALL26 0000000000000000 _ZNSt9exceptionD2Ev + 0
000000000020 004d0000011a R_AARCH64_JUMP26 0000000000000000 _ZdlPv + 0

Relocation section '.rela.text' at offset 0xf38 contains 2 entries:
  Offset Info Type Sym. Value Sym. Name + Addend
000000000010 00480000011b R_AARCH64_CALL26 0000000000000000 _ZNSt9exceptionD2Ev + 0
000000000020 004d0000011a R_AARCH64_JUMP26 0000000000000000 _ZdlPv + 0

However seems that LLD is indeed condescending them, but create duplicated references
for the wrong segments:

Writing atom: _Z4funcj | 1520
                Handle relocJump26 - S: 400460 A: 0 P: 400660 result: 3ffff98
                Handle relocJump26 - S: 400470 A: 0 P: 400670 result: 3ffff98

The first relocJump26 shouldn't be applied to .text segment 0x400660, but solely on the
_ZN4BaseD0Ev section. I am trying to debug how lld exactly is generating this wrong
Reference, but I still can right figure out. Any idea of what is happening here?

Does this test pass on X86_64 ? Groups are read in the Reader and is documented below :-

See http://lld.llvm.org/design.html#linking-steps on Section Groups to get more information.

Looks like it is also not working on x86_64, using clang/lld I am seeing
a segmentation fault:

Dump of assembler code for function _Z4funcj:
   0x0000000000400590 <+0>: push %rbp
   0x0000000000400591 <+1>: push %rbx
   0x0000000000400592 <+2>: push %rax
   0x0000000000400593 <+3>: mov %edi,%ebp
   0x0000000000400595 <+5>: pop %rdx
   0x0000000000400596 <+6>: cld
=> 0x0000000000400597 <+7>: or %esi,0x46(%rdi)
   0x000000000040059a <+10>: mov $0xde000018,%edi

Where the disassemble should be:

Disassembly of section .text:

0000000000000000 <_Z4funcj>:
   0: 55 push %rbp
   1: 53 push %rbx
   2: 50 push %rax
   3: 89 fd mov %edi,%ebp
   5: 83 fd 09 cmp $0x9,%ebp
   8: 77 46 ja 50 <_Z4funcj+0x50>
   f: e8 00 00 00 00 callq 14 <_Z4funcj+0x14>
  14: 48 89 c3 mov %rax,%rbx
  17: 48 c7 03 00 00 00 00 movq $0x0,(%rbx)
  1e: 89 6b 08 mov %ebp,0x8(%rbx)
  21: bf 0e 00 00 00 mov $0xe,%edi
  26: e8 00 00 00 00 callq 2b <_Z4funcj+0x2b>

As for aarch64, x86_64 object shows some relocation in group sections:

Relocation section '.rela.text' at offset 0xb48 contains 2 entries:
  Offset Info Type Sym. Value Sym. Name + Addend
000000000005 003200000002 R_X86_64_PC32 0000000000000000 _ZNSt9exceptionD2Ev - 4
00000000000e 003700000002 R_X86_64_PC32 0000000000000000 _ZdlPv - 4

That should me meant only for the group section text, not the default text
segment.

And I think the problem is somewhat related to 'ELFFile<ELFT>::createAtoms'
where it first creates a StringMap only with segment name and then
process the groups based atoms. With just a map related the segment's name
to the atom, the COMDAT group section will find for all atom's in all 'text'
segment, where it should handle only the one with the index listed in the
groups section.

I am still tinkering a better strategy to organize this, any suggestions?

You could use map that contains section header instead of name.

Yeah, I just tried and I am still seeing the wrong relocation being applied.
It is something else. Is this test-suite testcase suppose to work or is it
something noone really tested?