1 //===- XCOFFWriter.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/Errc.h"
10 #include "XCOFFWriter.h"
16 using namespace object
;
18 void XCOFFWriter::finalizeHeaders() {
20 FileSize
+= sizeof(XCOFFFileHeader32
);
21 // Optional file header.
22 FileSize
+= Obj
.FileHeader
.AuxHeaderSize
;
24 FileSize
+= sizeof(XCOFFSectionHeader32
) * Obj
.Sections
.size();
27 void XCOFFWriter::finalizeSections() {
28 for (const Section
&Sec
: Obj
.Sections
) {
30 FileSize
+= Sec
.Contents
.size();
33 Sec
.SectionHeader
.NumberOfRelocations
* sizeof(XCOFFRelocation32
);
37 void XCOFFWriter::finalizeSymbolStringTable() {
38 assert(Obj
.FileHeader
.SymbolTableOffset
>= FileSize
);
39 FileSize
= Obj
.FileHeader
.SymbolTableOffset
;
40 // Symbols and auxiliary entries.
42 Obj
.FileHeader
.NumberOfSymTableEntries
* XCOFF::SymbolTableEntrySize
;
44 FileSize
+= Obj
.StringTable
.size();
47 void XCOFFWriter::finalize() {
51 finalizeSymbolStringTable();
54 void 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
);
60 // Write the optional header.
61 if (Obj
.FileHeader
.AuxHeaderSize
) {
62 memcpy(Ptr
, &Obj
.OptionalFileHeader
, Obj
.FileHeader
.AuxHeaderSize
);
63 Ptr
+= Obj
.FileHeader
.AuxHeaderSize
;
66 // Write section headers.
67 for (const Section
&Sec
: Obj
.Sections
) {
68 memcpy(Ptr
, &Sec
.SectionHeader
, sizeof(XCOFFSectionHeader32
));
69 Ptr
+= sizeof(XCOFFSectionHeader32
);
73 void 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
= std::copy(Sec
.Contents
.begin(), Sec
.Contents
.end(), Ptr
);
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
);
92 void XCOFFWriter::writeSymbolStringTable() {
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
;
100 memcpy(Ptr
, Sym
.AuxSymbolEntries
.data(), Sym
.AuxSymbolEntries
.size());
101 Ptr
+= Sym
.AuxSymbolEntries
.size();
103 // Write the string table.
104 memcpy(Ptr
, Obj
.StringTable
.data(), Obj
.StringTable
.size());
105 Ptr
+= Obj
.StringTable
.size();
108 Error
XCOFFWriter::write() {
110 Buf
= WritableMemoryBuffer::getNewMemBuffer(FileSize
);
112 return createStringError(errc::not_enough_memory
,
113 "failed to allocate memory buffer of " +
114 Twine::utohexstr(FileSize
) + " bytes");
118 writeSymbolStringTable();
119 Out
.write(Buf
->getBufferStart(), Buf
->getBufferSize());
120 return Error::success();
123 } // end namespace xcoff
124 } // end namespace objcopy
125 } // end namespace llvm