LLVM: lib/ObjectYAML/XCOFFEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

23

24using namespace llvm;

26

27namespace {

28

29constexpr unsigned DefaultSectionAlign = 4;

30constexpr int16_t MaxSectionIndex = INT16_MAX;

31constexpr uint32_t MaxRawDataSize = UINT32_MAX;

32

33class XCOFFWriter {

34public:

35 XCOFFWriter(XCOFFYAML::Object &Obj, raw_ostream &OS, yaml::ErrorHandler EH)

37 StrTblBuilder(StringTableBuilder::XCOFF) {

39 }

40 bool writeXCOFF();

41

42private:

43 void reportOverwrite(uint64_t currentOffset, uint64_t specifiedOffset,

44 const Twine &fieldName);

45 bool nameShouldBeInStringTable(StringRef SymbolName);

46 bool initFileHeader(uint64_t CurrentOffset);

47 void initAuxFileHeader();

48 bool initSectionHeaders(uint64_t &CurrentOffset);

50 bool initStringTable();

51 bool assignAddressesAndIndices();

52

53 void writeFileHeader();

54 void writeAuxFileHeader();

55 void writeSectionHeaders();

56 bool writeSectionData();

57 bool writeRelocations();

58 bool writeSymbols();

60

61 bool writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);

62 bool writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);

63 bool writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);

64 bool writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);

65 bool writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);

66 bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);

67 bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);

68 bool writeAuxSymbol(const std::unique_ptrXCOFFYAML::AuxSymbolEnt &AuxSym);

69

70 XCOFFYAML::Object &Obj;

71 bool Is64Bit = false;

72 support::endian::Writer W;

74 StringTableBuilder StrTblBuilder;

75 uint64_t StartOffset = 0u;

76

77 DenseMap<StringRef, int16_t> SectionIndexMap = {

81 XCOFFYAML::FileHeader InitFileHdr = Obj.Header;

82 XCOFFYAML::AuxiliaryHeader InitAuxFileHdr;

83 std::vectorXCOFFYAML::Section InitSections = Obj.Sections;

84};

85

89 char SrcName[] = "";

90 memcpy(Name, StrName.size() ? StrName.data() : SrcName, StrName.size());

92 W.write(NameRef);

93}

94

95void XCOFFWriter::reportOverwrite(uint64_t CurrentOffset,

97 const Twine &fieldName) {

98 ErrHandler("current file offset (" + Twine(CurrentOffset) +

99 ") is bigger than the specified " + fieldName + " (" +

100 Twine(specifiedOffset) + ") ");

101}

102

103bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {

104

106}

107

108bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {

109 for (XCOFFYAML::Section &InitSection : InitSections) {

110 if (!InitSection.Relocations.empty()) {

113 uint64_t UsedSize = RelSize * InitSection.Relocations.size();

114

115

116

117 if (!InitSection.NumberOfRelocations)

118 InitSection.NumberOfRelocations = InitSection.Relocations.size();

119

120

121 if (InitSection.FileOffsetToRelocations) {

122 if (CurrentOffset > InitSection.FileOffsetToRelocations) {

123 reportOverwrite(CurrentOffset, InitSection.FileOffsetToRelocations,

124 "FileOffsetToRelocations for the " +

125 InitSection.SectionName + " section");

126 return false;

127 }

128 CurrentOffset = InitSection.FileOffsetToRelocations;

129 } else

130 InitSection.FileOffsetToRelocations = CurrentOffset;

131 CurrentOffset += UsedSize;

132 if (CurrentOffset > MaxRawDataSize) {

133 ErrHandler("maximum object size (" + Twine(MaxRawDataSize) +

134 ") exceeded when writing relocation data for section " +

135 Twine(InitSection.SectionName));

136 return false;

137 }

138 }

139 }

140 return true;

141}

142

143bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {

144 uint64_t CurrentEndDataAddr = 0;

145 uint64_t CurrentEndTDataAddr = 0;

146 for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {

147

149 int16_t &SectionIndex = SectionIndexMap[InitSections[I].SectionName];

150 if (!SectionIndex) {

151

152 SectionIndex = I + 1;

153 if ((I + 1) > MaxSectionIndex) {

154 ErrHandler("exceeded the maximum permitted section index of " +

155 Twine(MaxSectionIndex));

156 return false;

157 }

158 }

159 }

160

161 if (!InitSections[I].Size)

162 InitSections[I].Size = InitSections[I].SectionData.binary_size();

163

164

165

166

167

168

169

170

171

172

173

174

175 switch (InitSections[I].Flags) {

177 CurrentEndDataAddr = InitSections[I].Address + InitSections[I].Size;

178 break;

180 if (!InitSections[I].Address)

181 InitSections[I].Address = CurrentEndDataAddr;

182 break;

184 CurrentEndTDataAddr = InitSections[I].Address + InitSections[I].Size;

185 break;

187 if (!InitSections[I].Address)

188 InitSections[I].Address = CurrentEndTDataAddr;

189 break;

190 }

191

192 if (InitSections[I].SectionData.binary_size()) {

193 if (InitSections[I].FileOffsetToData) {

194

195 if (CurrentOffset > InitSections[I].FileOffsetToData) {

196 reportOverwrite(CurrentOffset, InitSections[I].FileOffsetToData,

197 "FileOffsetToData for the " +

198 InitSections[I].SectionName + " section");

199 return false;

200 }

201 CurrentOffset = InitSections[I].FileOffsetToData;

202 } else {

203 CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);

204 InitSections[I].FileOffsetToData = CurrentOffset;

205 }

206 CurrentOffset += InitSections[I].SectionData.binary_size();

207 if (CurrentOffset > MaxRawDataSize) {

208 ErrHandler("maximum object size (" + Twine(MaxRawDataSize) +

209 ") exceeded when writing data for section " + Twine(I + 1) +

210 " (" + Twine(InitSections[I].SectionName) + ")");

211 return false;

212 }

213 }

214 if (InitSections[I].SectionSubtype) {

215 uint32_t DWARFSubtype =

216 static_cast<uint32_t>(*InitSections[I].SectionSubtype);

218 ErrHandler("a DWARFSectionSubtype is only allowed for a DWARF section");

219 return false;

220 }

221 unsigned Mask = Is64Bit ? XCOFFSectionHeader64::SectionFlagsTypeMask

222 : XCOFFSectionHeader32::SectionFlagsTypeMask;

223 if (DWARFSubtype & Mask) {

224 ErrHandler("the low-order bits of DWARFSectionSubtype must be 0");

225 return false;

226 }

227 InitSections[I].Flags |= DWARFSubtype;

228 }

229 }

231}

232

233bool XCOFFWriter::initStringTable() {

234 if (Obj.StrTbl.RawContent) {

235 size_t RawSize = Obj.StrTbl.RawContent->binary_size();

236 if (Obj.StrTbl.Strings || Obj.StrTbl.Length) {

237 ErrHandler(

238 "can't specify Strings or Length when RawContent is specified");

239 return false;

240 }

241 if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize < RawSize) {

242 ErrHandler("specified ContentSize (" + Twine(*Obj.StrTbl.ContentSize) +

243 ") is less than the RawContent data size (" + Twine(RawSize) +

244 ")");

245 return false;

246 }

247 return true;

248 }

249 if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize <= 3) {

250 ErrHandler("ContentSize shouldn't be less than 4 without RawContent");

251 return false;

252 }

253

254

255 StrTblBuilder.clear();

256

257 if (Obj.StrTbl.Strings) {

258

259 for (StringRef StringEnt : *Obj.StrTbl.Strings)

260 StrTblBuilder.add(StringEnt);

261

262 size_t StrTblIdx = 0;

263 size_t NumOfStrings = Obj.StrTbl.Strings->size();

264 for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {

265 if (nameShouldBeInStringTable(YamlSym.SymbolName)) {

266 if (StrTblIdx < NumOfStrings) {

267

268 YamlSym.SymbolName = (*Obj.StrTbl.Strings)[StrTblIdx];

269 ++StrTblIdx;

270 } else

271

272

273 StrTblBuilder.add(YamlSym.SymbolName);

274 }

275 }

276 } else {

277 for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {

278 if (nameShouldBeInStringTable(YamlSym.SymbolName))

279 StrTblBuilder.add(YamlSym.SymbolName);

280 }

281 }

282

283

284

285 for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {

286 for (const std::unique_ptrXCOFFYAML::AuxSymbolEnt &AuxSym :

289 if (nameShouldBeInStringTable(AS->FileNameOrString.value_or("")))

290 StrTblBuilder.add(AS->FileNameOrString.value_or(""));

291 }

292 }

293

294 StrTblBuilder.finalize();

295

296 size_t StrTblSize = StrTblBuilder.getSize();

297 if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize < StrTblSize) {

298 ErrHandler("specified ContentSize (" + Twine(*Obj.StrTbl.ContentSize) +

299 ") is less than the size of the data that would otherwise be "

300 "written (" +

301 Twine(StrTblSize) + ")");

302 return false;

303 }

304

305 return true;

306}

307

308bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {

309

311 InitFileHdr.NumberOfSections = Obj.Sections.size();

312 InitFileHdr.NumberOfSymTableEntries = Obj.Symbols.size();

313

314 for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {

315 uint32_t AuxCount = YamlSym.AuxEntries.size();

317 ErrHandler("specified NumberOfAuxEntries " +

319 " is less than the actual number "

320 "of auxiliary entries " +

321 Twine(AuxCount));

322 return false;

323 }

325

327 }

328

329

330 if (InitFileHdr.NumberOfSymTableEntries) {

331 if (Obj.Header.SymbolTableOffset) {

332 if (CurrentOffset > Obj.Header.SymbolTableOffset) {

333 reportOverwrite(CurrentOffset, Obj.Header.SymbolTableOffset,

334 "SymbolTableOffset");

335 return false;

336 }

337 CurrentOffset = Obj.Header.SymbolTableOffset;

338 }

339 InitFileHdr.SymbolTableOffset = CurrentOffset;

340 CurrentOffset +=

342 if (CurrentOffset > MaxRawDataSize) {

343 ErrHandler("maximum object size of " + Twine(MaxRawDataSize) +

344 " exceeded when writing symbols");

345 return false;

346 }

347 }

348

349 return true;

350}

351

352void XCOFFWriter::initAuxFileHeader() {

353 if (Obj.AuxHeader)

354 InitAuxFileHdr = *Obj.AuxHeader;

355

356

357

358

359

360

361

362

363 for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {

364 switch (InitSections[I].Flags) {

366 if (!InitAuxFileHdr.TextSize)

367 InitAuxFileHdr.TextSize = InitSections[I].Size;

368 if (!InitAuxFileHdr.TextStartAddr)

369 InitAuxFileHdr.TextStartAddr = InitSections[I].Address;

370 if (!InitAuxFileHdr.SecNumOfText)

371 InitAuxFileHdr.SecNumOfText = I + 1;

372 break;

374 if (!InitAuxFileHdr.InitDataSize)

375 InitAuxFileHdr.InitDataSize = InitSections[I].Size;

376 if (!InitAuxFileHdr.DataStartAddr)

377 InitAuxFileHdr.DataStartAddr = InitSections[I].Address;

378 if (!InitAuxFileHdr.SecNumOfData)

379 InitAuxFileHdr.SecNumOfData = I + 1;

380 break;

382 if (!InitAuxFileHdr.BssDataSize)

383 InitAuxFileHdr.BssDataSize = InitSections[I].Size;

384 if (!InitAuxFileHdr.SecNumOfBSS)

385 InitAuxFileHdr.SecNumOfBSS = I + 1;

386 break;

388 if (!InitAuxFileHdr.SecNumOfTData)

389 InitAuxFileHdr.SecNumOfTData = I + 1;

390 break;

392 if (!InitAuxFileHdr.SecNumOfTBSS)

393 InitAuxFileHdr.SecNumOfTBSS = I + 1;

394 break;

396 if (!InitAuxFileHdr.SecNumOfLoader)

397 InitAuxFileHdr.SecNumOfLoader = I + 1;

398 break;

399 default:

400 break;

401 }

402 }

403}

404

405bool XCOFFWriter::assignAddressesAndIndices() {

406 uint64_t FileHdrSize =

408

409

410

411 uint64_t AuxFileHdrSize = 0;

412

413 if (Obj.Header.AuxHeaderSize)

414 AuxFileHdrSize = Obj.Header.AuxHeaderSize;

415 else if (Obj.AuxHeader)

416 AuxFileHdrSize =

418 uint64_t SecHdrSize =

420 uint64_t CurrentOffset =

421 FileHdrSize + AuxFileHdrSize + InitSections.size() * SecHdrSize;

422

423

424 if (!initSectionHeaders(CurrentOffset))

425 return false;

426

427

428 if (!initFileHeader(CurrentOffset))

429 return false;

430 InitFileHdr.AuxHeaderSize = AuxFileHdrSize;

431

432

433 if (AuxFileHdrSize)

434 initAuxFileHeader();

435

436

437 return initStringTable();

438}

439

440void XCOFFWriter::writeFileHeader() {

441 W.write<uint16_t>(Obj.Header.Magic ? Obj.Header.Magic : InitFileHdr.Magic);

442 W.write<uint16_t>(Obj.Header.NumberOfSections ? Obj.Header.NumberOfSections

443 : InitFileHdr.NumberOfSections);

444 W.write<int32_t>(Obj.Header.TimeStamp);

445 if (Is64Bit) {

446 W.write<uint64_t>(InitFileHdr.SymbolTableOffset);

447 W.write<uint16_t>(InitFileHdr.AuxHeaderSize);

448 W.write<uint16_t>(Obj.Header.Flags);

449 W.write<int32_t>(Obj.Header.NumberOfSymTableEntries

450 ? Obj.Header.NumberOfSymTableEntries

451 : InitFileHdr.NumberOfSymTableEntries);

452 } else {

453 W.write<uint32_t>(InitFileHdr.SymbolTableOffset);

454 W.write<int32_t>(Obj.Header.NumberOfSymTableEntries

455 ? Obj.Header.NumberOfSymTableEntries

456 : InitFileHdr.NumberOfSymTableEntries);

457 W.write<uint16_t>(InitFileHdr.AuxHeaderSize);

458 W.write<uint16_t>(Obj.Header.Flags);

459 }

460}

461

462void XCOFFWriter::writeAuxFileHeader() {

463 W.write<uint16_t>(InitAuxFileHdr.Magic.value_or(yaml::Hex16(1)));

464 W.write<uint16_t>(InitAuxFileHdr.Version.value_or(yaml::Hex16(1)));

465 if (Is64Bit) {

466 W.OS.write_zeros(4);

467 W.write<uint64_t>(InitAuxFileHdr.TextStartAddr.value_or(yaml::Hex64(0)));

468 W.write<uint64_t>(InitAuxFileHdr.DataStartAddr.value_or(yaml::Hex64(0)));

469 W.write<uint64_t>(InitAuxFileHdr.TOCAnchorAddr.value_or(yaml::Hex64(0)));

470 } else {

471 W.write<uint32_t>(InitAuxFileHdr.TextSize.value_or(yaml::Hex64(0)));

472 W.write<uint32_t>(InitAuxFileHdr.InitDataSize.value_or(yaml::Hex64(0)));

473 W.write<uint32_t>(InitAuxFileHdr.BssDataSize.value_or(yaml::Hex64(0)));

474 W.write<uint32_t>(InitAuxFileHdr.EntryPointAddr.value_or(yaml::Hex64(0)));

475 W.write<uint32_t>(InitAuxFileHdr.TextStartAddr.value_or(yaml::Hex64(0)));

476 W.write<uint32_t>(InitAuxFileHdr.DataStartAddr.value_or(yaml::Hex64(0)));

477

479 return;

480 W.write<uint32_t>(InitAuxFileHdr.TOCAnchorAddr.value_or(yaml::Hex64(0)));

481 }

482 W.write<uint16_t>(InitAuxFileHdr.SecNumOfEntryPoint.value_or(0));

483 W.write<uint16_t>(InitAuxFileHdr.SecNumOfText.value_or(0));

484 W.write<uint16_t>(InitAuxFileHdr.SecNumOfData.value_or(0));

485 W.write<uint16_t>(InitAuxFileHdr.SecNumOfTOC.value_or(0));

486 W.write<uint16_t>(InitAuxFileHdr.SecNumOfLoader.value_or(0));

487 W.write<uint16_t>(InitAuxFileHdr.SecNumOfBSS.value_or(0));

488 W.write<uint16_t>(InitAuxFileHdr.MaxAlignOfText.value_or(yaml::Hex16(0)));

489 W.write<uint16_t>(InitAuxFileHdr.MaxAlignOfData.value_or(yaml::Hex16(0)));

490 W.write<uint16_t>(InitAuxFileHdr.ModuleType.value_or(yaml::Hex16(0)));

491 W.write<uint8_t>(InitAuxFileHdr.CpuFlag.value_or(yaml::Hex8(0)));

492 W.write<uint8_t>(0);

493 if (Is64Bit) {

494 W.write<uint8_t>(InitAuxFileHdr.TextPageSize.value_or(yaml::Hex8(0)));

495 W.write<uint8_t>(InitAuxFileHdr.DataPageSize.value_or(yaml::Hex8(0)));

496 W.write<uint8_t>(InitAuxFileHdr.StackPageSize.value_or(yaml::Hex8(0)));

497 W.write<uint8_t>(

498 InitAuxFileHdr.FlagAndTDataAlignment.value_or(yaml::Hex8(0x80)));

499 W.write<uint64_t>(InitAuxFileHdr.TextSize.value_or(yaml::Hex64(0)));

500 W.write<uint64_t>(InitAuxFileHdr.InitDataSize.value_or(yaml::Hex64(0)));

501 W.write<uint64_t>(InitAuxFileHdr.BssDataSize.value_or(yaml::Hex64(0)));

502 W.write<uint64_t>(InitAuxFileHdr.EntryPointAddr.value_or(yaml::Hex64(0)));

503 W.write<uint64_t>(InitAuxFileHdr.MaxStackSize.value_or(yaml::Hex64(0)));

504 W.write<uint64_t>(InitAuxFileHdr.MaxDataSize.value_or(yaml::Hex64(0)));

505 } else {

506 W.write<uint32_t>(InitAuxFileHdr.MaxStackSize.value_or(yaml::Hex64(0)));

507 W.write<uint32_t>(InitAuxFileHdr.MaxDataSize.value_or(yaml::Hex64(0)));

508 W.OS.write_zeros(4);

509 W.write<uint8_t>(InitAuxFileHdr.TextPageSize.value_or(yaml::Hex8(0)));

510 W.write<uint8_t>(InitAuxFileHdr.DataPageSize.value_or(yaml::Hex8(0)));

511 W.write<uint8_t>(InitAuxFileHdr.StackPageSize.value_or(yaml::Hex8(0)));

512 W.write<uint8_t>(

513 InitAuxFileHdr.FlagAndTDataAlignment.value_or(yaml::Hex8(0)));

514 }

515 W.write<uint16_t>(InitAuxFileHdr.SecNumOfTData.value_or(0));

516 W.write<uint16_t>(InitAuxFileHdr.SecNumOfTBSS.value_or(0));

517 if (Is64Bit) {

518 W.write<uint16_t>(

522 } else {

525 }

526}

527

528void XCOFFWriter::writeSectionHeaders() {

529 for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {

530 XCOFFYAML::Section DerivedSec = InitSections[I];

532 if (Is64Bit) {

533

534 W.write<uint64_t>(DerivedSec.Address);

535 W.write<uint64_t>(DerivedSec.Address);

536 W.write<uint64_t>(DerivedSec.Size);

542 W.write<int32_t>(DerivedSec.Flags);

543 W.OS.write_zeros(4);

544 } else {

545

546 W.write<uint32_t>(DerivedSec.Address);

547 W.write<uint32_t>(DerivedSec.Address);

548 W.write<uint32_t>(DerivedSec.Size);

554 W.write<int32_t>(DerivedSec.Flags);

555 }

556 }

557}

558

559bool XCOFFWriter::writeSectionData() {

560 for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {

561 XCOFFYAML::Section YamlSec = Obj.Sections[I];

563

564 int64_t PaddingSize = (uint64_t)InitSections[I].FileOffsetToData -

565 (W.OS.tell() - StartOffset);

566 if (PaddingSize < 0) {

567 ErrHandler("redundant data was written before section data");

568 return false;

569 }

570 W.OS.write_zeros(PaddingSize);

572 }

573 }

574 return true;

575}

576

577bool XCOFFWriter::writeRelocations() {

578 for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {

579 XCOFFYAML::Section YamlSec = Obj.Sections[I];

581 int64_t PaddingSize =

582 InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset);

583 if (PaddingSize < 0) {

584 ErrHandler("redundant data was written before relocations");

585 return false;

586 }

587 W.OS.write_zeros(PaddingSize);

588 for (const XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations) {

589 if (Is64Bit)

591 else

594 W.write<uint8_t>(YamlRel.Info);

595 W.write<uint8_t>(YamlRel.Type);

596 }

597 }

598 }

599 return true;

600}

601

602bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {

603 uint8_t SymAlignAndType = 0;

606 ErrHandler("cannot specify SymbolType or SymbolAlignment if "

607 "SymbolAlignmentAndType is specified");

608 return false;

609 }

611 } else {

615 ErrHandler("symbol type must be less than " +

617 return false;

618 }

620 }

622 const uint8_t ShiftedSymbolAlignmentMask =

625

626 if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {

627 ErrHandler("symbol alignment must be less than " +

628 Twine(1 + ShiftedSymbolAlignmentMask));

629 return false;

630 }

633 }

634 }

635 if (Is64Bit) {

639 W.write<uint8_t>(SymAlignAndType);

642 W.write<uint8_t>(0);

644 } else {

648 W.write<uint8_t>(SymAlignAndType);

651 W.write<uint16_t>(AuxSym.StabSectNum.value_or(0));

652 }

653 return true;

654}

655

656bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {

657 assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32");

661 W.write<uint8_t>(0);

663 return true;

664}

665

666bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {

667 if (Is64Bit) {

668 W.write<uint64_t>(AuxSym.PtrToLineNum.value_or(0));

671 W.write<uint8_t>(0);

673 } else {

676 W.write<uint32_t>(AuxSym.PtrToLineNum.value_or(0));

678 W.OS.write_zeros(2);

679 }

680 return true;

681}

682

683bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {

685 if (nameShouldBeInStringTable(FileName)) {

686 W.write<int32_t>(0);

687 W.write<uint32_t>(StrTblBuilder.getOffset(FileName));

688 } else {

689 writeName(FileName, W);

690 }

693 if (Is64Bit) {

694 W.OS.write_zeros(2);

696 } else {

697 W.OS.write_zeros(3);

698 }

699 return true;

700}

701

702bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {

703 if (Is64Bit) {

704 W.write<uint32_t>(AuxSym.LineNum.value_or(0));

705 W.OS.write_zeros(13);

707 } else {

708 W.OS.write_zeros(2);

709 W.write<uint16_t>(AuxSym.LineNumHi.value_or(0));

710 W.write<uint16_t>(AuxSym.LineNumLo.value_or(0));

711 W.OS.write_zeros(12);

712 }

713 return true;

714}

715

716bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {

717 if (Is64Bit) {

720 W.write<uint8_t>(0);

722 } else {

724 W.OS.write_zeros(4);

726 W.OS.write_zeros(6);

727 }

728 return true;

729}

730

731bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {

732 assert(!Is64Bit && "can't write the stat auxiliary symbol for XCOFF64");

736 W.OS.write_zeros(10);

737 return true;

738}

739

740bool XCOFFWriter::writeAuxSymbol(

741 const std::unique_ptrXCOFFYAML::AuxSymbolEnt &AuxSym) {

743 return writeAuxSymbol(*AS);

745 return writeAuxSymbol(*AS);

747 return writeAuxSymbol(*AS);

749 return writeAuxSymbol(*AS);

751 return writeAuxSymbol(*AS);

753 return writeAuxSymbol(*AS);

755 return writeAuxSymbol(*AS);

757 return false;

758}

759

760bool XCOFFWriter::writeSymbols() {

761 int64_t PaddingSize =

762 InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);

763 if (PaddingSize < 0) {

764 ErrHandler("redundant data was written before symbols");

765 return false;

766 }

767 W.OS.write_zeros(PaddingSize);

