LLVM: include/llvm/Object/ELF.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_OBJECT_ELF_H

14#define LLVM_OBJECT_ELF_H

15

27#include

28#include

29#include

30#include

31#include <type_traits>

32#include

33

34namespace llvm {

36

41

50 std::vector AuxV;

51};

52

60

66 std::vector AuxV;

67};

68

73

79

80

81inline std::pair<unsigned char, unsigned char>

89

99

100template class ELFFile;

101

103

104

106

107

108

111

117 "the index is greater than or equal to the number of entries (" +

119 } else {

121 if (EntryStart + sizeof(T) > BufEnd)

122 return createError("can't read past the end of the file");

123 }

125 }

126

128 std::optional<uint64_t> Size;

130};

131

132template

134 const typename ELFT::Shdr &Sec) {

135 auto TableOrErr = Obj.sections();

136 if (TableOrErr)

137 return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";

138

139

140

141

143 return "[unknown index]";

144}

145

146template

148 const typename ELFT::Shdr &Sec) {

149 unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();

151 Sec.sh_type) +

152 " section with index " + Twine(SecNdx))

153 .str();

154}

155

156template

158 const typename ELFT::Phdr &Phdr) {

159 auto Headers = Obj.program_headers();

160 if (Headers)

161 return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();

162

164 return "[unknown index]";

165}

166

170

171template

173 const typename ELFT::Shdr &Sec) {

174

176 return true;

177

178 if (Sec.sh_offset < Phdr.p_offset)

179 return false;

180

181

182 if (Sec.sh_size == 0)

183 return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);

184 return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;

185}

186

187

188

189template

191 const typename ELFT::Shdr &Sec) {

193 return true;

194

195 if (Sec.sh_addr < Phdr.p_vaddr)

196 return false;

197

198 bool IsTbss =

200

201 bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;

202

203 if (Sec.sh_size == 0 || IsTbssInNonTLS)

204 return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;

205 return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;

206}

207

208template

210 const typename ELFT::Shdr &Sec) {

213}

214

215

216

217template

221 HdrHandler,

223 DataExtractor Data(Content, true, 8);

226 size_t Count = Hdr / 8;

230 uint Offset = 0, Addend = 0;

234

235

236

239 if (B >= 0x80)

240 Offset += (Data.getULEB128(Cur) << (7 - FlagBits)) - (0x80 >> FlagBits);

241

242 if (B & 1)

243 SymIdx += Data.getSLEB128(Cur);

244 if (B & 2)

245 Type += Data.getSLEB128(Cur);

246 if (B & 4 & Hdr)

247 Addend += Data.getSLEB128(Cur);

248 if (!Cur)

249 break;

250 EntryHandler(

252 }

254}

255

256template

258public:

260

261

262

265

267

268

269

270

271

272

274

277

279

280private:

282 std::vector<Elf_Shdr> FakeSections;

284

285

286

287 std::optional<uint32_t> RealPhNum;

288

289

290 std::optional<uint64_t> RealShNum;

291

292

293

294 std::optional<uint32_t> RealShStrNdx;

295

297

298 Error readShdrZero();

299

300public:

302 if (!RealPhNum) {

304 return std::move(E);

305 }

306 return *RealPhNum;

307 }

308

310 if (!RealShNum) {

312 return std::move(E);

313 }

314 return *RealShNum;

315 }

316

318 if (!RealShStrNdx) {

320 return std::move(E);

321 }

322 return *RealShStrNdx;

323 }

324

326 return *reinterpret_cast<const Elf_Ehdr *>(base());

327 }

328

329 template

331 template

333

337 const Elf_Shdr &Sec,

340 uint32_t SymbolVersionIndex, bool &IsDefault,

341 SmallVector<std::optional, 0> &VersionMap,

342 std::optional IsSymHidden) const;

343

349 Elf_Shdr_Range Sections) const;

351

354 Elf_Shdr_Range Sections) const;

355

357

362

365

366

368 const Elf_Shdr *SymTab) const;

369

371 loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;

372

374

378

383

385

387

389

393

399

403

407

411

413

415 using RelsOrRelas = std::pair<std::vector<Elf_Rel>, std::vector<Elf_Rela>>;

418

420

421

425 NumPh = *PhNumOrErr;

426 else

427 return PhNumOrErr.takeError();

428 if (NumPh && getHeader().e_phentsize != sizeof(Elf_Phdr))

429 return createError("invalid e_phentsize: " +

431

434 if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())

435 return createError("program headers are longer than binary of size " +

438 ", e_phnum = " + Twine(NumPh) +

439 ", e_phentsize = " + Twine(getHeader().e_phentsize));

440

441 auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);

