This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Do not forget to include to .dymsym symbols that were converted to Defined.
ClosedPublic

Authored by grimar on Oct 1 2018, 7:08 AM.

Details

Summary

This is the fix for
"Bug 39104 - LLD links incorrect ELF executable if version script contains "local: *;" (https://bugs.llvm.org/show_bug.cgi?id=39104).

The issue happens when we have non-PIC program call to function in a shared library.
(for example, the PR above has R_X86_64_PC32 relocation against __libc_start_main)

LLD converts symbol to Defined in that case with the use of replaceWithDefined()

The issue is that after above we create a broken relocation because do not
include the symbol into .dynsym:

location section '.rela.plt' at offset 0x2a0 contains 1 entries:
   Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000202018  000000000007 R_X86_64_JUMP_SLO                    0

Symbol table '.dynsym' contains 2 entries:
  Num:    Value          Size Type    Bind   Vis      Ndx Name
    0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    1: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT    7 main

That happens when the version script is used because we treat the symbol as
STB_LOCAL if the following condition match:
VersionId == VER_NDX_LOCAL && isDefined() and do not include it to
.dynsym because of that.

The patch shows the change I am suggesting.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Oct 1 2018, 7:08 AM
grimar edited the summary of this revision. (Show Details)Oct 1 2018, 7:17 AM
ruiu added inline comments.Oct 1 2018, 9:44 AM
test/ELF/local-ver-preemptible.s
1 ↗(On Diff #167732)

Can you write this in assembly?

smeenai added inline comments.
test/ELF/local-ver-preemptible.s
1 ↗(On Diff #167732)

I think that's addressed in the summary?

Note that I had to use YAML input, because llvm-mc does not produce R_X86_64_PC32 for call foo and jmp foo since rL325569 (https://reviews.llvm.org/D43383).

ruiu added inline comments.Oct 1 2018, 1:14 PM
test/ELF/local-ver-preemptible.s
1 ↗(On Diff #167732)

Yeah, but since I could reproduce https://bugs.llvm.org/show_bug.cgi?id=39104 without a YAML file, I believe you can do it without YAML.

grimar updated this revision to Diff 167887.Oct 2 2018, 1:11 AM
grimar edited the summary of this revision. (Show Details)
  • Stop using YAML for the test.
ruiu accepted this revision.Oct 2 2018, 9:38 AM

LGTM

This revision is now accepted and ready to land.Oct 2 2018, 9:38 AM
orivej accepted this revision.Oct 2 2018, 5:22 PM

Thank you! This patch works as intended.

It seems a bit undesirable that the test generates a warning cannot find entry symbol _start; defaulting to 0x201000, and that it expects a possibly unstable number 0x288, but maybe it's OK.

grimar added a comment.Oct 3 2018, 1:50 AM

Thank you! This patch works as intended.

It seems a bit undesirable that the test generates a warning cannot find entry symbol _start; defaulting to 0x201000, and that it expects a possibly unstable number 0x288, but maybe it's OK.

I'll add the _start symbol before commit. Generally, we have test cases which adds it to avoid the warning, but also have tests without. Personally, I have no preference here.

This revision was automatically updated to reflect the committed changes.