768 for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {

769 if (Is64Bit) {

770 W.write<uint64_t>(YamlSym.Value);

771 W.write<uint32_t>(StrTblBuilder.getOffset(YamlSym.SymbolName));

772 } else {

773 if (nameShouldBeInStringTable(YamlSym.SymbolName)) {

774

775

776 W.write<int32_t>(0);

777 W.write<uint32_t>(StrTblBuilder.getOffset(YamlSym.SymbolName));

778 } else {

780 }

781 W.write<uint32_t>(YamlSym.Value);

782 }

784 auto It = SectionIndexMap.find(*YamlSym.SectionName);

785 if (It == SectionIndexMap.end()) {

786 ErrHandler("the SectionName " + *YamlSym.SectionName +

787 " specified in the symbol does not exist");

788 return false;

789 }

791 ErrHandler("the SectionName " + *YamlSym.SectionName +

792 " and the SectionIndex (" + Twine(*YamlSym.SectionIndex) +

793 ") refer to different sections");

794 return false;

795 }

796 W.write<int16_t>(It->second);

797 } else {

798 W.write<int16_t>(YamlSym.SectionIndex.value_or(0));

799 }

800 W.write<uint16_t>(YamlSym.Type);

802

804 W.write<uint8_t>(NumOfAuxSym);

805

806 if (!NumOfAuxSym && !YamlSym.AuxEntries.size())

807 continue;

808

809

812 } else {

813 for (const std::unique_ptrXCOFFYAML::AuxSymbolEnt &AuxSym :

815 if (!writeAuxSymbol(AuxSym))

816 return false;

817 }

818

819 if (NumOfAuxSym > YamlSym.AuxEntries.size())

821 (NumOfAuxSym - YamlSym.AuxEntries.size()));

822 }

823 }

824 return true;

825}

826

827void XCOFFWriter::writeStringTable() {

828 if (Obj.StrTbl.RawContent) {

829 Obj.StrTbl.RawContent->writeAsBinary(W.OS);

830 if (Obj.StrTbl.ContentSize) {

831 assert(*Obj.StrTbl.ContentSize >= Obj.StrTbl.RawContent->binary_size() &&

832 "Specified ContentSize is less than the RawContent size.");

833 W.OS.write_zeros(*Obj.StrTbl.ContentSize -

834 Obj.StrTbl.RawContent->binary_size());

835 }

836 return;

837 }

838

839 size_t StrTblBuilderSize = StrTblBuilder.getSize();

840

841

842 if (Obj.StrTbl.Length && Obj.StrTbl.ContentSize) {

843 if (StrTblBuilderSize <= 4)

844 return;

845 StrTblBuilder.write(W.OS);

846 return;

847 }

848

849

850 std::unique_ptr Buf =

852 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart());

853 StrTblBuilder.write(Ptr);

854

855

856 memset(Ptr, 0, 4);

858 : *Obj.StrTbl.ContentSize);

859

860 W.OS.write(Buf->getBufferStart(), Buf->getBufferSize());

861

862 if (Obj.StrTbl.ContentSize) {

863 assert(*Obj.StrTbl.ContentSize >= StrTblBuilderSize &&

864 "Specified ContentSize is less than the StringTableBuilder size.");

865 W.OS.write_zeros(*Obj.StrTbl.ContentSize - StrTblBuilderSize);

866 }

867}

868

869bool XCOFFWriter::writeXCOFF() {

870 if (!assignAddressesAndIndices())

871 return false;

872 StartOffset = W.OS.tell();

873 writeFileHeader();

874 if (InitFileHdr.AuxHeaderSize)

875 writeAuxFileHeader();

876 if (Obj.Sections.empty()) {

877 writeSectionHeaders();

878 if (!writeSectionData())

879 return false;

880 if (!writeRelocations())

881 return false;

882 }

883 if (Obj.Symbols.empty() && !writeSymbols())

884 return false;

886 return true;

887}

888

889}

890

891namespace llvm {

892namespace yaml {

893

895 XCOFFWriter Writer(Doc, Out, EH);

896 return Writer.writeXCOFF();

897}

898

899}

900}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file defines the DenseMap class.

static Error initRelocations(RelocationSection *Relocs, T RelRange)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static LLVM_ABI std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")

Allocate a new zero-initialized MemoryBuffer of the specified size.

static constexpr uint8_t SymbolTypeMask

static constexpr size_t SymbolAlignmentBitOffset