442 return ArrayRef(Begin, Begin + NumPh);

443 }

444

445

446

447

448

449

450

451

453 assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");

455 if (Phdr.p_offset + Phdr.p_filesz > getBufSize() ||

456 Phdr.p_offset + Phdr.p_filesz < Phdr.p_offset) {

457 Err =

460 return Elf_Note_Iterator(Err);

461 }

462

463

464 if (Phdr.p_align != 0 && Phdr.p_align != 1 && Phdr.p_align != 4 &&

465 Phdr.p_align != 8) {

466 Err =

467 createError("alignment (" + Twine(Phdr.p_align) + ") is not 4 or 8");

468 return Elf_Note_Iterator(Err);

469 }

470 return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz,

471 std::max<size_t>(Phdr.p_align, 4), Err);

472 }

473

474

475

476

477

478

479

480

484 if (Shdr.sh_offset + Shdr.sh_size > getBufSize() ||

485 Shdr.sh_offset + Shdr.sh_size < Shdr.sh_offset) {

486 Err =

489 return Elf_Note_Iterator(Err);

490 }

491

492 if (Shdr.sh_addralign != 0 && Shdr.sh_addralign != 1 &&

493 Shdr.sh_addralign != 4 && Shdr.sh_addralign != 8) {

495 ") is not 4 or 8");

496 return Elf_Note_Iterator(Err);

497 }

498 return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size,

499 std::max<size_t>(Shdr.sh_addralign, 4), Err);

500 }

501

502

504 return Elf_Note_Iterator();

505 }

506

507

508

509

510

511

512

513

515 Error &Err) const {

517 }

518

519

520

521

522

523

524

525

527 Error &Err) const {

529 }

530

532 Elf_Shdr_Range Sections,

537 const Elf_Shdr *SymTab,

540 Elf_Sym_Range Symtab,

543

546

552 template

556

557

558

559

560

561

562

563

565 decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr,

566 std::vector *PGOAnalyses = nullptr) const;

567

568

569

570

571

574 std::function<Expected(const Elf_Shdr &)> IsMatch) const;

575

577};

578

583

584template

587 if (Index >= Sections.size())

588 return createError("invalid section index: " + Twine(Index));

589 return &Sections[Index];

590}

591

592template

597 if (!ShndxTable.First)

599 "found an extended symbol index (" + Twine(SymIndex) +

600 "), but unable to locate the extended symbol index table");

601

603 if (!TableOrErr)

604 return createError("unable to read an extended symbol table at index " +

605 Twine(SymIndex) + ": " +

607 return *TableOrErr;

608}

609

610template

614 uint32_t Index = Sym.st_shndx;

618 if (!ErrorOrIndex)

620 return *ErrorOrIndex;

621 }

623 return 0;

624 return Index;

625}

626

627template

631 auto SymsOrErr = symbols(SymTab);

632 if (!SymsOrErr)

633 return SymsOrErr.takeError();

634 return getSection(Sym, *SymsOrErr, ShndxTable);

635}

636

637template

641 auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);

642 if (!IndexOrErr)

643 return IndexOrErr.takeError();

644 uint32_t Index = *IndexOrErr;

645 if (Index == 0)

646 return nullptr;

648}

649

650template

653 auto SymsOrErr = symbols(Sec);

654 if (!SymsOrErr)

655 return SymsOrErr.takeError();

656

657 Elf_Sym_Range Symbols = *SymsOrErr;

658 if (Index >= Symbols.size())

659 return createError("unable to get symbol from section " +

661 ": invalid symbol index (" + Twine(Index) + ")");

662 return &Symbols[Index];

663}

664

665template

666template

669 if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)

671 " has invalid sh_entsize: expected " + Twine(sizeof(T)) +

672 ", but got " + Twine(Sec.sh_entsize));

673

674 uintX_t Offset = Sec.sh_offset;

675 uintX_t Size = Sec.sh_size;

676

677 if (Size % sizeof(T))

679 " has an invalid sh_size (" + Twine(Size) +

680 ") which is not a multiple of its sh_entsize (" +

681 Twine(Sec.sh_entsize) + ")");

682 if (std::numeric_limits<uintX_t>::max() - Offset < Size)

686 ") that cannot be represented");

691 ") that is greater than the file size (0x" +

693

695

697

698 const T *Start = reinterpret_cast<const T *>(base() + Offset);

700}

701

702template

705 uintX_t Offset = Phdr.p_offset;

706 uintX_t Size = Phdr.p_filesz;

707

708 if (std::numeric_limits<uintX_t>::max() - Offset < Size)

712 ") that cannot be represented");

717 ") that is greater than the file size (0x" +

720}

721

722template

727

728template

732

733template

