-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[RISCV] RFC: Add PE/COFF file output support #148045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-debuginfo Author: Jason Xu (JasonBrave) ChangesAdding support for PE file output for RISC-V target, mainly targeted for producing UEFI Applications. Full diff: https://github.com/llvm/llvm-project/pull/148045.diff 13 Files Affected:
diff --git a/llvm/docs/CodeGenerator.rst b/llvm/docs/CodeGenerator.rst
index 020eb09ba7e1e..21c6b289e8c26 100644
--- a/llvm/docs/CodeGenerator.rst
+++ b/llvm/docs/CodeGenerator.rst
@@ -723,7 +723,7 @@ The table below captures a snapshot of object file support in LLVM:
================== ========================================================
Format Supported Targets
================== ========================================================
- ``COFF`` AArch64, ARM, X86
+ ``COFF`` AArch64, ARM, RISCV, X86
``DXContainer`` DirectX
``ELF`` AArch64, AMDGPU, ARM, AVR, BPF, CSKY, Hexagon, Lanai, LoongArch, M86k, MSP430, MIPS, PowerPC, RISCV, SPARC, SystemZ, VE, X86
``GOFF`` SystemZ
diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h
index f3b5d5e3f23c6..7b428d0e76c67 100644
--- a/llvm/include/llvm/BinaryFormat/COFF.h
+++ b/llvm/include/llvm/BinaryFormat/COFF.h
@@ -132,7 +132,8 @@ template <typename T> bool isAnyArm64(T Machine) {
}
template <typename T> bool is64Bit(T Machine) {
- return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine);
+ return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine) ||
+ IMAGE_FILE_MACHINE_RISCV64;
}
enum Characteristics : unsigned {
@@ -726,7 +727,10 @@ enum BaseRelocationType : unsigned {
IMAGE_REL_BASED_HIGHADJ = 4,
IMAGE_REL_BASED_MIPS_JMPADDR = 5,
IMAGE_REL_BASED_ARM_MOV32A = 5,
+ IMAGE_REL_BASED_RISCV_HI20 = 5,
IMAGE_REL_BASED_ARM_MOV32T = 7,
+ IMAGE_REL_BASED_RISCV_LOW12I = 7,
+ IMAGE_REL_BASED_RISCV_LOW12S = 8,
IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
IMAGE_REL_BASED_DIR64 = 10
};
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index bc74daf983e40..277afa384927f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -32,6 +32,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
@@ -125,6 +126,9 @@ static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
return CPUType::ARM64;
case Triple::ArchType::mipsel:
return CPUType::MIPS;
+ case llvm::Triple::ArchType::riscv32:
+ case llvm::Triple::ArchType::riscv64:
+ return CPUType::Unknown;
case Triple::ArchType::UnknownArch:
return CPUType::Unknown;
default:
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 242c123665f76..4c50507f697eb 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1115,11 +1115,14 @@ dynamic_reloc_iterator COFFObjectFile::dynamic_reloc_end() const {
}
uint8_t COFFObjectFile::getBytesInAddress() const {
- return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4;
+ return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ||
+ getArch() == Triple::riscv64
+ ? 8
+ : 4;
}
StringRef COFFObjectFile::getFileFormatName() const {
- switch(getMachine()) {
+ switch (getMachine()) {
case COFF::IMAGE_FILE_MACHINE_I386:
return "COFF-i386";
case COFF::IMAGE_FILE_MACHINE_AMD64:
@@ -1134,6 +1137,10 @@ StringRef COFFObjectFile::getFileFormatName() const {
return "COFF-ARM64X";
case COFF::IMAGE_FILE_MACHINE_R4000:
return "COFF-MIPS";
+ case COFF::IMAGE_FILE_MACHINE_RISCV32:
+ return "COFF-RISCV32";
+ case COFF::IMAGE_FILE_MACHINE_RISCV64:
+ return "COFF-RISCV64";
default:
return "COFF-<unknown arch>";
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
index e68c956f888e4..19f8ab17bf32e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
@@ -11,6 +11,8 @@ add_llvm_component_library(LLVMRISCVDesc
RISCVMatInt.cpp
RISCVTargetStreamer.cpp
RISCVELFStreamer.cpp
+ RISCVWinCOFFObjectWriter.cpp
+ RISCVWinCOFFStreamer.cpp
LINK_COMPONENTS
MC
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 89a87798d71e4..b10f3e2174f81 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -895,6 +895,30 @@ bool RISCVAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm,
return true;
}
+namespace {
+
+class WindowsRISCVAsmBackend : public RISCVAsmBackend {
+ bool is64Bit;
+
+public:
+ WindowsRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options)
+ : RISCVAsmBackend(
+ STI,
+ MCELFObjectTargetWriter::getOSABI(STI.getTargetTriple().getOS()),
+ STI.getTargetTriple().isArch64Bit(), Options) {
+ is64Bit = STI.getTargetTriple().isArch64Bit();
+ }
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createRISCVWinCOFFObjectWriter(is64Bit);
+ }
+};
+
+} // namespace
+
std::unique_ptr<MCObjectTargetWriter>
RISCVAsmBackend::createObjectTargetWriter() const {
return createRISCVELFObjectWriter(OSABI, Is64Bit);
@@ -905,6 +929,11 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TT = STI.getTargetTriple();
+
+ if (TT.isOSWindows() && TT.isOSBinFormatCOFF()) {
+ return new WindowsRISCVAsmBackend(T, STI, MRI, Options);
+ }
+
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 090d331d99cab..8b6b13f239707 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -57,3 +57,15 @@ void RISCVMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
if (HasSpecifier)
OS << ')';
}
+
+
+void RISCVCOFFMCAsmInfo::anchor() {}
+
+RISCVCOFFMCAsmInfo::RISCVCOFFMCAsmInfo() {
+ HasSingleParameterDotFile = true;
+ WinEHEncodingType = WinEH::EncodingType::Itanium;
+
+ ExceptionsType = ExceptionHandling::WinEH;
+
+ AllowAtInName = true;
+}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
index 097e94b6117c7..1403f07bb7888 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
+#include "llvm/MC/MCAsmInfoCOFF.h"
#include "llvm/MC/MCAsmInfoELF.h"
#include "llvm/MC/MCFixup.h"
@@ -31,6 +32,13 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
const MCSpecifierExpr &Expr) const override;
};
+class RISCVCOFFMCAsmInfo : public MCAsmInfoGNUCOFF {
+ void anchor() override;
+
+public:
+ explicit RISCVCOFFMCAsmInfo();
+};
+
namespace RISCV {
using Specifier = uint16_t;
// Specifiers mapping to relocation types below FirstTargetFixupKind are
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
index f66c2d5f99cb3..75de3eeb096ba 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -44,6 +44,13 @@
using namespace llvm;
+namespace {
+class RISCVWinCOFFTargetStreamer : public RISCVTargetStreamer {
+public:
+ RISCVWinCOFFTargetStreamer(MCStreamer &S) : RISCVTargetStreamer(S) {}
+};
+} // end namespace
+
static MCInstrInfo *createRISCVMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitRISCVMCInstrInfo(X);
@@ -59,7 +66,13 @@ static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) {
static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
- MCAsmInfo *MAI = new RISCVMCAsmInfo(TT);
+ MCAsmInfo *MAI;
+
+ if(TT.isOSWindows()){
+ MAI = new RISCVCOFFMCAsmInfo();
+ } else {
+ MAI = new RISCVMCAsmInfo(TT);
+ }
unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true);
MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0);
@@ -110,6 +123,8 @@ static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T,
static MCTargetStreamer *
createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
const Triple &TT = STI.getTargetTriple();
+ if(TT.isOSBinFormatCOFF())
+ return new RISCVWinCOFFTargetStreamer(S);
if (TT.isOSBinFormatELF())
return new RISCVTargetELFStreamer(S, STI);
return nullptr;
@@ -344,6 +359,7 @@ LLVMInitializeRISCVTargetMC() {
TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter);
TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo);
TargetRegistry::RegisterELFStreamer(*T, createRISCVELFStreamer);
+ TargetRegistry::RegisterCOFFStreamer(*T, createRISCVWinCOFFStreamer);
TargetRegistry::RegisterObjectTargetStreamer(
*T, createRISCVObjectTargetStreamer);
TargetRegistry::RegisterMCInstrAnalysis(*T, createRISCVInstrAnalysis);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
index bdee7ed4f011e..2cfd1abdc12b3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
@@ -13,6 +13,8 @@
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Support/DataTypes.h"
#include <memory>
@@ -23,7 +25,9 @@ class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCObjectTargetWriter;
+class MCObjectWriter;
class MCRegisterInfo;
+class MCStreamer;
class MCSubtargetInfo;
class Target;
@@ -34,8 +38,16 @@ MCAsmBackend *createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options);
+MCStreamer *createRISCVWinCOFFStreamer(MCContext &C,
+ std::unique_ptr<MCAsmBackend> &&AB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&CE);
+
std::unique_ptr<MCObjectTargetWriter> createRISCVELFObjectWriter(uint8_t OSABI,
bool Is64Bit);
+
+std::unique_ptr<MCObjectTargetWriter> createRISCVWinCOFFObjectWriter(bool Is64Bit);
+
} // namespace llvm
// Defines symbolic names for RISC-V registers.
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp
new file mode 100644
index 0000000000000..207c81cd8c598
--- /dev/null
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp
@@ -0,0 +1,51 @@
+//===- RISCVWinCOFFObjectWriter.cpp-----------------------------*- 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
+//
+//===---------------------------------------------------------------------===//
+
+#include "MCTargetDesc/RISCVFixupKinds.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCWinCOFFObjectWriter.h"
+
+using namespace llvm;
+
+namespace {
+
+class RISCVWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
+public:
+ RISCVWinCOFFObjectWriter(bool Is64Bit);
+
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
+ const MCAsmBackend &MAB) const override;
+};
+
+} // namespace
+
+RISCVWinCOFFObjectWriter::RISCVWinCOFFObjectWriter(bool Is64Bit)
+ : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_RISCV64
+ : COFF::IMAGE_FILE_MACHINE_RISCV32) {}
+
+unsigned RISCVWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
+ const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsCrossSection,
+ const MCAsmBackend &MAB) const {
+ unsigned FixupKind = Fixup.getKind();
+
+ switch (FixupKind) {
+ default:
+ Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
+ return COFF::IMAGE_REL_BASED_RISCV_HI20; // FIXME
+ }
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createRISCVWinCOFFObjectWriter(bool Is64Bit) {
+ return std::make_unique<RISCVWinCOFFObjectWriter>(Is64Bit);
+}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFStreamer.cpp
new file mode 100644
index 0000000000000..7cc6dea804a83
--- /dev/null
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFStreamer.cpp
@@ -0,0 +1,33 @@
+//===- RISCVWinCOFFStreamer.cpp----------------------------------*- 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
+//
+//===---------------------------------------------------------------------===//
+
+#include "RISCVMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCWinCOFFStreamer.h"
+
+using namespace llvm;
+
+namespace {
+class RISCVWinCOFFStreamer : public MCWinCOFFStreamer {
+public:
+ RISCVWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
+ std::unique_ptr<MCCodeEmitter> CE,
+ std::unique_ptr<MCObjectWriter> OW)
+ : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
+};
+} // namespace
+
+MCStreamer *llvm::createRISCVWinCOFFStreamer(
+ MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
+ std::unique_ptr<MCObjectWriter> &&OW, std::unique_ptr<MCCodeEmitter> &&CE) {
+ return new RISCVWinCOFFStreamer(C, std::move(AB), std::move(CE),
+ std::move(OW));
+}
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 0584c941d2e6e..00ee55fd61726 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -927,6 +927,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::aarch64:
case Triple::aarch64_32:
case Triple::arm:
+ case Triple::riscv32:
+ case Triple::riscv64:
case Triple::thumb:
case Triple::x86:
case Triple::x86_64:
@@ -966,8 +968,6 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
- case Triple::riscv32:
- case Triple::riscv64:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
|
@@ -726,7 +727,10 @@ enum BaseRelocationType : unsigned { | |||
IMAGE_REL_BASED_HIGHADJ = 4, | |||
IMAGE_REL_BASED_MIPS_JMPADDR = 5, | |||
IMAGE_REL_BASED_ARM_MOV32A = 5, | |||
IMAGE_REL_BASED_RISCV_HI20 = 5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMAGE_REL_BASED_RISCV_HI20 = 5, | |
IMAGE_REL_BASED_RISCV_HIGH20 = 5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like IMAGE_REL_BASED_RISCV_HI20 already appears in other code according to google.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well they're wrong... https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types is the canonical location for the specification and is as I wrote
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFStreamer.cpp llvm/include/llvm/BinaryFormat/COFF.h llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp llvm/lib/Object/COFFObjectFile.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h llvm/lib/TargetParser/Triple.cpp View the diff from clang-format here.diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 8b6b13f23..c1dc32e2e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -58,7 +58,6 @@ void RISCVMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
OS << ')';
}
-
void RISCVCOFFMCAsmInfo::anchor() {}
RISCVCOFFMCAsmInfo::RISCVCOFFMCAsmInfo() {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
index 75de3eeb0..62773dc09 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -68,10 +68,10 @@ static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
MCAsmInfo *MAI;
- if(TT.isOSWindows()){
- MAI = new RISCVCOFFMCAsmInfo();
+ if (TT.isOSWindows()) {
+ MAI = new RISCVCOFFMCAsmInfo();
} else {
- MAI = new RISCVMCAsmInfo(TT);
+ MAI = new RISCVMCAsmInfo(TT);
}
unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true);
@@ -123,8 +123,8 @@ static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T,
static MCTargetStreamer *
createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
const Triple &TT = STI.getTargetTriple();
- if(TT.isOSBinFormatCOFF())
- return new RISCVWinCOFFTargetStreamer(S);
+ if (TT.isOSBinFormatCOFF())
+ return new RISCVWinCOFFTargetStreamer(S);
if (TT.isOSBinFormatELF())
return new RISCVTargetELFStreamer(S, STI);
return nullptr;
@@ -359,7 +359,7 @@ LLVMInitializeRISCVTargetMC() {
TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter);
TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo);
TargetRegistry::RegisterELFStreamer(*T, createRISCVELFStreamer);
- TargetRegistry::RegisterCOFFStreamer(*T, createRISCVWinCOFFStreamer);
+ TargetRegistry::RegisterCOFFStreamer(*T, createRISCVWinCOFFStreamer);
TargetRegistry::RegisterObjectTargetStreamer(
*T, createRISCVObjectTargetStreamer);
TargetRegistry::RegisterMCInstrAnalysis(*T, createRISCVInstrAnalysis);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
index 2cfd1abdc..48fb4733e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
@@ -46,8 +46,9 @@ MCStreamer *createRISCVWinCOFFStreamer(MCContext &C,
std::unique_ptr<MCObjectTargetWriter> createRISCVELFObjectWriter(uint8_t OSABI,
bool Is64Bit);
-std::unique_ptr<MCObjectTargetWriter> createRISCVWinCOFFObjectWriter(bool Is64Bit);
-
+std::unique_ptr<MCObjectTargetWriter>
+createRISCVWinCOFFObjectWriter(bool Is64Bit);
+
} // namespace llvm
// Defines symbolic names for RISC-V registers.
|
@@ -1115,11 +1115,14 @@ dynamic_reloc_iterator COFFObjectFile::dynamic_reloc_end() const { | |||
} | |||
|
|||
uint8_t COFFObjectFile::getBytesInAddress() const { | |||
return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4; | |||
return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this just is64Bit?
@@ -1134,6 +1137,10 @@ StringRef COFFObjectFile::getFileFormatName() const { | |||
return "COFF-ARM64X"; | |||
case COFF::IMAGE_FILE_MACHINE_R4000: | |||
return "COFF-MIPS"; | |||
case COFF::IMAGE_FILE_MACHINE_RISCV32: | |||
return "COFF-RISCV32"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there some standard these need to conform to (if so, where is this documented?) or are they whatever we want them to be?
Missing testcases. You probably want testcases for dump, and for the assembler, even you can't assemble very much yet. The patch is missing relocations for object files. IMAGE_REL_RISCV_* are necessary for producing non-trivial object files. |
namespace { | ||
|
||
class WindowsRISCVAsmBackend : public RISCVAsmBackend { | ||
bool is64Bit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RISCVAsmBackend already has an Is64Bit member you can just read in createObjectTargetWriter
const MCTargetOptions &Options) | ||
: RISCVAsmBackend( | ||
STI, | ||
MCELFObjectTargetWriter::getOSABI(STI.getTargetTriple().getOS()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems dubious
@@ -895,6 +895,30 @@ bool RISCVAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm, | |||
return true; | |||
} | |||
|
|||
namespace { | |||
|
|||
class WindowsRISCVAsmBackend : public RISCVAsmBackend { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
COFF rather than Windows?... AFAIK there is no Windows for RISC-V in existence anywhere, but PE/COFF is broader than Windows and does exist.
@@ -905,6 +929,11 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T, | |||
const MCRegisterInfo &MRI, | |||
const MCTargetOptions &Options) { | |||
const Triple &TT = STI.getTargetTriple(); | |||
|
|||
if (TT.isOSWindows() && TT.isOSBinFormatCOFF()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no Windows RISC-V systems. Why is this not just isOSBinFormatCOFF like AArch64?
@@ -31,6 +32,13 @@ class RISCVMCAsmInfo : public MCAsmInfoELF { | |||
const MCSpecifierExpr &Expr) const override; | |||
}; | |||
|
|||
class RISCVCOFFMCAsmInfo : public MCAsmInfoGNUCOFF { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AArch64 calls this AArch64MCAsmInfoGNUCOFF
if(TT.isOSWindows()){ | ||
MAI = new RISCVCOFFMCAsmInfo(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confused between Windows and PE/COFF again, not to mention the obvious formatting problems
if(TT.isOSBinFormatCOFF()) | ||
return new RISCVWinCOFFTargetStreamer(S); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
@@ -344,6 +359,7 @@ LLVMInitializeRISCVTargetMC() { | |||
TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); | |||
TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); | |||
TargetRegistry::RegisterELFStreamer(*T, createRISCVELFStreamer); | |||
TargetRegistry::RegisterCOFFStreamer(*T, createRISCVWinCOFFStreamer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting?
@@ -927,6 +927,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { | |||
case Triple::aarch64: | |||
case Triple::aarch64_32: | |||
case Triple::arm: | |||
case Triple::riscv32: | |||
case Triple::riscv64: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds both Darwin and Win32 support, but AFAIK UEFI is the only extra case that should be handled?
Yeah. They don't exist because Microsoft own the PE/COFF spec and there is no Windows for RISC-V, so haven't defined them. See past discussions in https://reviews.llvm.org/D145539?id=503211. There's just nothing really to do in LLVM for PE/COFF until either Microsoft define object relocations for RISC-V or llvm-objcopy supports converting between ELF and PE/COFF. |
Someone needs to define relocation numbers. Ideally, it would be Microsoft, but I'm not sure that's a hard constraint. |
If someone else defines them, would Microsoft honour them if it decided to port Windows (or some other part of its ecosystem that needs PE/COFF, maybe some in-house RTOS on a microprocessor) to RISC-V? There's a serious risk of divergence and incompatibility if you go down that road without Microsoft's blessing. Not to mention that it's not exactly friendly behaviour to treat one party's specification as if you own it (in a production context). |
I mean, yes, we don't want to step on Microsoft's toes, but I don't think waiting indefinitely for Microsoft to start caring about RISCV is the right answer, either. Probably the best first step is for someone to write up exactly what's necessary, and ask Microsoft to rubber-stamp it. |
Adding support for PE file output for RISC-V target, mainly targeted for producing UEFI Applications.