126 lines · cpp
1//===- XCOFFWriter.cpp ----------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/Errc.h"10#include "XCOFFWriter.h"11 12namespace llvm {13namespace objcopy {14namespace xcoff {15 16using namespace object;17 18void XCOFFWriter::finalizeHeaders() {19 // File header.20 FileSize += sizeof(XCOFFFileHeader32);21 // Optional file header.22 FileSize += Obj.FileHeader.AuxHeaderSize;23 // Section headers.24 FileSize += sizeof(XCOFFSectionHeader32) * Obj.Sections.size();25}26 27void XCOFFWriter::finalizeSections() {28 for (const Section &Sec : Obj.Sections) {29 // Section data.30 FileSize += Sec.Contents.size();31 // Relocations.32 FileSize +=33 Sec.SectionHeader.NumberOfRelocations * sizeof(XCOFFRelocation32);34 }35}36 37void XCOFFWriter::finalizeSymbolStringTable() {38 assert(Obj.FileHeader.SymbolTableOffset >= FileSize);39 FileSize = Obj.FileHeader.SymbolTableOffset;40 // Symbols and auxiliary entries.41 FileSize +=42 Obj.FileHeader.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;43 // String table.44 FileSize += Obj.StringTable.size();45}46 47void XCOFFWriter::finalize() {48 FileSize = 0;49 finalizeHeaders();50 finalizeSections();51 finalizeSymbolStringTable();52}53 54void XCOFFWriter::writeHeaders() {55 // Write the file header.56 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart());57 memcpy(Ptr, &Obj.FileHeader, sizeof(XCOFFFileHeader32));58 Ptr += sizeof(XCOFFFileHeader32);59 60 // Write the optional header.61 if (Obj.FileHeader.AuxHeaderSize) {62 memcpy(Ptr, &Obj.OptionalFileHeader, Obj.FileHeader.AuxHeaderSize);63 Ptr += Obj.FileHeader.AuxHeaderSize;64 }65 66 // Write section headers.67 for (const Section &Sec : Obj.Sections) {68 memcpy(Ptr, &Sec.SectionHeader, sizeof(XCOFFSectionHeader32));69 Ptr += sizeof(XCOFFSectionHeader32);70 }71}72 73void XCOFFWriter::writeSections() {74 // Write section data.75 for (const Section &Sec : Obj.Sections) {76 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +77 Sec.SectionHeader.FileOffsetToRawData;78 Ptr = llvm::copy(Sec.Contents, Ptr);79 }80 81 // Write relocations.82 for (const Section &Sec : Obj.Sections) {83 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +84 Sec.SectionHeader.FileOffsetToRelocationInfo;85 for (const XCOFFRelocation32 &Rel : Sec.Relocations) {86 memcpy(Ptr, &Rel, sizeof(XCOFFRelocation32));87 Ptr += sizeof(XCOFFRelocation32);88 }89 }90}91 92void XCOFFWriter::writeSymbolStringTable() {93 // Write symbols.94 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +95 Obj.FileHeader.SymbolTableOffset;96 for (const Symbol &Sym : Obj.Symbols) {97 memcpy(Ptr, &Sym.Sym, XCOFF::SymbolTableEntrySize);98 Ptr += XCOFF::SymbolTableEntrySize;99 // Auxiliary symbols.100 memcpy(Ptr, Sym.AuxSymbolEntries.data(), Sym.AuxSymbolEntries.size());101 Ptr += Sym.AuxSymbolEntries.size();102 }103 // Write the string table.104 memcpy(Ptr, Obj.StringTable.data(), Obj.StringTable.size());105 Ptr += Obj.StringTable.size();106}107 108Error XCOFFWriter::write() {109 finalize();110 Buf = WritableMemoryBuffer::getNewMemBuffer(FileSize);111 if (!Buf)112 return createStringError(errc::not_enough_memory,113 "failed to allocate memory buffer of " +114 Twine::utohexstr(FileSize) + " bytes");115 116 writeHeaders();117 writeSections();118 writeSymbolStringTable();119 Out.write(Buf->getBufferStart(), Buf->getBufferSize());120 return Error::success();121}122 123} // end namespace xcoff124} // end namespace objcopy125} // end namespace llvm126