738 Result.append(Name.begin(), Name.end());

739 } else {

740

741

742

743

744

745

749

750

752 Result.append(Name.begin(), Name.end());

753

755 Result.append(1, '/');

756 Result.append(Name.begin(), Name.end());

757

759 Result.append(1, '/');

760 Result.append(Name.begin(), Name.end());

761 }

762}

763

764template

768

769template

772 const Elf_Shdr *VerDefSec) const {

774

775

776

779

780 auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {

781 if (N >= VersionMap.size())

782 VersionMap.resize(N + 1);

783 VersionMap[N] = {std::string(Version), IsVerdef};

784 };

785

786 if (VerDefSec) {

788 if (!Defs)

790 for (const VerDef &Def : *Defs)

792 }

793

794 if (VerNeedSec) {

796 if (!Deps)

798 for (const VerNeed &Dep : *Deps)

799 for (const VernAux &Aux : Dep.AuxV)

801 }

802

803 return VersionMap;

804}

805

806template

809 const Elf_Shdr *SymTab) const {

811 if (Index == 0)

812 return nullptr;

814}

815

816template

821 if (!ShStrNdxOrErr)

822 return ShStrNdxOrErr.takeError();

823

824 if (*ShStrNdxOrErr == ELF::SHN_XINDEX && Sections.empty())

826 "e_shstrndx == SHN_XINDEX, but the section header table is empty");

827

828 uint32_t Index = *ShStrNdxOrErr;

829

830

831 if (!Index)

832 return FakeSectionStrings;

833

834 if (Index >= Sections.size())

835 return createError("section header string table index " + Twine(Index) +

836 " does not exist");

838}

839

840

841

842

843template

846 const void *BufEnd) {

847 using Elf_Word = typename ELFT::Word;

848 if (Table.nbuckets == 0)

849 return Table.symndx + 1;

851

852 for (Elf_Word Val : Table.buckets())

853 LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);

854 const Elf_Word *It =

855 reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());

856

857 while (It < BufEnd && (*It & 1) == 0) {

858 ++LastSymIdx;

859 ++It;

860 }

861 if (It >= BufEnd) {

864 "no terminator found for GNU hash section before buffer end");

865 }

866 return LastSymIdx + 1;

867}

868

869

870

871

872template

874

876 if (!SectionsOrError)

877 return SectionsOrError.takeError();

878 for (const Elf_Shdr &Sec : *SectionsOrError) {

880 if (Sec.sh_size % Sec.sh_entsize != 0) {

882 "SHT_DYNSYM section has sh_size (" +

883 Twine(Sec.sh_size) + ") % sh_entsize (" +

884 Twine(Sec.sh_entsize) + ") that is not 0");

885 }

886 return Sec.sh_size / Sec.sh_entsize;

887 }

888 }

889

890 if (!SectionsOrError->empty()) {

891

892

893 return 0;

894 }

895

896

897

899 if (!DynTable)

901 std::optional<uint64_t> ElfHash;

902 std::optional<uint64_t> ElfGnuHash;

903 for (const Elf_Dyn &Entry : *DynTable) {

904 switch (Entry.d_tag) {

905 case ELF::DT_HASH:

906 ElfHash = Entry.d_un.d_ptr;

907 break;

908 case ELF::DT_GNU_HASH:

909 ElfGnuHash = Entry.d_un.d_ptr;

910 break;

911 }

912 }

913 if (ElfGnuHash) {

915 if (!TablePtr)

917 const Elf_GnuHash *Table =

918 reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());

920 }

921

922

923 if (ElfHash) {

925 if (!TablePtr)

927 const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());

928 return Table->nchain;

929 }

930 return 0;

931}

932

934

935template Error ELFFile::readShdrZero() {

936 const Elf_Ehdr &Header = getHeader();

937

938 if ((Header.e_phnum == ELF::PN_XNUM || Header.e_shnum == 0 ||

940 Header.e_shoff != 0) {

941

942

943 RealShNum = 1;

945 if (!SecOrErr) {

946 RealShNum = std::nullopt;

947 return SecOrErr.takeError();

948 }

949

950 RealPhNum =

951 Header.e_phnum == ELF::PN_XNUM ? (*SecOrErr)->sh_info : Header.e_phnum;

952 RealShNum = Header.e_shnum == 0 ? (*SecOrErr)->sh_size : Header.e_shnum;

953 RealShStrNdx = Header.e_shstrndx == ELF::SHN_XINDEX ? (*SecOrErr)->sh_link

954 : Header.e_shstrndx;

955 } else {

956 RealPhNum = Header.e_phnum;

957 RealShNum = Header.e_shnum;

958 RealShStrNdx = Header.e_shstrndx;

959 }

960

962}

963

964template

966 if (sizeof(Elf_Ehdr) > Object.size())

967 return createError("invalid buffer: the size (" + Twine(Object.size()) +

968 ") is smaller than an ELF header (" +

969 Twine(sizeof(Elf_Ehdr)) + ")");

971}

972

973

974

975

977 if (!FakeSections.empty())

978 return;

980 if (!PhdrsOrErr)

981 return;

982

983 FakeSectionStrings += '\0';

986 continue;

987 Elf_Shdr FakeShdr = {};

990 FakeShdr.sh_addr = Phdr.p_vaddr;

991 FakeShdr.sh_size = Phdr.p_memsz;

992 FakeShdr.sh_offset = Phdr.p_offset;

993

994 FakeShdr.sh_name = FakeSectionStrings.size();

995 FakeSectionStrings += ("PT_LOAD#" + Twine(Idx)).str();

996 FakeSectionStrings += '\0';

997 FakeSections.push_back(FakeShdr);

998 }

999}

1000

1001template

1003 const uintX_t SectionTableOffset = getHeader().e_shoff;

1004 if (SectionTableOffset == 0) {

1005 if (!FakeSections.empty())

1006 return ArrayRef(FakeSections);

1008 }

1009

1010 if (getHeader().e_shentsize != sizeof(Elf_Shdr))

1011 return createError("invalid e_shentsize in ELF header: " +

1013

1014 const uint64_t FileSize = Buf.size();

1015 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||

1016 SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)

1018 "section header table goes past the end of the file: e_shoff = 0x" +

1020

1021

1022 if (SectionTableOffset & (alignof(Elf_Shdr) - 1))

1023

1024 return createError("invalid alignment of section headers");

1025

1026 const Elf_Shdr *First =

1027 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);

1028

1029 uintX_t NumSections = 0;

1031 NumSections = *ShNumOrErr;

1032 else

1033 return ShNumOrErr.takeError();

1034

1035 if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))

1036 return createError("invalid number of sections specified in the NULL "

1037 "section's sh_size field (" +

1038 Twine(NumSections) + ")");

1039

1040 const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);

1041 if (SectionTableOffset + SectionTableSize < SectionTableOffset)

1043 "invalid section header table offset (e_shoff = 0x" +

1045 ") or invalid number of sections specified in the first section "

1046 "header's sh_size field (0x" +

1048

1049

1050 if (SectionTableOffset + SectionTableSize > FileSize)

1051 return createError("section table goes past the end of file");

1053}

1054

1055template

1056template

1059 auto SecOrErr = getSection(Section);

1060 if (!SecOrErr)

1061 return SecOrErr.takeError();

1063}

1064

1065template

1066template

1070 if (!EntriesOrErr)

1071 return EntriesOrErr.takeError();

1072

1074 if (Entry >= Arr.size())

1076 "can't read an entry at 0x" +

1078 ": it goes past the end of the section (0x" +

1080 return &Arr[Entry];

1081}

1082

1083template

1085 uint32_t SymbolVersionIndex, bool &IsDefault,

1086 SmallVector<std::optional, 0> &VersionMap,

1087 std::optional IsSymHidden) const {

1089

1090

1093 IsDefault = false;

1094 return "";

1095 }

1096

1097

1098 if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])

1099 return createError("SHT_GNU_versym section refers to a version index " +

1100 Twine(VersionIndex) + " which is missing");

1101

1102 const VersionEntry &Entry = *VersionMap[VersionIndex];

1103

1104 if (!Entry.IsVerDef || IsSymHidden.value_or(false))

1105 IsDefault = false;

1106 else

1108 return Entry.Name.c_str();

1109}

1110

1111template

1115 if (!StrTabOrErr)

1117

1119 if (!ContentsOrErr)

1120 return createError("cannot read content of " + describe(*this, Sec) + ": " +

1122

1123 const uint8_t *Start = ContentsOrErr->data();

1124 const uint8_t *End = Start + ContentsOrErr->size();

1125

1126 auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,

1128 if (VerdauxBuf + sizeof(Elf_Verdaux) > End)

1130 ": version definition " + Twine(VerDefNdx) +

1131 " refers to an auxiliary entry that goes past the end "

1132 "of the section");

1133

1134 auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);

1135 VerdauxBuf += Verdaux->vda_next;

1136

1138 Aux.Offset = VerdauxBuf - Start;

1139 if (Verdaux->vda_name < StrTabOrErr->size())

1140 Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name).data());

1141 else

1142 Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();

1143 return Aux;

1144 };

1145

1146 std::vector Ret;

1147 const uint8_t *VerdefBuf = Start;

1148 for (unsigned I = 1; I <= Sec.sh_info; ++I) {

1149 if (VerdefBuf + sizeof(Elf_Verdef) > End)

1151 ": version definition " + Twine(I) +

1152 " goes past the end of the section");

1153

1154 if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)

1156 "invalid " + describe(*this, Sec) +

1157 ": found a misaligned version definition entry at offset 0x" +

1159

1160 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);

1164 " is not yet supported");

1165

1166 const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);

1167 VerDef &VD = *Ret.emplace(Ret.end());

1168 VD.Offset = VerdefBuf - Start;

1170 VD.Flags = D->vd_flags;

1171 VD.Ndx = D->vd_ndx;

1172 VD.Cnt = D->vd_cnt;

1173 VD.Hash = D->vd_hash;

1174

1175 const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;

1176 for (unsigned J = 0; J < D->vd_cnt; ++J) {

1177 if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)

1179 ": found a misaligned auxiliary entry at offset 0x" +

1181

1183 if (!AuxOrErr)

1185

1186 if (J == 0)

1187 VD.Name = AuxOrErr->Name;

1188 else

1189 VD.AuxV.push_back(*AuxOrErr);

1190 }

1191

1192 VerdefBuf += D->vd_next;

1193 }

1194

1195 return Ret;

1196}

1197

1198template

1204 if (!StrTabOrErr) {

1206 return std::move(E);

1207 } else {

1208 StrTab = *StrTabOrErr;

1209 }

1210

1212 if (!ContentsOrErr)

1213 return createError("cannot read content of " + describe(*this, Sec) + ": " +

1215

1216 const uint8_t *Start = ContentsOrErr->data();

1217 const uint8_t *End = Start + ContentsOrErr->size();

1218 const uint8_t *VerneedBuf = Start;

1219

1220 std::vector Ret;

1221 for (unsigned I = 1; I <= Sec.sh_info; ++I) {

1222 if (VerneedBuf + sizeof(Elf_Verdef) > End)

1224 ": version dependency " + Twine(I) +

1225 " goes past the end of the section");

1226

1227 if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)

1229 "invalid " + describe(*this, Sec) +

1230 ": found a misaligned version dependency entry at offset 0x" +

1232

1233 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);

1237 " is not yet supported");

1238

1239 const Elf_Verneed *Verneed =

1240 reinterpret_cast<const Elf_Verneed *>(VerneedBuf);

1241

1242 VerNeed &VN = *Ret.emplace(Ret.end());

1243 VN.Version = Verneed->vn_version;

1244 VN.Cnt = Verneed->vn_cnt;

1245 VN.Offset = VerneedBuf - Start;

1246

1247 if (Verneed->vn_file < StrTab.size())

1248 VN.File = std::string(StrTab.data() + Verneed->vn_file);

1249 else

1250 VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();

1251

1252 const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;

1253 for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {

1254 if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)

1256 ": found a misaligned auxiliary entry at offset 0x" +

1258

1259 if (VernauxBuf + sizeof(Elf_Vernaux) > End)

1261 "invalid " + describe(*this, Sec) + ": version dependency " +

1263 " refers to an auxiliary entry that goes past the end "

1264 "of the section");

1265

1266 const Elf_Vernaux *Vernaux =

1267 reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);

1268

1270 Aux.Hash = Vernaux->vna_hash;

1271 Aux.Flags = Vernaux->vna_flags;

1272 Aux.Other = Vernaux->vna_other;

1273 Aux.Offset = VernauxBuf - Start;

1274 if (StrTab.size() <= Vernaux->vna_name)

1275 Aux.Name = "";

1276 else

1277 Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));

1278

1279 VernauxBuf += Vernaux->vna_next;

1280 }

1281 VerneedBuf += Verneed->vn_next;

1282 }

1283 return Ret;

1284}

1285

1286template

1289 auto TableOrErr = sections();

1290 if (!TableOrErr)

1291 return TableOrErr.takeError();

1293}

1294

1295template

1300 if (Error E = WarnHandler("invalid sh_type for string table section " +

1302 ": expected SHT_STRTAB, but got " +

1304 getHeader().e_machine, Section.sh_type)))

1305 return std::move(E);

1306

1308 if (!V)

1309 return V.takeError();

1311 if (Data.empty())

1312 return createError("SHT_STRTAB string table section " +

1314 if (Data.back() != '\0')

1315 return createError("SHT_STRTAB string table section " +

1317 " is non-null terminated");

1319}

1320

1321template

1324 auto SectionsOrErr = sections();

1325 if (!SectionsOrErr)

1326 return SectionsOrErr.takeError();

1328}

1329

1330template

