From 1ec49110a7239a0be65bb0d4aea3f86fbdba48fa Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 18 Dec 2018 12:15:01 +0000 Subject: [PATCH] [llvm-dwarfdump] - Do not error out on R_X86_64_DTPOFF64/R_X86_64_DTPOFF32 relocations. This is https://bugs.llvm.org/show_bug.cgi?id=39992, If we have the following code (test.cpp): thread_local int tdata = 24; and build an .o file with debug information: clang --target=x86_64-pc-linux -c bar.cpp -g Then object produced may have R_X86_64_DTPOFF64/R_X86_64_DTPOFF32 relocations. (clang emits R_X86_64_DTPOFF64 and gcc emits R_X86_64_DTPOFF32 for the code above for me) Currently, llvm-dwarfdump fails to compute this TLS relocation when dumping object and reports an error: failed to compute relocation: R_X86_64_DTPOFF64, Invalid data was encountered while parsing the file This relocation represents the offset in the TLS block and resolved by the linker, but this info is unavailable at the point when the object file is dumped by this tool. The patch adds the simple evaluation for such relocations to avoid emitting errors. Resulting behavior seems to be equal to GNU dwarfdump. Differential revision: https://reviews.llvm.org/D55762 llvm-svn: 349476 --- llvm/include/llvm/Object/RelocVisitor.h | 2 + .../llvm-dwarfdump/X86/debug_tls_relocs.s | 68 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 llvm/test/tools/llvm-dwarfdump/X86/debug_tls_relocs.s diff --git a/llvm/include/llvm/Object/RelocVisitor.h b/llvm/include/llvm/Object/RelocVisitor.h index 23e796c6ec4d..9a978de2e599 100644 --- a/llvm/include/llvm/Object/RelocVisitor.h +++ b/llvm/include/llvm/Object/RelocVisitor.h @@ -129,6 +129,8 @@ private: case ELF::R_X86_64_NONE: return 0; case ELF::R_X86_64_64: + case ELF::R_X86_64_DTPOFF32: + case ELF::R_X86_64_DTPOFF64: return Value + getELFAddend(R); case ELF::R_X86_64_PC32: return Value + getELFAddend(R) - R.getOffset(); diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_tls_relocs.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_tls_relocs.s new file mode 100644 index 000000000000..d432ecf2baf9 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_tls_relocs.s @@ -0,0 +1,68 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o +# RUN: llvm-dwarfdump -v %t.o | FileCheck %s + +# CHECK-NOT: error +# CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address) +# CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_const4u 0x0, DW_OP_GNU_push_tls_address) + +.section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "X" + +.section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 0 # EOM(1) + .byte 0 # EOM(2) + + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + + .byte 0 # EOM(3) + +.section .debug_info,"",@progbits + .long 49 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x6c DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 4 # DW_AT_language + .long .Linfo_string0 # DW_AT_name + + .byte 2 # Abbrev [2] 0x2a:0x16 DW_TAG_variable + .long .Linfo_string0 # DW_AT_name + .long 0 # DW_AT_type + .byte 10 # DW_AT_location + .byte 14 + .quad tdata1@DTPOFF + .byte 224 + + .byte 2 # Abbrev [2] 0x47:0x16 DW_TAG_variable + .long .Linfo_string0 # DW_AT_name + .long 0 # DW_AT_type + .byte 6 # DW_AT_location + .byte 12 + .long tdata2@DTPOFF + .byte 224 + + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark -- GitLab