1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
Saleem Abdulrasool f56e4f6d3d RISCV: adjust handling of relocation emission for RISCV
This re-architects the RISCV relocation handling to bring the
implementation closer in line with the implementation in binutils.  We
would previously aggressively resolve the relocation.  With this
restructuring, we always will emit a paired relocation for any symbolic
difference of the type of S±T[±C] where S and T are labels and C is a
constant.

GAS has a special target hook controlled by `RELOC_EXPANSION_POSSIBLE`
which indicates that a fixup may be expanded into multiple relocations.
This is used by the RISCV backend to always emit a paired relocation -
either ADD[WIDTH] + SUB[WIDTH] for text relocations or SET[WIDTH] +
SUB[WIDTH] for a debug info relocation.  Irrespective of whether linker
relaxation support is enabled, symbolic difference is always emitted as
a paired relocation.

This change also sinks the target specific behaviour down into the
target specific area rather than exposing it to the shared relocation
handling.  In the process, we also sink the "special" handling for debug
information down into the RISCV target.  Although this improves the path
for the other targets, this is not necessarily entirely ideal either.
The changes in the debug info emission could be done through another
type of hook as this functionality would be required by any other target
which wishes to do linker relaxation.  However, as there are no other
targets in LLVM which currently do this, this is a reasonable thing to
do until such time as the code needs to be shared.

Improve the handling of the relocation (and add a reduced test case from
the Linux kernel) to ensure that we handle complex expressions for
symbolic difference.  This ensures that we correct relocate symbols with
the adddends normalized and associated with the addition portion of the
paired relocation.

This change also addresses some review comments from Alex Bradbury about
the relocations meant for use in the DWARF CFA being named incorrectly
(using ADD6 instead of SET6) in the original change which introduced the
relocation type.

This resolves the issues with the symbolic difference emission
sufficiently to enable building the Linux kernel with clang+IAS+lld
(without linker relaxation).

Resolves PR50153, PR50156!
Fixes: ClangBuiltLinux/linux#1023, ClangBuiltLinux/linux#1143

Reviewed By: nickdesaulniers, maskray

Differential Revision: https://reviews.llvm.org/D103539
2021-06-17 08:20:02 -07:00

116 lines
4.6 KiB
C++

//===-- RISCVFixupKinds.h - RISCV Specific Fixup Entries --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVFIXUPKINDS_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVFIXUPKINDS_H
#include "llvm/MC/MCFixup.h"
#undef RISCV
namespace llvm {
namespace RISCV {
enum Fixups {
// 20-bit fixup corresponding to %hi(foo) for instructions like lui
fixup_riscv_hi20 = FirstTargetFixupKind,
// 12-bit fixup corresponding to %lo(foo) for instructions like addi
fixup_riscv_lo12_i,
// 12-bit fixup corresponding to %lo(foo) for the S-type store instructions
fixup_riscv_lo12_s,
// 20-bit fixup corresponding to %pcrel_hi(foo) for instructions like auipc
fixup_riscv_pcrel_hi20,
// 12-bit fixup corresponding to %pcrel_lo(foo) for instructions like addi
fixup_riscv_pcrel_lo12_i,
// 12-bit fixup corresponding to %pcrel_lo(foo) for the S-type store
// instructions
fixup_riscv_pcrel_lo12_s,
// 20-bit fixup corresponding to %got_pcrel_hi(foo) for instructions like
// auipc
fixup_riscv_got_hi20,
// 20-bit fixup corresponding to %tprel_hi(foo) for instructions like lui
fixup_riscv_tprel_hi20,
// 12-bit fixup corresponding to %tprel_lo(foo) for instructions like addi
fixup_riscv_tprel_lo12_i,
// 12-bit fixup corresponding to %tprel_lo(foo) for the S-type store
// instructions
fixup_riscv_tprel_lo12_s,
// Fixup corresponding to %tprel_add(foo) for PseudoAddTPRel, used as a linker
// hint
fixup_riscv_tprel_add,
// 20-bit fixup corresponding to %tls_ie_pcrel_hi(foo) for instructions like
// auipc
fixup_riscv_tls_got_hi20,
// 20-bit fixup corresponding to %tls_gd_pcrel_hi(foo) for instructions like
// auipc
fixup_riscv_tls_gd_hi20,
// 20-bit fixup for symbol references in the jal instruction
fixup_riscv_jal,
// 12-bit fixup for symbol references in the branch instructions
fixup_riscv_branch,
// 11-bit fixup for symbol references in the compressed jump instruction
fixup_riscv_rvc_jump,
// 8-bit fixup for symbol references in the compressed branch instruction
fixup_riscv_rvc_branch,
// Fixup representing a legacy no-pic function call attached to the auipc
// instruction in a pair composed of adjacent auipc+jalr instructions.
fixup_riscv_call,
// Fixup representing a function call attached to the auipc instruction in a
// pair composed of adjacent auipc+jalr instructions.
fixup_riscv_call_plt,
// Used to generate an R_RISCV_RELAX relocation, which indicates the linker
// may relax the instruction pair.
fixup_riscv_relax,
// Used to generate an R_RISCV_ALIGN relocation, which indicates the linker
// should fixup the alignment after linker relaxation.
fixup_riscv_align,
// 8-bit fixup corresponding to R_RISCV_SET8 for local label assignment.
fixup_riscv_set_8,
// 8-bit fixup corresponding to R_RISCV_ADD8 for 8-bit symbolic difference
// paired relocations.
fixup_riscv_add_8,
// 8-bit fixup corresponding to R_RISCV_SUB8 for 8-bit symbolic difference
// paired relocations.
fixup_riscv_sub_8,
// 16-bit fixup corresponding to R_RISCV_SET16 for local label assignment.
fixup_riscv_set_16,
// 16-bit fixup corresponding to R_RISCV_ADD16 for 16-bit symbolic difference
// paired reloctions.
fixup_riscv_add_16,
// 16-bit fixup corresponding to R_RISCV_SUB16 for 16-bit symbolic difference
// paired reloctions.
fixup_riscv_sub_16,
// 32-bit fixup corresponding to R_RISCV_SET32 for local label assignment.
fixup_riscv_set_32,
// 32-bit fixup corresponding to R_RISCV_ADD32 for 32-bit symbolic difference
// paired relocations.
fixup_riscv_add_32,
// 32-bit fixup corresponding to R_RISCV_SUB32 for 32-bit symbolic difference
// paired relocations.
fixup_riscv_sub_32,
// 64-bit fixup corresponding to R_RISCV_ADD64 for 64-bit symbolic difference
// paired relocations.
fixup_riscv_add_64,
// 64-bit fixup corresponding to R_RISCV_SUB64 for 64-bit symbolic difference
// paired relocations.
fixup_riscv_sub_64,
// 6-bit fixup corresponding to R_RISCV_SET6 for local label assignment in
// DWARF CFA.
fixup_riscv_set_6b,
// 6-bit fixup corresponding to R_RISCV_SUB6 for local label assignment in
// DWARF CFA.
fixup_riscv_sub_6b,
// Used as a sentinel, must be the last
fixup_riscv_invalid,
NumTargetFixupKinds = fixup_riscv_invalid - FirstTargetFixupKind
};
} // end namespace RISCV
} // end namespace llvm
#endif