New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 41385 - --emit-relocs shows some relocations moving to *ABS* when they should not
Summary: --emit-relocs shows some relocations moving to *ABS* when they should not
Status: RESOLVED FIXED
Alias: None
Product: lld
Classification: Unclassified
Component: ELF (show other bugs)
Version: unspecified
Hardware: PC Linux
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks: release-8.0.1
  Show dependency tree
 
Reported: 2019-04-04 13:48 PDT by Kees Cook
Modified: 2019-05-15 18:07 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s): r357885 r359956


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kees Cook 2019-04-04 13:48:18 PDT
While doing Linux kernel builds linked with lld, I've tracked down a
difference that breaks relocation of the kernel image (e.g. under
KASLR[1]). Some relocations are changed to ABS (weirdly, all are in
.rodata section). Note the difference below in the resulting linked
output. .L__const._start.instance becomes *ABS* only under lld:


$ cat minimal.c
struct minimal {
        void *pointer;
        int value;
};

void _start(void)
{
        struct minimal instance = {
                .value = 1,
        };
}
$ llvm-build/x86/bin/clang -c minimal.c
$ /usr/bin/ld.bfd --emit-relocs minimal.o -o minimal.bfd
$ llvm-build/x86/bin/ld.lld --emit-relocs minimal.o -o minimal.lld
$ objdump -Sdr minimal.bfd
...
00000000004000b0 <_start>:
  4000b0:       55                      push   %rbp
  4000b1:       48 89 e5                mov    %rsp,%rbp
  4000b4:       48 8b 04 25 d0 00 40    mov    0x4000d0,%rax
  4000bb:       00
                        4000b8: R_X86_64_32S    .rodata
  4000bc:       48 89 45 f0             mov    %rax,-0x10(%rbp)
  4000c0:       48 8b 04 25 d8 00 40    mov    0x4000d8,%rax
  4000c7:       00
                        4000c4: R_X86_64_32S    .L__const._start.instance+0x8
  4000c8:       48 89 45 f8             mov    %rax,-0x8(%rbp)
  4000cc:       5d                      pop    %rbp
  4000cd:       c3                      retq

$ objdump -Sdr minimal.lld
...
0000000000201000 <_start>:
  201000:       55                      push   %rbp
  201001:       48 89 e5                mov    %rsp,%rbp
  201004:       48 8b 04 25 20 01 20    mov    0x200120,%rax
  20100b:       00
                        201008: R_X86_64_32S    .rodata
  20100c:       48 89 45 f0             mov    %rax,-0x10(%rbp)
  201010:       48 8b 04 25 28 01 20    mov    0x200128,%rax
  201017:       00
                        201014: R_X86_64_32S    *ABS*+0x8
  201018:       48 89 45 f8             mov    %rax,-0x8(%rbp)
  20101c:       5d                      pop    %rbp
  20101d:       c3                      retq

I'm not sure where to start looking for solving this...

Thanks!

[1] https://github.com/ClangBuiltLinux/linux/issues/404
Comment 1 Kees Cook 2019-04-04 14:03:48 PDT
I just read through every lld runtime flag and just found "--discard-none". It seems the default is "--discard-local"? So perhaps this is NOT a bug?
Comment 2 Kees Cook 2019-04-04 14:19:30 PDT
It seems shouldKeepInSymtab has no knowledge of "DiscardPolicy::Default"? Or is "Default" supposed to mean the logic here with SHF_MERGE vs .L symbols?


static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
                               const Symbol &B) {
  if (B.isSection())
    return false;

  if (Config->Discard == DiscardPolicy::None)
    return true;

  // In ELF assembly .L symbols are normally discarded by the assembler.
  // If the assembler fails to do so, the linker discards them if
  // * --discard-locals is used.
  // * The symbol is in a SHF_MERGE section, which is normally the reason for
  //   the assembler keeping the .L symbol.
  if (!SymName.startswith(".L") && !SymName.empty())
    return true;

  if (Config->Discard == DiscardPolicy::Locals)
    return false;

  return !Sec || !(Sec->Flags & SHF_MERGE);
}
Comment 3 Tom Stellard 2019-04-05 08:56:15 PDT
Proposed Patch: https://reviews.llvm.org/D60306
Comment 4 Rui Ueyama 2019-04-08 23:18:47 PDT
That fix has landed.