Skip to content

Commit

Permalink
[MC] Rename temporary symbols of empty name to ".L0 " (#89693)
Browse files Browse the repository at this point in the history
Temporary symbols generated for .eh_frame and .debug_line have an empty
name, which appear in .symtab in the presence of RISC-V style linker
relaxation and will not be discarded by ld/objcopy --discard-locals
(-X).

In contrast, GNU assembler's riscv port assigns a fake name ".L0 " (with
a trailing space) to these symbols so that will be discarded by
ld/objcopy --discard-locals.

This patch matches the GNU behavior. Since Clang's RISC-V targets pass
-X to ld, and GNU ld defaults to -X for RISC-V targets, these ".L0 "
symbols will be discarded after linking by default, as expected by
users.

The llvm-symbolizer special case for RISC-V `SF_FormatSpecific` symbols
https://reviews.llvm.org/D98669 needs to be adjusted.

Note: `"":` in assembly currently crashes.

Note: bolt tests used /usr/bin/clang before
llvmorg-19-init-9532-g59bfc3106874.
The revert llvmorg-19-init-9531-g28b55342e1a8 actually broke
bolt/test/RISCV/fake-label-no-entry.c
  • Loading branch information
MaskRay committed Apr 26, 2024
1 parent 571831a commit bf67610
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 52 deletions.
4 changes: 2 additions & 2 deletions lld/test/ELF/mips-eh_frame-pic.s
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
# RELOCS: .rel{{a?}}.eh_frame {
# ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text
# ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text
# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE <null>
# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 <null>
# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE .L0
# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 .L0
# RELOCS-NEXT: }

# ABS64-EH-FRAME: Augmentation data: 0C
Expand Down
5 changes: 2 additions & 3 deletions llvm/include/llvm/Object/ELFObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,8 @@ Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
} else if (EF.getHeader().e_machine == ELF::EM_RISCV) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
// Mark empty name symbols (used for label differences) and mapping
// symbols.
if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x"))
// Mark fake labels (used for label differences) and mapping symbols.
if (Name == ".L0 " || Name.starts_with("$d") || Name.starts_with("$x"))
Result |= SymbolRef::SF_FormatSpecific;
} else {
// TODO: Actually report errors helpfully.
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/MC/ELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,13 @@ void ELFWriter::computeSymbolTable(
HasLargeSectionIndex = true;
}

// Temporary symbols generated for certain assembler features (.eh_frame,
// .debug_line) of an empty name may be referenced by relocations due to
// linker relaxation. Rename them to ".L0 " to match the gas fake label name
// and allow ld/objcopy --discard-locals to discard such symbols.
StringRef Name = Symbol.getName();
if (Name.empty())
Name = ".L0 ";

// Sections have their own string table
if (Symbol.getType() != ELF::STT_SECTION) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/fixups-diff.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ entry:
; CHECK: }

; CHECK: Section {{.*}} .rela.eh_frame {
; CHECK-NEXT: 0x1C R_RISCV_32_PCREL <null> 0x0
; CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0
; CHECK-NEXT: }

!llvm.dbg.cu = !{!0}
Expand Down
18 changes: 9 additions & 9 deletions llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@
; RELOCS-BOTH: Section ({{.*}}) .rela.debug_frame {
; RELOCS-NORL-NEXT: 0x1C R_LARCH_32 .debug_frame 0x0
; RELOCS-NORL-NEXT: 0x20 R_LARCH_64 .text 0x0
; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 <null> 0x0
; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 <null> 0x0
; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 <null> 0x0
; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 <null> 0x0
; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 <null> 0x0
; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 <null> 0x0
; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 .L0 0x0
; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 .L0 0x0
; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 .L0 0x0
; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 .L0 0x0
; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 .L0 0x0
; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 .L0 0x0
; RELOCS-BOTH-NEXT: }
; RELOCS-BOTH: Section ({{.*}}) .rela.debug_line {
; RELOCS-BOTH-NEXT: 0x22 R_LARCH_32 .debug_line_str 0x0
; RELOCS-BOTH-NEXT: 0x31 R_LARCH_32 .debug_line_str 0x2
; RELOCS-BOTH-NEXT: 0x46 R_LARCH_32 .debug_line_str 0x1B
; RELOCS-NORL-NEXT: 0x4F R_LARCH_64 .text 0x0
; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 <null> 0x0
; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 <null> 0x0
; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 <null> 0x0
; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 .L0 0x0
; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 .L0 0x0
; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 .L0 0x0
; RELOCS-BOTH-NEXT: }
; RELOCS-BOTH-NEXT: ]

Expand Down
12 changes: 6 additions & 6 deletions llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

; Check that we actually have relocations, otherwise this is kind of pointless.
; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_info {
; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 <null> 0x0
; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 <null> 0x0
; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 .L0 0x0
; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 .L0 0x0
; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_frame {
; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 <null> 0x0
; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 <null> 0x0
; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 .L0 0x0
; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0
; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_line {
; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 <null> 0x0
; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 <null> 0x0
; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 .L0 0x0
; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 .L0 0x0

; Check that we can print the source, even with relocations.
; OBJDUMP-SOURCE: Disassembly of section .text:
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/DebugInfo/RISCV/relax-debug-frame.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
; RUN: | FileCheck -check-prefix=RELAX-DWARFDUMP %s
;
; RELAX: Section ({{.*}}) .rela.eh_frame {
; RELAX-NEXT: 0x1C R_RISCV_32_PCREL <null> 0x0
; RELAX-NEXT: 0x30 R_RISCV_32_PCREL <null> 0x0
; RELAX-NEXT: 0x44 R_RISCV_32_PCREL <null> 0x0
; RELAX-NEXT: 0x48 R_RISCV_ADD32 <null> 0x0
; RELAX-NEXT: 0x48 R_RISCV_SUB32 <null> 0x0
; RELAX-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0
; RELAX-NEXT: 0x30 R_RISCV_32_PCREL .L0 0x0
; RELAX-NEXT: 0x44 R_RISCV_32_PCREL .L0 0x0
; RELAX-NEXT: 0x48 R_RISCV_ADD32 .L0 0x0
; RELAX-NEXT: 0x48 R_RISCV_SUB32 .L0 0x0
; RELAX-NEXT: }

; RELAX-DWARFDUMP-NOT: error: failed to compute relocation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# REQUIRES: riscv-registered-target
## Ignore empty name symbols.
## Ignore .L0 symbols that are generated by LLVM integrated assembler and GNU
## assembler for .debug_line/.eh_frame related assembler directives.

# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t
# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM

# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] {{$}}
# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] .L0 {{$}}
# SYM: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [[#]] foo

## Make sure we test at an address larger than or equal to an empty name symbol.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# the section start and section end. So that by relocating these symbol, the section length
# can be calculated.
#
# CHECK: Creating defined graph symbol for ELF symbol ""
# CHECK: Creating defined graph symbol for ELF symbol ".L0 "
# CHECK: Creating defined graph symbol for ELF symbol "main"
.text
.globl main
Expand Down
26 changes: 13 additions & 13 deletions llvm/test/MC/ELF/RISCV/gen-dwarf.s
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,28 @@
# CHECK-NEXT: 0x00000020: [DW_RLE_end_of_list ]

# RELOC: Section ([[#]]) .rela.eh_frame {
# RELOC-NEXT: 0x1C R_RISCV_32_PCREL <null> 0x0
# RELOC-NEXT: 0x20 R_RISCV_ADD32 <null> 0x0
# RELOC-NEXT: 0x20 R_RISCV_SUB32 <null> 0x0
# RELOC-NEXT: 0x25 R_RISCV_SET6 <null> 0x0
# RELOC-NEXT: 0x25 R_RISCV_SUB6 <null> 0x0
# RELOC-NEXT: 0x34 R_RISCV_32_PCREL <null> 0x0
# RELOC-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0
# RELOC-NEXT: 0x20 R_RISCV_ADD32 .L0 0x0
# RELOC-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0
# RELOC-NEXT: 0x25 R_RISCV_SET6 .L0 0x0
# RELOC-NEXT: 0x25 R_RISCV_SUB6 .L0 0x0
# RELOC-NEXT: 0x34 R_RISCV_32_PCREL .L0 0x0
# RELOC-NEXT: }

# RELOC: Section ([[#]]) .rela.debug_rnglists {
# RELOC-NEXT: 0xD R_RISCV_64 .text.foo 0x0
# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 <null> 0x0
# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 .L0 0x0
# RELOC-NEXT: 0x15 R_RISCV_SUB_ULEB128 .text.foo 0x0
# RELOC-NEXT: 0x17 R_RISCV_64 .text.bar 0x0
# RELOC-NEXT: }

# RELOC: Section ([[#]]) .rela.debug_line {
# RELOC: R_RISCV_ADD16 <null> 0x0
# RELOC-NEXT: R_RISCV_SUB16 <null> 0x0
# RELOC-NEXT: R_RISCV_ADD16 <null> 0x0
# RELOC-NEXT: R_RISCV_SUB16 <null> 0x0
# RELOC-NEXT: R_RISCV_ADD16 <null> 0x0
# RELOC-NEXT: R_RISCV_SUB16 <null> 0x0
# RELOC: R_RISCV_ADD16 .L0 0x0
# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0
# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0
# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0
# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0
# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0
# RELOC: }

# RELOC: Hex dump of section '.eh_frame':
Expand Down
32 changes: 26 additions & 6 deletions llvm/test/MC/RISCV/cfi-advance.s
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
# RUN: llvm-mc -filetype=obj -triple riscv32 %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=CHECK %s
# RUN: llvm-readelf -sr %t.o | FileCheck %s
# RUN: llvm-dwarfdump --debug-frame %t.o 2>&1 \
# RUN: | FileCheck -check-prefix=CHECK-DWARFDUMP %s

# CHECK: .rela.eh_frame {
# CHECK-NEXT: 0x1C R_RISCV_32_PCREL <null> 0x0
# CHECK-NEXT: 0x35 R_RISCV_SET6 <null> 0x0
# CHECK-NEXT: 0x35 R_RISCV_SUB6 <null> 0x0
# CHECK-NEXT: }

# CHECK: Relocation section '.rela.text1' at offset {{.*}} contains 1 entries:
# CHECK-NEXT: Offset Info Type Sym. Value Symbol's Name + Addend
# CHECK-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000004 .L0 + 0
# CHECK-EMPTY:
# CHECK-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 3 entries:
# CHECK: Offset Info Type Sym. Value Symbol's Name + Addend
# CHECK-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0
# CHECK-NEXT: 00000035 00000b35 R_RISCV_SET6 00010178 .L0 + 0
# CHECK-NEXT: 00000035 00000934 R_RISCV_SUB6 0001016e .L0 + 0
# CHECK-EMPTY:
# CHECK: Symbol table '.symtab' contains 15 entries:
# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
# CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
# CHECK-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
# CHECK: 3: 00000004 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}}
# CHECK: 9: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
# CHECK: 11: 00010178 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}

# CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104
# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259
Expand All @@ -23,6 +37,9 @@
test:
.cfi_startproc
nop
## This looks similar to fake label names ".L0 ". Even if this is ".L0 ",
## the assembler will not conflate it with fake labels.
.L0:
.zero 100, 0x90
.cfi_def_cfa_offset 8
nop
Expand All @@ -36,3 +53,6 @@ test:
.cfi_def_cfa_offset 8
nop
.cfi_endproc

.section .text1,"ax"
call .L0
2 changes: 1 addition & 1 deletion llvm/test/MC/RISCV/fde-reloc.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func:
.cfi_endproc

# CHECK: Section (4) .rela.eh_frame {
# CHECK-NEXT: 0x1C R_RISCV_32_PCREL <null> 0x0
# CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0
# CHECK-NEXT: }
# CHECK: Hex dump of section '.eh_frame':
# CHECK-NEXT: 0x00000000 10000000 00000000 017a5200 017c0101
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/MC/RISCV/scoped-relaxation.s
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.dword function - .

# CHECK: 0x0 R_RISCV_ADD64 function 0x0
# CHECK-NEXT: 0x0 R_RISCV_SUB64 <null> 0x0
# CHECK-NEXT: 0x0 R_RISCV_SUB64 .L0 0x0

# Relaxed reference, this will resolve to a pair of `RISCV_ADD64` and
# `RISCV_SUB64` relocation.
Expand All @@ -19,7 +19,7 @@
.option pop

# CHECK: 0x8 R_RISCV_ADD64 function 0x0
# CHECK-NEXT: 0x8 R_RISCV_SUB64 <null> 0x0
# CHECK-NEXT: 0x8 R_RISCV_SUB64 .L0 0x0

# Unrelaxed reference, this will resolve to a pair of `RISCV_ADD64` and
# `RISCV_SUB64` relocation due to relaxation being sticky to the file.
Expand All @@ -29,6 +29,6 @@
.option pop

# CHECK: 0x10 R_RISCV_ADD64 function 0x0
# CHECK-NEXT: 0x10 R_RISCV_SUB64 <null> 0x0
# CHECK-NEXT: 0x10 R_RISCV_SUB64 .L0 0x0

# CHECK: }

0 comments on commit bf67610

Please sign in to comment.