diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -560,8 +560,7 @@ // The main function of the writer. template void Writer::run() { - if (config->discard != DiscardPolicy::All) - copyLocalSymbols(); + copyLocalSymbols(); if (config->copyRelocs) addSectionSymbols(); @@ -642,14 +641,16 @@ if (sym.isSection()) return false; - if (config->discard == DiscardPolicy::None) - return true; - // If -emit-reloc is given, all symbols including local ones need to be // copied because they may be referenced by relocations. if (config->emitRelocs) return true; + if (config->discard == DiscardPolicy::None) + return true; + if (config->discard == DiscardPolicy::All) + return false; + // 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. diff --git a/lld/test/ELF/emit-relocs-discard-locals.s b/lld/test/ELF/emit-relocs-discard-locals.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/emit-relocs-discard-locals.s @@ -0,0 +1,43 @@ +# REQUIRES: x86 +## Test that --emit-relocs keeps local symbols and overrides --discard-{locals,all}. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 -save-temp-labels %s -o %t.o + +# RUN: ld.lld --emit-relocs --discard-locals %t.o -o %tlocal +# RUN: llvm-nm %tlocal | FileCheck --check-prefixes=NM,NM-NOGC %s +# RUN: llvm-readobj -r %tlocal | FileCheck --check-prefix=REL %s +# RUN: ld.lld --emit-relocs --discard-locals --gc-sections %t.o -o %tlocal.gc +# RUN: llvm-nm %tlocal.gc | FileCheck --check-prefix=NM %s +# RUN: llvm-readobj -r %tlocal | FileCheck --check-prefix=REL %s + +# RUN: ld.lld --emit-relocs --discard-all %t.o -o %tall +# RUN: llvm-nm %tall | FileCheck --check-prefixes=NM,NM-NOGC %s +# RUN: llvm-readobj -r %tall | FileCheck --check-prefix=REL %s + +# NM: t .Lunused +# NM-NOGC-NEXT: t .Lunused_gc +# NM-NEXT: t .Lused +# NM-NEXT: T _start +# NM-NEXT: t unused +# NM-NOGC-NEXT: t unused_gc +# NM-NEXT: t used + +# REL: .rela.text { +# REL-NEXT: R_X86_64_PLT32 .Lused 0xFFFFFFFFFFFFFFFC +# REL-NEXT: R_X86_64_PLT32 used 0xFFFFFFFFFFFFFFFC +# REL-NEXT: } + +.globl _start +_start: + jmp .Lused@plt + call used@plt + +.Lunused: +.Lused: +unused: +used: + +.section unreferenced,"ax" +.Lunused_gc: +unused_gc: + ret diff --git a/lld/test/ELF/relocatable-discard-locals.s b/lld/test/ELF/relocatable-discard-locals.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/relocatable-discard-locals.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 +## Test that -r keeps local symbols and overrides --discard-{locals,all}. +## Also see --emit-relocs-discard-locals.s + +# RUN: llvm-mc -filetype=obj -triple=x86_64 -save-temp-labels %s -o %t.o + +# RUN: ld.lld -r --discard-locals %t.o -o %tlocal.ro +# RUN: llvm-nm %tlocal.ro | FileCheck --check-prefixes=NM,NM_NOGC %s +# RUN: llvm-readobj -r %tlocal.ro | FileCheck --check-prefix=REL %s + +# RUN: ld.lld -r --discard-all %t.o -o %tall.ro +# RUN: llvm-nm %tall.ro | FileCheck --check-prefixes=NM,NM_NOGC %s +# RUN: llvm-readobj -r %tall.ro | FileCheck --check-prefix=REL %s + +# NM: t .Lunused +# NM_NOGC-NEXT: t .Lunused_gc +# NM-NEXT: t .Lused +# NM-NEXT: T _start +# NM-NEXT: t unused +# NM_NOGC-NEXT: t unused_gc +# NM-NEXT: t used + +# REL: .rela.text { +# REL-NEXT: R_X86_64_PLT32 .Lused 0xFFFFFFFFFFFFFFFC +# REL-NEXT: R_X86_64_PLT32 used 0xFFFFFFFFFFFFFFFC +# REL-NEXT: } + +.globl _start +_start: + jmp .Lused@plt + call used@plt + +.Lunused: +.Lused: +unused: +used: + +.section unreferenced,"ax" +.Lunused_gc: +unused_gc: + ret