1*9880d681SAndroid Build Coastguard Worker //===-- WebAssemblyELFObjectWriter.cpp - WebAssembly ELF Writer -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker ///
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief This file handles ELF-specific object emission, converting LLVM's
12*9880d681SAndroid Build Coastguard Worker /// internal fixups into the appropriate relocations.
13*9880d681SAndroid Build Coastguard Worker ///
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFObjectWriter.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixup.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker namespace {
23*9880d681SAndroid Build Coastguard Worker class WebAssemblyELFObjectWriter final : public MCELFObjectTargetWriter {
24*9880d681SAndroid Build Coastguard Worker public:
25*9880d681SAndroid Build Coastguard Worker WebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker protected:
28*9880d681SAndroid Build Coastguard Worker unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup, bool IsPCRel) const override;
30*9880d681SAndroid Build Coastguard Worker };
31*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
32*9880d681SAndroid Build Coastguard Worker
WebAssemblyELFObjectWriter(bool Is64Bit,uint8_t OSABI)33*9880d681SAndroid Build Coastguard Worker WebAssemblyELFObjectWriter::WebAssemblyELFObjectWriter(bool Is64Bit,
34*9880d681SAndroid Build Coastguard Worker uint8_t OSABI)
35*9880d681SAndroid Build Coastguard Worker : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_WEBASSEMBLY,
36*9880d681SAndroid Build Coastguard Worker /*HasRelocationAddend=*/false) {}
37*9880d681SAndroid Build Coastguard Worker
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const38*9880d681SAndroid Build Coastguard Worker unsigned WebAssemblyELFObjectWriter::getRelocType(MCContext &Ctx,
39*9880d681SAndroid Build Coastguard Worker const MCValue &Target,
40*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup,
41*9880d681SAndroid Build Coastguard Worker bool IsPCRel) const {
42*9880d681SAndroid Build Coastguard Worker // WebAssembly functions are not allocated in the address space. To resolve a
43*9880d681SAndroid Build Coastguard Worker // pointer to a function, we must use a special relocation type.
44*9880d681SAndroid Build Coastguard Worker if (const MCSymbolRefExpr *SyExp =
45*9880d681SAndroid Build Coastguard Worker dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
46*9880d681SAndroid Build Coastguard Worker if (SyExp->getKind() == MCSymbolRefExpr::VK_WebAssembly_FUNCTION)
47*9880d681SAndroid Build Coastguard Worker return ELF::R_WEBASSEMBLY_FUNCTION;
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker switch (Fixup.getKind()) {
50*9880d681SAndroid Build Coastguard Worker case FK_Data_4:
51*9880d681SAndroid Build Coastguard Worker assert(!is64Bit() && "4-byte relocations only supported on wasm32");
52*9880d681SAndroid Build Coastguard Worker return ELF::R_WEBASSEMBLY_DATA;
53*9880d681SAndroid Build Coastguard Worker case FK_Data_8:
54*9880d681SAndroid Build Coastguard Worker assert(is64Bit() && "8-byte relocations only supported on wasm64");
55*9880d681SAndroid Build Coastguard Worker return ELF::R_WEBASSEMBLY_DATA;
56*9880d681SAndroid Build Coastguard Worker default:
57*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unimplemented fixup kind");
58*9880d681SAndroid Build Coastguard Worker }
59*9880d681SAndroid Build Coastguard Worker }
60*9880d681SAndroid Build Coastguard Worker
createWebAssemblyELFObjectWriter(raw_pwrite_stream & OS,bool Is64Bit,uint8_t OSABI)61*9880d681SAndroid Build Coastguard Worker MCObjectWriter *llvm::createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
62*9880d681SAndroid Build Coastguard Worker bool Is64Bit,
63*9880d681SAndroid Build Coastguard Worker uint8_t OSABI) {
64*9880d681SAndroid Build Coastguard Worker MCELFObjectTargetWriter *MOTW =
65*9880d681SAndroid Build Coastguard Worker new WebAssemblyELFObjectWriter(Is64Bit, OSABI);
66*9880d681SAndroid Build Coastguard Worker return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
67*9880d681SAndroid Build Coastguard Worker }
68