1333 Elf_Shdr_Range Sections) const {

1336 if (!VOrErr)

1337 return VOrErr.takeError();

1340 if (!SymTableOrErr)

1341 return SymTableOrErr.takeError();

1342 const Elf_Shdr &SymTable = **SymTableOrErr;

1346 "SHT_SYMTAB_SHNDX section is linked with " +

1348 " section (expected SHT_SYMTAB/SHT_DYNSYM)");

1349

1350 uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);

1351 if (V.size() != Syms)

1352 return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +

1353 " entries, but the symbol table associated has " +

1355

1356 return V;

1357}

1358

1359template

1362 auto SectionsOrErr = sections();

1363 if (!SectionsOrErr)

1364 return SectionsOrErr.takeError();

1366}

1367

1368template

1371 Elf_Shdr_Range Sections) const {

1372

1375 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");

1378 if (!SectionOrErr)

1379 return SectionOrErr.takeError();

1381}

1382

1383template

1388 if (!StrTabSecOrErr)

1389 return createError("invalid section linked to " + describe(*this, Sec) +

1391

1393 if (!StrTabOrErr)

1394 return createError("invalid string table linked to " +

1395 describe(*this, Sec) + ": " +

1397 return *StrTabOrErr;

1398}

1399

1400template

1404 auto SectionsOrErr = sections();

1405 if (!SectionsOrErr)

1406 return SectionsOrErr.takeError();

1408 if (!Table)

1409 return Table.takeError();

1411}

1412

1413template

1421 " has an invalid sh_name (0x" +

1423 ") offset which goes past the end of the "

1424 "section name string table");

1426}

1427

1428

1429

1430

1433 for (uint8_t C : SymbolName) {

1434 H = (H << 4) + C;

1435 H ^= (H >> 24) & 0xf0;

1436 }

1437 return H & 0x0fffffff;

1438}

1439

1440

1441

1442

1446 H = (H << 5) + H + C;

1447 return H;

1448}

1449

1454

1455}

1456}

1457

1458#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

bbsections Prepares for basic block sections

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_TEMPLATE_ABI

static bool isMips64EL(const ELFYAML::Object &Obj)

#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

This file implements a map that provides insertion order iteration.

Function const char TargetMachine * Machine

This file defines the SmallString class.

This file defines the SmallVector class.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Helper for Errors used as out-parameters.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

const unsigned char * bytes_end() const

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static Twine utohexstr(uint64_t Val)

The instances of the Type class are immutable: once they are created, they are never changed.

An efficient, type-erasing, non-owning reference to a callable.

A range adaptor for a pair of iterators.

ELFFile(const ELFFile &)=default

llvm::function_ref< Error(const Twine &Msg)> WarningHandler

Definition ELF.h:273

const Elf_Ehdr & getHeader() const

Definition ELF.h:325

Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const

Expected< StringRef > getLinkAsStrtab(const typename ELFT::Shdr &Sec) const

Definition ELF.h:1385

static Expected< ELFFile > create(StringRef Object)

Definition ELF.h:965

Expected< const Elf_Shdr * > getSection(uint32_t Index) const

Definition ELF.h:1288

Expected< StringRef > getSectionName(const Elf_Shdr &Section, StringRef DotShstrtab) const

Definition ELF.h:1414

Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section, Elf_Shdr_Range Sections) const

Definition ELF.h:1332

Expected< const Elf_Sym * > getSymbol(const Elf_Shdr *Sec, uint32_t Index) const

Definition ELF.h:652

Expected< std::vector< VerDef > > getVersionDefinitions(const Elf_Shdr &Sec) const

Definition ELF.h:1113

std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const

Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section) const

Definition ELF.h:1323

Expected< const Elf_Shdr * > getSection(const Elf_Sym &Sym, Elf_Sym_Range Symtab, DataRegion< Elf_Word > ShndxTable) const

Definition ELF.h:639

Expected< Elf_Sym_Range > symbols(const Elf_Shdr *Sec) const

Definition ELF.h:394

Expected< uint64_t > getShNum() const

Definition ELF.h:309

Expected< ArrayRef< uint8_t > > getSegmentContents(const Elf_Phdr &Phdr) const

Definition ELF.h:704

Expected< std::vector< BBAddrMap > > decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec=nullptr, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr) const

Returns a vector of BBAddrMap structs corresponding to each function within the text section that the...

Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const

Get an iterator over notes in a section.

Definition ELF.h:481

uint32_t getRelativeRelocationType() const

Definition ELF.h:765

iterator_range< Elf_Note_Iterator > notes(const Elf_Phdr &Phdr, Error &Err) const

Get an iterator range over notes of a program header.

Definition ELF.h:514

Expected< StringRef > getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault, SmallVector< std::optional< VersionEntry >, 0 > &VersionMap, std::optional< bool > IsSymHidden) const

