# Changeset View

Changeset View

# Standalone View

Standalone View

# ELF/Relocations.cpp

Show First 20 Lines • Show All 349 Lines • ▼ Show 20 Line(s) | 348 | return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE, | |||
---|---|---|---|---|---|

350 | R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END, | 350 | R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END, | ||

351 | R_GOT_PLT>(Expr); | 351 | R_GOT_PLT>(Expr); | ||

352 | } | 352 | } | ||

353 | 353 | | |||

354 | // True if this expression is of the form Sym - X, where X is a position in the | 354 | // True if this expression is of the form Sym - X, where X is a position in the | ||

355 | // file (PC, or GOT for example). | 355 | // file (PC, or GOT for example). | ||

356 | static bool isRelExpr(RelExpr Expr) { | 356 | static bool isRelExpr(RelExpr Expr) { | ||

357 | return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL, | 357 | return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL, | ||

358 | R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC, | 358 | R_PPC_CALL, R_PPC_CALL_PLT, R_PPC64_RELAX_TOC, | ||

359 | R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr); | 359 | R_AARCH64_PAGE_PC, R_AARCH64_PLT_PAGE_PC, | ||

360 | R_RELAX_GOT_PC>(Expr); | ||||

360 | } | 361 | } | ||

361 | 362 | | |||

362 | // Returns true if a given relocation can be computed at link-time. | 363 | // Returns true if a given relocation can be computed at link-time. | ||

363 | // | 364 | // | ||

364 | // For instance, we know the offset from a relocation to its target at | 365 | // For instance, we know the offset from a relocation to its target at | ||

365 | // link-time if the relocation is PC-relative and refers a | 366 | // link-time if the relocation is PC-relative and refers a | ||

366 | // non-interposable function in the same executable. This function | 367 | // non-interposable function in the same executable. This function | ||

367 | // will return true for such relocation. | 368 | // will return true for such relocation. | ||

368 | // | 369 | // | ||

369 | // If this function returns false, that means we need to emit a | 370 | // If this function returns false, that means we need to emit a | ||

370 | // dynamic relocation so that the relocation will be fixed at load-time. | 371 | // dynamic relocation so that the relocation will be fixed at load-time. | ||

371 | static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, | 372 | static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, | ||

372 | InputSectionBase &S, uint64_t RelOff) { | 373 | InputSectionBase &S, uint64_t RelOff) { | ||

373 | // These expressions always compute a constant | 374 | // These expressions always compute a constant | ||

374 | if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF, | 375 | if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF, | ||

375 | R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF, | 376 | R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF, | ||

376 | R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, | 377 | R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, | ||

377 | R_AARCH64_GOT_PAGE_PC, R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, | 378 | R_AARCH64_GOT_PAGE_PC, R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, | ||

378 | R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, | 379 | R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, | ||

379 | R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT, | 380 | R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT, | ||

380 | R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, R_HINT, | 381 | R_PPC64_RELAX_TOC, R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, | ||

381 | R_TLSLD_HINT, R_TLSIE_HINT>(E)) | 382 | R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E)) | ||

382 | return true; | 383 | return true; | ||

383 | 384 | | |||

384 | // These never do, except if the entire file is position dependent or if | 385 | // These never do, except if the entire file is position dependent or if | ||

385 | // only the low bits are used. | 386 | // only the low bits are used. | ||

386 | if (E == R_GOT || E == R_GOT_PLT || E == R_PLT || E == R_TLSDESC) | 387 | if (E == R_GOT || E == R_GOT_PLT || E == R_PLT || E == R_TLSDESC) | ||

387 | return Target->usesOnlyLowPageBits(Type) || !Config->Pic; | 388 | return Target->usesOnlyLowPageBits(Type) || !Config->Pic; | ||

388 | 389 | | |||

389 | if (Sym.IsPreemptible) | 390 | if (Sym.IsPreemptible) | ||

▲ Show 20 Lines • Show All 637 Lines • ▼ Show 20 Line(s) | 1027 | } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) { | |||

1027 | Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr); | 1028 | Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr); | ||

1028 | } else if (!Sym.IsPreemptible) { | 1029 | } else if (!Sym.IsPreemptible) { | ||

1029 | Expr = fromPlt(Expr); | 1030 | Expr = fromPlt(Expr); | ||

1030 | } | 1031 | } | ||

1031 | 1032 | | |||

1032 | // This relocation does not require got entry, but it is relative to got and | 1033 | // This relocation does not require got entry, but it is relative to got and | ||

1033 | // needs it to be created. Here we request for that. | 1034 | // needs it to be created. Here we request for that. | ||

1034 | if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, | 1035 | if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, | ||

1035 | R_GOTREL_FROM_END, R_PPC_TOC>(Expr)) | 1036 | R_GOTREL_FROM_END, R_PPC_TOC, R_PPC64_RELAX_TOC>(Expr)) | ||

1036 | In.Got->HasGotOffRel = true; | 1037 | In.Got->HasGotOffRel = true; | ||

1037 | 1038 | | |||

1038 | // Read an addend. | 1039 | // Read an addend. | ||

1039 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | 1040 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | ||

1040 | 1041 | | |||

1041 | // Process some TLS relocations, including relaxing TLS relocations. | 1042 | // Process some TLS relocations, including relaxing TLS relocations. | ||

1042 | // Note that this function does not handle all TLS relocations. | 1043 | // Note that this function does not handle all TLS relocations. | ||

1043 | if (unsigned Processed = | 1044 | if (unsigned Processed = | ||

Show All 35 Lines | 1079 | static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { | |||

1079 | OffsetGetter GetOffset(Sec); | 1080 | OffsetGetter GetOffset(Sec); | ||

1080 | 1081 | | |||

1081 | // Not all relocations end up in Sec.Relocations, but a lot do. | 1082 | // Not all relocations end up in Sec.Relocations, but a lot do. | ||

1082 | Sec.Relocations.reserve(Rels.size()); | 1083 | Sec.Relocations.reserve(Rels.size()); | ||

1083 | 1084 | | |||

1084 | for (auto I = Rels.begin(), End = Rels.end(); I != End;) | 1085 | for (auto I = Rels.begin(), End = Rels.end(); I != End;) | ||

1085 | scanReloc<ELFT>(Sec, GetOffset, I, End); | 1086 | scanReloc<ELFT>(Sec, GetOffset, I, End); | ||

1086 | 1087 | | |||

1087 | // Sort relocations by offset to binary search for R_RISCV_PCREL_HI20 | 1088 | // Sort relocations by offset for more efficient searching for | ||

1088 | if (Config->EMachine == EM_RISCV) | 1089 | // R_RISCV_PCREL_HI20 and targets of toc-indirections on PPC64. | ||

1090 | if (Config->EMachine == EM_RISCV || | ||||

1091 | (Config->EMachine == EM_PPC64 && Sec.Name == ".toc")) | ||||

1089 | std::stable_sort(Sec.Relocations.begin(), Sec.Relocations.end(), | 1092 | std::stable_sort(Sec.Relocations.begin(), Sec.Relocations.end(), | ||

1090 | RelocationOffsetComparator{}); | 1093 | RelocationOffsetComparator{}); | ||

1091 | } | 1094 | } | ||

1092 | 1095 | | |||

1093 | template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { | 1096 | template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { | ||

1094 | if (S.AreRelocsRela) | 1097 | if (S.AreRelocsRela) | ||

1095 | scanRelocs<ELFT>(S, S.relas<ELFT>()); | 1098 | scanRelocs<ELFT>(S, S.relas<ELFT>()); | ||

1096 | else | 1099 | else | ||

▲ Show 20 Lines • Show All 416 Lines • Show Last 20 Lines |