1 //===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements XCOFF object file writer information. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCObjectWriter.h" 15 #include "llvm/MC/MCValue.h" 16 #include "llvm/MC/MCXCOFFObjectWriter.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 class XCOFFObjectWriter : public MCObjectWriter { 23 support::endian::Writer W; 24 std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter; 25 26 void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override; 27 28 void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *, 29 const MCFixup &, MCValue, uint64_t &) override; 30 31 uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override; 32 33 public: 34 XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, 35 raw_pwrite_stream &OS); 36 }; 37 38 XCOFFObjectWriter::XCOFFObjectWriter( 39 std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) 40 : W(OS, support::big), TargetObjectWriter(std::move(MOTW)) {} 41 42 void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &, 43 const MCAsmLayout &) { 44 // TODO Implement once we have sections and symbols to handle. 45 } 46 47 void XCOFFObjectWriter::recordRelocation(MCAssembler &, const MCAsmLayout &, 48 const MCFragment *, const MCFixup &, 49 MCValue, uint64_t &) { 50 report_fatal_error("XCOFF relocations not supported."); 51 } 52 53 uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &) { 54 // We always emit a timestamp of 0 for reproducibility, so ensure incremental 55 // linking is not enabled, in case, like with Windows COFF, such a timestamp 56 // is incompatible with incremental linking of XCOFF. 57 if (Asm.isIncrementalLinkerCompatible()) 58 report_fatal_error("Incremental linking not supported for XCOFF."); 59 60 if (TargetObjectWriter->is64Bit()) 61 report_fatal_error("64-bit XCOFF object files are not supported yet."); 62 63 uint64_t StartOffset = W.OS.tell(); 64 65 // TODO FIXME Assign section numbers/finalize sections. 66 67 // TODO FIXME Finalize symbols. 68 69 // Magic. 70 W.write<uint16_t>(0x01df); 71 // Number of sections. 72 W.write<uint16_t>(0); 73 // Timestamp field. For reproducible output we write a 0, which represents no 74 // timestamp. 75 W.write<int32_t>(0); 76 // Byte Offset to the start of the symbol table. 77 W.write<uint32_t>(0); 78 // Number of entries in the symbol table. 79 W.write<int32_t>(0); 80 // Size of the optional header. 81 W.write<uint16_t>(0); 82 // Flags. 83 W.write<uint16_t>(0); 84 85 return W.OS.tell() - StartOffset; 86 } 87 88 } // end anonymous namespace 89 90 std::unique_ptr<MCObjectWriter> 91 llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, 92 raw_pwrite_stream &OS) { 93 return llvm::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS); 94 } 95