[JITLink] Add anonymous symbols in LinkGraph for unnamed temporary symbols

In RISCV, temporary symbols will be used to generate dwarf, eh_frame sections..., and will be placed in object code's symbol table. However, LLVM does not use names on these temporary symbols. This patch add anonymous symbols in LinkGraph for these temporary symbols.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D116475
This commit is contained in:
luxufan 2022-01-22 16:07:17 +08:00
parent b6098c07cb
commit de87238295
5 changed files with 45 additions and 5 deletions

View File

@ -79,6 +79,12 @@ enum EdgeKind_riscv : Edge::Kind {
/// Fixup <- (Target - Fixup + Addend)
R_RISCV_CALL,
/// 32 bits PC relative relocation
///
/// Fixup expression:
/// Fixup <- (Target - Fixup + Addend)
R_RISCV_32_PCREL,
/// PC relative GOT offset
///
/// Fixup expression:
@ -137,7 +143,7 @@ enum EdgeKind_riscv : Edge::Kind {
///
/// Fixup expression
/// Fixup <- (Target - *{1}Fixup - Addend)
R_RISCV_SUB8
R_RISCV_SUB8,
};
/// Returns a string name for the given riscv edge. For debugging purposes

View File

@ -441,11 +441,15 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
<< "\"\n";
});
// Model the section symbols as anonymous symbol.
// In RISCV, temporary symbols (Used to generate dwarf, eh_frame
// sections...) will appear in object code's symbol table, and LLVM does
// not use names on these temporary symbols (RISCV gnu toolchain uses
// names on these temporary symbols). If the symbol is unnamed, add an
// anonymous symbol.
auto &GSym =
Sym.getType() == ELF::STT_SECTION
? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size, false,
false)
Name->empty()
? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
false, false)
: G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
S, Sym.getType() == ELF::STT_FUNC, false);
setGraphSymbol(SymIndex, GSym);

View File

@ -359,6 +359,12 @@ private:
*FixupPtr = static_cast<uint8_t>(Value);
break;
}
case R_RISCV_32_PCREL: {
// FIXME: It seems that R_RISCV_32_PCREL relocation will only appear in debug sections
// like eh_frame section. Currently, because of eh_frame will not be processed in JITLink's RISCV
// backend, test this relocation is difficult, so here report error if needs to fixup this relocation
return make_error<JITLinkError>("Fixup of relocation type R_RISCV_32_PCREL is not supportted");
}
}
return Error::success();
}
@ -409,6 +415,8 @@ private:
return EdgeKind_riscv::R_RISCV_SUB16;
case ELF::R_RISCV_SUB8:
return EdgeKind_riscv::R_RISCV_SUB8;
case ELF::R_RISCV_32_PCREL:
return EdgeKind_riscv::R_RISCV_32_PCREL;
}
return make_error<JITLinkError>("Unsupported riscv relocation:" +

View File

@ -38,6 +38,8 @@ const char *getEdgeKindName(Edge::Kind K) {
return "R_RISCV_PCREL_LO12_S";
case R_RISCV_CALL:
return "R_RISCV_CALL";
case R_RISCV_32_PCREL:
return "R_RISCV_32_PCREL";
case R_RISCV_ADD64:
return "R_RISCV_ADD64";
case R_RISCV_ADD32:

View File

@ -0,0 +1,20 @@
# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t %s
# RUN: llvm-jitlink -debug-only=jitlink -noexec %t 2>&1 | FileCheck %s
#
# Because of the exist of cfi directive, sections like eh_frame section will be emitted
# in llvm's object code emission phase. Anonymous symbols will also be emitted to indicate
# 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 ""
.text
.globl main
.p2align 2
.type main,@function
main:
.cfi_startproc
ret
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc