Bug Summary

File:build/source/llvm/lib/MC/XCOFFObjectWriter.cpp
Warning:line 1405, column 5
Value stored to 'Address' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name XCOFFObjectWriter.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/MC -I /build/source/llvm/lib/MC -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/llvm/lib/MC/XCOFFObjectWriter.cpp
1//===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===//
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// This file implements XCOFF object file writer information.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/BinaryFormat/XCOFF.h"
14#include "llvm/MC/MCAsmBackend.h"
15#include "llvm/MC/MCAsmLayout.h"
16#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCFixup.h"
18#include "llvm/MC/MCFixupKindInfo.h"
19#include "llvm/MC/MCObjectWriter.h"
20#include "llvm/MC/MCSectionXCOFF.h"
21#include "llvm/MC/MCSymbolXCOFF.h"
22#include "llvm/MC/MCValue.h"
23#include "llvm/MC/MCXCOFFObjectWriter.h"
24#include "llvm/MC/StringTableBuilder.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/EndianStream.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Support/MathExtras.h"
29
30#include <deque>
31#include <map>
32
33using namespace llvm;
34
35// An XCOFF object file has a limited set of predefined sections. The most
36// important ones for us (right now) are:
37// .text --> contains program code and read-only data.
38// .data --> contains initialized data, function descriptors, and the TOC.
39// .bss --> contains uninitialized data.
40// Each of these sections is composed of 'Control Sections'. A Control Section
41// is more commonly referred to as a csect. A csect is an indivisible unit of
42// code or data, and acts as a container for symbols. A csect is mapped
43// into a section based on its storage-mapping class, with the exception of
44// XMC_RW which gets mapped to either .data or .bss based on whether it's
45// explicitly initialized or not.
46//
47// We don't represent the sections in the MC layer as there is nothing
48// interesting about them at at that level: they carry information that is
49// only relevant to the ObjectWriter, so we materialize them in this class.
50namespace {
51
52constexpr unsigned DefaultSectionAlign = 4;
53constexpr int16_t MaxSectionIndex = INT16_MAX(32767);
54
55// Packs the csect's alignment and type into a byte.
56uint8_t getEncodedType(const MCSectionXCOFF *);
57
58struct XCOFFRelocation {
59 uint32_t SymbolTableIndex;
60 uint32_t FixupOffsetInCsect;
61 uint8_t SignAndSize;
62 uint8_t Type;
63};
64
65// Wrapper around an MCSymbolXCOFF.
66struct Symbol {
67 const MCSymbolXCOFF *const MCSym;
68 uint32_t SymbolTableIndex;
69
70 XCOFF::VisibilityType getVisibilityType() const {
71 return MCSym->getVisibilityType();
72 }
73
74 XCOFF::StorageClass getStorageClass() const {
75 return MCSym->getStorageClass();
76 }
77 StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); }
78 Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {}
79};
80
81// Wrapper for an MCSectionXCOFF.
82// It can be a Csect or debug section or DWARF section and so on.
83struct XCOFFSection {
84 const MCSectionXCOFF *const MCSec;
85 uint32_t SymbolTableIndex;
86 uint64_t Address;
87 uint64_t Size;
88
89 SmallVector<Symbol, 1> Syms;
90 SmallVector<XCOFFRelocation, 1> Relocations;
91 StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }
92 XCOFF::VisibilityType getVisibilityType() const {
93 return MCSec->getVisibilityType();
94 }
95 XCOFFSection(const MCSectionXCOFF *MCSec)
96 : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
97};
98
99// Type to be used for a container representing a set of csects with
100// (approximately) the same storage mapping class. For example all the csects
101// with a storage mapping class of `xmc_pr` will get placed into the same
102// container.
103using CsectGroup = std::deque<XCOFFSection>;
104using CsectGroups = std::deque<CsectGroup *>;
105
106// The basic section entry defination. This Section represents a section entry
107// in XCOFF section header table.
108struct SectionEntry {
109 char Name[XCOFF::NameSize];
110 // The physical/virtual address of the section. For an object file these
111 // values are equivalent, except for in the overflow section header, where
112 // the physical address specifies the number of relocation entries and the
113 // virtual address specifies the number of line number entries.
114 // TODO: Divide Address into PhysicalAddress and VirtualAddress when line
115 // number entries are supported.
116 uint64_t Address;
117 uint64_t Size;
118 uint64_t FileOffsetToData;
119 uint64_t FileOffsetToRelocations;
120 uint32_t RelocationCount;
121 int32_t Flags;
122
123 int16_t Index;
124
125 // XCOFF has special section numbers for symbols:
126 // -2 Specifies N_DEBUG, a special symbolic debugging symbol.
127 // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not
128 // relocatable.
129 // 0 Specifies N_UNDEF, an undefined external symbol.
130 // Therefore, we choose -3 (N_DEBUG - 1) to represent a section index that
131 // hasn't been initialized.
132 static constexpr int16_t UninitializedIndex =
133 XCOFF::ReservedSectionNum::N_DEBUG - 1;
134
135 SectionEntry(StringRef N, int32_t Flags)
136 : Name(), Address(0), Size(0), FileOffsetToData(0),
137 FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
138 Index(UninitializedIndex) {
139 assert(N.size() <= XCOFF::NameSize && "section name too long")(static_cast <bool> (N.size() <= XCOFF::NameSize &&
"section name too long") ? void (0) : __assert_fail ("N.size() <= XCOFF::NameSize && \"section name too long\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 139, __extension__ __PRETTY_FUNCTION__
))
;
140 memcpy(Name, N.data(), N.size());
141 }
142
143 virtual void reset() {
144 Address = 0;
145 Size = 0;
146 FileOffsetToData = 0;
147 FileOffsetToRelocations = 0;
148 RelocationCount = 0;
149 Index = UninitializedIndex;
150 }
151
152 virtual ~SectionEntry() = default;
153};
154
155// Represents the data related to a section excluding the csects that make up
156// the raw data of the section. The csects are stored separately as not all
157// sections contain csects, and some sections contain csects which are better
158// stored separately, e.g. the .data section containing read-write, descriptor,
159// TOCBase and TOC-entry csects.
160struct CsectSectionEntry : public SectionEntry {
161 // Virtual sections do not need storage allocated in the object file.
162 const bool IsVirtual;
163
164 // This is a section containing csect groups.
165 CsectGroups Groups;
166
167 CsectSectionEntry(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
168 CsectGroups Groups)
169 : SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) {
170 assert(N.size() <= XCOFF::NameSize && "section name too long")(static_cast <bool> (N.size() <= XCOFF::NameSize &&
"section name too long") ? void (0) : __assert_fail ("N.size() <= XCOFF::NameSize && \"section name too long\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 170, __extension__ __PRETTY_FUNCTION__
))
;
171 memcpy(Name, N.data(), N.size());
172 }
173
174 void reset() override {
175 SectionEntry::reset();
176 // Clear any csects we have stored.
177 for (auto *Group : Groups)
178 Group->clear();
179 }
180
181 virtual ~CsectSectionEntry() = default;
182};
183
184struct DwarfSectionEntry : public SectionEntry {
185 // For DWARF section entry.
186 std::unique_ptr<XCOFFSection> DwarfSect;
187
188 // For DWARF section, we must use real size in the section header. MemorySize
189 // is for the size the DWARF section occupies including paddings.
190 uint32_t MemorySize;
191
192 DwarfSectionEntry(StringRef N, int32_t Flags,
193 std::unique_ptr<XCOFFSection> Sect)
194 : SectionEntry(N, Flags | XCOFF::STYP_DWARF), DwarfSect(std::move(Sect)),
195 MemorySize(0) {
196 assert(DwarfSect->MCSec->isDwarfSect() &&(static_cast <bool> (DwarfSect->MCSec->isDwarfSect
() && "This should be a DWARF section!") ? void (0) :
__assert_fail ("DwarfSect->MCSec->isDwarfSect() && \"This should be a DWARF section!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 197, __extension__ __PRETTY_FUNCTION__
))
197 "This should be a DWARF section!")(static_cast <bool> (DwarfSect->MCSec->isDwarfSect
() && "This should be a DWARF section!") ? void (0) :
__assert_fail ("DwarfSect->MCSec->isDwarfSect() && \"This should be a DWARF section!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 197, __extension__ __PRETTY_FUNCTION__
))
;
198 assert(N.size() <= XCOFF::NameSize && "section name too long")(static_cast <bool> (N.size() <= XCOFF::NameSize &&
"section name too long") ? void (0) : __assert_fail ("N.size() <= XCOFF::NameSize && \"section name too long\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 198, __extension__ __PRETTY_FUNCTION__
))
;
199 memcpy(Name, N.data(), N.size());
200 }
201
202 DwarfSectionEntry(DwarfSectionEntry &&s) = default;
203
204 virtual ~DwarfSectionEntry() = default;
205};
206
207struct ExceptionTableEntry {
208 const MCSymbol *Trap;
209 uint64_t TrapAddress = ~0ul;
210 unsigned Lang;
211 unsigned Reason;
212
213 ExceptionTableEntry(const MCSymbol *Trap, unsigned Lang, unsigned Reason)
214 : Trap(Trap), Lang(Lang), Reason(Reason) {}
215};
216
217struct ExceptionInfo {
218 const MCSymbol *FunctionSymbol;
219 unsigned FunctionSize;
220 std::vector<ExceptionTableEntry> Entries;
221};
222
223struct ExceptionSectionEntry : public SectionEntry {
224 std::map<const StringRef, ExceptionInfo> ExceptionTable;
225 bool isDebugEnabled = false;
226
227 ExceptionSectionEntry(StringRef N, int32_t Flags)
228 : SectionEntry(N, Flags | XCOFF::STYP_EXCEPT) {
229 assert(N.size() <= XCOFF::NameSize && "Section too long.")(static_cast <bool> (N.size() <= XCOFF::NameSize &&
"Section too long.") ? void (0) : __assert_fail ("N.size() <= XCOFF::NameSize && \"Section too long.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 229, __extension__ __PRETTY_FUNCTION__
))
;
230 memcpy(Name, N.data(), N.size());
231 }
232
233 virtual ~ExceptionSectionEntry() = default;
234};
235
236class XCOFFObjectWriter : public MCObjectWriter {
237
238 uint32_t SymbolTableEntryCount = 0;
239 uint64_t SymbolTableOffset = 0;
240 uint16_t SectionCount = 0;
241 uint32_t PaddingsBeforeDwarf = 0;
242 std::vector<std::pair<std::string, size_t>> FileNames;
243 bool HasVisibility = false;
244
245 support::endian::Writer W;
246 std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
247 StringTableBuilder Strings;
248
249 const uint64_t MaxRawDataSize =
250 TargetObjectWriter->is64Bit() ? UINT64_MAX(18446744073709551615UL) : UINT32_MAX(4294967295U);
251
252 // Maps the MCSection representation to its corresponding XCOFFSection
253 // wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into
254 // from its containing MCSectionXCOFF.
255 DenseMap<const MCSectionXCOFF *, XCOFFSection *> SectionMap;
256
257 // Maps the MCSymbol representation to its corrresponding symbol table index.
258 // Needed for relocation.
259 DenseMap<const MCSymbol *, uint32_t> SymbolIndexMap;
260
261 // CsectGroups. These store the csects which make up different parts of
262 // the sections. Should have one for each set of csects that get mapped into
263 // the same section and get handled in a 'similar' way.
264 CsectGroup UndefinedCsects;
265 CsectGroup ProgramCodeCsects;
266 CsectGroup ReadOnlyCsects;
267 CsectGroup DataCsects;
268 CsectGroup FuncDSCsects;
269 CsectGroup TOCCsects;
270 CsectGroup BSSCsects;
271 CsectGroup TDataCsects;
272 CsectGroup TBSSCsects;
273
274 // The Predefined sections.
275 CsectSectionEntry Text;
276 CsectSectionEntry Data;
277 CsectSectionEntry BSS;
278 CsectSectionEntry TData;
279 CsectSectionEntry TBSS;
280
281 // All the XCOFF sections, in the order they will appear in the section header
282 // table.
283 std::array<CsectSectionEntry *const, 5> Sections{
284 {&Text, &Data, &BSS, &TData, &TBSS}};
285
286 std::vector<DwarfSectionEntry> DwarfSections;
287 std::vector<SectionEntry> OverflowSections;
288
289 ExceptionSectionEntry ExceptionSection;
290
291 CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec);
292
293 void reset() override;
294
295 void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override;
296
297 void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *,
298 const MCFixup &, MCValue, uint64_t &) override;
299
300 uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override;
301
302 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
303 bool nameShouldBeInStringTable(const StringRef &);
304 void writeSymbolName(const StringRef &);
305
306 void writeSymbolEntryForCsectMemberLabel(const Symbol &SymbolRef,
307 const XCOFFSection &CSectionRef,
308 int16_t SectionIndex,
309 uint64_t SymbolOffset);
310 void writeSymbolEntryForControlSection(const XCOFFSection &CSectionRef,
311 int16_t SectionIndex,
312 XCOFF::StorageClass StorageClass);
313 void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,
314 int16_t SectionIndex);
315 void writeFileHeader();
316 void writeAuxFileHeader();
317 void writeSectionHeader(const SectionEntry *Sec);
318 void writeSectionHeaderTable();
319 void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
320 void writeSectionForControlSectionEntry(const MCAssembler &Asm,
321 const MCAsmLayout &Layout,
322 const CsectSectionEntry &CsectEntry,
323 uint64_t &CurrentAddressLocation);
324 void writeSectionForDwarfSectionEntry(const MCAssembler &Asm,
325 const MCAsmLayout &Layout,
326 const DwarfSectionEntry &DwarfEntry,
327 uint64_t &CurrentAddressLocation);
328 void writeSectionForExceptionSectionEntry(
329 const MCAssembler &Asm, const MCAsmLayout &Layout,
330 ExceptionSectionEntry &ExceptionEntry, uint64_t &CurrentAddressLocation);
331 void writeSymbolTable(const MCAsmLayout &Layout);
332 void writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,
333 uint64_t NumberOfRelocEnt = 0);
334 void writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
335 uint8_t SymbolAlignmentAndType,
336 uint8_t StorageMappingClass);
337 void writeSymbolAuxFunctionEntry(uint32_t EntryOffset, uint32_t FunctionSize,
338 uint64_t LineNumberPointer,
339 uint32_t EndIndex);
340 void writeSymbolAuxExceptionEntry(uint64_t EntryOffset, uint32_t FunctionSize,
341 uint32_t EndIndex);
342 void writeSymbolEntry(StringRef SymbolName, uint64_t Value,
343 int16_t SectionNumber, uint16_t SymbolType,
344 uint8_t StorageClass, uint8_t NumberOfAuxEntries = 1);
345 void writeRelocations();
346 void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &Section);
347
348 // Called after all the csects and symbols have been processed by
349 // `executePostLayoutBinding`, this function handles building up the majority
350 // of the structures in the object file representation. Namely:
351 // *) Calculates physical/virtual addresses, raw-pointer offsets, and section
352 // sizes.
353 // *) Assigns symbol table indices.
354 // *) Builds up the section header table by adding any non-empty sections to
355 // `Sections`.
356 void assignAddressesAndIndices(const MCAsmLayout &);
357 // Called after relocations are recorded.
358 void finalizeSectionInfo();
359 void finalizeRelocationInfo(SectionEntry *Sec, uint64_t RelCount);
360 void calcOffsetToRelocations(SectionEntry *Sec, uint64_t &RawPointer);
361
362 void addExceptionEntry(const MCSymbol *Symbol, const MCSymbol *Trap,
363 unsigned LanguageCode, unsigned ReasonCode,
364 unsigned FunctionSize, bool hasDebug) override;
365 bool hasExceptionSection() {
366 return !ExceptionSection.ExceptionTable.empty();
367 }
368 unsigned getExceptionSectionSize();
369 unsigned getExceptionOffset(const MCSymbol *Symbol);
370
371 size_t auxiliaryHeaderSize() const {
372 // 64-bit object files have no auxiliary header.
373 return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0;
374 }
375
376public:
377 XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
378 raw_pwrite_stream &OS);
379
380 void writeWord(uint64_t Word) {
381 is64Bit() ? W.write<uint64_t>(Word) : W.write<uint32_t>(Word);
382 }
383};
384
385XCOFFObjectWriter::XCOFFObjectWriter(
386 std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
387 : W(OS, support::big), TargetObjectWriter(std::move(MOTW)),
388 Strings(StringTableBuilder::XCOFF),
389 Text(".text", XCOFF::STYP_TEXT, /* IsVirtual */ false,
390 CsectGroups{&ProgramCodeCsects, &ReadOnlyCsects}),
391 Data(".data", XCOFF::STYP_DATA, /* IsVirtual */ false,
392 CsectGroups{&DataCsects, &FuncDSCsects, &TOCCsects}),
393 BSS(".bss", XCOFF::STYP_BSS, /* IsVirtual */ true,
394 CsectGroups{&BSSCsects}),
395 TData(".tdata", XCOFF::STYP_TDATA, /* IsVirtual */ false,
396 CsectGroups{&TDataCsects}),
397 TBSS(".tbss", XCOFF::STYP_TBSS, /* IsVirtual */ true,
398 CsectGroups{&TBSSCsects}),
399 ExceptionSection(".except", XCOFF::STYP_EXCEPT) {}
400
401void XCOFFObjectWriter::reset() {
402 // Clear the mappings we created.
403 SymbolIndexMap.clear();
404 SectionMap.clear();
405
406 UndefinedCsects.clear();
407 // Reset any sections we have written to, and empty the section header table.
408 for (auto *Sec : Sections)
409 Sec->reset();
410 for (auto &DwarfSec : DwarfSections)
411 DwarfSec.reset();
412 for (auto &OverflowSec : OverflowSections)
413 OverflowSec.reset();
414 ExceptionSection.reset();
415
416 // Reset states in XCOFFObjectWriter.
417 SymbolTableEntryCount = 0;
418 SymbolTableOffset = 0;
419 SectionCount = 0;
420 PaddingsBeforeDwarf = 0;
421 Strings.clear();
422
423 MCObjectWriter::reset();
424}
425
426CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
427 switch (MCSec->getMappingClass()) {
428 case XCOFF::XMC_PR:
429 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain program code."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain program code.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 430, __extension__ __PRETTY_FUNCTION__
))
430 "Only an initialized csect can contain program code.")(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain program code."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain program code.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 430, __extension__ __PRETTY_FUNCTION__
))
;
431 return ProgramCodeCsects;
432 case XCOFF::XMC_RO:
433 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain read only data."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain read only data.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 434, __extension__ __PRETTY_FUNCTION__
))
434 "Only an initialized csect can contain read only data.")(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain read only data."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain read only data.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 434, __extension__ __PRETTY_FUNCTION__
))
;
435 return ReadOnlyCsects;
436 case XCOFF::XMC_RW:
437 if (XCOFF::XTY_CM == MCSec->getCSectType())
438 return BSSCsects;
439
440 if (XCOFF::XTY_SD == MCSec->getCSectType())
441 return DataCsects;
442
443 report_fatal_error("Unhandled mapping of read-write csect to section.");
444 case XCOFF::XMC_DS:
445 return FuncDSCsects;
446 case XCOFF::XMC_BS:
447 assert(XCOFF::XTY_CM == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with bss storage class must be "
"common type.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with bss storage class must be \" \"common type.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 449, __extension__ __PRETTY_FUNCTION__
))
448 "Mapping invalid csect. CSECT with bss storage class must be "(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with bss storage class must be "
"common type.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with bss storage class must be \" \"common type.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 449, __extension__ __PRETTY_FUNCTION__
))
449 "common type.")(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with bss storage class must be "
"common type.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with bss storage class must be \" \"common type.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 449, __extension__ __PRETTY_FUNCTION__
))
;
450 return BSSCsects;
451 case XCOFF::XMC_TL:
452 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tdata storage class must be "
"an initialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tdata storage class must be \" \"an initialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 454, __extension__ __PRETTY_FUNCTION__
))
453 "Mapping invalid csect. CSECT with tdata storage class must be "(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tdata storage class must be "
"an initialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tdata storage class must be \" \"an initialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 454, __extension__ __PRETTY_FUNCTION__
))
454 "an initialized csect.")(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tdata storage class must be "
"an initialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tdata storage class must be \" \"an initialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 454, __extension__ __PRETTY_FUNCTION__
))
;
455 return TDataCsects;
456 case XCOFF::XMC_UL:
457 assert(XCOFF::XTY_CM == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tbss storage class must be "
"an uninitialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tbss storage class must be \" \"an uninitialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 459, __extension__ __PRETTY_FUNCTION__
))
458 "Mapping invalid csect. CSECT with tbss storage class must be "(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tbss storage class must be "
"an uninitialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tbss storage class must be \" \"an uninitialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 459, __extension__ __PRETTY_FUNCTION__
))
459 "an uninitialized csect.")(static_cast <bool> (XCOFF::XTY_CM == MCSec->getCSectType
() && "Mapping invalid csect. CSECT with tbss storage class must be "
"an uninitialized csect.") ? void (0) : __assert_fail ("XCOFF::XTY_CM == MCSec->getCSectType() && \"Mapping invalid csect. CSECT with tbss storage class must be \" \"an uninitialized csect.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 459, __extension__ __PRETTY_FUNCTION__
))
;
460 return TBSSCsects;
461 case XCOFF::XMC_TC0:
462 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain TOC-base."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain TOC-base.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 463, __extension__ __PRETTY_FUNCTION__
))
463 "Only an initialized csect can contain TOC-base.")(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain TOC-base."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain TOC-base.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 463, __extension__ __PRETTY_FUNCTION__
))
;
464 assert(TOCCsects.empty() &&(static_cast <bool> (TOCCsects.empty() && "We should have only one TOC-base, and it should be the first csect "
"in this CsectGroup.") ? void (0) : __assert_fail ("TOCCsects.empty() && \"We should have only one TOC-base, and it should be the first csect \" \"in this CsectGroup.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 466, __extension__ __PRETTY_FUNCTION__
))
465 "We should have only one TOC-base, and it should be the first csect "(static_cast <bool> (TOCCsects.empty() && "We should have only one TOC-base, and it should be the first csect "
"in this CsectGroup.") ? void (0) : __assert_fail ("TOCCsects.empty() && \"We should have only one TOC-base, and it should be the first csect \" \"in this CsectGroup.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 466, __extension__ __PRETTY_FUNCTION__
))
466 "in this CsectGroup.")(static_cast <bool> (TOCCsects.empty() && "We should have only one TOC-base, and it should be the first csect "
"in this CsectGroup.") ? void (0) : __assert_fail ("TOCCsects.empty() && \"We should have only one TOC-base, and it should be the first csect \" \"in this CsectGroup.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 466, __extension__ __PRETTY_FUNCTION__
))
;
467 return TOCCsects;
468 case XCOFF::XMC_TC:
469 case XCOFF::XMC_TE:
470 case XCOFF::XMC_TD:
471 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain TC entry."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain TC entry.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 472, __extension__ __PRETTY_FUNCTION__
))
472 "Only an initialized csect can contain TC entry.")(static_cast <bool> (XCOFF::XTY_SD == MCSec->getCSectType
() && "Only an initialized csect can contain TC entry."
) ? void (0) : __assert_fail ("XCOFF::XTY_SD == MCSec->getCSectType() && \"Only an initialized csect can contain TC entry.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 472, __extension__ __PRETTY_FUNCTION__
))
;
473 assert(!TOCCsects.empty() &&(static_cast <bool> (!TOCCsects.empty() && "We should at least have a TOC-base in this CsectGroup."
) ? void (0) : __assert_fail ("!TOCCsects.empty() && \"We should at least have a TOC-base in this CsectGroup.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 474, __extension__ __PRETTY_FUNCTION__
))
474 "We should at least have a TOC-base in this CsectGroup.")(static_cast <bool> (!TOCCsects.empty() && "We should at least have a TOC-base in this CsectGroup."
) ? void (0) : __assert_fail ("!TOCCsects.empty() && \"We should at least have a TOC-base in this CsectGroup.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 474, __extension__ __PRETTY_FUNCTION__
))
;
475 return TOCCsects;
476 default:
477 report_fatal_error("Unhandled mapping of csect to section.");
478 }
479}
480
481static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {
482 if (XSym->isDefined())
483 return cast<MCSectionXCOFF>(XSym->getFragment()->getParent());
484 return XSym->getRepresentedCsect();
485}
486
487void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
488 const MCAsmLayout &Layout) {
489 for (const auto &S : Asm) {
490 const auto *MCSec = cast<const MCSectionXCOFF>(&S);
491 assert(!SectionMap.contains(MCSec) && "Cannot add a section twice.")(static_cast <bool> (!SectionMap.contains(MCSec) &&
"Cannot add a section twice.") ? void (0) : __assert_fail ("!SectionMap.contains(MCSec) && \"Cannot add a section twice.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 491, __extension__ __PRETTY_FUNCTION__
))
;
492
493 // If the name does not fit in the storage provided in the symbol table
494 // entry, add it to the string table.
495 if (nameShouldBeInStringTable(MCSec->getSymbolTableName()))
496 Strings.add(MCSec->getSymbolTableName());
497 if (MCSec->isCsect()) {
498 // A new control section. Its CsectSectionEntry should already be staticly
499 // generated as Text/Data/BSS/TDATA/TBSS. Add this section to the group of
500 // the CsectSectionEntry.
501 assert(XCOFF::XTY_ER != MCSec->getCSectType() &&(static_cast <bool> (XCOFF::XTY_ER != MCSec->getCSectType
() && "An undefined csect should not get registered."
) ? void (0) : __assert_fail ("XCOFF::XTY_ER != MCSec->getCSectType() && \"An undefined csect should not get registered.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 502, __extension__ __PRETTY_FUNCTION__
))
502 "An undefined csect should not get registered.")(static_cast <bool> (XCOFF::XTY_ER != MCSec->getCSectType
() && "An undefined csect should not get registered."
) ? void (0) : __assert_fail ("XCOFF::XTY_ER != MCSec->getCSectType() && \"An undefined csect should not get registered.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 502, __extension__ __PRETTY_FUNCTION__
))
;
503 CsectGroup &Group = getCsectGroup(MCSec);
504 Group.emplace_back(MCSec);
505 SectionMap[MCSec] = &Group.back();
506 } else if (MCSec->isDwarfSect()) {
507 // A new DwarfSectionEntry.
508 std::unique_ptr<XCOFFSection> DwarfSec =
509 std::make_unique<XCOFFSection>(MCSec);
510 SectionMap[MCSec] = DwarfSec.get();
511
512 DwarfSectionEntry SecEntry(MCSec->getName(),
513 *MCSec->getDwarfSubtypeFlags(),
514 std::move(DwarfSec));
515 DwarfSections.push_back(std::move(SecEntry));
516 } else
517 llvm_unreachable("unsupport section type!")::llvm::llvm_unreachable_internal("unsupport section type!", "llvm/lib/MC/XCOFFObjectWriter.cpp"
, 517)
;
518 }
519
520 for (const MCSymbol &S : Asm.symbols()) {
521 // Nothing to do for temporary symbols.
522 if (S.isTemporary())
523 continue;
524
525 const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(&S);
526 const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym);
527
528 if (XSym->getVisibilityType() != XCOFF::SYM_V_UNSPECIFIED)
529 HasVisibility = true;
530
531 if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) {
532 // Handle undefined symbol.
533 UndefinedCsects.emplace_back(ContainingCsect);
534 SectionMap[ContainingCsect] = &UndefinedCsects.back();
535 if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName()))
536 Strings.add(ContainingCsect->getSymbolTableName());
537 continue;
538 }
539
540 // If the symbol is the csect itself, we don't need to put the symbol
541 // into csect's Syms.
542 if (XSym == ContainingCsect->getQualNameSymbol())
543 continue;
544
545 // Only put a label into the symbol table when it is an external label.
546 if (!XSym->isExternal())
547 continue;
548
549 assert(SectionMap.contains(ContainingCsect) &&(static_cast <bool> (SectionMap.contains(ContainingCsect
) && "Expected containing csect to exist in map") ? void
(0) : __assert_fail ("SectionMap.contains(ContainingCsect) && \"Expected containing csect to exist in map\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 550, __extension__ __PRETTY_FUNCTION__
))
550 "Expected containing csect to exist in map")(static_cast <bool> (SectionMap.contains(ContainingCsect
) && "Expected containing csect to exist in map") ? void
(0) : __assert_fail ("SectionMap.contains(ContainingCsect) && \"Expected containing csect to exist in map\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 550, __extension__ __PRETTY_FUNCTION__
))
;
551 XCOFFSection *Csect = SectionMap[ContainingCsect];
552 // Lookup the containing csect and add the symbol to it.
553 assert(Csect->MCSec->isCsect() && "only csect is supported now!")(static_cast <bool> (Csect->MCSec->isCsect() &&
"only csect is supported now!") ? void (0) : __assert_fail (
"Csect->MCSec->isCsect() && \"only csect is supported now!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 553, __extension__ __PRETTY_FUNCTION__
))
;
554 Csect->Syms.emplace_back(XSym);
555
556 // If the name does not fit in the storage provided in the symbol table
557 // entry, add it to the string table.
558 if (nameShouldBeInStringTable(XSym->getSymbolTableName()))
559 Strings.add(XSym->getSymbolTableName());
560 }
561
562 FileNames = Asm.getFileNames();
563 // Emit ".file" as the source file name when there is no file name.
564 if (FileNames.empty())
565 FileNames.emplace_back(".file", 0);
566 for (const std::pair<std::string, size_t> &F : FileNames) {
567 if (nameShouldBeInStringTable(F.first))
568 Strings.add(F.first);
569 }
570
571 Strings.finalize();
572 assignAddressesAndIndices(Layout);
573}
574
575void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
576 const MCAsmLayout &Layout,
577 const MCFragment *Fragment,
578 const MCFixup &Fixup, MCValue Target,
579 uint64_t &FixedValue) {
580 auto getIndex = [this](const MCSymbol *Sym,
581 const MCSectionXCOFF *ContainingCsect) {
582 // If we could not find the symbol directly in SymbolIndexMap, this symbol
583 // could either be a temporary symbol or an undefined symbol. In this case,
584 // we would need to have the relocation reference its csect instead.
585 return SymbolIndexMap.contains(Sym)
586 ? SymbolIndexMap[Sym]
587 : SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
588 };
589
590 auto getVirtualAddress =
591 [this, &Layout](const MCSymbol *Sym,
592 const MCSectionXCOFF *ContainingSect) -> uint64_t {
593 // A DWARF section.
594 if (ContainingSect->isDwarfSect())
595 return Layout.getSymbolOffset(*Sym);
596
597 // A csect.
598 if (!Sym->isDefined())
599 return SectionMap[ContainingSect]->Address;
600
601 // A label.
602 assert(Sym->isDefined() && "not a valid object that has address!")(static_cast <bool> (Sym->isDefined() && "not a valid object that has address!"
) ? void (0) : __assert_fail ("Sym->isDefined() && \"not a valid object that has address!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 602, __extension__ __PRETTY_FUNCTION__
))
;
603 return SectionMap[ContainingSect]->Address + Layout.getSymbolOffset(*Sym);
604 };
605
606 const MCSymbol *const SymA = &Target.getSymA()->getSymbol();
607
608 MCAsmBackend &Backend = Asm.getBackend();
609 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
610 MCFixupKindInfo::FKF_IsPCRel;
611
612 uint8_t Type;
613 uint8_t SignAndSize;
614 std::tie(Type, SignAndSize) =
615 TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
616
617 const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
618 assert(SectionMap.contains(SymASec) &&(static_cast <bool> (SectionMap.contains(SymASec) &&
"Expected containing csect to exist in map.") ? void (0) : __assert_fail
("SectionMap.contains(SymASec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 619, __extension__ __PRETTY_FUNCTION__
))
619 "Expected containing csect to exist in map.")(static_cast <bool> (SectionMap.contains(SymASec) &&
"Expected containing csect to exist in map.") ? void (0) : __assert_fail
("SectionMap.contains(SymASec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 619, __extension__ __PRETTY_FUNCTION__
))
;
620
621 const uint32_t Index = getIndex(SymA, SymASec);
622 if (Type == XCOFF::RelocationType::R_POS ||
623 Type == XCOFF::RelocationType::R_TLS)
624 // The FixedValue should be symbol's virtual address in this object file
625 // plus any constant value that we might get.
626 FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
627 else if (Type == XCOFF::RelocationType::R_TLSM)
628 // The FixedValue should always be zero since the region handle is only
629 // known at load time.
630 FixedValue = 0;
631 else if (Type == XCOFF::RelocationType::R_TOC ||
632 Type == XCOFF::RelocationType::R_TOCL) {
633 // For non toc-data external symbols, R_TOC type relocation will relocate to
634 // data symbols that have XCOFF::XTY_SD type csect. For toc-data external
635 // symbols, R_TOC type relocation will relocate to data symbols that have
636 // XCOFF_ER type csect. For XCOFF_ER kind symbols, there will be no TOC
637 // entry for them, so the FixedValue should always be 0.
638 if (SymASec->getCSectType() == XCOFF::XTY_ER) {
639 FixedValue = 0;
640 } else {
641 // The FixedValue should be the TOC entry offset from the TOC-base plus
642 // any constant offset value.
643 const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
644 TOCCsects.front().Address +
645 Target.getConstant();
646 if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
647 report_fatal_error("TOCEntryOffset overflows in small code model mode");
648
649 FixedValue = TOCEntryOffset;
650 }
651 } else if (Type == XCOFF::RelocationType::R_RBR) {
652 MCSectionXCOFF *ParentSec = cast<MCSectionXCOFF>(Fragment->getParent());
653 assert((SymASec->getMappingClass() == XCOFF::XMC_PR &&(static_cast <bool> ((SymASec->getMappingClass() == XCOFF
::XMC_PR && ParentSec->getMappingClass() == XCOFF::
XMC_PR) && "Only XMC_PR csect may have the R_RBR relocation."
) ? void (0) : __assert_fail ("(SymASec->getMappingClass() == XCOFF::XMC_PR && ParentSec->getMappingClass() == XCOFF::XMC_PR) && \"Only XMC_PR csect may have the R_RBR relocation.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 655, __extension__ __PRETTY_FUNCTION__
))
654 ParentSec->getMappingClass() == XCOFF::XMC_PR) &&(static_cast <bool> ((SymASec->getMappingClass() == XCOFF
::XMC_PR && ParentSec->getMappingClass() == XCOFF::
XMC_PR) && "Only XMC_PR csect may have the R_RBR relocation."
) ? void (0) : __assert_fail ("(SymASec->getMappingClass() == XCOFF::XMC_PR && ParentSec->getMappingClass() == XCOFF::XMC_PR) && \"Only XMC_PR csect may have the R_RBR relocation.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 655, __extension__ __PRETTY_FUNCTION__
))
655 "Only XMC_PR csect may have the R_RBR relocation.")(static_cast <bool> ((SymASec->getMappingClass() == XCOFF
::XMC_PR && ParentSec->getMappingClass() == XCOFF::
XMC_PR) && "Only XMC_PR csect may have the R_RBR relocation."
) ? void (0) : __assert_fail ("(SymASec->getMappingClass() == XCOFF::XMC_PR && ParentSec->getMappingClass() == XCOFF::XMC_PR) && \"Only XMC_PR csect may have the R_RBR relocation.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 655, __extension__ __PRETTY_FUNCTION__
))
;
656
657 // The address of the branch instruction should be the sum of section
658 // address, fragment offset and Fixup offset.
659 uint64_t BRInstrAddress = SectionMap[ParentSec]->Address +
660 Layout.getFragmentOffset(Fragment) +
661 Fixup.getOffset();
662 // The FixedValue should be the difference between SymA csect address and BR
663 // instr address plus any constant value.
664 FixedValue =
665 SectionMap[SymASec]->Address - BRInstrAddress + Target.getConstant();
666 } else if (Type == XCOFF::RelocationType::R_REF)
667 // The FixedValue should always be 0 since it specifies a nonrelocating
668 // reference.
669 FixedValue = 0;
670
671 assert((Fixup.getOffset() <=(static_cast <bool> ((Fixup.getOffset() <= MaxRawDataSize
- Layout.getFragmentOffset(Fragment)) && "Fragment offset + fixup offset is overflowed."
) ? void (0) : __assert_fail ("(Fixup.getOffset() <= MaxRawDataSize - Layout.getFragmentOffset(Fragment)) && \"Fragment offset + fixup offset is overflowed.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 673, __extension__ __PRETTY_FUNCTION__
))
672 MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&(static_cast <bool> ((Fixup.getOffset() <= MaxRawDataSize
- Layout.getFragmentOffset(Fragment)) && "Fragment offset + fixup offset is overflowed."
) ? void (0) : __assert_fail ("(Fixup.getOffset() <= MaxRawDataSize - Layout.getFragmentOffset(Fragment)) && \"Fragment offset + fixup offset is overflowed.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 673, __extension__ __PRETTY_FUNCTION__
))
673 "Fragment offset + fixup offset is overflowed.")(static_cast <bool> ((Fixup.getOffset() <= MaxRawDataSize
- Layout.getFragmentOffset(Fragment)) && "Fragment offset + fixup offset is overflowed."
) ? void (0) : __assert_fail ("(Fixup.getOffset() <= MaxRawDataSize - Layout.getFragmentOffset(Fragment)) && \"Fragment offset + fixup offset is overflowed.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 673, __extension__ __PRETTY_FUNCTION__
))
;
674 uint32_t FixupOffsetInCsect =
675 Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
676
677 XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type};
678 MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent());
679 assert(SectionMap.contains(RelocationSec) &&(static_cast <bool> (SectionMap.contains(RelocationSec)
&& "Expected containing csect to exist in map.") ? void
(0) : __assert_fail ("SectionMap.contains(RelocationSec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 680, __extension__ __PRETTY_FUNCTION__
))
680 "Expected containing csect to exist in map.")(static_cast <bool> (SectionMap.contains(RelocationSec)
&& "Expected containing csect to exist in map.") ? void
(0) : __assert_fail ("SectionMap.contains(RelocationSec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 680, __extension__ __PRETTY_FUNCTION__
))
;
681 SectionMap[RelocationSec]->Relocations.push_back(Reloc);
682
683 if (!Target.getSymB())
684 return;
685
686 const MCSymbol *const SymB = &Target.getSymB()->getSymbol();
687 if (SymA == SymB)
688 report_fatal_error("relocation for opposite term is not yet supported");
689
690 const MCSectionXCOFF *SymBSec = getContainingCsect(cast<MCSymbolXCOFF>(SymB));
691 assert(SectionMap.contains(SymBSec) &&(static_cast <bool> (SectionMap.contains(SymBSec) &&
"Expected containing csect to exist in map.") ? void (0) : __assert_fail
("SectionMap.contains(SymBSec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 692, __extension__ __PRETTY_FUNCTION__
))
692 "Expected containing csect to exist in map.")(static_cast <bool> (SectionMap.contains(SymBSec) &&
"Expected containing csect to exist in map.") ? void (0) : __assert_fail
("SectionMap.contains(SymBSec) && \"Expected containing csect to exist in map.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 692, __extension__ __PRETTY_FUNCTION__
))
;
693 if (SymASec == SymBSec)
694 report_fatal_error(
695 "relocation for paired relocatable term is not yet supported");
696
697 assert(Type == XCOFF::RelocationType::R_POS &&(static_cast <bool> (Type == XCOFF::RelocationType::R_POS
&& "SymA must be R_POS here if it's not opposite term or paired "
"relocatable term.") ? void (0) : __assert_fail ("Type == XCOFF::RelocationType::R_POS && \"SymA must be R_POS here if it's not opposite term or paired \" \"relocatable term.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 699, __extension__ __PRETTY_FUNCTION__
))
698 "SymA must be R_POS here if it's not opposite term or paired "(static_cast <bool> (Type == XCOFF::RelocationType::R_POS
&& "SymA must be R_POS here if it's not opposite term or paired "
"relocatable term.") ? void (0) : __assert_fail ("Type == XCOFF::RelocationType::R_POS && \"SymA must be R_POS here if it's not opposite term or paired \" \"relocatable term.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 699, __extension__ __PRETTY_FUNCTION__
))
699 "relocatable term.")(static_cast <bool> (Type == XCOFF::RelocationType::R_POS
&& "SymA must be R_POS here if it's not opposite term or paired "
"relocatable term.") ? void (0) : __assert_fail ("Type == XCOFF::RelocationType::R_POS && \"SymA must be R_POS here if it's not opposite term or paired \" \"relocatable term.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 699, __extension__ __PRETTY_FUNCTION__
))
;
700 const uint32_t IndexB = getIndex(SymB, SymBSec);
701 // SymB must be R_NEG here, given the general form of Target(MCValue) is
702 // "SymbolA - SymbolB + imm64".
703 const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
704 XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
705 SectionMap[RelocationSec]->Relocations.push_back(RelocB);
706 // We already folded "SymbolA + imm64" above when Type is R_POS for SymbolA,
707 // now we just need to fold "- SymbolB" here.
708 FixedValue -= getVirtualAddress(SymB, SymBSec);
709}
710
711void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
712 const MCAsmLayout &Layout) {
713 uint64_t CurrentAddressLocation = 0;
714 for (const auto *Section : Sections)
715 writeSectionForControlSectionEntry(Asm, Layout, *Section,
716 CurrentAddressLocation);
717 for (const auto &DwarfSection : DwarfSections)
718 writeSectionForDwarfSectionEntry(Asm, Layout, DwarfSection,
719 CurrentAddressLocation);
720 writeSectionForExceptionSectionEntry(Asm, Layout, ExceptionSection,
721 CurrentAddressLocation);
722}
723
724uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
725 const MCAsmLayout &Layout) {
726 // We always emit a timestamp of 0 for reproducibility, so ensure incremental
727 // linking is not enabled, in case, like with Windows COFF, such a timestamp
728 // is incompatible with incremental linking of XCOFF.
729 if (Asm.isIncrementalLinkerCompatible())
730 report_fatal_error("Incremental linking not supported for XCOFF.");
731
732 finalizeSectionInfo();
733 uint64_t StartOffset = W.OS.tell();
734
735 writeFileHeader();
736 writeAuxFileHeader();
737 writeSectionHeaderTable();
738 writeSections(Asm, Layout);
739 writeRelocations();
740 writeSymbolTable(Layout);
741 // Write the string table.
742 Strings.write(W.OS);
743
744 return W.OS.tell() - StartOffset;
745}
746
747bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
748 return SymbolName.size() > XCOFF::NameSize || is64Bit();
749}
750
751void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
752 // Magic, Offset or SymbolName.
753 if (nameShouldBeInStringTable(SymbolName)) {
754 W.write<int32_t>(0);
755 W.write<uint32_t>(Strings.getOffset(SymbolName));
756 } else {
757 char Name[XCOFF::NameSize + 1];
758 std::strncpy(Name, SymbolName.data(), XCOFF::NameSize);
759 ArrayRef<char> NameRef(Name, XCOFF::NameSize);
760 W.write(NameRef);
761 }
762}
763
764void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
765 int16_t SectionNumber,
766 uint16_t SymbolType,
767 uint8_t StorageClass,
768 uint8_t NumberOfAuxEntries) {
769 if (is64Bit()) {
770 W.write<uint64_t>(Value);
771 W.write<uint32_t>(Strings.getOffset(SymbolName));
772 } else {
773 writeSymbolName(SymbolName);
774 W.write<uint32_t>(Value);
775 }
776 W.write<int16_t>(SectionNumber);
777 W.write<uint16_t>(SymbolType);
778 W.write<uint8_t>(StorageClass);
779 W.write<uint8_t>(NumberOfAuxEntries);
780}
781
782void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
783 uint8_t SymbolAlignmentAndType,
784 uint8_t StorageMappingClass) {
785 W.write<uint32_t>(is64Bit() ? Lo_32(SectionOrLength) : SectionOrLength);
786 W.write<uint32_t>(0); // ParameterHashIndex
787 W.write<uint16_t>(0); // TypeChkSectNum
788 W.write<uint8_t>(SymbolAlignmentAndType);
789 W.write<uint8_t>(StorageMappingClass);
790 if (is64Bit()) {
791 W.write<uint32_t>(Hi_32(SectionOrLength));
792 W.OS.write_zeros(1); // Reserved
793 W.write<uint8_t>(XCOFF::AUX_CSECT);
794 } else {
795 W.write<uint32_t>(0); // StabInfoIndex
796 W.write<uint16_t>(0); // StabSectNum
797 }
798}
799
800void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
801 uint64_t LengthOfSectionPortion, uint64_t NumberOfRelocEnt) {
802 writeWord(LengthOfSectionPortion);
803 if (!is64Bit())
804 W.OS.write_zeros(4); // Reserved
805 writeWord(NumberOfRelocEnt);
806 if (is64Bit()) {
807 W.OS.write_zeros(1); // Reserved
808 W.write<uint8_t>(XCOFF::AUX_SECT);
809 } else {
810 W.OS.write_zeros(6); // Reserved
811 }
812}
813
814void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
815 const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
816 int16_t SectionIndex, uint64_t SymbolOffset) {
817 assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&(static_cast <bool> (SymbolOffset <= MaxRawDataSize -
CSectionRef.Address && "Symbol address overflowed.")
? void (0) : __assert_fail ("SymbolOffset <= MaxRawDataSize - CSectionRef.Address && \"Symbol address overflowed.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 818, __extension__ __PRETTY_FUNCTION__
))
818 "Symbol address overflowed.")(static_cast <bool> (SymbolOffset <= MaxRawDataSize -
CSectionRef.Address && "Symbol address overflowed.")
? void (0) : __assert_fail ("SymbolOffset <= MaxRawDataSize - CSectionRef.Address && \"Symbol address overflowed.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 818, __extension__ __PRETTY_FUNCTION__
))
;
819
820 auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName());
821 if (Entry != ExceptionSection.ExceptionTable.end()) {
822 writeSymbolEntry(SymbolRef.getSymbolTableName(),
823 CSectionRef.Address + SymbolOffset, SectionIndex,
824 // In the old version of the 32-bit XCOFF interpretation,
825 // symbols may require bit 10 (0x0020) to be set if the
826 // symbol is a function, otherwise the bit should be 0.
827 is64Bit() ? SymbolRef.getVisibilityType()
828 : SymbolRef.getVisibilityType() | 0x0020,
829 SymbolRef.getStorageClass(),
830 (is64Bit() && ExceptionSection.isDebugEnabled) ? 3 : 2);
831 if (is64Bit() && ExceptionSection.isDebugEnabled) {
832 // On 64 bit with debugging enabled, we have a csect, exception, and
833 // function auxilliary entries, so we must increment symbol index by 4.
834 writeSymbolAuxExceptionEntry(
835 ExceptionSection.FileOffsetToData +
836 getExceptionOffset(Entry->second.FunctionSymbol),
837 Entry->second.FunctionSize,
838 SymbolIndexMap[Entry->second.FunctionSymbol] + 4);
839 }
840 // For exception section entries, csect and function auxilliary entries
841 // must exist. On 64-bit there is also an exception auxilliary entry.
842 writeSymbolAuxFunctionEntry(
843 ExceptionSection.FileOffsetToData +
844 getExceptionOffset(Entry->second.FunctionSymbol),
845 Entry->second.FunctionSize, 0,
846 (is64Bit() && ExceptionSection.isDebugEnabled)
847 ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4
848 : SymbolIndexMap[Entry->second.FunctionSymbol] + 3);
849 } else {
850 writeSymbolEntry(SymbolRef.getSymbolTableName(),
851 CSectionRef.Address + SymbolOffset, SectionIndex,
852 SymbolRef.getVisibilityType(),
853 SymbolRef.getStorageClass());
854 }
855 writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex, XCOFF::XTY_LD,
856 CSectionRef.MCSec->getMappingClass());
857}
858
859void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
860 const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
861 assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!")(static_cast <bool> (DwarfSectionRef.MCSec->isDwarfSect
() && "Not a DWARF section!") ? void (0) : __assert_fail
("DwarfSectionRef.MCSec->isDwarfSect() && \"Not a DWARF section!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 861, __extension__ __PRETTY_FUNCTION__
))
;
862
863 writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), /*Value=*/0,
864 SectionIndex, /*SymbolType=*/0, XCOFF::C_DWARF);
865
866 writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
867}
868
869void XCOFFObjectWriter::writeSymbolEntryForControlSection(
870 const XCOFFSection &CSectionRef, int16_t SectionIndex,
871 XCOFF::StorageClass StorageClass) {
872 writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
873 SectionIndex, CSectionRef.getVisibilityType(), StorageClass);
874
875 writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),
876 CSectionRef.MCSec->getMappingClass());
877}
878
879void XCOFFObjectWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
880 uint32_t FunctionSize,
881 uint64_t LineNumberPointer,
882 uint32_t EndIndex) {
883 if (is64Bit())
884 writeWord(LineNumberPointer);
885 else
886 W.write<uint32_t>(EntryOffset);
887 W.write<uint32_t>(FunctionSize);
888 if (!is64Bit())
889 writeWord(LineNumberPointer);
890 W.write<uint32_t>(EndIndex);
891 if (is64Bit()) {
892 W.OS.write_zeros(1);
893 W.write<uint8_t>(XCOFF::AUX_FCN);
894 } else {
895 W.OS.write_zeros(2);
896 }
897}
898
899void XCOFFObjectWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
900 uint32_t FunctionSize,
901 uint32_t EndIndex) {
902 assert(is64Bit() && "Exception auxilliary entries are 64-bit only.")(static_cast <bool> (is64Bit() && "Exception auxilliary entries are 64-bit only."
) ? void (0) : __assert_fail ("is64Bit() && \"Exception auxilliary entries are 64-bit only.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 902, __extension__ __PRETTY_FUNCTION__
))
;
903 W.write<uint64_t>(EntryOffset);
904 W.write<uint32_t>(FunctionSize);
905 W.write<uint32_t>(EndIndex);
906 W.OS.write_zeros(1); // Pad (unused)
907 W.write<uint8_t>(XCOFF::AUX_EXCEPT);
908}
909
910void XCOFFObjectWriter::writeFileHeader() {
911 W.write<uint16_t>(is64Bit() ? XCOFF::XCOFF64 : XCOFF::XCOFF32);
912 W.write<uint16_t>(SectionCount);
913 W.write<int32_t>(0); // TimeStamp
914 writeWord(SymbolTableOffset);
915 if (is64Bit()) {
916 W.write<uint16_t>(auxiliaryHeaderSize());
917 W.write<uint16_t>(0); // Flags
918 W.write<int32_t>(SymbolTableEntryCount);
919 } else {
920 W.write<int32_t>(SymbolTableEntryCount);
921 W.write<uint16_t>(auxiliaryHeaderSize());
922 W.write<uint16_t>(0); // Flags
923 }
924}
925
926void XCOFFObjectWriter::writeAuxFileHeader() {
927 if (!auxiliaryHeaderSize())
928 return;
929 W.write<uint16_t>(0); // Magic
930 W.write<uint16_t>(
931 XCOFF::NEW_XCOFF_INTERPRET); // Version. The new interpretation of the
932 // n_type field in the symbol table entry is
933 // used in XCOFF32.
934 W.write<uint32_t>(Sections[0]->Size); // TextSize
935 W.write<uint32_t>(Sections[1]->Size); // InitDataSize
936 W.write<uint32_t>(Sections[2]->Size); // BssDataSize
937 W.write<uint32_t>(0); // EntryPointAddr
938 W.write<uint32_t>(Sections[0]->Address); // TextStartAddr
939 W.write<uint32_t>(Sections[1]->Address); // DataStartAddr
940}
941
942void XCOFFObjectWriter::writeSectionHeader(const SectionEntry *Sec) {
943 bool IsDwarf = (Sec->Flags & XCOFF::STYP_DWARF) != 0;
944 bool IsOvrflo = (Sec->Flags & XCOFF::STYP_OVRFLO) != 0;
945 // Nothing to write for this Section.
946 if (Sec->Index == SectionEntry::UninitializedIndex)
947 return;
948
949 // Write Name.
950 ArrayRef<char> NameRef(Sec->Name, XCOFF::NameSize);
951 W.write(NameRef);
952
953 // Write the Physical Address and Virtual Address.
954 // We use 0 for DWARF sections' Physical and Virtual Addresses.
955 writeWord(IsDwarf ? 0 : Sec->Address);
956 // Since line number is not supported, we set it to 0 for overflow sections.
957 writeWord((IsDwarf || IsOvrflo) ? 0 : Sec->Address);
958
959 writeWord(Sec->Size);
960 writeWord(Sec->FileOffsetToData);
961 writeWord(Sec->FileOffsetToRelocations);
962 writeWord(0); // FileOffsetToLineNumberInfo. Not supported yet.
963
964 if (is64Bit()) {
965 W.write<uint32_t>(Sec->RelocationCount);
966 W.write<uint32_t>(0); // NumberOfLineNumbers. Not supported yet.
967 W.write<int32_t>(Sec->Flags);
968 W.OS.write_zeros(4);
969 } else {
970 // For the overflow section header, s_nreloc provides a reference to the
971 // primary section header and s_nlnno must have the same value.
972 // For common section headers, if either of s_nreloc or s_nlnno are set to
973 // 65535, the other one must also be set to 65535.
974 W.write<uint16_t>(Sec->RelocationCount);
975 W.write<uint16_t>((IsOvrflo || Sec->RelocationCount == XCOFF::RelocOverflow)
976 ? Sec->RelocationCount
977 : 0); // NumberOfLineNumbers. Not supported yet.
978 W.write<int32_t>(Sec->Flags);
979 }
980}
981
982void XCOFFObjectWriter::writeSectionHeaderTable() {
983 for (const auto *CsectSec : Sections)
984 writeSectionHeader(CsectSec);
985 for (const auto &DwarfSec : DwarfSections)
986 writeSectionHeader(&DwarfSec);
987 for (const auto &OverflowSec : OverflowSections)
988 writeSectionHeader(&OverflowSec);
989 if (hasExceptionSection())
990 writeSectionHeader(&ExceptionSection);
991}
992
993void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
994 const XCOFFSection &Section) {
995 if (Section.MCSec->isCsect())
996 writeWord(Section.Address + Reloc.FixupOffsetInCsect);
997 else {
998 // DWARF sections' address is set to 0.
999 assert(Section.MCSec->isDwarfSect() && "unsupport section type!")(static_cast <bool> (Section.MCSec->isDwarfSect() &&
"unsupport section type!") ? void (0) : __assert_fail ("Section.MCSec->isDwarfSect() && \"unsupport section type!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 999, __extension__ __PRETTY_FUNCTION__
))
;
1000 writeWord(Reloc.FixupOffsetInCsect);
1001 }
1002 W.write<uint32_t>(Reloc.SymbolTableIndex);
1003 W.write<uint8_t>(Reloc.SignAndSize);
1004 W.write<uint8_t>(Reloc.Type);
1005}
1006
1007void XCOFFObjectWriter::writeRelocations() {
1008 for (const auto *Section : Sections) {
1009 if (Section->Index == SectionEntry::UninitializedIndex)
1010 // Nothing to write for this Section.
1011 continue;
1012
1013 for (const auto *Group : Section->Groups) {
1014 if (Group->empty())
1015 continue;
1016
1017 for (const auto &Csect : *Group) {
1018 for (const auto Reloc : Csect.Relocations)
1019 writeRelocation(Reloc, Csect);
1020 }
1021 }
1022 }
1023
1024 for (const auto &DwarfSection : DwarfSections)
1025 for (const auto &Reloc : DwarfSection.DwarfSect->Relocations)
1026 writeRelocation(Reloc, *DwarfSection.DwarfSect);
1027}
1028
1029void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
1030 // Write C_FILE symbols.
1031 // The n_name of a C_FILE symbol is the source file's name when no auxiliary
1032 // entries are present.
1033 for (const std::pair<std::string, size_t> &F : FileNames) {
1034 writeSymbolEntry(F.first, /*Value=*/0, XCOFF::ReservedSectionNum::N_DEBUG,
1035 /*SymbolType=*/0, XCOFF::C_FILE,
1036 /*NumberOfAuxEntries=*/0);
1037 }
1038
1039 for (const auto &Csect : UndefinedCsects) {
1040 writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,
1041 Csect.MCSec->getStorageClass());
1042 }
1043
1044 for (const auto *Section : Sections) {
1045 if (Section->Index == SectionEntry::UninitializedIndex)
1046 // Nothing to write for this Section.
1047 continue;
1048
1049 for (const auto *Group : Section->Groups) {
1050 if (Group->empty())
1051 continue;
1052
1053 const int16_t SectionIndex = Section->Index;
1054 for (const auto &Csect : *Group) {
1055 // Write out the control section first and then each symbol in it.
1056 writeSymbolEntryForControlSection(Csect, SectionIndex,
1057 Csect.MCSec->getStorageClass());
1058
1059 for (const auto &Sym : Csect.Syms)
1060 writeSymbolEntryForCsectMemberLabel(
1061 Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym)));
1062 }
1063 }
1064 }
1065
1066 for (const auto &DwarfSection : DwarfSections)
1067 writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,
1068 DwarfSection.Index);
1069}
1070
1071void XCOFFObjectWriter::finalizeRelocationInfo(SectionEntry *Sec,
1072 uint64_t RelCount) {
1073 // Handles relocation field overflows in an XCOFF32 file. An XCOFF64 file
1074 // may not contain an overflow section header.
1075 if (!is64Bit() && (RelCount >= static_cast<uint32_t>(XCOFF::RelocOverflow))) {
1076 // Generate an overflow section header.
1077 SectionEntry SecEntry(".ovrflo", XCOFF::STYP_OVRFLO);
1078
1079 // This field specifies the file section number of the section header that
1080 // overflowed.
1081 SecEntry.RelocationCount = Sec->Index;
1082
1083 // This field specifies the number of relocation entries actually
1084 // required.
1085 SecEntry.Address = RelCount;
1086 SecEntry.Index = ++SectionCount;
1087 OverflowSections.push_back(std::move(SecEntry));
1088
1089 // The field in the primary section header is always 65535
1090 // (XCOFF::RelocOverflow).
1091 Sec->RelocationCount = XCOFF::RelocOverflow;
1092 } else {
1093 Sec->RelocationCount = RelCount;
1094 }
1095}
1096
1097void XCOFFObjectWriter::calcOffsetToRelocations(SectionEntry *Sec,
1098 uint64_t &RawPointer) {
1099 if (!Sec->RelocationCount)
1100 return;
1101
1102 Sec->FileOffsetToRelocations = RawPointer;
1103 uint64_t RelocationSizeInSec = 0;
1104 if (!is64Bit() &&
1105 Sec->RelocationCount == static_cast<uint32_t>(XCOFF::RelocOverflow)) {
1106 // Find its corresponding overflow section.
1107 for (auto &OverflowSec : OverflowSections) {
1108 if (OverflowSec.RelocationCount == static_cast<uint32_t>(Sec->Index)) {
1109 RelocationSizeInSec =
1110 OverflowSec.Address * XCOFF::RelocationSerializationSize32;
1111
1112 // This field must have the same values as in the corresponding
1113 // primary section header.
1114 OverflowSec.FileOffsetToRelocations = Sec->FileOffsetToRelocations;
1115 }
1116 }
1117 assert(RelocationSizeInSec && "Overflow section header doesn't exist.")(static_cast <bool> (RelocationSizeInSec && "Overflow section header doesn't exist."
) ? void (0) : __assert_fail ("RelocationSizeInSec && \"Overflow section header doesn't exist.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1117, __extension__ __PRETTY_FUNCTION__
))
;
1118 } else {
1119 RelocationSizeInSec = Sec->RelocationCount *
1120 (is64Bit() ? XCOFF::RelocationSerializationSize64
1121 : XCOFF::RelocationSerializationSize32);
1122 }
1123
1124 RawPointer += RelocationSizeInSec;
1125 if (RawPointer > MaxRawDataSize)
1126 report_fatal_error("Relocation data overflowed this object file.");
1127}
1128
1129void XCOFFObjectWriter::finalizeSectionInfo() {
1130 for (auto *Section : Sections) {
1131 if (Section->Index == SectionEntry::UninitializedIndex)
1132 // Nothing to record for this Section.
1133 continue;
1134
1135 uint64_t RelCount = 0;
1136 for (const auto *Group : Section->Groups) {
1137 if (Group->empty())
1138 continue;
1139
1140 for (auto &Csect : *Group)
1141 RelCount += Csect.Relocations.size();
1142 }
1143 finalizeRelocationInfo(Section, RelCount);
1144 }
1145
1146 for (auto &DwarfSection : DwarfSections)
1147 finalizeRelocationInfo(&DwarfSection,
1148 DwarfSection.DwarfSect->Relocations.size());
1149
1150 // Calculate the RawPointer value for all headers.
1151 uint64_t RawPointer =
1152 (is64Bit() ? (XCOFF::FileHeaderSize64 +
1153 SectionCount * XCOFF::SectionHeaderSize64)
1154 : (XCOFF::FileHeaderSize32 +
1155 SectionCount * XCOFF::SectionHeaderSize32)) +
1156 auxiliaryHeaderSize();
1157
1158 // Calculate the file offset to the section data.
1159 for (auto *Sec : Sections) {
1160 if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
1161 continue;
1162
1163 Sec->FileOffsetToData = RawPointer;
1164 RawPointer += Sec->Size;
1165 if (RawPointer > MaxRawDataSize)
1166 report_fatal_error("Section raw data overflowed this object file.");
1167 }
1168
1169 if (!DwarfSections.empty()) {
1170 RawPointer += PaddingsBeforeDwarf;
1171 for (auto &DwarfSection : DwarfSections) {
1172 DwarfSection.FileOffsetToData = RawPointer;
1173 RawPointer += DwarfSection.MemorySize;
1174 if (RawPointer > MaxRawDataSize)
1175 report_fatal_error("Section raw data overflowed this object file.");
1176 }
1177 }
1178
1179 if (hasExceptionSection()) {
1180 ExceptionSection.FileOffsetToData = RawPointer;
1181 RawPointer += ExceptionSection.Size;
1182
1183 assert(RawPointer <= MaxRawDataSize &&(static_cast <bool> (RawPointer <= MaxRawDataSize &&
"Section raw data overflowed this object file.") ? void (0) :
__assert_fail ("RawPointer <= MaxRawDataSize && \"Section raw data overflowed this object file.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1184, __extension__ __PRETTY_FUNCTION__
))
1184 "Section raw data overflowed this object file.")(static_cast <bool> (RawPointer <= MaxRawDataSize &&
"Section raw data overflowed this object file.") ? void (0) :
__assert_fail ("RawPointer <= MaxRawDataSize && \"Section raw data overflowed this object file.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1184, __extension__ __PRETTY_FUNCTION__
))
;
1185 }
1186
1187 for (auto *Sec : Sections) {
1188 if (Sec->Index != SectionEntry::UninitializedIndex)
1189 calcOffsetToRelocations(Sec, RawPointer);
1190 }
1191
1192 for (auto &DwarfSec : DwarfSections)
1193 calcOffsetToRelocations(&DwarfSec, RawPointer);
1194
1195 // TODO Error check that the number of symbol table entries fits in 32-bits
1196 // signed ...
1197 if (SymbolTableEntryCount)
1198 SymbolTableOffset = RawPointer;
1199}
1200
1201void XCOFFObjectWriter::addExceptionEntry(
1202 const MCSymbol *Symbol, const MCSymbol *Trap, unsigned LanguageCode,
1203 unsigned ReasonCode, unsigned FunctionSize, bool hasDebug) {
1204 // If a module had debug info, debugging is enabled and XCOFF emits the
1205 // exception auxilliary entry.
1206 if (hasDebug)
1207 ExceptionSection.isDebugEnabled = true;
1208 auto Entry = ExceptionSection.ExceptionTable.find(Symbol->getName());
1209 if (Entry != ExceptionSection.ExceptionTable.end()) {
1210 Entry->second.Entries.push_back(
1211 ExceptionTableEntry(Trap, LanguageCode, ReasonCode));
1212 return;
1213 }
1214 ExceptionInfo NewEntry;
1215 NewEntry.FunctionSymbol = Symbol;
1216 NewEntry.FunctionSize = FunctionSize;
1217 NewEntry.Entries.push_back(
1218 ExceptionTableEntry(Trap, LanguageCode, ReasonCode));
1219 ExceptionSection.ExceptionTable.insert(
1220 std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry));
1221}
1222
1223unsigned XCOFFObjectWriter::getExceptionSectionSize() {
1224 unsigned EntryNum = 0;
1225
1226 for (auto it = ExceptionSection.ExceptionTable.begin();
1227 it != ExceptionSection.ExceptionTable.end(); ++it)
1228 // The size() gets +1 to account for the initial entry containing the
1229 // symbol table index.
1230 EntryNum += it->second.Entries.size() + 1;
1231
1232 return EntryNum * (is64Bit() ? XCOFF::ExceptionSectionEntrySize64
1233 : XCOFF::ExceptionSectionEntrySize32);
1234}
1235
1236unsigned XCOFFObjectWriter::getExceptionOffset(const MCSymbol *Symbol) {
1237 unsigned EntryNum = 0;
1238 for (auto it = ExceptionSection.ExceptionTable.begin();
1239 it != ExceptionSection.ExceptionTable.end(); ++it) {
1240 if (Symbol == it->second.FunctionSymbol)
1241 break;
1242 EntryNum += it->second.Entries.size() + 1;
1243 }
1244 return EntryNum * (is64Bit() ? XCOFF::ExceptionSectionEntrySize64
1245 : XCOFF::ExceptionSectionEntrySize32);
1246}
1247
1248void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
1249 // The symbol table starts with all the C_FILE symbols.
1250 uint32_t SymbolTableIndex = FileNames.size();
1251
1252 // Calculate indices for undefined symbols.
1253 for (auto &Csect : UndefinedCsects) {
1254 Csect.Size = 0;
1255 Csect.Address = 0;
1256 Csect.SymbolTableIndex = SymbolTableIndex;
1257 SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1258 // 1 main and 1 auxiliary symbol table entry for each contained symbol.
1259 SymbolTableIndex += 2;
1260 }
1261
1262 // The address corrresponds to the address of sections and symbols in the
1263 // object file. We place the shared address 0 immediately after the
1264 // section header table.
1265 uint64_t Address = 0;
1266 // Section indices are 1-based in XCOFF.
1267 int32_t SectionIndex = 1;
1268 bool HasTDataSection = false;
1269
1270 for (auto *Section : Sections) {
1271 const bool IsEmpty =
1272 llvm::all_of(Section->Groups,
1273 [](const CsectGroup *Group) { return Group->empty(); });
1274 if (IsEmpty)
1275 continue;
1276
1277 if (SectionIndex > MaxSectionIndex)
1278 report_fatal_error("Section index overflow!");
1279 Section->Index = SectionIndex++;
1280 SectionCount++;
1281
1282 bool SectionAddressSet = false;
1283 // Reset the starting address to 0 for TData section.
1284 if (Section->Flags == XCOFF::STYP_TDATA) {
1285 Address = 0;
1286 HasTDataSection = true;
1287 }
1288 // Reset the starting address to 0 for TBSS section if the object file does
1289 // not contain TData Section.
1290 if ((Section->Flags == XCOFF::STYP_TBSS) && !HasTDataSection)
1291 Address = 0;
1292
1293 for (auto *Group : Section->Groups) {
1294 if (Group->empty())
1295 continue;
1296
1297 for (auto &Csect : *Group) {
1298 const MCSectionXCOFF *MCSec = Csect.MCSec;
1299 Csect.Address = alignTo(Address, MCSec->getAlign());
1300 Csect.Size = Layout.getSectionAddressSize(MCSec);
1301 Address = Csect.Address + Csect.Size;
1302 Csect.SymbolTableIndex = SymbolTableIndex;
1303 SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1304 // 1 main and 1 auxiliary symbol table entry for the csect.
1305 SymbolTableIndex += 2;
1306
1307 for (auto &Sym : Csect.Syms) {
1308 bool hasExceptEntry = false;
1309 auto Entry =
1310 ExceptionSection.ExceptionTable.find(Sym.MCSym->getName());
1311 if (Entry != ExceptionSection.ExceptionTable.end()) {
1312 hasExceptEntry = true;
1313 for (auto &TrapEntry : Entry->second.Entries) {
1314 TrapEntry.TrapAddress = Layout.getSymbolOffset(*(Sym.MCSym)) +
1315 TrapEntry.Trap->getOffset();
1316 }
1317 }
1318 Sym.SymbolTableIndex = SymbolTableIndex;
1319 SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex;
1320 // 1 main and 1 auxiliary symbol table entry for each contained
1321 // symbol. For symbols with exception section entries, a function
1322 // auxilliary entry is needed, and on 64-bit XCOFF with debugging
1323 // enabled, an additional exception auxilliary entry is needed.
1324 SymbolTableIndex += 2;
1325 if (hasExceptionSection() && hasExceptEntry) {
1326 if (is64Bit() && ExceptionSection.isDebugEnabled)
1327 SymbolTableIndex += 2;
1328 else
1329 SymbolTableIndex += 1;
1330 }
1331 }
1332 }
1333
1334 if (!SectionAddressSet) {
1335 Section->Address = Group->front().Address;
1336 SectionAddressSet = true;
1337 }
1338 }
1339
1340 // Make sure the address of the next section aligned to
1341 // DefaultSectionAlign.
1342 Address = alignTo(Address, DefaultSectionAlign);
1343 Section->Size = Address - Section->Address;
1344 }
1345
1346 // Start to generate DWARF sections. Sections other than DWARF section use
1347 // DefaultSectionAlign as the default alignment, while DWARF sections have
1348 // their own alignments. If these two alignments are not the same, we need
1349 // some paddings here and record the paddings bytes for FileOffsetToData
1350 // calculation.
1351 if (!DwarfSections.empty())
1352 PaddingsBeforeDwarf =
1353 alignTo(Address,
1354 (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -
1355 Address;
1356
1357 DwarfSectionEntry *LastDwarfSection = nullptr;
1358 for (auto &DwarfSection : DwarfSections) {
1359 assert((SectionIndex <= MaxSectionIndex) && "Section index overflow!")(static_cast <bool> ((SectionIndex <= MaxSectionIndex
) && "Section index overflow!") ? void (0) : __assert_fail
("(SectionIndex <= MaxSectionIndex) && \"Section index overflow!\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1359, __extension__ __PRETTY_FUNCTION__
))
;
1360
1361 XCOFFSection &DwarfSect = *DwarfSection.DwarfSect;
1362 const MCSectionXCOFF *MCSec = DwarfSect.MCSec;
1363
1364 // Section index.
1365 DwarfSection.Index = SectionIndex++;
1366 SectionCount++;
1367
1368 // Symbol index.
1369 DwarfSect.SymbolTableIndex = SymbolTableIndex;
1370 SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex;
1371 // 1 main and 1 auxiliary symbol table entry for the csect.
1372 SymbolTableIndex += 2;
1373
1374 // Section address. Make it align to section alignment.
1375 // We use address 0 for DWARF sections' Physical and Virtual Addresses.
1376 // This address is used to tell where is the section in the final object.
1377 // See writeSectionForDwarfSectionEntry().
1378 DwarfSection.Address = DwarfSect.Address =
1379 alignTo(Address, MCSec->getAlign());
1380
1381 // Section size.
1382 // For DWARF section, we must use the real size which may be not aligned.
1383 DwarfSection.Size = DwarfSect.Size = Layout.getSectionAddressSize(MCSec);
1384
1385 Address = DwarfSection.Address + DwarfSection.Size;
1386
1387 if (LastDwarfSection)
1388 LastDwarfSection->MemorySize =
1389 DwarfSection.Address - LastDwarfSection->Address;
1390 LastDwarfSection = &DwarfSection;
1391 }
1392 if (LastDwarfSection) {
1393 // Make the final DWARF section address align to the default section
1394 // alignment for follow contents.
1395 Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size,
1396 DefaultSectionAlign);
1397 LastDwarfSection->MemorySize = Address - LastDwarfSection->Address;
1398 }
1399 if (hasExceptionSection()) {
1400 ExceptionSection.Index = SectionIndex++;
1401 SectionCount++;
1402 ExceptionSection.Address = 0;
1403 ExceptionSection.Size = getExceptionSectionSize();
1404 Address += ExceptionSection.Size;
1405 Address = alignTo(Address, DefaultSectionAlign);
Value stored to 'Address' is never read
1406 }
1407
1408 SymbolTableEntryCount = SymbolTableIndex;
1409}
1410
1411void XCOFFObjectWriter::writeSectionForControlSectionEntry(
1412 const MCAssembler &Asm, const MCAsmLayout &Layout,
1413 const CsectSectionEntry &CsectEntry, uint64_t &CurrentAddressLocation) {
1414 // Nothing to write for this Section.
1415 if (CsectEntry.Index == SectionEntry::UninitializedIndex)
1416 return;
1417
1418 // There could be a gap (without corresponding zero padding) between
1419 // sections.
1420 // There could be a gap (without corresponding zero padding) between
1421 // sections.
1422 assert(((CurrentAddressLocation <= CsectEntry.Address) ||(static_cast <bool> (((CurrentAddressLocation <= CsectEntry
.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry
.Flags == XCOFF::STYP_TBSS)) && "CurrentAddressLocation should be less than or equal to section "
"address if the section is not TData or TBSS.") ? void (0) :
__assert_fail ("((CurrentAddressLocation <= CsectEntry.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry.Flags == XCOFF::STYP_TBSS)) && \"CurrentAddressLocation should be less than or equal to section \" \"address if the section is not TData or TBSS.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1426, __extension__ __PRETTY_FUNCTION__
))
1423 (CsectEntry.Flags == XCOFF::STYP_TDATA) ||(static_cast <bool> (((CurrentAddressLocation <= CsectEntry
.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry
.Flags == XCOFF::STYP_TBSS)) && "CurrentAddressLocation should be less than or equal to section "
"address if the section is not TData or TBSS.") ? void (0) :
__assert_fail ("((CurrentAddressLocation <= CsectEntry.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry.Flags == XCOFF::STYP_TBSS)) && \"CurrentAddressLocation should be less than or equal to section \" \"address if the section is not TData or TBSS.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1426, __extension__ __PRETTY_FUNCTION__
))
1424 (CsectEntry.Flags == XCOFF::STYP_TBSS)) &&(static_cast <bool> (((CurrentAddressLocation <= CsectEntry
.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry
.Flags == XCOFF::STYP_TBSS)) && "CurrentAddressLocation should be less than or equal to section "
"address if the section is not TData or TBSS.") ? void (0) :
__assert_fail ("((CurrentAddressLocation <= CsectEntry.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry.Flags == XCOFF::STYP_TBSS)) && \"CurrentAddressLocation should be less than or equal to section \" \"address if the section is not TData or TBSS.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1426, __extension__ __PRETTY_FUNCTION__
))
1425 "CurrentAddressLocation should be less than or equal to section "(static_cast <bool> (((CurrentAddressLocation <= CsectEntry
.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry
.Flags == XCOFF::STYP_TBSS)) && "CurrentAddressLocation should be less than or equal to section "
"address if the section is not TData or TBSS.") ? void (0) :
__assert_fail ("((CurrentAddressLocation <= CsectEntry.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry.Flags == XCOFF::STYP_TBSS)) && \"CurrentAddressLocation should be less than or equal to section \" \"address if the section is not TData or TBSS.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1426, __extension__ __PRETTY_FUNCTION__
))
1426 "address if the section is not TData or TBSS.")(static_cast <bool> (((CurrentAddressLocation <= CsectEntry
.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry
.Flags == XCOFF::STYP_TBSS)) && "CurrentAddressLocation should be less than or equal to section "
"address if the section is not TData or TBSS.") ? void (0) :
__assert_fail ("((CurrentAddressLocation <= CsectEntry.Address) || (CsectEntry.Flags == XCOFF::STYP_TDATA) || (CsectEntry.Flags == XCOFF::STYP_TBSS)) && \"CurrentAddressLocation should be less than or equal to section \" \"address if the section is not TData or TBSS.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1426, __extension__ __PRETTY_FUNCTION__
))
;
1427
1428 CurrentAddressLocation = CsectEntry.Address;
1429
1430 // For virtual sections, nothing to write. But need to increase
1431 // CurrentAddressLocation for later sections like DWARF section has a correct
1432 // writing location.
1433 if (CsectEntry.IsVirtual) {
1434 CurrentAddressLocation += CsectEntry.Size;
1435 return;
1436 }
1437
1438 for (const auto &Group : CsectEntry.Groups) {
1439 for (const auto &Csect : *Group) {
1440 if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
1441 W.OS.write_zeros(PaddingSize);
1442 if (Csect.Size)
1443 Asm.writeSectionData(W.OS, Csect.MCSec, Layout);
1444 CurrentAddressLocation = Csect.Address + Csect.Size;
1445 }
1446 }
1447
1448 // The size of the tail padding in a section is the end virtual address of
1449 // the current section minus the the end virtual address of the last csect
1450 // in that section.
1451 if (uint64_t PaddingSize =
1452 CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {
1453 W.OS.write_zeros(PaddingSize);
1454 CurrentAddressLocation += PaddingSize;
1455 }
1456}
1457
1458void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
1459 const MCAssembler &Asm, const MCAsmLayout &Layout,
1460 const DwarfSectionEntry &DwarfEntry, uint64_t &CurrentAddressLocation) {
1461 // There could be a gap (without corresponding zero padding) between
1462 // sections. For example DWARF section alignment is bigger than
1463 // DefaultSectionAlign.
1464 assert(CurrentAddressLocation <= DwarfEntry.Address &&(static_cast <bool> (CurrentAddressLocation <= DwarfEntry
.Address && "CurrentAddressLocation should be less than or equal to section "
"address.") ? void (0) : __assert_fail ("CurrentAddressLocation <= DwarfEntry.Address && \"CurrentAddressLocation should be less than or equal to section \" \"address.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1466, __extension__ __PRETTY_FUNCTION__
))
1465 "CurrentAddressLocation should be less than or equal to section "(static_cast <bool> (CurrentAddressLocation <= DwarfEntry
.Address && "CurrentAddressLocation should be less than or equal to section "
"address.") ? void (0) : __assert_fail ("CurrentAddressLocation <= DwarfEntry.Address && \"CurrentAddressLocation should be less than or equal to section \" \"address.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1466, __extension__ __PRETTY_FUNCTION__
))
1466 "address.")(static_cast <bool> (CurrentAddressLocation <= DwarfEntry
.Address && "CurrentAddressLocation should be less than or equal to section "
"address.") ? void (0) : __assert_fail ("CurrentAddressLocation <= DwarfEntry.Address && \"CurrentAddressLocation should be less than or equal to section \" \"address.\""
, "llvm/lib/MC/XCOFFObjectWriter.cpp", 1466, __extension__ __PRETTY_FUNCTION__
))
;
1467
1468 if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)
1469 W.OS.write_zeros(PaddingSize);
1470
1471 if (DwarfEntry.Size)
1472 Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec, Layout);
1473
1474 CurrentAddressLocation = DwarfEntry.Address + DwarfEntry.Size;
1475
1476 // DWARF section size is not aligned to DefaultSectionAlign.
1477 // Make sure CurrentAddressLocation is aligned to DefaultSectionAlign.
1478 uint32_t Mod = CurrentAddressLocation % DefaultSectionAlign;
1479 uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0;
1480 if (TailPaddingSize)
1481 W.OS.write_zeros(TailPaddingSize);
1482
1483 CurrentAddressLocation += TailPaddingSize;
1484}
1485
1486void XCOFFObjectWriter::writeSectionForExceptionSectionEntry(
1487 const MCAssembler &Asm, const MCAsmLayout &Layout,
1488 ExceptionSectionEntry &ExceptionEntry, uint64_t &CurrentAddressLocation) {
1489 for (auto it = ExceptionEntry.ExceptionTable.begin();
1490 it != ExceptionEntry.ExceptionTable.end(); it++) {
1491 // For every symbol that has exception entries, you must start the entries
1492 // with an initial symbol table index entry
1493 W.write<uint32_t>(SymbolIndexMap[it->second.FunctionSymbol]);
1494 if (is64Bit()) {
1495 // 4-byte padding on 64-bit.
1496 W.OS.write_zeros(4);
1497 }
1498 W.OS.write_zeros(2);
1499 for (auto &TrapEntry : it->second.Entries) {
1500 writeWord(TrapEntry.TrapAddress);
1501 W.write<uint8_t>(TrapEntry.Lang);
1502 W.write<uint8_t>(TrapEntry.Reason);
1503 }
1504 }
1505
1506 CurrentAddressLocation += getExceptionSectionSize();
1507}
1508
1509// Takes the log base 2 of the alignment and shifts the result into the 5 most
1510// significant bits of a byte, then or's in the csect type into the least
1511// significant 3 bits.
1512uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
1513 unsigned Log2Align = Log2(Sec->getAlign());
1514 // Result is a number in the range [0, 31] which fits in the 5 least
1515 // significant bits. Shift this value into the 5 most significant bits, and
1516 // bitwise-or in the csect type.
1517 uint8_t EncodedAlign = Log2Align << 3;
1518 return EncodedAlign | Sec->getCSectType();
1519}
1520
1521} // end anonymous namespace
1522
1523std::unique_ptr<MCObjectWriter>
1524llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
1525 raw_pwrite_stream &OS) {
1526 return std::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS);
1527}