^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* This is included from relocs_32/64.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #define ElfW(type) _ElfW(ELF_BITS, type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #define _ElfW(bits, type) __ElfW(bits, type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define __ElfW(bits, type) Elf##bits##_##type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define Elf_Addr ElfW(Addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define Elf_Ehdr ElfW(Ehdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define Elf_Phdr ElfW(Phdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define Elf_Shdr ElfW(Shdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define Elf_Sym ElfW(Sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static Elf_Ehdr ehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static unsigned long shnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static unsigned int shstrndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct relocs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) uint32_t *offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned long count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct relocs relocs16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct relocs relocs32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct relocs relocs32neg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static struct relocs relocs64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct section {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) Elf_Shdr shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct section *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) Elf_Sym *symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) Elf_Rel *reltab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) char *strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static struct section *secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const char * const sym_regex_kernel[S_NSYMTYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Following symbols have been audited. There values are constant and do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * not change if bzImage is loaded at a different physical address than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * the address for which it has been compiled. Don't warn user about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * absolute relocations present w.r.t these symbols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [S_ABS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) "^(xen_irq_disable_direct_reloc$|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "xen_save_fl_direct_reloc$|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "VDSO|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "__typeid__|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "__crc_)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * These symbols are known to be relative, even if the linker marks them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * as absolute (typically defined outside any section in the linker script.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [S_REL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "^(__init_(begin|end)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "__x86_cpu_dev_(start|end)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "(__parainstructions|__alt_instructions)(|_end)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "__(start|end)_pci_.*|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "__(start|end)_builtin_fw|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "__(start|stop)___ksymtab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "__(start|stop)___kcrctab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "__(start|stop)___param|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "__(start|stop)___modver|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "__(start|stop)___bug_table|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "__tracedata_(start|end)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "__(start|stop)_notes|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "__end_rodata|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "__end_rodata_aligned|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) "__initramfs_start|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "(jiffies|jiffies_64)|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "__per_cpu_load|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "init_per_cpu__.*|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "__end_rodata_hpage_align|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "__vvar_page|"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "_end)$"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static const char * const sym_regex_realmode[S_NSYMTYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * These symbols are known to be relative, even if the linker marks them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * as absolute (typically defined outside any section in the linker script.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [S_REL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) "^pa_",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * These are 16-bit segment symbols when compiling 16-bit code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [S_SEG] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) "^real_mode_seg$",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * These are offsets belonging to segments, as opposed to linear addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * when compiling 16-bit code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) [S_LIN] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "^pa_",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const char * const *sym_regex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static regex_t sym_regex_c[S_NSYMTYPES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int is_reloc(enum symtype type, const char *sym_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return sym_regex[type] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void regex_init(int use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) char errbuf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sym_regex = sym_regex_realmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sym_regex = sym_regex_kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (i = 0; i < S_NSYMTYPES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (!sym_regex[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) err = regcomp(&sym_regex_c[i], sym_regex[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) REG_EXTENDED|REG_NOSUB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) die("%s", errbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static const char *sym_type(unsigned type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const char *type_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SYM_TYPE(X) [X] = #X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) SYM_TYPE(STT_NOTYPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SYM_TYPE(STT_OBJECT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) SYM_TYPE(STT_FUNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) SYM_TYPE(STT_SECTION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) SYM_TYPE(STT_FILE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SYM_TYPE(STT_COMMON),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) SYM_TYPE(STT_TLS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #undef SYM_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const char *name = "unknown sym type name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (type < ARRAY_SIZE(type_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) name = type_name[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static const char *sym_bind(unsigned bind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static const char *bind_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define SYM_BIND(X) [X] = #X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SYM_BIND(STB_LOCAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) SYM_BIND(STB_GLOBAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) SYM_BIND(STB_WEAK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #undef SYM_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const char *name = "unknown sym bind name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (bind < ARRAY_SIZE(bind_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) name = bind_name[bind];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static const char *sym_visibility(unsigned visibility)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static const char *visibility_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define SYM_VISIBILITY(X) [X] = #X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) SYM_VISIBILITY(STV_DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) SYM_VISIBILITY(STV_INTERNAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) SYM_VISIBILITY(STV_HIDDEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) SYM_VISIBILITY(STV_PROTECTED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #undef SYM_VISIBILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) const char *name = "unknown sym visibility name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (visibility < ARRAY_SIZE(visibility_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) name = visibility_name[visibility];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static const char *rel_type(unsigned type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static const char *type_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define REL_TYPE(X) [X] = #X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) REL_TYPE(R_X86_64_NONE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) REL_TYPE(R_X86_64_64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) REL_TYPE(R_X86_64_PC64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) REL_TYPE(R_X86_64_PC32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) REL_TYPE(R_X86_64_GOT32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) REL_TYPE(R_X86_64_PLT32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) REL_TYPE(R_X86_64_COPY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) REL_TYPE(R_X86_64_GLOB_DAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) REL_TYPE(R_X86_64_JUMP_SLOT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) REL_TYPE(R_X86_64_RELATIVE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) REL_TYPE(R_X86_64_GOTPCREL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) REL_TYPE(R_X86_64_32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) REL_TYPE(R_X86_64_32S),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) REL_TYPE(R_X86_64_16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) REL_TYPE(R_X86_64_PC16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) REL_TYPE(R_X86_64_8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) REL_TYPE(R_X86_64_PC8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) REL_TYPE(R_386_NONE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) REL_TYPE(R_386_32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) REL_TYPE(R_386_PC32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) REL_TYPE(R_386_GOT32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) REL_TYPE(R_386_PLT32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) REL_TYPE(R_386_COPY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) REL_TYPE(R_386_GLOB_DAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) REL_TYPE(R_386_JMP_SLOT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) REL_TYPE(R_386_RELATIVE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) REL_TYPE(R_386_GOTOFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) REL_TYPE(R_386_GOTPC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) REL_TYPE(R_386_8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) REL_TYPE(R_386_PC8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) REL_TYPE(R_386_16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) REL_TYPE(R_386_PC16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #undef REL_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) const char *name = "unknown type rel type name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (type < ARRAY_SIZE(type_name) && type_name[type]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) name = type_name[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const char *sec_name(unsigned shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const char *sec_strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) sec_strtab = secs[shstrndx].strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) name = "<noname>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (shndx < shnum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) name = sec_strtab + secs[shndx].shdr.sh_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) else if (shndx == SHN_ABS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) name = "ABSOLUTE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) else if (shndx == SHN_COMMON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) name = "COMMON";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) name = "<noname>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (sym->st_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) name = sym_strtab + sym->st_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) name = sec_name(sym->st_shndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static Elf_Sym *sym_lookup(const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) long nsyms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) char *strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) Elf_Sym *symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (sec->shdr.sh_type != SHT_SYMTAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) symtab = sec->symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) strtab = sec->link->strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) for (sym = symtab; --nsyms >= 0; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (!sym->st_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (strcmp(symname, strtab + sym->st_name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #if BYTE_ORDER == LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define le16_to_cpu(val) (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define le32_to_cpu(val) (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define le64_to_cpu(val) (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #if BYTE_ORDER == BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) #define le16_to_cpu(val) bswap_16(val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #define le32_to_cpu(val) bswap_32(val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #define le64_to_cpu(val) bswap_64(val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static uint16_t elf16_to_cpu(uint16_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return le16_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static uint32_t elf32_to_cpu(uint32_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return le32_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #define elf_half_to_cpu(x) elf16_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define elf_word_to_cpu(x) elf32_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static uint64_t elf64_to_cpu(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return le64_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define elf_addr_to_cpu(x) elf64_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define elf_off_to_cpu(x) elf64_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #define elf_xword_to_cpu(x) elf64_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define elf_addr_to_cpu(x) elf32_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define elf_off_to_cpu(x) elf32_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define elf_xword_to_cpu(x) elf32_to_cpu(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void read_ehdr(FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) die("Cannot read ELF header: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) die("No ELF magic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) die("Not a %d bit executable\n", ELF_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) die("Not a LSB ELF executable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) die("Unknown ELF version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Convert the fields to native endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ehdr.e_type = elf_half_to_cpu(ehdr.e_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ehdr.e_machine = elf_half_to_cpu(ehdr.e_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ehdr.e_version = elf_word_to_cpu(ehdr.e_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ehdr.e_entry = elf_addr_to_cpu(ehdr.e_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ehdr.e_phoff = elf_off_to_cpu(ehdr.e_phoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ehdr.e_shoff = elf_off_to_cpu(ehdr.e_shoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ehdr.e_flags = elf_word_to_cpu(ehdr.e_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ehdr.e_ehsize = elf_half_to_cpu(ehdr.e_ehsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ehdr.e_phnum = elf_half_to_cpu(ehdr.e_phnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) shnum = ehdr.e_shnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) shstrndx = ehdr.e_shstrndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) die("Unsupported ELF header type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ehdr.e_machine != ELF_MACHINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) die("Not for %s\n", ELF_MACHINE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (ehdr.e_version != EV_CURRENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) die("Unknown ELF version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) die("Bad Elf header size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ehdr.e_phentsize != sizeof(Elf_Phdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) die("Bad program header entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ehdr.e_shentsize != sizeof(Elf_Shdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) die("Bad section header entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) Elf_Shdr shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) die("Cannot read initial ELF section header: %s\n", strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (shnum == SHN_UNDEF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) shnum = elf_xword_to_cpu(shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (shstrndx == SHN_XINDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) shstrndx = elf_word_to_cpu(shdr.sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (shstrndx >= shnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) die("String table index out of bounds\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static void read_shdrs(FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) Elf_Shdr shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) secs = calloc(shnum, sizeof(struct section));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!secs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) die("Unable to allocate %d section headers\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) die("Seek to %d failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ehdr.e_shoff, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) die("Cannot read ELF section headers %d/%d: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) i, shnum, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) sec->shdr.sh_addr = elf_addr_to_cpu(shdr.sh_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) sec->shdr.sh_offset = elf_off_to_cpu(shdr.sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) sec->shdr.sh_size = elf_xword_to_cpu(shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) sec->shdr.sh_link = elf_word_to_cpu(shdr.sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (sec->shdr.sh_link < shnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) sec->link = &secs[sec->shdr.sh_link];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void read_strtabs(FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (sec->shdr.sh_type != SHT_STRTAB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) sec->strtab = malloc(sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!sec->strtab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) die("malloc of %d bytes for strtab failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) die("Seek to %d failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) sec->shdr.sh_offset, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) != sec->shdr.sh_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) die("Cannot read symbol table: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static void read_symtabs(FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int i,j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (sec->shdr.sh_type != SHT_SYMTAB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sec->symtab = malloc(sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!sec->symtab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) die("malloc of %d bytes for symtab failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) die("Seek to %d failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) sec->shdr.sh_offset, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) != sec->shdr.sh_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) die("Cannot read symbol table: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) Elf_Sym *sym = &sec->symtab[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sym->st_name = elf_word_to_cpu(sym->st_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) sym->st_value = elf_addr_to_cpu(sym->st_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) sym->st_size = elf_xword_to_cpu(sym->st_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static void read_relocs(FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int i,j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (sec->shdr.sh_type != SHT_REL_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) sec->reltab = malloc(sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (!sec->reltab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) die("malloc of %d bytes for relocs failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) sec->shdr.sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) die("Seek to %d failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) sec->shdr.sh_offset, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) != sec->shdr.sh_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) die("Cannot read symbol table: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) Elf_Rel *rel = &sec->reltab[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) rel->r_offset = elf_addr_to_cpu(rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) rel->r_info = elf_xword_to_cpu(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #if (SHT_REL_TYPE == SHT_RELA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) rel->r_addend = elf_xword_to_cpu(rel->r_addend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static void print_absolute_symbols(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) const char *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (ELF_BITS == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) format = "%5d %08"PRIx32" %5"PRId32" %10s %10s %12s %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) printf("Absolute symbols\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) printf(" Num: Value Size Type Bind Visibility Name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) char *sym_strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (sec->shdr.sh_type != SHT_SYMTAB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) sym_strtab = sec->link->strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) sym = &sec->symtab[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) name = sym_name(sym_strtab, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (sym->st_shndx != SHN_ABS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) printf(format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) j, sym->st_value, sym->st_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) sym_type(ELF_ST_TYPE(sym->st_info)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) sym_bind(ELF_ST_BIND(sym->st_info)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) sym_visibility(ELF_ST_VISIBILITY(sym->st_other)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void print_absolute_relocs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int i, printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) const char *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ELF_BITS == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64" %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct section *sec_applies, *sec_symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) char *sym_strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) Elf_Sym *sh_symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (sec->shdr.sh_type != SHT_REL_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) sec_symtab = sec->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) sec_applies = &secs[sec->shdr.sh_info];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) sh_symtab = sec_symtab->symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) sym_strtab = sec_symtab->link->strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) Elf_Rel *rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) rel = &sec->reltab[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) name = sym_name(sym_strtab, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (sym->st_shndx != SHN_ABS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Absolute symbols are not relocated if bzImage is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * loaded at a non-compiled address. Display a warning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * to user at compile time about the absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * relocations present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * User need to audit the code to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * some symbols which should have been section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * relative have not become absolute because of some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * linker optimization or wrong programming usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * Before warning check if this absolute symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * relocation is harmless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (!printed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) printf("WARNING: Absolute relocations"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) " present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) printf("Offset Info Type Sym.Value "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) "Sym.Name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) printed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) printf(format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) rel->r_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) rel->r_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) rel_type(ELF_R_TYPE(rel->r_info)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) sym->st_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (printed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static void add_reloc(struct relocs *r, uint32_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (r->count == r->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned long newsize = r->size + 50000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) die("realloc of %ld entries for relocs failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) r->offset = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) r->size = newsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) r->offset[r->count++] = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) Elf_Sym *sym, const char *symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* Walk through the relocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) char *sym_strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) Elf_Sym *sh_symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct section *sec_applies, *sec_symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct section *sec = &secs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (sec->shdr.sh_type != SHT_REL_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) sec_symtab = sec->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sec_applies = &secs[sec->shdr.sh_info];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) sh_symtab = sec_symtab->symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) sym_strtab = sec_symtab->link->strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) Elf_Rel *rel = &sec->reltab[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) const char *symname = sym_name(sym_strtab, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) process(sec, rel, sym, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * The .data..percpu section is a special case for x86_64 SMP kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * It is used to initialize the actual per_cpu areas and to provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * definitions for the per_cpu variables that correspond to their offsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * within the percpu area. Since the values of all of the symbols need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * to be offsets from the start of the per_cpu area the virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * (sh_addr) of .data..percpu is 0 in SMP kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * This means that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * Relocations that reference symbols in the per_cpu area do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * need further relocation (since the value is an offset relative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * to the start of the per_cpu area that does not change).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Relocations that apply to the per_cpu area need to have their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * offset adjusted by by the value of __per_cpu_load to make them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * point to the correct place in the loaded image (because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * virtual address of .data..percpu is 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * For non SMP kernels .data..percpu is linked as part of the normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * kernel data and does not require special treatment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static int per_cpu_shndx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static Elf_Addr per_cpu_load_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static void percpu_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) for (i = 0; i < shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ElfW(Sym) *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (strcmp(sec_name(i), ".data..percpu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (secs[i].shdr.sh_addr != 0) /* non SMP kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sym = sym_lookup("__per_cpu_load");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) die("can't find __per_cpu_load\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) per_cpu_shndx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) per_cpu_load_addr = sym->st_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * Check to see if a symbol lies in the .data..percpu section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * The linker incorrectly associates some symbols with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * .data..percpu section so we also need to check the symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * name to make sure that we classify the symbol correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * The GNU linker incorrectly associates:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * __init_begin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * __per_cpu_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * The "gold" linker incorrectly associates:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * init_per_cpu__fixed_percpu_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * init_per_cpu__gdt_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return (sym->st_shndx == per_cpu_shndx) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) strcmp(symname, "__init_begin") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) strcmp(symname, "__per_cpu_load") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) strncmp(symname, "init_per_cpu_", 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) unsigned r_type = ELF64_R_TYPE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ElfW(Addr) offset = rel->r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (sym->st_shndx == SHN_UNDEF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * Adjust the offset if this reloc applies to the percpu section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (sec->shdr.sh_info == per_cpu_shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) offset += per_cpu_load_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) switch (r_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case R_X86_64_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* NONE can be ignored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case R_X86_64_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case R_X86_64_PLT32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * PC relative relocations don't need to be adjusted unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * referencing a percpu symbol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (is_percpu_sym(sym, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) add_reloc(&relocs32neg, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case R_X86_64_PC64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * Only used by jump labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (is_percpu_sym(sym, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case R_X86_64_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!shn_abs || !is_reloc(S_ABS, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) die("Non-whitelisted %s relocation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) rel_type(r_type), symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case R_X86_64_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) case R_X86_64_32S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case R_X86_64_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * References to the percpu area don't need to be adjusted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (is_percpu_sym(sym, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (shn_abs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * Whitelisted absolute symbols do not require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * relocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (is_reloc(S_ABS, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) die("Invalid absolute %s relocation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) rel_type(r_type), symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * Relocation offsets for 64 bit kernels are output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * as 32 bits and sign extended back to 64 bits when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * the relocations are processed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * Make sure that the offset will fit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if ((int32_t)offset != (int64_t)offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) die("Relocation offset doesn't fit in 32 bits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (r_type == R_X86_64_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) add_reloc(&relocs64, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) add_reloc(&relocs32, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) die("Unsupported relocation type: %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) rel_type(r_type), r_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) unsigned r_type = ELF32_R_TYPE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) switch (r_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case R_386_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case R_386_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case R_386_PC16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case R_386_PC8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case R_386_PLT32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * NONE can be ignored and PC relative relocations don't need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * to be adjusted. Because sym must be defined, R_386_PLT32 can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * be treated the same way as R_386_PC32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) case R_386_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (shn_abs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * Whitelisted absolute symbols do not require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * relocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (is_reloc(S_ABS, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) die("Invalid absolute %s relocation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) rel_type(r_type), symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) add_reloc(&relocs32, rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) die("Unsupported relocation type: %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) rel_type(r_type), r_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) unsigned r_type = ELF32_R_TYPE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) switch (r_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case R_386_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) case R_386_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case R_386_PC16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case R_386_PC8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) case R_386_PLT32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * NONE can be ignored and PC relative relocations don't need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * to be adjusted. Because sym must be defined, R_386_PLT32 can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * be treated the same way as R_386_PC32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) case R_386_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (shn_abs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * Whitelisted absolute symbols do not require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * relocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (is_reloc(S_ABS, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (is_reloc(S_SEG, symname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) add_reloc(&relocs16, rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (!is_reloc(S_LIN, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) die("Invalid %s %s relocation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) shn_abs ? "absolute" : "relative",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) rel_type(r_type), symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case R_386_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (shn_abs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * Whitelisted absolute symbols do not require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * relocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (is_reloc(S_ABS, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (is_reloc(S_REL, symname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) add_reloc(&relocs32, rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (is_reloc(S_LIN, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) add_reloc(&relocs32, rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) die("Invalid %s %s relocation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) shn_abs ? "absolute" : "relative",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) rel_type(r_type), symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) die("Unsupported relocation type: %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) rel_type(r_type), r_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int cmp_relocs(const void *va, const void *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) const uint32_t *a, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) a = va; b = vb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return (*a == *b)? 0 : (*a > *b)? 1 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static void sort_relocs(struct relocs *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int write32(uint32_t v, FILE *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) unsigned char buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) put_unaligned_le32(v, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static int write32_as_text(uint32_t v, FILE *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return fprintf(f, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static void emit_relocs(int as_text, int use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int (*write_reloc)(uint32_t, FILE *) = write32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) const char *symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (!use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) do_reloc = do_reloc64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) die("--realmode not valid for a 64-bit ELF file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (!use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) do_reloc = do_reloc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) do_reloc = do_reloc_real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Collect up the relocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) walk_relocs(do_reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (relocs16.count && !use_real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) die("Segment relocations found but --realmode not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* Order the relocations for more efficient processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) sort_relocs(&relocs32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) sort_relocs(&relocs32neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sort_relocs(&relocs64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) sort_relocs(&relocs16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /* Print the relocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (as_text) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Print the relocations in a form suitable that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * gas will like.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) printf(".section \".data.reloc\",\"a\"\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) printf(".balign 4\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) write_reloc = write32_as_text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (use_real_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) write_reloc(relocs16.count, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) for (i = 0; i < relocs16.count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) write_reloc(relocs16.offset[i], stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) write_reloc(relocs32.count, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) for (i = 0; i < relocs32.count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) write_reloc(relocs32.offset[i], stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* Print a stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) write_reloc(0, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* Now print each relocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) for (i = 0; i < relocs64.count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) write_reloc(relocs64.offset[i], stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /* Print a stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) write_reloc(0, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* Now print each inverse 32-bit relocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) for (i = 0; i < relocs32neg.count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) write_reloc(relocs32neg.offset[i], stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* Print a stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) write_reloc(0, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) /* Now print each relocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) for (i = 0; i < relocs32.count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) write_reloc(relocs32.offset[i], stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * As an aid to debugging problems with different linkers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * print summary information about the relocs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * Since different linkers tend to emit the sections in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * different orders we use the section names in the output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) printf("%s\t%s\t%s\t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) sec_name(sec->shdr.sh_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) rel_type(ELF_R_TYPE(rel->r_info)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) symname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) sec_name(sym->st_shndx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static void print_reloc_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) printf("reloc section\treloc type\tsymbol\tsymbol section\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) walk_relocs(do_reloc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) #if ELF_BITS == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) # define process process_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) # define process process_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) void process(FILE *fp, int use_real_mode, int as_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int show_absolute_syms, int show_absolute_relocs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) int show_reloc_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) regex_init(use_real_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) read_ehdr(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) read_shdrs(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) read_strtabs(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) read_symtabs(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) read_relocs(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (ELF_BITS == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) percpu_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (show_absolute_syms) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) print_absolute_symbols();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (show_absolute_relocs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) print_absolute_relocs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (show_reloc_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) print_reloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) emit_relocs(as_text, use_real_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }