LLVM  16.0.0git
XCOFFWriter.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Support/Errc.h"
10 #include "XCOFFWriter.h"
11 
12 namespace llvm {
13 namespace objcopy {
14 namespace xcoff {
15 
16 using namespace object;
17 
18 void 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 
27 void 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 
37 void 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 
47 void XCOFFWriter::finalize() {
48  FileSize = 0;
49  finalizeHeaders();
50  finalizeSections();
51  finalizeSymbolStringTable();
52 }
53 
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);
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 
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);
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 
92 void 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) {
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 
109  finalize();
111  if (!Buf)
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 xcoff
124 } // end namespace objcopy
125 } // end namespace llvm
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
XCOFFWriter.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Errc.h
finalize
arc branch finalize
Definition: ARCBranchFinalize.cpp:65
llvm::XCOFF::SymbolTableEntrySize
constexpr size_t SymbolTableEntrySize
Definition: XCOFF.h:37
llvm::WritableMemoryBuffer::getNewMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
Definition: MemoryBuffer.cpp:310
llvm::errc::not_enough_memory
@ not_enough_memory
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:404
llvm::objcopy::xcoff::XCOFFWriter::write
Error write()
Definition: XCOFFWriter.cpp:108
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
copy
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
Definition: README.txt:101