@@ -88,8 +88,8 @@ class ELFWriter {
88
88
uint64_t writeSectionData (const uint8_t * data, uint64_t size, uint32_t padding);
89
89
// write symbol table section, return section size
90
90
uint64_t writeSymTab ();
91
- // write relocation table section
92
- uint64_t writeRelocTab (const RelocationListTy& relocs);
91
+ // write rel or rela relocation table section
92
+ uint64_t writeRelocTab (const RelocationListTy& relocs, bool isRelFormat );
93
93
// write ze info section
94
94
uint64_t writeZEInfo ();
95
95
// write string table
@@ -118,13 +118,14 @@ class ELFWriter {
118
118
SectionHdrEntry& createNullSectionHdrEntry ();
119
119
120
120
uint32_t getSymTabEntSize ();
121
- uint32_t getRelocTabEntSize ();
121
+ uint32_t getRelocTabEntSize (bool isRelFormat );
122
122
123
123
// name is the string table index of the symbol name
124
124
void writeSymbol (uint32_t name, uint64_t value, uint64_t size,
125
125
uint8_t binding, uint8_t type, uint8_t other, uint16_t shndx);
126
126
127
- void writeRelocation (uint64_t offset, uint64_t type, uint64_t symIdx);
127
+ void writeRelRelocation (uint64_t offset, uint64_t type, uint64_t symIdx);
128
+ void writeRelaRelocation (uint64_t offset, uint64_t type, uint64_t symIdx, uint64_t addend);
128
129
129
130
void writeSecHdrEntry (uint32_t name, uint32_t type, uint64_t flags,
130
131
uint64_t address, uint64_t offset,
@@ -171,8 +172,8 @@ ZEELFObjectBuilder::addStandardSection(
171
172
// total required padding is (padding + need_padding_for_align)
172
173
sections.emplace_back (
173
174
ZEELFObjectBuilder::StandardSection (sectName, data, size, type,
174
- (need_padding_for_align + padding), m_sectionId ));
175
- ++m_sectionId ;
175
+ (need_padding_for_align + padding), m_sectionIdCount ));
176
+ ++m_sectionIdCount ;
176
177
return sections.back ();
177
178
}
178
179
@@ -263,8 +264,8 @@ ZEELFObjectBuilder::addSectionZEInfo(zeInfoContainer& zeInfo)
263
264
{
264
265
// every object should have exactly one ze_info section
265
266
IGC_ASSERT (nullptr == m_zeInfoSection);
266
- m_zeInfoSection = new ZEInfoSection (zeInfo, m_sectionId );
267
- ++m_sectionId ;
267
+ m_zeInfoSection = new ZEInfoSection (zeInfo, m_sectionIdCount );
268
+ ++m_sectionIdCount ;
268
269
}
269
270
270
271
void ZEELFObjectBuilder::addSymbol (
@@ -280,40 +281,49 @@ void ZEELFObjectBuilder::addSymbol(
280
281
}
281
282
282
283
ZEELFObjectBuilder::RelocSection&
283
- ZEELFObjectBuilder::getOrCreateRelocSection (SectionID targetSectId)
284
+ ZEELFObjectBuilder::getOrCreateRelocSection (SectionID targetSectId, bool isRelFormat )
284
285
{
285
- // linear search to see if there's existed reloc section with given target id
286
+ // linear search to see if there's existed reloc section with given target id and rel format
286
287
// reversly iterate that the latest added might hit first
287
288
for (RelocSectionListTy::reverse_iterator it = m_relocSections.rbegin ();
288
289
it != m_relocSections.rend (); ++it) {
289
- if ((*it).m_TargetID == targetSectId)
290
+ if ((*it).m_TargetID == targetSectId && (*it). isRelFormat () == isRelFormat )
290
291
return *it;
291
292
}
292
293
// if not found, create one
293
- // adjust the section name to be .rel.applyTergetName
294
- // If the targt name is empty, we use the defualt name .rel as the section name
294
+ // adjust the section name to be .rel.applyTargetName or .rela.applyTargetName
295
+ // If the targt name is empty, we use the defualt name .rel/.rela as the section name
295
296
// though in our case this should not happen
296
297
std::string sectName;
297
298
std::string targetName = getSectionNameBySectionID (targetSectId);
298
299
if (!targetName.empty ())
299
- sectName = m_RelName + targetName;
300
+ sectName = (isRelFormat? m_RelName : m_RelaName) + targetName;
300
301
else
301
- sectName = m_RelName;
302
+ sectName = isRelFormat? m_RelName : m_RelaName ;
302
303
303
- m_relocSections.emplace_back (m_sectionId , targetSectId, sectName);
304
- ++m_sectionId ;
304
+ m_relocSections.emplace_back (RelocSection (m_sectionIdCount , targetSectId, sectName, isRelFormat) );
305
+ ++m_sectionIdCount ;
305
306
return m_relocSections.back ();
306
307
}
307
308
308
- void ZEELFObjectBuilder::addRelocation (
309
+ void ZEELFObjectBuilder::addRelRelocation (
309
310
uint64_t offset, std::string symName, R_TYPE_ZEBIN type, SectionID sectionId)
310
311
{
311
- RelocSection& reloc_sect = getOrCreateRelocSection (sectionId);
312
+ RelocSection& reloc_sect = getOrCreateRelocSection (sectionId, true );
312
313
// create the relocation
313
314
reloc_sect.m_Relocations .emplace_back (
314
315
ZEELFObjectBuilder::Relocation (offset, symName, type));
315
316
}
316
317
318
+ void ZEELFObjectBuilder::addRelaRelocation (
319
+ uint64_t offset, std::string symName, R_TYPE_ZEBIN type, uint64_t addend, SectionID sectionId)
320
+ {
321
+ RelocSection& reloc_sect = getOrCreateRelocSection (sectionId, false );
322
+ // create the relocation
323
+ reloc_sect.m_Relocations .emplace_back (
324
+ ZEELFObjectBuilder::Relocation (offset, symName, type, addend));
325
+ }
326
+
317
327
uint64_t ZEELFObjectBuilder::finalize (llvm::raw_pwrite_stream& os)
318
328
{
319
329
ELFWriter w (os, *this );
@@ -387,12 +397,12 @@ uint32_t ELFWriter::getSymTabEntSize()
387
397
return sizeof (ELF::Elf32_Sym);
388
398
}
389
399
390
- uint32_t ELFWriter::getRelocTabEntSize ()
400
+ uint32_t ELFWriter::getRelocTabEntSize (bool isRelFormat )
391
401
{
392
402
if (is64Bit ())
393
- return sizeof (ELF::Elf64_Rel);
403
+ return isRelFormat ? sizeof (ELF::Elf64_Rel) : sizeof (ELF::Elf64_Rela );
394
404
else
395
- return sizeof (ELF::Elf32_Rel);
405
+ return isRelFormat ? sizeof (ELF::Elf32_Rel) : sizeof (ELF::Elf32_Rela );
396
406
}
397
407
398
408
void ELFWriter::writeSymbol (uint32_t name, uint64_t value, uint64_t size,
@@ -416,7 +426,7 @@ void ELFWriter::writeSymbol(uint32_t name, uint64_t value, uint64_t size,
416
426
}
417
427
}
418
428
419
- void ELFWriter::writeRelocation (uint64_t offset, uint64_t type, uint64_t symIdx)
429
+ void ELFWriter::writeRelRelocation (uint64_t offset, uint64_t type, uint64_t symIdx)
420
430
{
421
431
if (is64Bit ()) {
422
432
uint64_t info = (symIdx << 32 ) | (type & 0xffffffffL );
@@ -429,15 +439,30 @@ void ELFWriter::writeRelocation(uint64_t offset, uint64_t type, uint64_t symIdx)
429
439
}
430
440
}
431
441
432
- uint64_t ELFWriter::writeRelocTab (const RelocationListTy& relocs)
442
+ void ELFWriter::writeRelaRelocation (uint64_t offset, uint64_t type, uint64_t symIdx, uint64_t addend)
443
+ {
444
+ writeRelRelocation (offset, type, symIdx);
445
+ if (is64Bit ()) {
446
+ m_W.write (addend);
447
+ } else {
448
+ m_W.write (uint32_t (addend));
449
+ }
450
+ }
451
+
452
+ uint64_t ELFWriter::writeRelocTab (const RelocationListTy& relocs, bool isRelFormat)
433
453
{
434
454
uint64_t start_off = m_W.OS .tell ();
435
455
436
456
for (const ZEELFObjectBuilder::Relocation& reloc : relocs) {
437
457
// the target symbol's name must have been added into symbol table
438
458
IGC_ASSERT (m_SymNameIdxMap.find (reloc.symName ()) != m_SymNameIdxMap.end ());
439
- writeRelocation (
440
- reloc.offset (), reloc.type (), m_SymNameIdxMap[reloc.symName ()]);
459
+
460
+ if (isRelFormat)
461
+ writeRelRelocation (
462
+ reloc.offset (), reloc.type (), m_SymNameIdxMap[reloc.symName ()]);
463
+ else
464
+ writeRelaRelocation (
465
+ reloc.offset (), reloc.type (), m_SymNameIdxMap[reloc.symName ()], reloc.addend ());
441
466
}
442
467
443
468
return m_W.OS .tell () - start_off;
@@ -576,14 +601,15 @@ void ELFWriter::writeSections()
576
601
entry.info = m_ObjBuilder.m_localSymbols .size () + 1 ;
577
602
break ;
578
603
579
- case ELF::SHT_REL: {
604
+ case ELF::SHT_REL:
605
+ case ELF::SHT_RELA: {
580
606
IGC_ASSERT (nullptr != entry.section );
581
607
IGC_ASSERT (entry.section ->getKind () == Section::RELOC);
582
608
const RelocSection* const relocSec =
583
609
static_cast <const RelocSection*>(entry.section );
584
610
IGC_ASSERT (nullptr != relocSec);
585
- entry.size = writeRelocTab (relocSec->m_Relocations );
586
- entry.entsize = getRelocTabEntSize ();
611
+ entry.size = writeRelocTab (relocSec->m_Relocations , relocSec-> isRelFormat () );
612
+ entry.entsize = getRelocTabEntSize (relocSec-> isRelFormat () );
587
613
break ;
588
614
}
589
615
case SHT_ZEBIN_ZEINFO:
@@ -737,7 +763,7 @@ void ELFWriter::createSectionHdrEntries()
737
763
// .data
738
764
// .symtab
739
765
// all other standard sections follow the order of being added (spv, debug)
740
- // .rel
766
+ // .rel and .rela
741
767
// .ze_info
742
768
// .strtab
743
769
@@ -774,12 +800,14 @@ void ELFWriter::createSectionHdrEntries()
774
800
createSectionHdrEntry (sect.m_sectName , sect.m_type , §);
775
801
}
776
802
777
- // .rel
803
+ // .rel and .rela
778
804
if (!m_ObjBuilder.m_relocSections .empty ()) {
779
805
// go through relocation sections
780
806
for (RelocSection& sect : m_ObjBuilder.m_relocSections ) {
781
807
SectionHdrEntry& entry =
782
- createSectionHdrEntry (sect.m_sectName , ELF::SHT_REL, §);
808
+ sect.isRelFormat () ?
809
+ createSectionHdrEntry (sect.m_sectName , ELF::SHT_REL, §) :
810
+ createSectionHdrEntry (sect.m_sectName , ELF::SHT_RELA, §);
783
811
// set apply target's section index
784
812
// relocations could only apply to standard sections. At this point,
785
813
// all standard section's section index should be adjusted
0 commit comments