staticint cmp_rela(constvoid *a, constvoid *b)
{ const Elf64_Rela *x = a, *y = b; int i;
/* sort by type, symbol index and addend */
i = cmp_3way(ELF64_R_TYPE(x->r_info), ELF64_R_TYPE(y->r_info)); if (i == 0)
i = cmp_3way(ELF64_R_SYM(x->r_info), ELF64_R_SYM(y->r_info)); if (i == 0)
i = cmp_3way(x->r_addend, y->r_addend); return i;
}
staticbool duplicate_rel(const Elf64_Rela *rela, int num)
{ /* *Entriesaresortedbytype,symbolindexandaddend.Thatmeans *that,ifaduplicateentryexists,itmustbeinthepreceding *slot.
*/ return num > 0 && cmp_rela(rela + num, rela + num - 1) == 0;
}
staticunsignedint count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
Elf64_Word dstidx, Elf_Shdr *dstsec)
{ unsignedint ret = 0;
Elf64_Sym *s; int i;
for (i = 0; i < num; i++) {
u64 min_align;
switch (ELF64_R_TYPE(rela[i].r_info)) { case R_AARCH64_JUMP26: case R_AARCH64_CALL26: /* *Weonlyhavetoconsiderbranchtargetsthatresolve *tosymbolsthataredefinedinadifferentsection. *Thisisnotsimplyaheuristic,itisafundamental *limitation,sincethereisnoguaranteedwaytoemit *PLTentriessufficientlyclosetothebranchifthe *sectionsizeexceedstherangeofabranch *instruction.Soignorerelocationsagainstdefined *symbolsiftheyliveinthesamesectionasthe *relocationtarget.
*/
s = syms + ELF64_R_SYM(rela[i].r_info); if (s->st_shndx == dstidx) break;
/* *Jumprelocationswithnon-zeroaddendsagainst *undefinedsymbolsaresupportedbytheELFspec,but *donotoccurinpractice(e.g.,'jumpnbytespast *theentrypointofundefinedfunctionsymbolf'). *Soweneedtosupportthem,butthereisnoneedto *takethemintoconsiderationwhentryingtooptimize *thiscode.Solet'sonlycheckforduplicateswhen *theaddendiszero:thisallowsustorecordthePLT *entryaddressinthesymboltableitself,ratherthan *havingtosearchthelistforduplicateseachtimewe *emitone.
*/ if (rela[i].r_addend != 0 || !duplicate_rel(rela, i))
ret++; break; case R_AARCH64_ADR_PREL_PG_HI21_NC: case R_AARCH64_ADR_PREL_PG_HI21: if (!cpus_have_final_cap(ARM64_WORKAROUND_843419)) break;
/* Group branch PLT relas at the front end of the array. */ staticint partition_branch_plt_relas(Elf64_Sym *syms, Elf64_Rela *rela, int numrels, Elf64_Word dstidx)
{ int i = 0, j = numrels - 1;
while (i < j) { if (branch_rela_needs_plt(syms, &rela[i], dstidx))
i++; elseif (branch_rela_needs_plt(syms, &rela[j], dstidx))
swap(rela[i], rela[j]); else
j--;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.