2929#include " llvm/Support/ELFAttributes.h"
3030#include " llvm/Support/Error.h"
3131#include " llvm/Support/ErrorHandling.h"
32+ #include " llvm/Support/LEB128.h"
3233#include " llvm/Support/MemoryBufferRef.h"
3334#include " llvm/Support/ScopedPrinter.h"
3435#include " llvm/TargetParser/SubtargetFeature.h"
@@ -122,6 +123,8 @@ class ELFObjectFileBase : public ObjectFile {
122123 Expected<std::vector<BBAddrMap>>
123124 readBBAddrMap (std::optional<unsigned > TextSectionIndex = std::nullopt ,
124125 std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr ) const ;
126+
127+ StringRef getCrelDecodeProblem (SectionRef Sec) const ;
125128};
126129
127130class ELFSectionRef : public SectionRef {
@@ -292,6 +295,10 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
292295 const Elf_Shdr *DotSymtabSec = nullptr ; // Symbol table section.
293296 const Elf_Shdr *DotSymtabShndxSec = nullptr ; // SHT_SYMTAB_SHNDX section.
294297
298+ // Hold CREL relocations for SectionRef::relocations().
299+ mutable SmallVector<SmallVector<Elf_Crel, 0 >, 0 > Crels;
300+ mutable SmallVector<std::string, 0 > CrelDecodeProblems;
301+
295302 Error initContent () override ;
296303
297304 void moveSymbolNext (DataRefImpl &Symb) const override ;
@@ -446,6 +453,7 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
446453
447454 const Elf_Rel *getRel (DataRefImpl Rel) const ;
448455 const Elf_Rela *getRela (DataRefImpl Rela) const ;
456+ Elf_Crel getCrel (DataRefImpl Crel) const ;
449457
450458 Expected<const Elf_Sym *> getSymbol (DataRefImpl Sym) const {
451459 return EF.template getEntry <Elf_Sym>(Sym.d .a , Sym.d .b );
@@ -499,6 +507,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
499507 bool isRelocatableObject () const override ;
500508
501509 void createFakeSections () { EF.createFakeSections (); }
510+
511+ StringRef getCrelDecodeProblem (DataRefImpl Sec) const ;
502512};
503513
504514using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
@@ -1022,6 +1032,24 @@ ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
10221032 uintptr_t SHT = reinterpret_cast <uintptr_t >((*SectionsOrErr).begin ());
10231033 RelData.d .a = (Sec.p - SHT) / EF.getHeader ().e_shentsize ;
10241034 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+ }
10251053 return relocation_iterator (RelocationRef (RelData, this ));
10261054}
10271055
@@ -1030,9 +1058,13 @@ relocation_iterator
10301058ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
10311059 const Elf_Shdr *S = reinterpret_cast <const Elf_Shdr *>(Sec.p );
10321060 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+ }
10331066 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
10341067 return Begin;
1035- DataRefImpl RelData = Begin->getRawDataRefImpl ();
10361068 const Elf_Shdr *RelSec = getRelSection (RelData);
10371069
10381070 // Error check sh_link here so that getRelocationSymbol can just use it.
@@ -1050,7 +1082,7 @@ Expected<section_iterator>
10501082ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
10511083 const Elf_Shdr *EShdr = getSection (Sec);
10521084 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 )
10541086 return section_end ();
10551087
10561088 Expected<const Elf_Shdr *> SecOrErr = EF.getSection (EShdr->sh_info );
@@ -1070,7 +1102,9 @@ symbol_iterator
10701102ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
10711103 uint32_t symbolIdx;
10721104 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)
10741108 symbolIdx = getRel (Rel)->getSymbol (EF.isMips64EL ());
10751109 else
10761110 symbolIdx = getRela (Rel)->getSymbol (EF.isMips64EL ());
@@ -1087,6 +1121,8 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
10871121template <class ELFT >
10881122uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
10891123 const Elf_Shdr *sec = getRelSection (Rel);
1124+ if (sec->sh_type == ELF::SHT_CREL)
1125+ return getCrel (Rel).r_offset ;
10901126 if (sec->sh_type == ELF::SHT_REL)
10911127 return getRel (Rel)->r_offset ;
10921128
@@ -1096,6 +1132,8 @@ uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
10961132template <class ELFT >
10971133uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
10981134 const Elf_Shdr *sec = getRelSection (Rel);
1135+ if (sec->sh_type == ELF::SHT_CREL)
1136+ return getCrel (Rel).r_type ;
10991137 if (sec->sh_type == ELF::SHT_REL)
11001138 return getRel (Rel)->getType (EF.isMips64EL ());
11011139 else
@@ -1117,9 +1155,11 @@ void ELFObjectFile<ELFT>::getRelocationTypeName(
11171155template <class ELFT >
11181156Expected<int64_t >
11191157ELFObjectFile<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" );
11231163}
11241164
11251165template <class ELFT >
@@ -1142,6 +1182,14 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
11421182 return *Ret;
11431183}
11441184
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+
11451193template <class ELFT >
11461194Expected<ELFObjectFile<ELFT>>
11471195ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
@@ -1453,6 +1501,15 @@ template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
14531501 return EF.getHeader ().e_type == ELF::ET_REL;
14541502}
14551503
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+
14561513} // end namespace object
14571514} // end namespace llvm
14581515
0 commit comments