123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- //===- XCOFFWriter.cpp ----------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Support/Errc.h"
- #include "XCOFFWriter.h"
- namespace llvm {
- namespace objcopy {
- namespace xcoff {
- using namespace object;
- void XCOFFWriter::finalizeHeaders() {
- // File header.
- FileSize += sizeof(XCOFFFileHeader32);
- // Optional file header.
- FileSize += Obj.FileHeader.AuxHeaderSize;
- // Section headers.
- FileSize += sizeof(XCOFFSectionHeader32) * Obj.Sections.size();
- }
- void XCOFFWriter::finalizeSections() {
- for (const Section &Sec : Obj.Sections) {
- // Section data.
- FileSize += Sec.Contents.size();
- // Relocations.
- FileSize +=
- Sec.SectionHeader.NumberOfRelocations * sizeof(XCOFFRelocation32);
- }
- }
- void XCOFFWriter::finalizeSymbolStringTable() {
- assert(Obj.FileHeader.SymbolTableOffset >= FileSize);
- FileSize = Obj.FileHeader.SymbolTableOffset;
- // Symbols and auxiliary entries.
- FileSize +=
- Obj.FileHeader.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;
- // String table.
- FileSize += Obj.StringTable.size();
- }
- void XCOFFWriter::finalize() {
- FileSize = 0;
- finalizeHeaders();
- finalizeSections();
- finalizeSymbolStringTable();
- }
- void XCOFFWriter::writeHeaders() {
- // Write the file header.
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart());
- memcpy(Ptr, &Obj.FileHeader, sizeof(XCOFFFileHeader32));
- Ptr += sizeof(XCOFFFileHeader32);
- // Write the optional header.
- if (Obj.FileHeader.AuxHeaderSize) {
- memcpy(Ptr, &Obj.OptionalFileHeader, Obj.FileHeader.AuxHeaderSize);
- Ptr += Obj.FileHeader.AuxHeaderSize;
- }
- // Write section headers.
- for (const Section &Sec : Obj.Sections) {
- memcpy(Ptr, &Sec.SectionHeader, sizeof(XCOFFSectionHeader32));
- Ptr += sizeof(XCOFFSectionHeader32);
- }
- }
- void XCOFFWriter::writeSections() {
- // Write section data.
- for (const Section &Sec : Obj.Sections) {
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +
- Sec.SectionHeader.FileOffsetToRawData;
- Ptr = std::copy(Sec.Contents.begin(), Sec.Contents.end(), Ptr);
- }
- // Write relocations.
- for (const Section &Sec : Obj.Sections) {
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +
- Sec.SectionHeader.FileOffsetToRelocationInfo;
- for (const XCOFFRelocation32 &Rel : Sec.Relocations) {
- memcpy(Ptr, &Rel, sizeof(XCOFFRelocation32));
- Ptr += sizeof(XCOFFRelocation32);
- }
- }
- }
- void XCOFFWriter::writeSymbolStringTable() {
- // Write symbols.
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +
- Obj.FileHeader.SymbolTableOffset;
- for (const Symbol &Sym : Obj.Symbols) {
- memcpy(Ptr, &Sym.Sym, XCOFF::SymbolTableEntrySize);
- Ptr += XCOFF::SymbolTableEntrySize;
- // Auxiliary symbols.
- memcpy(Ptr, Sym.AuxSymbolEntries.data(), Sym.AuxSymbolEntries.size());
- Ptr += Sym.AuxSymbolEntries.size();
- }
- // Write the string table.
- memcpy(Ptr, Obj.StringTable.data(), Obj.StringTable.size());
- Ptr += Obj.StringTable.size();
- }
- Error XCOFFWriter::write() {
- finalize();
- Buf = WritableMemoryBuffer::getNewMemBuffer(FileSize);
- if (!Buf)
- return createStringError(errc::not_enough_memory,
- "failed to allocate memory buffer of " +
- Twine::utohexstr(FileSize) + " bytes");
- writeHeaders();
- writeSections();
- writeSymbolStringTable();
- Out.write(Buf->getBufferStart(), Buf->getBufferSize());
- return Error::success();
- }
- } // end namespace xcoff
- } // end namespace objcopy
- } // end namespace llvm
|