@@ -160,10 +160,12 @@ class ELFObjectWriter : public MCObjectWriter {
160
160
bool ZLibStyle, unsigned Alignment);
161
161
162
162
public:
163
+ support::endian::Writer W;
164
+
163
165
ELFObjectWriter (std::unique_ptr<MCELFObjectTargetWriter> MOTW,
164
166
raw_pwrite_stream &OS, bool IsLittleEndian)
165
- : MCObjectWriter(OS, IsLittleEndian),
166
- TargetObjectWriter (std::move(MOTW) ) {}
167
+ : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(std::move(MOTW)),
168
+ W (OS, IsLittleEndian ? support::little : support::big ) {}
167
169
168
170
~ELFObjectWriter () override = default ;
169
171
@@ -175,16 +177,15 @@ class ELFObjectWriter : public MCObjectWriter {
175
177
MCObjectWriter::reset ();
176
178
}
177
179
178
- void WriteWord (uint64_t W ) {
180
+ void WriteWord (uint64_t Word ) {
179
181
if (is64Bit ())
180
- write64 (W );
182
+ W. write < uint64_t >(Word );
181
183
else
182
- write32 (W );
184
+ W. write < uint32_t >(Word );
183
185
}
184
186
185
187
template <typename T> void write (T Val) {
186
- support::endian::write (getStream (), Val,
187
- IsLittleEndian ? support::little : support::big);
188
+ W.write (Val);
188
189
}
189
190
190
191
void writeHeader (const MCAssembler &Asm);
@@ -255,8 +256,8 @@ class ELFObjectWriter : public MCObjectWriter {
255
256
} // end anonymous namespace
256
257
257
258
void ELFObjectWriter::align (unsigned Alignment) {
258
- uint64_t Padding = OffsetToAlignment (getStream () .tell (), Alignment);
259
- WriteZeros (Padding);
259
+ uint64_t Padding = OffsetToAlignment (W. OS .tell (), Alignment);
260
+ W. OS . write_zeros (Padding);
260
261
}
261
262
262
263
unsigned ELFObjectWriter::addToSectionTable (const MCSectionELF *Sec) {
@@ -325,47 +326,50 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
325
326
// emitWord method behaves differently for ELF32 and ELF64, writing
326
327
// 4 bytes in the former and 8 in the latter.
327
328
328
- writeBytes ( ELF::ElfMagic) ; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
329
+ W. OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
329
330
330
- write8 (is64Bit () ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
331
+ W. OS << char (is64Bit () ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
331
332
332
333
// e_ident[EI_DATA]
333
- write8 (isLittleEndian () ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
334
+ W.OS << char (W.Endian == support::little ? ELF::ELFDATA2LSB
335
+ : ELF::ELFDATA2MSB);
334
336
335
- write8 (ELF::EV_CURRENT); // e_ident[EI_VERSION]
337
+ W. OS << char (ELF::EV_CURRENT); // e_ident[EI_VERSION]
336
338
// e_ident[EI_OSABI]
337
- write8 (TargetObjectWriter->getOSABI ());
338
- write8 (0 ); // e_ident[EI_ABIVERSION]
339
+ W. OS << char (TargetObjectWriter->getOSABI ());
340
+ W. OS << char (0 ); // e_ident[EI_ABIVERSION]
339
341
340
- WriteZeros (ELF::EI_NIDENT - ELF::EI_PAD);
342
+ W. OS . write_zeros (ELF::EI_NIDENT - ELF::EI_PAD);
341
343
342
- write16 (ELF::ET_REL); // e_type
344
+ W. write < uint16_t > (ELF::ET_REL); // e_type
343
345
344
- write16 (TargetObjectWriter->getEMachine ()); // e_machine = target
346
+ W. write < uint16_t > (TargetObjectWriter->getEMachine ()); // e_machine = target
345
347
346
- write32 (ELF::EV_CURRENT); // e_version
348
+ W. write < uint32_t > (ELF::EV_CURRENT); // e_version
347
349
WriteWord (0 ); // e_entry, no entry point in .o file
348
350
WriteWord (0 ); // e_phoff, no program header for .o
349
351
WriteWord (0 ); // e_shoff = sec hdr table off in bytes
350
352
351
353
// e_flags = whatever the target wants
352
- write32 (Asm.getELFHeaderEFlags ());
354
+ W. write < uint32_t > (Asm.getELFHeaderEFlags ());
353
355
354
356
// e_ehsize = ELF header size
355
- write16 (is64Bit () ? sizeof (ELF::Elf64_Ehdr) : sizeof (ELF::Elf32_Ehdr));
357
+ W.write <uint16_t >(is64Bit () ? sizeof (ELF::Elf64_Ehdr)
358
+ : sizeof (ELF::Elf32_Ehdr));
356
359
357
- write16 (0 ); // e_phentsize = prog header entry size
358
- write16 (0 ); // e_phnum = # prog header entries = 0
360
+ W. write < uint16_t > (0 ); // e_phentsize = prog header entry size
361
+ W. write < uint16_t > (0 ); // e_phnum = # prog header entries = 0
359
362
360
363
// e_shentsize = Section header entry size
361
- write16 (is64Bit () ? sizeof (ELF::Elf64_Shdr) : sizeof (ELF::Elf32_Shdr));
364
+ W.write <uint16_t >(is64Bit () ? sizeof (ELF::Elf64_Shdr)
365
+ : sizeof (ELF::Elf32_Shdr));
362
366
363
367
// e_shnum = # of section header ents
364
- write16 (0 );
368
+ W. write < uint16_t > (0 );
365
369
366
370
// e_shstrndx = Section # of '.shstrtab'
367
371
assert (StringTableIndex < ELF::SHN_LORESERVE);
368
- write16 (StringTableIndex);
372
+ W. write < uint16_t > (StringTableIndex);
369
373
}
370
374
371
375
uint64_t ELFObjectWriter::SymbolValue (const MCSymbol &Sym,
@@ -784,7 +788,7 @@ void ELFObjectWriter::computeSymbolTable(
784
788
SymbolTableIndex = addToSectionTable (SymtabSection);
785
789
786
790
align (SymtabSection->getAlignment ());
787
- uint64_t SecStart = getStream () .tell ();
791
+ uint64_t SecStart = W. OS .tell ();
788
792
789
793
// The first entry is the undefined symbol entry.
790
794
Writer.writeSymbol (0 , 0 , 0 , 0 , 0 , 0 , false );
@@ -900,7 +904,7 @@ void ELFObjectWriter::computeSymbolTable(
900
904
assert (MSD.Symbol ->getBinding () != ELF::STB_LOCAL);
901
905
}
902
906
903
- uint64_t SecEnd = getStream () .tell ();
907
+ uint64_t SecEnd = W. OS .tell ();
904
908
SectionOffsets[SymtabSection] = std::make_pair (SecStart, SecEnd);
905
909
906
910
ArrayRef<uint32_t > ShndxIndexes = Writer.getShndxIndexes ();
@@ -910,12 +914,12 @@ void ELFObjectWriter::computeSymbolTable(
910
914
}
911
915
assert (SymtabShndxSectionIndex != 0 );
912
916
913
- SecStart = getStream () .tell ();
917
+ SecStart = W. OS .tell ();
914
918
const MCSectionELF *SymtabShndxSection =
915
919
SectionTable[SymtabShndxSectionIndex - 1 ];
916
920
for (uint32_t Index : ShndxIndexes)
917
921
write (Index);
918
- SecEnd = getStream () .tell ();
922
+ SecEnd = W. OS .tell ();
919
923
SectionOffsets[SymtabShndxSection] = std::make_pair (SecStart, SecEnd);
920
924
}
921
925
@@ -976,8 +980,8 @@ bool ELFObjectWriter::maybeWriteCompression(
976
980
const StringRef Magic = " ZLIB" ;
977
981
if (Size <= Magic.size () + sizeof (Size ) + CompressedContents.size ())
978
982
return false ;
979
- write (ArrayRef< char >(Magic. begin (), Magic. size ())) ;
980
- writeBE64 ( Size );
983
+ W. OS << Magic;
984
+ support::endian::write (W. OS , Size , support::big );
981
985
return true ;
982
986
}
983
987
@@ -996,7 +1000,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
996
1000
MAI->compressDebugSections () != DebugCompressionType::None;
997
1001
if (!CompressionEnabled || !SectionName.startswith (" .debug_" ) ||
998
1002
SectionName == " .debug_frame" ) {
999
- Asm.writeSectionData (getStream () , &Section, Layout);
1003
+ Asm.writeSectionData (W. OS , &Section, Layout);
1000
1004
return ;
1001
1005
}
1002
1006
@@ -1013,14 +1017,14 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
1013
1017
StringRef (UncompressedData.data (), UncompressedData.size ()),
1014
1018
CompressedContents)) {
1015
1019
consumeError (std::move (E));
1016
- getStream () << UncompressedData;
1020
+ W. OS << UncompressedData;
1017
1021
return ;
1018
1022
}
1019
1023
1020
1024
bool ZlibStyle = MAI->compressDebugSections () == DebugCompressionType::Z;
1021
1025
if (!maybeWriteCompression (UncompressedData.size (), CompressedContents,
1022
1026
ZlibStyle, Sec.getAlignment ())) {
1023
- getStream () << UncompressedData;
1027
+ W. OS << UncompressedData;
1024
1028
return ;
1025
1029
}
1026
1030
@@ -1030,7 +1034,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
1030
1034
else
1031
1035
// Add "z" prefix to section name. This is zlib-gnu style.
1032
1036
MC.renameELFSection (&Section, (" .z" + SectionName.drop_front (1 )).str ());
1033
- getStream () << CompressedContents;
1037
+ W. OS << CompressedContents;
1034
1038
}
1035
1039
1036
1040
void ELFObjectWriter::WriteSecHdrEntry (uint32_t Name, uint32_t Type,
@@ -1039,14 +1043,14 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1039
1043
uint32_t Link, uint32_t Info,
1040
1044
uint64_t Alignment,
1041
1045
uint64_t EntrySize) {
1042
- write32 (Name); // sh_name: index into string table
1043
- write32 (Type); // sh_type
1046
+ W. write < uint32_t > (Name); // sh_name: index into string table
1047
+ W. write < uint32_t > (Type); // sh_type
1044
1048
WriteWord (Flags); // sh_flags
1045
1049
WriteWord (Address); // sh_addr
1046
1050
WriteWord (Offset); // sh_offset
1047
1051
WriteWord (Size ); // sh_size
1048
- write32 (Link); // sh_link
1049
- write32 (Info); // sh_info
1052
+ W. write < uint32_t > (Link); // sh_link
1053
+ W. write < uint32_t > (Info); // sh_info
1050
1054
WriteWord (Alignment); // sh_addralign
1051
1055
WriteWord (EntrySize); // sh_entsize
1052
1056
}
@@ -1116,7 +1120,7 @@ void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
1116
1120
1117
1121
const MCSectionELF *ELFObjectWriter::createStringTable (MCContext &Ctx) {
1118
1122
const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1 ];
1119
- StrTabBuilder.write (getStream () );
1123
+ StrTabBuilder.write (W. OS );
1120
1124
return StrtabSection;
1121
1125
}
1122
1126
@@ -1226,12 +1230,12 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
1226
1230
align (Section.getAlignment ());
1227
1231
1228
1232
// Remember the offset into the file for this section.
1229
- uint64_t SecStart = getStream () .tell ();
1233
+ uint64_t SecStart = W. OS .tell ();
1230
1234
1231
1235
const MCSymbolELF *SignatureSymbol = Section.getGroup ();
1232
1236
writeSectionData (Asm, Section, Layout);
1233
1237
1234
- uint64_t SecEnd = getStream () .tell ();
1238
+ uint64_t SecEnd = W. OS .tell ();
1235
1239
SectionOffsets[&Section] = std::make_pair (SecStart, SecEnd);
1236
1240
1237
1241
MCSectionELF *RelSection = createRelocationSection (Ctx, Section);
@@ -1263,7 +1267,7 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
1263
1267
align (Group->getAlignment ());
1264
1268
1265
1269
// Remember the offset into the file for this section.
1266
- uint64_t SecStart = getStream () .tell ();
1270
+ uint64_t SecStart = W. OS .tell ();
1267
1271
1268
1272
const MCSymbol *SignatureSymbol = Group->getGroup ();
1269
1273
assert (SignatureSymbol);
@@ -1273,7 +1277,7 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
1273
1277
write (SecIndex);
1274
1278
}
1275
1279
1276
- uint64_t SecEnd = getStream () .tell ();
1280
+ uint64_t SecEnd = W. OS .tell ();
1277
1281
SectionOffsets[Group] = std::make_pair (SecStart, SecEnd);
1278
1282
}
1279
1283
@@ -1284,54 +1288,52 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
1284
1288
align (RelSection->getAlignment ());
1285
1289
1286
1290
// Remember the offset into the file for this section.
1287
- uint64_t SecStart = getStream () .tell ();
1291
+ uint64_t SecStart = W. OS .tell ();
1288
1292
1289
1293
writeRelocations (Asm,
1290
1294
cast<MCSectionELF>(*RelSection->getAssociatedSection ()));
1291
1295
1292
- uint64_t SecEnd = getStream () .tell ();
1296
+ uint64_t SecEnd = W. OS .tell ();
1293
1297
SectionOffsets[RelSection] = std::make_pair (SecStart, SecEnd);
1294
1298
}
1295
1299
1296
1300
{
1297
- uint64_t SecStart = getStream () .tell ();
1301
+ uint64_t SecStart = W. OS .tell ();
1298
1302
const MCSectionELF *Sec = createStringTable (Ctx);
1299
- uint64_t SecEnd = getStream () .tell ();
1303
+ uint64_t SecEnd = W. OS .tell ();
1300
1304
SectionOffsets[Sec] = std::make_pair (SecStart, SecEnd);
1301
1305
}
1302
1306
1303
1307
uint64_t NaturalAlignment = is64Bit () ? 8 : 4 ;
1304
1308
align (NaturalAlignment);
1305
1309
1306
- const uint64_t SectionHeaderOffset = getStream () .tell ();
1310
+ const uint64_t SectionHeaderOffset = W. OS .tell ();
1307
1311
1308
1312
// ... then the section header table ...
1309
1313
writeSectionHeader (Layout, SectionIndexMap, SectionOffsets);
1310
1314
1311
- uint16_t NumSections = (SectionTable.size () + 1 >= ELF::SHN_LORESERVE)
1312
- ? (uint16_t )ELF::SHN_UNDEF
1313
- : SectionTable.size () + 1 ;
1314
- if (sys::IsLittleEndianHost != IsLittleEndian)
1315
- sys::swapByteOrder (NumSections);
1315
+ uint16_t NumSections = support::endian::byte_swap<uint16_t >(
1316
+ (SectionTable.size () + 1 >= ELF::SHN_LORESERVE) ? (uint16_t )ELF::SHN_UNDEF
1317
+ : SectionTable.size () + 1 ,
1318
+ W.Endian );
1316
1319
unsigned NumSectionsOffset;
1317
1320
1321
+ auto &Stream = static_cast <raw_pwrite_stream &>(W.OS );
1318
1322
if (is64Bit ()) {
1319
- uint64_t Val = SectionHeaderOffset;
1320
- if (sys::IsLittleEndianHost != IsLittleEndian)
1321
- sys::swapByteOrder (Val);
1322
- getStream ().pwrite (reinterpret_cast <char *>(&Val), sizeof (Val),
1323
- offsetof (ELF::Elf64_Ehdr, e_shoff));
1323
+ uint64_t Val =
1324
+ support::endian::byte_swap<uint64_t >(SectionHeaderOffset, W.Endian );
1325
+ Stream.pwrite (reinterpret_cast <char *>(&Val), sizeof (Val),
1326
+ offsetof (ELF::Elf64_Ehdr, e_shoff));
1324
1327
NumSectionsOffset = offsetof (ELF::Elf64_Ehdr, e_shnum);
1325
1328
} else {
1326
- uint32_t Val = SectionHeaderOffset;
1327
- if (sys::IsLittleEndianHost != IsLittleEndian)
1328
- sys::swapByteOrder (Val);
1329
- getStream ().pwrite (reinterpret_cast <char *>(&Val), sizeof (Val),
1330
- offsetof (ELF::Elf32_Ehdr, e_shoff));
1329
+ uint32_t Val =
1330
+ support::endian::byte_swap<uint32_t >(SectionHeaderOffset, W.Endian );
1331
+ Stream.pwrite (reinterpret_cast <char *>(&Val), sizeof (Val),
1332
+ offsetof (ELF::Elf32_Ehdr, e_shoff));
1331
1333
NumSectionsOffset = offsetof (ELF::Elf32_Ehdr, e_shnum);
1332
1334
}
1333
- getStream () .pwrite (reinterpret_cast <char *>(&NumSections),
1334
- sizeof (NumSections), NumSectionsOffset);
1335
+ Stream .pwrite (reinterpret_cast <char *>(&NumSections), sizeof ( NumSections),
1336
+ NumSectionsOffset);
1335
1337
}
1336
1338
1337
1339
bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl (
0 commit comments