Path: blob/main/contrib/llvm-project/llvm/lib/ObjCopy/XCOFF/XCOFFWriter.cpp
35266 views
//===- XCOFFWriter.cpp ----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/Support/Errc.h"9#include "XCOFFWriter.h"1011namespace llvm {12namespace objcopy {13namespace xcoff {1415using namespace object;1617void XCOFFWriter::finalizeHeaders() {18// File header.19FileSize += sizeof(XCOFFFileHeader32);20// Optional file header.21FileSize += Obj.FileHeader.AuxHeaderSize;22// Section headers.23FileSize += sizeof(XCOFFSectionHeader32) * Obj.Sections.size();24}2526void XCOFFWriter::finalizeSections() {27for (const Section &Sec : Obj.Sections) {28// Section data.29FileSize += Sec.Contents.size();30// Relocations.31FileSize +=32Sec.SectionHeader.NumberOfRelocations * sizeof(XCOFFRelocation32);33}34}3536void XCOFFWriter::finalizeSymbolStringTable() {37assert(Obj.FileHeader.SymbolTableOffset >= FileSize);38FileSize = Obj.FileHeader.SymbolTableOffset;39// Symbols and auxiliary entries.40FileSize +=41Obj.FileHeader.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;42// String table.43FileSize += Obj.StringTable.size();44}4546void XCOFFWriter::finalize() {47FileSize = 0;48finalizeHeaders();49finalizeSections();50finalizeSymbolStringTable();51}5253void XCOFFWriter::writeHeaders() {54// Write the file header.55uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart());56memcpy(Ptr, &Obj.FileHeader, sizeof(XCOFFFileHeader32));57Ptr += sizeof(XCOFFFileHeader32);5859// Write the optional header.60if (Obj.FileHeader.AuxHeaderSize) {61memcpy(Ptr, &Obj.OptionalFileHeader, Obj.FileHeader.AuxHeaderSize);62Ptr += Obj.FileHeader.AuxHeaderSize;63}6465// Write section headers.66for (const Section &Sec : Obj.Sections) {67memcpy(Ptr, &Sec.SectionHeader, sizeof(XCOFFSectionHeader32));68Ptr += sizeof(XCOFFSectionHeader32);69}70}7172void XCOFFWriter::writeSections() {73// Write section data.74for (const Section &Sec : Obj.Sections) {75uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +76Sec.SectionHeader.FileOffsetToRawData;77Ptr = std::copy(Sec.Contents.begin(), Sec.Contents.end(), Ptr);78}7980// Write relocations.81for (const Section &Sec : Obj.Sections) {82uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +83Sec.SectionHeader.FileOffsetToRelocationInfo;84for (const XCOFFRelocation32 &Rel : Sec.Relocations) {85memcpy(Ptr, &Rel, sizeof(XCOFFRelocation32));86Ptr += sizeof(XCOFFRelocation32);87}88}89}9091void XCOFFWriter::writeSymbolStringTable() {92// Write symbols.93uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +94Obj.FileHeader.SymbolTableOffset;95for (const Symbol &Sym : Obj.Symbols) {96memcpy(Ptr, &Sym.Sym, XCOFF::SymbolTableEntrySize);97Ptr += XCOFF::SymbolTableEntrySize;98// Auxiliary symbols.99memcpy(Ptr, Sym.AuxSymbolEntries.data(), Sym.AuxSymbolEntries.size());100Ptr += Sym.AuxSymbolEntries.size();101}102// Write the string table.103memcpy(Ptr, Obj.StringTable.data(), Obj.StringTable.size());104Ptr += Obj.StringTable.size();105}106107Error XCOFFWriter::write() {108finalize();109Buf = WritableMemoryBuffer::getNewMemBuffer(FileSize);110if (!Buf)111return createStringError(errc::not_enough_memory,112"failed to allocate memory buffer of " +113Twine::utohexstr(FileSize) + " bytes");114115writeHeaders();116writeSections();117writeSymbolStringTable();118Out.write(Buf->getBufferStart(), Buf->getBufferSize());119return Error::success();120}121122} // end namespace xcoff123} // end namespace objcopy124} // end namespace llvm125126127