static constexpr uint8_t SymbolAlignmentMask

This class implements an extremely fast bulk output stream that can only output to a stream.

ArrayRef< uint8_t >::size_type binary_size() const

The number of bytes that are represented by this BinaryRef.

LLVM_ABI void writeAsBinary(raw_ostream &OS, uint64_t N=UINT64_MAX) const

Write the contents (regardless of whether it is binary or a hex string) as binary to the given raw_os...

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char SymbolName[]

Key for Kernel::Metadata::mSymbolName.

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

@ SHR_SYMTAB

At exec time, create shared symbol table for program (main program only).

constexpr size_t RelocationSerializationSize32

constexpr size_t RelocationSerializationSize64

constexpr size_t FileHeaderSize64

constexpr size_t AuxFileHeaderSize64

constexpr size_t SectionHeaderSize64

@ AUX_SECT

Identifies a SECT auxiliary entry.

@ AUX_FILE

Identifies a file auxiliary entry.

@ AUX_EXCEPT

Identifies an exception auxiliary entry.

@ AUX_FCN

Identifies a function auxiliary entry.

@ AUX_SYM

Identifies a symbol auxiliary entry.

@ AUX_CSECT

Identifies a csect auxiliary entry.

constexpr size_t NameSize

constexpr size_t AuxFileHeaderSizeShort

constexpr size_t AuxFileHeaderSize32

@ XFT_FN

Specifies the source-file name.

constexpr size_t FileHeaderSize32

constexpr size_t SectionHeaderSize32

constexpr size_t SymbolTableEntrySize

constexpr size_t FileNamePadSize

static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string_view > Strings)

void write32be(void *P, uint32_t V)

llvm::function_ref< void(const Twine &Msg)> ErrorHandler

LLVM_ABI bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH)

Definition XCOFFEmitter.cpp:894

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

std::optional< uint32_t > LineNum

std::optional< uint16_t > LineNumHi

std::optional< uint16_t > LineNumLo

std::optional< uint16_t > TypeChkSectNum

std::optional< uint32_t > ParameterHashIndex

std::optional< uint32_t > SectionOrLength

std::optional< uint32_t > SectionOrLengthHi

std::optional< uint8_t > SymbolAlignmentAndType

std::optional< uint32_t > SectionOrLengthLo

std::optional< uint8_t > SymbolAlignment

std::optional< uint16_t > StabSectNum

std::optional< XCOFF::StorageMappingClass > StorageMappingClass

std::optional< uint32_t > StabInfoIndex

std::optional< XCOFF::SymbolType > SymbolType

std::optional< int32_t > SymIdxOfNextBeyond

std::optional< uint32_t > SizeOfFunction

std::optional< uint64_t > OffsetToExceptionTbl

std::optional< XCOFF::CFileStringType > FileStringType

std::optional< StringRef > FileNameOrString

std::optional< int32_t > SymIdxOfNextBeyond

std::optional< uint32_t > OffsetToExceptionTbl

std::optional< uint64_t > PtrToLineNum

std::optional< uint32_t > SizeOfFunction

llvm::yaml::Hex64 SymbolIndex

llvm::yaml::Hex64 VirtualAddress

std::optional< uint32_t > NumberOfRelocEnt

std::optional< uint32_t > LengthOfSectionPortion

std::optional< uint16_t > NumberOfRelocEnt

std::optional< uint16_t > NumberOfLineNum

std::optional< uint32_t > SectionLength

llvm::yaml::Hex64 FileOffsetToRelocations

llvm::yaml::Hex64 Address

llvm::yaml::Hex64 FileOffsetToData

yaml::BinaryRef SectionData

std::vector< Relocation > Relocations

llvm::yaml::Hex16 NumberOfLineNumbers

llvm::yaml::Hex16 NumberOfRelocations

llvm::yaml::Hex64 FileOffsetToLineNumbers

std::vector< std::unique_ptr< AuxSymbolEnt > > AuxEntries

std::optional< uint16_t > SectionIndex

std::optional< uint8_t > NumberOfAuxEntries

XCOFF::StorageClass StorageClass

std::optional< StringRef > SectionName

Adapter to write values to a stream in a particular byte order.

Common declarations for yaml2obj.