29
29
#include " llvm/Support/ELFAttributes.h"
30
30
#include " llvm/Support/Error.h"
31
31
#include " llvm/Support/ErrorHandling.h"
32
+ #include " llvm/Support/LEB128.h"
32
33
#include " llvm/Support/MemoryBufferRef.h"
33
34
#include " llvm/Support/ScopedPrinter.h"
34
35
#include " llvm/TargetParser/SubtargetFeature.h"
@@ -122,6 +123,8 @@ class ELFObjectFileBase : public ObjectFile {
122
123
Expected<std::vector<BBAddrMap>>
123
124
readBBAddrMap (std::optional<unsigned > TextSectionIndex = std::nullopt,
124
125
std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr ) const ;
126
+
127
+ StringRef getCrelDecodeProblem (SectionRef Sec) const ;
125
128
};
126
129
127
130
class ELFSectionRef : public SectionRef {
@@ -292,6 +295,10 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
292
295
const Elf_Shdr *DotSymtabSec = nullptr ; // Symbol table section.
293
296
const Elf_Shdr *DotSymtabShndxSec = nullptr ; // SHT_SYMTAB_SHNDX section.
294
297
298
+ // Hold CREL relocations for SectionRef::relocations().
299
+ mutable SmallVector<SmallVector<Elf_Crel, 0 >, 0 > Crels;
300
+ mutable SmallVector<std::string, 0 > CrelDecodeProblems;
301
+
295
302
Error initContent () override ;
296
303
297
304
void moveSymbolNext (DataRefImpl &Symb) const override ;
@@ -446,6 +453,7 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
446
453
447
454
const Elf_Rel *getRel (DataRefImpl Rel) const ;
448
455
const Elf_Rela *getRela (DataRefImpl Rela) const ;
456
+ Elf_Crel getCrel (DataRefImpl Crel) const ;
449
457
450
458
Expected<const Elf_Sym *> getSymbol (DataRefImpl Sym) const {
451
459
return EF.template getEntry <Elf_Sym>(Sym.d .a , Sym.d .b );
@@ -499,6 +507,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
499
507
bool isRelocatableObject () const override ;
500
508
501
509
void createFakeSections () { EF.createFakeSections (); }
510
+
511
+ StringRef getCrelDecodeProblem (DataRefImpl Sec) const ;
502
512
};
503
513
504
514
using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
@@ -1022,6 +1032,24 @@ ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
1022
1032
uintptr_t SHT = reinterpret_cast <uintptr_t >((*SectionsOrErr).begin ());
1023
1033
RelData.d .a = (Sec.p - SHT) / EF.getHeader ().e_shentsize ;
1024
1034
RelData.d .b = 0 ;
1035
+ if (reinterpret_cast <const Elf_Shdr *>(Sec.p )->sh_type == ELF::SHT_CREL) {
1036
+ if (RelData.d .a + 1 > Crels.size ())
1037
+ Crels.resize (RelData.d .a + 1 );
1038
+ auto &Crel = Crels[RelData.d .a ];
1039
+ if (Crel.empty ()) {
1040
+ ArrayRef<uint8_t > Content = cantFail (getSectionContents (Sec));
1041
+ size_t I = 0 ;
1042
+ Error Err = decodeCrel<ELFT::Is64Bits>(
1043
+ Content, [&](uint64_t Count, bool ) { Crel.resize (Count); },
1044
+ [&](Elf_Crel Crel) { Crels[RelData.d .a ][I++] = Crel; });
1045
+ if (Err) {
1046
+ Crel.assign (1 , Elf_Crel{0 , 0 , 0 , 0 });
1047
+ if (RelData.d .a + 1 > CrelDecodeProblems.size ())
1048
+ CrelDecodeProblems.resize (RelData.d .a + 1 );
1049
+ CrelDecodeProblems[RelData.d .a ] = toString (std::move (Err));
1050
+ }
1051
+ }
1052
+ }
1025
1053
return relocation_iterator (RelocationRef (RelData, this ));
1026
1054
}
1027
1055
@@ -1030,9 +1058,13 @@ relocation_iterator
1030
1058
ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
1031
1059
const Elf_Shdr *S = reinterpret_cast <const Elf_Shdr *>(Sec.p );
1032
1060
relocation_iterator Begin = section_rel_begin (Sec);
1061
+ DataRefImpl RelData = Begin->getRawDataRefImpl ();
1062
+ if (S->sh_type == ELF::SHT_CREL) {
1063
+ RelData.d .b = Crels[RelData.d .a ].size ();
1064
+ return relocation_iterator (RelocationRef (RelData, this ));
1065
+ }
1033
1066
if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
1034
1067
return Begin;
1035
- DataRefImpl RelData = Begin->getRawDataRefImpl ();
1036
1068
const Elf_Shdr *RelSec = getRelSection (RelData);
1037
1069
1038
1070
// Error check sh_link here so that getRelocationSymbol can just use it.
@@ -1050,7 +1082,7 @@ Expected<section_iterator>
1050
1082
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
1051
1083
const Elf_Shdr *EShdr = getSection (Sec);
1052
1084
uintX_t Type = EShdr->sh_type ;
1053
- if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
1085
+ if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA && Type != ELF::SHT_CREL )
1054
1086
return section_end ();
1055
1087
1056
1088
Expected<const Elf_Shdr *> SecOrErr = EF.getSection (EShdr->sh_info );
@@ -1070,7 +1102,9 @@ symbol_iterator
1070
1102
ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
1071
1103
uint32_t symbolIdx;
1072
1104
const Elf_Shdr *sec = getRelSection (Rel);
1073
- if (sec->sh_type == ELF::SHT_REL)
1105
+ if (sec->sh_type == ELF::SHT_CREL)
1106
+ symbolIdx = getCrel (Rel).r_symidx ;
1107
+ else if (sec->sh_type == ELF::SHT_REL)
1074
1108
symbolIdx = getRel (Rel)->getSymbol (EF.isMips64EL ());
1075
1109
else
1076
1110
symbolIdx = getRela (Rel)->getSymbol (EF.isMips64EL ());
@@ -1087,6 +1121,8 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
1087
1121
template <class ELFT >
1088
1122
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
1089
1123
const Elf_Shdr *sec = getRelSection (Rel);
1124
+ if (sec->sh_type == ELF::SHT_CREL)
1125
+ return getCrel (Rel).r_offset ;
1090
1126
if (sec->sh_type == ELF::SHT_REL)
1091
1127
return getRel (Rel)->r_offset ;
1092
1128
@@ -1096,6 +1132,8 @@ uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
1096
1132
template <class ELFT >
1097
1133
uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
1098
1134
const Elf_Shdr *sec = getRelSection (Rel);
1135
+ if (sec->sh_type == ELF::SHT_CREL)
1136
+ return getCrel (Rel).r_type ;
1099
1137
if (sec->sh_type == ELF::SHT_REL)
1100
1138
return getRel (Rel)->getType (EF.isMips64EL ());
1101
1139
else
@@ -1117,9 +1155,11 @@ void ELFObjectFile<ELFT>::getRelocationTypeName(
1117
1155
template <class ELFT >
1118
1156
Expected<int64_t >
1119
1157
ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
1120
- if (getRelSection (Rel)->sh_type != ELF::SHT_RELA)
1121
- return createError (" Section is not SHT_RELA" );
1122
- return (int64_t )getRela (Rel)->r_addend ;
1158
+ if (getRelSection (Rel)->sh_type == ELF::SHT_RELA)
1159
+ return (int64_t )getRela (Rel)->r_addend ;
1160
+ if (getRelSection (Rel)->sh_type == ELF::SHT_CREL)
1161
+ return (int64_t )getCrel (Rel).r_addend ;
1162
+ return createError (" Relocation section does not have addends" );
1123
1163
}
1124
1164
1125
1165
template <class ELFT >
@@ -1142,6 +1182,14 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
1142
1182
return *Ret;
1143
1183
}
1144
1184
1185
+ template <class ELFT >
1186
+ typename ELFObjectFile<ELFT>::Elf_Crel
1187
+ ELFObjectFile<ELFT>::getCrel(DataRefImpl Crel) const {
1188
+ assert (getRelSection (Crel)->sh_type == ELF::SHT_CREL);
1189
+ assert (Crel.d .a < Crels.size ());
1190
+ return Crels[Crel.d .a ][Crel.d .b ];
1191
+ }
1192
+
1145
1193
template <class ELFT >
1146
1194
Expected<ELFObjectFile<ELFT>>
1147
1195
ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
@@ -1453,6 +1501,15 @@ template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
1453
1501
return EF.getHeader ().e_type == ELF::ET_REL;
1454
1502
}
1455
1503
1504
+ template <class ELFT >
1505
+ StringRef ELFObjectFile<ELFT>::getCrelDecodeProblem(DataRefImpl Sec) const {
1506
+ uintptr_t SHT = reinterpret_cast <uintptr_t >(cantFail (EF.sections ()).begin ());
1507
+ auto I = (Sec.p - SHT) / EF.getHeader ().e_shentsize ;
1508
+ if (I < CrelDecodeProblems.size ())
1509
+ return CrelDecodeProblems[I];
1510
+ return " " ;
1511
+ }
1512
+
1456
1513
} // end namespace object
1457
1514
} // end namespace llvm
1458
1515
0 commit comments