Definition ELF.h:1084

Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const

Get an iterator over notes in a program header.

Definition ELF.h:452

Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr &Sec) const

Definition ELF.h:724

Expected< Elf_Rela_Range > relas(const Elf_Shdr &Sec) const

Definition ELF.h:400

Expected< Elf_Phdr_Range > program_headers() const

Iterate over program header table.

Definition ELF.h:422

Expected< uint32_t > getShStrNdx() const

Definition ELF.h:317

Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const

Definition ELF.h:1361

Expected< std::vector< VerNeed > > getVersionDependencies(const Elf_Shdr &Sec, WarningHandler WarnHandler=&defaultWarningHandler) const

Definition ELF.h:1200

size_t getBufSize() const

Definition ELF.h:278

Expected< const T * > getEntry(uint32_t Section, uint32_t Entry) const

Definition ELF.h:1057

void getRelocationTypeName(uint32_t Type, SmallVectorImpl< char > &Result) const

Definition ELF.h:734

Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel &Rel, const Elf_Shdr *SymTab) const

Get the symbol for a given relocation.

Definition ELF.h:808

Expected< RelsOrRelas > decodeCrel(ArrayRef< uint8_t > Content) const

const uint8_t * end() const

Definition ELF.h:276

Expected< StringRef > getSectionStringTable(Elf_Shdr_Range Sections, WarningHandler WarnHandler=&defaultWarningHandler) const

Definition ELF.h:818

Expected< uint64_t > getDynSymtabSize() const

This function determines the number of dynamic symbols.

Definition ELF.h:873

Expected< const T * > getEntry(const Elf_Shdr &Section, uint32_t Entry) const

Definition ELF.h:1067

Expected< uint64_t > getCrelHeader(ArrayRef< uint8_t > Content) const

Expected< Elf_Dyn_Range > dynamicEntries() const

void createFakeSections()

Used by llvm-objdump -d (which needs sections for disassembly) to disassemble objects without a secti...

Definition ELF.h:976

ELFFile(const ELFFile &)=default

Expected< Elf_Shdr_Range > sections() const

Definition ELF.h:1002

iterator_range< Elf_Note_Iterator > notes(const Elf_Shdr &Shdr, Error &Err) const

Get an iterator range over notes of a section.

Definition ELF.h:526

const uint8_t * base() const

Definition ELF.h:275

bool isMipsELF64() const

Definition ELF.h:379

Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const

Expected< Elf_Relr_Range > relrs(const Elf_Shdr &Sec) const

Definition ELF.h:408

Expected< MapVector< const Elf_Shdr *, const Elf_Shdr * > > getSectionAndRelocations(std::function< Expected< bool >(const Elf_Shdr &)> IsMatch) const

Returns a map from every section matching IsMatch to its relocation section, or nullptr if it has no ...

std::string getDynamicTagAsString(uint64_t Type) const

bool isLE() const

Definition ELF.h:375

bool isMips64EL() const

Definition ELF.h:384

Elf_Note_Iterator notes_end() const

Get the end iterator for notes.

Definition ELF.h:503

Expected< StringRef > getSectionName(const Elf_Shdr &Section, WarningHandler WarnHandler=&defaultWarningHandler) const

Definition ELF.h:1402

StringRef getRelocationTypeName(uint32_t Type) const

Definition ELF.h:729

Expected< StringRef > getStringTable(const Elf_Shdr &Section, WarningHandler WarnHandler=&defaultWarningHandler) const

Definition ELF.h:1297

llvm::function_ref< Error(const Twine &Msg)> WarningHandler

Definition ELF.h:273

Expected< uint32_t > getPhNum() const

Definition ELF.h:301

Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section, Elf_Shdr_Range Sections) const

Definition ELF.h:1370

Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr &Sec) const

Definition ELF.h:668

Expected< RelsOrRelas > crels(const Elf_Shdr &Sec) const

Expected< SmallVector< std::optional< VersionEntry >, 0 > > loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const

Definition ELF.h:771

Expected< Elf_Rel_Range > rels(const Elf_Shdr &Sec) const

Definition ELF.h:404

Expected< const Elf_Shdr * > getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab, DataRegion< Elf_Word > ShndxTable) const

Definition ELF.h:629

std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const

std::pair< std::vector< Elf_Rel >, std::vector< Elf_Rela > > RelsOrRelas

Definition ELF.h:415

Expected< uint32_t > getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms, DataRegion< Elf_Word > ShndxTable) const

Definition ELF.h:612

@ C

The default llvm calling convention, compatible with C.

constexpr unsigned CREL_HDR_ADDEND

static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)

Return the name of the section.

Expected< uint32_t > getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex, DataRegion< typename ELFT::Word > ShndxTable)

