brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · e8423ff Raw
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