/* Get the potential trampolines size required of the init and non-init sections */ static unsigned long get_plt_size(const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs, const char *secstrings, int is_init) { unsigned long ret = 0; unsigned i; /* Everything marked ALLOC (this includes the exported symbols) */ for (i = 1; i < hdr->e_shnum; i++) { /* If it's called *.init*, and we're not init, we're not interested */ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) != is_init) continue; /* We don't want to look at debug sections. */ if (strstr(secstrings + sechdrs[i].sh_name, ".debug") != 0) continue; if (sechdrs[i].sh_type == SHT_RELA) { DEBUGP("Found relocations in section %u\n", i); DEBUGP("Ptr: %p. Number: %u\n", (void *)hdr + sechdrs[i].sh_offset, sechdrs[i].sh_size / sizeof(Elf32_Rela)); /* Sort the relocation information based on a symbol and * addend key. This is a stable O(n*log n) complexity * alogrithm but it will reduce the complexity of * count_relocs() to linear complexity O(n) */ sort((void *)hdr + sechdrs[i].sh_offset, sechdrs[i].sh_size / sizeof(Elf32_Rela), sizeof(Elf32_Rela), relacmp, relaswap); ret += count_relocs((void *)hdr + sechdrs[i].sh_offset, sechdrs[i].sh_size / sizeof(Elf32_Rela)) * sizeof(struct ppc_plt_entry); } } return ret; }
/* Get size of potential trampolines required. */ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, const Elf64_Shdr *sechdrs) { /* One extra reloc so it's always 0-funcaddr terminated */ unsigned long relocs = 1; unsigned i; /* Every relocated section... */ for (i = 1; i < hdr->e_shnum; i++) { if (sechdrs[i].sh_type == SHT_RELA) { pr_debug("Found relocations in section %u\n", i); pr_debug("Ptr: %p. Number: %Lu\n", (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size / sizeof(Elf64_Rela)); /* Sort the relocation information based on a symbol and * addend key. This is a stable O(n*log n) complexity * alogrithm but it will reduce the complexity of * count_relocs() to linear complexity O(n) */ sort((void *)sechdrs[i].sh_addr, sechdrs[i].sh_size / sizeof(Elf64_Rela), sizeof(Elf64_Rela), relacmp, relaswap); relocs += count_relocs((void *)sechdrs[i].sh_addr, sechdrs[i].sh_size / sizeof(Elf64_Rela)); } } #ifdef CONFIG_DYNAMIC_FTRACE /* make the trampoline to the ftrace_caller */ relocs++; #endif pr_debug("Looks like a total of %lu stubs, max\n", relocs); return relocs * sizeof(struct ppc64_stub_entry); }