Definition ELF.h:594

Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)

Definition ELF.h:586

static bool isSectionInSegment(const typename ELFT::Phdr &Phdr, const typename ELFT::Shdr &Sec)

Definition ELF.h:209

Error createError(const Twine &Err)

LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)

static Expected< uint64_t > getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table, const void *BufEnd)

This function finds the number of dynamic symbols using a GNU hash table.

Definition ELF.h:845

LLVM_ABI uint32_t getELFRelativeRelocationType(uint32_t Machine)

LLVM_ABI StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)

static std::string describe(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)

Definition ELF.h:147

uint32_t hashGnu(StringRef Name)

This function returns the hash value for a symbol in the .dynsym section for the GNU hash table.

Definition ELF.h:1443

static bool checkSectionOffsets(const typename ELFT::Phdr &Phdr, const typename ELFT::Shdr &Sec)

Definition ELF.h:172

static std::string getPhdrIndexForError(const ELFFile< ELFT > &Obj, const typename ELFT::Phdr &Phdr)

Definition ELF.h:157

static bool checkSectionVMA(const typename ELFT::Phdr &Phdr, const typename ELFT::Shdr &Sec)

Definition ELF.h:190

LLVM_ABI StringRef getRISCVVendorRelocationTypeName(uint32_t Type, StringRef Vendor)

PPCInstrMasks

Definition ELF.h:90

@ PLD_R12_NO_DISP

Definition ELF.h:95

@ ADDIS_R12_TO_R2_NO_DISP

Definition ELF.h:92

@ ADDI_R12_TO_R12_NO_DISP

Definition ELF.h:94

@ ADDI_R12_TO_R2_NO_DISP

Definition ELF.h:93

@ PADDI_R12_NO_DISP

Definition ELF.h:91

@ BCTR

Definition ELF.h:97

@ MTCTR_R12

Definition ELF.h:96

std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)

Definition ELF.h:82

static Error defaultWarningHandler(const Twine &Msg)

Definition ELF.h:167

ELFFile< ELF32LE > ELF32LEFile

Definition ELF.h:579

ELFFile< ELF64BE > ELF64BEFile

Definition ELF.h:582

ELFFile< ELF32BE > ELF32BEFile

Definition ELF.h:581

uint32_t hashSysV(StringRef SymbolName)

This function returns the hash value for a symbol in the .dynsym section Name of the API remains cons...

Definition ELF.h:1431

static Error decodeCrel(ArrayRef< uint8_t > Content, function_ref< void(uint64_t, bool)> HdrHandler, function_ref< void(Elf_Crel_Impl< Is64 >)> EntryHandler)

Definition ELF.h:218

static std::string getSecIndexForError(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)

Definition ELF.h:133

ELFFile< ELF64LE > ELF64LEFile

Definition ELF.h:580

This is an optimization pass for GlobalISel generic memory operations.

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

FunctionAddr VTableAddr uintptr_t uintptr_t Version

FunctionAddr VTableAddr Count

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

ArrayRef(const T &OneElt) -> ArrayRef< T >

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

void consumeError(Error Err)

Consume a Error without doing anything.

Expected< T > operator[](uint64_t N)

Definition ELF.h:112

DataRegion(const T *Data, const uint8_t *BufferEnd)

Definition ELF.h:109

const T * First

Definition ELF.h:127

DataRegion(ArrayRef< T > Arr)

Definition ELF.h:105

const uint8_t * BufEnd

Definition ELF.h:129

std::optional< uint64_t > Size

Definition ELF.h:128

std::conditional_t< Is64, uint64_t, uint32_t > uint

std::string Name

Definition ELF.h:49

uint16_t Version

Definition ELF.h:44

uint16_t Flags

Definition ELF.h:45

uint16_t Ndx

Definition ELF.h:46

uint16_t Cnt

Definition ELF.h:47

unsigned Hash

Definition ELF.h:48

std::vector< VerdAux > AuxV

Definition ELF.h:50

unsigned Offset

Definition ELF.h:43

unsigned Cnt

Definition ELF.h:63

std::string File

Definition ELF.h:65

std::vector< VernAux > AuxV

Definition ELF.h:66

unsigned Offset

Definition ELF.h:64

unsigned Version

Definition ELF.h:62

unsigned Offset

Definition ELF.h:38

std::string Name

Definition ELF.h:39

unsigned Hash

Definition ELF.h:54

unsigned Offset

Definition ELF.h:57

unsigned Flags

Definition ELF.h:55

std::string Name

Definition ELF.h:58

unsigned Other

Definition ELF.h:56

bool IsVerDef

Definition ELF.h:71

std::string Name

Definition ELF.h:70