riscv-llvm
riscv-llvm copied to clipboard
file in wrong format
Hello,
I've managed to build the tool, but when running clang in the last step, I get a "/path/to/riscv64-unknown-elf/lib/crt0.o: error adding symbols: file in wrong format" error.
Does anyone have any insight as to what this could be and how to go about resolving this issue?
Thanks
Same here.
Here is the clang patch I applied to support unknown-elf (naively replacing 64 in place of 32 on the original):
Index: lib/Driver/CMakeLists.txt
===================================================================
--- lib/Driver/CMakeLists.txt
+++ lib/Driver/CMakeLists.txt
@@ -56,6 +56,7 @@
ToolChains/NetBSD.cpp
ToolChains/OpenBSD.cpp
ToolChains/PS4CPU.cpp
+ ToolChains/RISCV.cpp
ToolChains/Solaris.cpp
ToolChains/TCE.cpp
ToolChains/WebAssembly.cpp
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -36,6 +36,7 @@
#include "ToolChains/NetBSD.h"
#include "ToolChains/OpenBSD.h"
#include "ToolChains/PS4CPU.h"
+#include "ToolChains/RISCV.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
#include "ToolChains/WebAssembly.h"
@@ -4281,6 +4282,10 @@
case llvm::Triple::avr:
TC = llvm::make_unique<toolchains::AVRToolChain>(*this, Target, Args);
break;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ TC = llvm::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
+ break;
default:
if (Target.getVendor() == llvm::Triple::Myriad)
TC = llvm::make_unique<toolchains::MyriadToolChain>(*this, Target,
Index: lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- lib/Driver/ToolChains/Gnu.cpp
+++ lib/Driver/ToolChains/Gnu.cpp
@@ -1881,7 +1881,8 @@
static const char *const RISCV32LibDirs[] = {"/lib", "/lib32"};
static const char *const RISCVTriples[] = {"riscv32-unknown-linux-gnu",
- "riscv64-unknown-linux-gnu"};
+ "riscv64-unknown-linux-gnu",
+ "riscv64-unknown-elf"};
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
Index: lib/Driver/ToolChains/RISCV.h
===================================================================
--- /dev/null
+++ lib/Driver/ToolChains/RISCV.h
@@ -0,0 +1,57 @@
+//===--- RISCV.h - RISCV ToolChain Implementations --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H
+
+#include "Gnu.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF {
+public:
+ RISCVToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+
+ bool IsIntegratedAssemblerDefault() const override { return true; }
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void
+ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+protected:
+ Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+
+namespace tools {
+namespace RISCV {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+ Linker(const ToolChain &TC) : GnuTool("RISCV::Linker", "ld", TC) {}
+ bool hasIntegratedCPP() const override { return false; }
+ bool isLinkJob() const override { return true; }
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+} // end namespace RISCV
+} // end namespace tools
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H
Index: lib/Driver/ToolChains/RISCV.cpp
===================================================================
--- /dev/null
+++ lib/Driver/ToolChains/RISCV.cpp
@@ -0,0 +1,117 @@
+//===--- RISCV.cpp - RISCV ToolChain Implementations ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "CommonArgs.h"
+#include "InputInfo.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+/// RISCV Toolchain
+RISCVToolChain::RISCVToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : Generic_ELF(D, Triple, Args) {
+ GCCInstallation.init(Triple, Args);
+ getFilePaths().push_back(D.SysRoot + "/lib");
+ if (GCCInstallation.isValid()) {
+ getFilePaths().push_back(GCCInstallation.getInstallPath().str());
+ getProgramPaths().push_back(
+ (GCCInstallation.getParentLibPath() + "/../bin").str());
+ }
+}
+
+Tool *RISCVToolChain::buildLinker() const {
+ return new tools::RISCV::Linker(*this);
+}
+
+void RISCVToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+
+ if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
+ SmallString<128> Dir(getDriver().SysRoot);
+ llvm::sys::path::append(Dir, "include");
+ addSystemInclude(DriverArgs, CC1Args, Dir.str());
+ }
+}
+
+void RISCVToolChain::addLibStdCxxIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ StringRef LibDir = GCCInstallation.getParentLibPath();
+ const GCCVersion &Version = GCCInstallation.getVersion();
+ StringRef TripleStr = GCCInstallation.getTriple().str();
+ const Multilib &Multilib = GCCInstallation.getMultilib();
+ addLibStdCXXIncludePaths(
+ LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
+ "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
+}
+
+void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const ToolChain &ToolChain = getToolChain();
+ const Driver &D = ToolChain.getDriver();
+ ArgStringList CmdArgs;
+
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+ std::string Linker = getToolChain().GetProgramPath(getShortName());
+
+ bool WantCRTs =
+ !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
+
+ if (WantCRTs) {
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+ Args.AddAllArgs(CmdArgs,
+ {options::OPT_T_Group, options::OPT_e, options::OPT_s,
+ options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
+
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+ // TODO: add C++ includes and libs if compiling C++.
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+ if (ToolChain.ShouldLinkCXXStdlib(Args))
+ ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+ CmdArgs.push_back("--start-group");
+ CmdArgs.push_back("-lc");
+ CmdArgs.push_back("-lgloss");
+ CmdArgs.push_back("--end-group");
+ CmdArgs.push_back("-lgcc");
+ }
+
+ if (WantCRTs)
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+ CmdArgs, Inputs));
+}
+// RISCV tools end.
Index: test/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld
===================================================================
--- /dev/null
+++ test/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld
@@ -0,0 +1 @@
+#!/bin/true
Index: test/Driver/riscv64-toolchain.c
===================================================================
--- test/Driver/riscv64-toolchain.c
+++ test/Driver/riscv64-toolchain.c
@@ -3,6 +3,36 @@
// RUN: %clang %s -### -no-canonical-prefixes -target riscv64 2>&1 | FileCheck -check-prefix=CC1 %s
// CC1: clang{{.*}} "-cc1" "-triple" "riscv64"
+// RUN: %clang %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV64-BAREMETAL-ILP64 %s
+
+// C-RV64-BAREMETAL-ILP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// C-RV64-BAREMETAL-ILP64: "--sysroot={{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf"
+// C-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// C-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// C-RV64-BAREMETAL-ILP64: "-L{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib"
+// C-RV64-BAREMETAL-ILP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// C-RV64-BAREMETAL-ILP64: "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// C-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clangxx %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=CXX-RV64-BAREMETAL-ILP64 %s
+
+// CXX-RV64-BAREMETAL-ILP64: "-internal-isystem" "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf/include/c++{{/|\\\\}}8.0.1"
+// CXX-RV64-BAREMETAL-ILP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// CXX-RV64-BAREMETAL-ILP64: "--sysroot={{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf"
+// CXX-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// CXX-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// CXX-RV64-BAREMETAL-ILP64: "-L{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib"
+// CXX-RV64-BAREMETAL-ILP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// CXX-RV64-BAREMETAL-ILP64: "-lstdc++" "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// CXX-RV64-BAREMETAL-ILP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
// RUN: -target riscv64-linux-unknown-elf \
Here is the file I am trying to compile:
long main() {
long x = 42;
return x * x;
}
Here is the clang command with debug info:
x@msi:/d/boo$ /d/llvm/build/bin/clang sample.c -v -Wno-main-return-type
clang version 7.0.0 (https://git.llvm.org/git/clang.git/ 8deba4344428131861f909fd6d59b0f2c4d643e2) (https://git.llvm.org/git/llvm.git bd2bb96fb187f28aec8248e3a8f461686f22ea7a)
Target: riscv64-unknown--elf
Thread model: posix
InstalledDir: /d/llvm/build/bin
"/d/llvm/build/bin/clang-7" -cc1 -triple riscv64-unknown--elf -emit-obj -mrelax-all -disable-free -main-file-name sample.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-abi lp64 -dwarf-column-info -debugger-tuning=gdb -v -resource-dir /d/llvm/build/lib/clang/7.0.0 -isysroot /d/riscv/riscv64-unknown-elf -internal-isystem /d/riscv/riscv64-unknown-elf/include -Wno-main-return-type -fdebug-compilation-dir /d/boo -ferror-limit 19 -fmessage-length 380 -fno-signed-char -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/sample-ca27e4.o -x c sample.c -faddrsig
clang -cc1 version 7.0.0 based upon LLVM 7.0.0svn default target riscv64-unknown-elf
ignoring nonexistent directory "/d/riscv/riscv64-unknown-elf/usr/local/include"
ignoring nonexistent directory "/d/riscv/riscv64-unknown-elf/usr/include"
#include "..." search starts here:
#include <...> search starts here:
/d/riscv/riscv64-unknown-elf/include
/d/llvm/build/lib/clang/7.0.0/include
End of search list.
"/usr/bin/ld" --sysroot=/d/riscv/riscv64-unknown-elf /d/riscv/riscv64-unknown-elf/lib/crt0.o crtbegin.o -L/d/riscv/riscv64-unknown-elf/lib /tmp/sample-ca27e4.o --start-group -lc -lgloss --end-group -lgcc crtend.o -o a.out
/usr/bin/ld: /d/riscv/riscv64-unknown-elf/lib/crt0.o: Relocations in generic ELF (EM: 243)
/d/riscv/riscv64-unknown-elf/lib/crt0.o: error adding symbols: File in wrong format
clang-7: error: ld command failed with exit code 1 (use -v to see invocation)
I shared my experiences with lowRISC RISC-V LLVM 64-bit flow for reference.
1.Create source path :
$ mkdir /to/your/homepath/source_riscv_toolchain/
2.Create bin path :
$ mkdir /to/your/homepath/riscv_llvm_binary/
3.Put patch file RISCV64_Support.patch :
file: RISCV64_Support.patch.txt
$ mv RISCV64_Support.patch /to/your/homepath/source_riscv_toolchain/
4.Build riscv-gnu-toolchain [1] :
$ cd /to/your/homepath/source_riscv_toolchain/
$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
$ ./configure --prefix=/to/your/homepath/riscv_llvm_binary --with-arch=rv64ima --enable-multilib
// Installation (Newlib)
$ make -j9
// Installation (Linux)
$ make linux -j9
5.Build riscv-llvm(lowRISC version) [2] :
$ cd /to/your/homepath/source_riscv_toolchain/
$ git clone https://github.com/lowRISC/riscv-llvm.git lowriscv-llvm
// Check the most recent commit on this repo to ensure this is correct
$ export REV=326957
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk@$REV llvm
$ cd llvm/tools
$ svn co http://llvm.org/svn/llvm-project/cfe/trunk@$REV clang
$ cd ..
$ for P in /to/your/homepath/source_riscv_toolchain/lowriscv-llvm/*.patch; do patch -p1 < $P; done
$ for P in /to/your/homepath/source_riscv_toolchain/lowriscv-llvm/clang/*.patch; do patch -d tools/clang -p1 < $P; done
$ patch tools/clang/lib/Driver/ToolChains/Gnu.cpp < /to/your/homepath/source_riscv_toolchain/RISCV64_Support.patch
$ cd /to/your/homepath/riscv_llvm_binary/
$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Debug" \
-DBUILD_SHARED_LIBS=True -DLLVM_USE_SPLIT_DWARF=True \
-DLLVM_OPTIMIZED_TABLEGEN=True \
-DLLVM_BUILD_TESTS=True \
-DDEFAULT_SYSROOT="/to/your/homepath/riscv_llvm_binary/riscv64-unknown-elf" \
-DGCC_INSTALL_PREFIX="/to/your/homepath/riscv_llvm_binary" \
-DLLVM_DEFAULT_TARGET_TRIPLE="riscv64-unknown-elf" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" /to/your/homepath/source_riscv_toolchain/llvm
$ cmake --build .
6.Export environment variable :
$ export PATH="/to/your/homepath/riscv_llvm_binary/bin:$PATH"
7.Clang information :
$ clang -v
clang version 7.0.0 (trunk 326957)
Target: riscv64-unknown--elf
Thread model: posix
InstalledDir: /to/your/homepath/riscv_llvm_binary/bin
Found candidate GCC installation: /to/your/homepath/riscv_llvm_binary/lib/gcc/riscv64-unknown-elf/8.1.0
Found candidate GCC installation: /to/your/homepath/riscv_llvm_binary/lib/gcc/riscv64-unknown-linux-gnu/8.1.0
Selected GCC installation: /to/your/homepath/riscv_llvm_binary/lib/gcc/riscv64-unknown-linux-gnu/8.1.0
Candidate multilib: lib32/ilp32;@m32@mabi=ilp32
Candidate multilib: lib32/ilp32d;@m32@mabi=ilp32d
Candidate multilib: lib64/lp64;@m64@mabi=lp64
Candidate multilib: lib64/lp64d;@m64@mabi=lp64d
Selected multilib: lib64/lp64;@m64@mabi=lp64
8.Test and elf info. [3] :
$ cd /to/your/homepath/
$ echo -e '#include <stdio.h>\n int main(void) { printf("Hello world!\\n"); return 0; }' > hello.c
$ clang hello.c -o hello
$ spike pk hello
Hello world!
$ riscv64-unknown-elf-objdump -f hello
hello: file format elf64-littleriscv
architecture: riscv:rv64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000000100e8
$ riscv64-unknown-elf-readelf -h hello
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x100e8
Start of program headers: 64 (bytes into file)
Start of section headers: 148088 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 3
Size of section headers: 64 (bytes)
Number of section headers: 23
Section header string table index: 22
End~~~
References: [1] RISC-V GNU Compiler Toolchain, https://github.com/riscv/riscv-gnu-toolchain/ [2] RISC-V LLVM, https://github.com/lowRISC/riscv-llvm [3] RISC-V Tools, https://github.com/riscv/riscv-tools