[PATCH] D43351: Relax relocation type checking in a non-ALLOC section.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 15 13:44:05 PST 2018
Can you share an example of a program that generate these relocations or
are they internal?
What is the expected value? Or it just happens that these values are
never read?
Cheers,
Rafael
Rui Ueyama via Phabricator <reviews at reviews.llvm.org> writes:
> ruiu created this revision.
> ruiu added reviewers: rafael, grimar.
> Herald added subscribers: arichardson, emaste.
>
> Even though it doesn't make sense, there seems to be multiple programs
> in the wild that create PC-relative relocations in non-ALLOC sections.
> This is caused by the negligence of GNU linkers to not report any errors
> for such relocations.
>
> Currently, lld emits warnings against such relocations and exits.
> So, you cannot link any program that contains wrong relocations until
> you fix an issue in a program that generates wrong ELF files. It's often
> impractical because it isn't always easy to fix a problem in a ELF-
> generating program.
>
> This patch relaxes the error checking and emit a warning instead.
>
>
> https://reviews.llvm.org/D43351
>
> Files:
> lld/ELF/InputSection.cpp
> lld/test/ELF/invalid/invalid-debug-relocations.test
> lld/test/ELF/non-abs-reloc.s
>
> Index: lld/test/ELF/non-abs-reloc.s
> ===================================================================
> --- lld/test/ELF/non-abs-reloc.s
> +++ lld/test/ELF/non-abs-reloc.s
> @@ -1,11 +1,18 @@
> // REQUIRES: x86
> // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
> -// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
> -// CHECK: {{.*}}:(.dummy+0x0): has non-ABS relocation R_X86_64_GOTPCREL against symbol 'foo'
> +// RUN: ld.lld %t.o -o %t 2>&1 | FileCheck %s
> +// CHECK: (.nonalloc+0x1): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
> +// CHECK: (.nonalloc+0x6): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
> +
> +// RUN: llvm-objdump -D %t
> +// DISASM: <.nonalloc>:
> +// DISASM-NEXT: 0: e8 fb 0f 20 00 callq 201000 <_start>
> +// DISASM-NEXT: 5: e8 f6 0f 20 00 callq 201000 <_start>
>
> .globl _start
> _start:
> nop
>
> -.section .dummy
> - .long foo at gotpcrel
> +.section .nonalloc
> + call _start
> + call _start
> Index: lld/test/ELF/invalid/invalid-debug-relocations.test
> ===================================================================
> --- lld/test/ELF/invalid/invalid-debug-relocations.test
> +++ /dev/null
> @@ -1,40 +0,0 @@
> -# REQUIRES: x86
> -# RUN: yaml2obj %s -o %t.o
> -# RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s
> -
> -# CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): has non-ABS relocation Unknown (255) against symbol '_start'
> -
> -!ELF
> -FileHeader:
> - Class: ELFCLASS32
> - Data: ELFDATA2LSB
> - Type: ET_REL
> - Machine: EM_386
> -Sections:
> - - Type: SHT_PROGBITS
> - Name: .text
> - Flags: [ ]
> - AddressAlign: 0x04
> - Content: "0000"
> - - Type: SHT_PROGBITS
> - Name: .debug_info
> - Flags: [ ]
> - AddressAlign: 0x04
> - Content: "0000"
> - - Type: SHT_REL
> - Name: .rel.debug_info
> - Link: .symtab
> - Info: .debug_info
> - Relocations:
> - - Offset: 0
> - Symbol: _start
> - Type: 0xFF
> - - Offset: 4
> - Symbol: _start
> - Type: 0xFF
> -Symbols:
> - Global:
> - - Name: _start
> - Type: STT_FUNC
> - Section: .text
> - Value: 0x0
> Index: lld/ELF/InputSection.cpp
> ===================================================================
> --- lld/ELF/InputSection.cpp
> +++ lld/ELF/InputSection.cpp
> @@ -651,17 +651,25 @@
> RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
> if (Expr == R_NONE)
> continue;
> - if (Expr != R_ABS) {
> - // GCC 8.0 or earlier have a bug that it emits R_386_GOTPC relocations
> - // against _GLOBAL_OFFSET_TABLE for .debug_info. The bug seems to have
> - // been fixed in 2017: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630,
> - // but we need to keep this bug-compatible code for a while.
> - if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
> - continue;
>
> - error(getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
> - toString(Type) + " against symbol '" + toString(Sym) + "'");
> - return;
> + if (Expr != R_ABS) {
> + // If the control reaches here, we found a PC-relative relocation in a
> + // non-ALLOC section. Since non-ALLOC section is not loaded into memory
> + // at runtime, the notion of PC-relative in such section doesn't make
> + // sense. So, this is a usage error. However, GNU linkers historically
> + // accept such relocations without any error and relocate them as if
> + // they were at address 0. For bug-compatibilty, we accepts them with
> + // warnings.
> + //
> + // GCC 8.0 or earlier emit such relocations due to a bug [1]. Steel Bank
> + // Common Lisp as of 2018 emits them too.
> + //
> + // [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630
> + warn(getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
> + toString(Type) + " against symbol '" + toString(Sym) + "'");
> + Target->relocateOne(BufLoc, Type,
> + SignExtend64<Bits>(Sym.getVA(Addend - Offset)));
> + continue;
> }
>
> if (Sym.isTls() && !Out::TlsPhdr)
More information about the llvm-commits
mailing list