@@ -108,24 +108,49 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
108
108
Error graphifySections ();
109
109
Error graphifySymbols ();
110
110
111
- // / Traverse all matching relocation records in the given section. The handler
112
- // / function Func should be callable with this signature:
111
+ // / Traverse all matching ELFT::Rela relocation records in the given section.
112
+ // / The handler function Func should be callable with this signature:
113
113
// / Error(const typename ELFT::Rela &,
114
114
// / const typename ELFT::Shdr &, Section &)
115
115
// /
116
- template <typename RelocHandlerFunction>
117
- Error forEachRelocation (const typename ELFT::Shdr &RelSect,
118
- RelocHandlerFunction &&Func,
119
- bool ProcessDebugSections = false );
116
+ template <typename RelocHandlerMethod>
117
+ Error forEachRelaRelocation (const typename ELFT::Shdr &RelSect,
118
+ RelocHandlerMethod &&Func,
119
+ bool ProcessDebugSections = false );
120
+
121
+ // / Traverse all matching ELFT::Rel relocation records in the given section.
122
+ // / The handler function Func should be callable with this signature:
123
+ // / Error(const typename ELFT::Rel &,
124
+ // / const typename ELFT::Shdr &, Section &)
125
+ // /
126
+ template <typename RelocHandlerMethod>
127
+ Error forEachRelRelocation (const typename ELFT::Shdr &RelSect,
128
+ RelocHandlerMethod &&Func,
129
+ bool ProcessDebugSections = false );
130
+
131
+ // / Traverse all matching rela relocation records in the given section.
132
+ // / Convenience wrapper to allow passing a member function for the handler.
133
+ // /
134
+ template <typename ClassT, typename RelocHandlerMethod>
135
+ Error forEachRelaRelocation (const typename ELFT::Shdr &RelSect,
136
+ ClassT *Instance, RelocHandlerMethod &&Method,
137
+ bool ProcessDebugSections = false ) {
138
+ return forEachRelaRelocation (
139
+ RelSect,
140
+ [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
141
+ return (Instance->*Method)(Rel, Target, GS);
142
+ },
143
+ ProcessDebugSections);
144
+ }
120
145
121
- // / Traverse all matching relocation records in the given section. Convenience
122
- // / wrapper to allow passing a member function for the handler.
146
+ // / Traverse all matching rel relocation records in the given section.
147
+ // / Convenience wrapper to allow passing a member function for the handler.
123
148
// /
124
149
template <typename ClassT, typename RelocHandlerMethod>
125
- Error forEachRelocation (const typename ELFT::Shdr &RelSect, ClassT *Instance ,
126
- RelocHandlerMethod &&Method,
127
- bool ProcessDebugSections = false ) {
128
- return forEachRelocation (
150
+ Error forEachRelRelocation (const typename ELFT::Shdr &RelSect,
151
+ ClassT *Instance, RelocHandlerMethod &&Method,
152
+ bool ProcessDebugSections = false ) {
153
+ return forEachRelRelocation (
129
154
RelSect,
130
155
[Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
131
156
return (Instance->*Method)(Rel, Target, GS);
@@ -487,13 +512,12 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
487
512
}
488
513
489
514
template <typename ELFT>
490
- template <typename RelocHandlerFunction >
491
- Error ELFLinkGraphBuilder<ELFT>::forEachRelocation (
492
- const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
515
+ template <typename RelocHandlerMethod >
516
+ Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation (
517
+ const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func,
493
518
bool ProcessDebugSections) {
494
-
495
519
// Only look into sections that store relocation entries.
496
- if (RelSect.sh_type != ELF::SHT_RELA && RelSect. sh_type != ELF::SHT_REL )
520
+ if (RelSect.sh_type != ELF::SHT_RELA)
497
521
return Error::success ();
498
522
499
523
// sh_info contains the section header index of the target (FixupSection),
@@ -534,6 +558,53 @@ Error ELFLinkGraphBuilder<ELFT>::forEachRelocation(
534
558
return Error::success ();
535
559
}
536
560
561
+ template <typename ELFT>
562
+ template <typename RelocHandlerMethod>
563
+ Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(
564
+ const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func,
565
+ bool ProcessDebugSections) {
566
+ // Only look into sections that store relocation entries.
567
+ if (RelSect.sh_type != ELF::SHT_REL)
568
+ return Error::success ();
569
+
570
+ // sh_info contains the section header index of the target (FixupSection),
571
+ // which is the section to which all relocations in RelSect apply.
572
+ auto FixupSection = Obj.getSection (RelSect.sh_info );
573
+ if (!FixupSection)
574
+ return FixupSection.takeError ();
575
+
576
+ // Target sections have names in valid ELF object files.
577
+ Expected<StringRef> Name = Obj.getSectionName (**FixupSection);
578
+ if (!Name)
579
+ return Name.takeError ();
580
+ LLVM_DEBUG (dbgs () << " " << *Name << " :\n " );
581
+
582
+ // Consider skipping these relocations.
583
+ if (!ProcessDebugSections && isDwarfSection (*Name)) {
584
+ LLVM_DEBUG (dbgs () << " skipped (dwarf section)\n\n " );
585
+ return Error::success ();
586
+ }
587
+
588
+ // Lookup the link-graph node corresponding to the target section name.
589
+ auto *BlockToFix = getGraphBlock (RelSect.sh_info );
590
+ if (!BlockToFix)
591
+ return make_error<StringError>(
592
+ " Refencing a section that wasn't added to the graph: " + *Name,
593
+ inconvertibleErrorCode ());
594
+
595
+ auto RelEntries = Obj.rels (RelSect);
596
+ if (!RelEntries)
597
+ return RelEntries.takeError ();
598
+
599
+ // Let the callee process relocation entries one by one.
600
+ for (const typename ELFT::Rel &R : *RelEntries)
601
+ if (Error Err = Func (R, **FixupSection, *BlockToFix))
602
+ return Err;
603
+
604
+ LLVM_DEBUG (dbgs () << " \n " );
605
+ return Error::success ();
606
+ }
607
+
537
608
} // end namespace jitlink
538
609
} // end namespace llvm
539
610
0 commit comments