📄 dl-machine.h
字号:
sll %i5, 2, %o3\n\ ld [%l7+%o0], %o0\n\ add %o3, 4, %o3\n\ mov %i5, %o1\n\ add %o2, %o3, %o3\n\ call _dl_init_internal\n\ ld [%o0], %o0\n\ /* Pass our finalizer function to the user in %g1. */\n\ sethi %hi(_dl_fini), %g1\n\ or %g1, %lo(_dl_fini), %g1\n\ ld [%l7+%g1], %g1\n\ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ jmp %l0\n\ add %sp, 6*4, %sp\n\ .size _dl_start_user, . - _dl_start_user\n\ .previous");static inline __attribute__ ((always_inline)) Elf32_Addrsparc_fixup_plt (const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, Elf32_Addr value, int t, int do_flush){ Elf32_Sword disp = value - (Elf32_Addr) reloc_addr; if (0 && disp >= -0x800000 && disp < 0x800000) { /* Don't need to worry about thread safety. We're writing just one instruction. */ reloc_addr[0] = OPCODE_BA | ((disp >> 2) & 0x3fffff); if (do_flush) __asm __volatile ("flush %0" : : "r"(reloc_addr)); } else { /* For thread safety, write the instructions from the bottom and flush before we overwrite the critical "b,a". This of course need not be done during bootstrapping, since there are no threads. But we also can't tell if we _can_ use flush, so don't. */ reloc_addr += t; reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff); if (do_flush) __asm __volatile ("flush %0+4" : : "r"(reloc_addr)); reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10); if (do_flush) __asm __volatile ("flush %0" : : "r"(reloc_addr)); } return value;}static inline Elf32_Addrelf_machine_fixup_plt (struct link_map *map, lookup_t t, const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, Elf32_Addr value){#ifdef __sparc_v9__ /* Sparc v9 can assume flush is always present. */ const int do_flush = 1;#else /* Note that we don't mask the hwcap here, as the flush is essential to functionality on those cpu's that implement it. */ const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH;#endif return sparc_fixup_plt (reloc, reloc_addr, value, 1, do_flush);}/* Return the final value of a plt relocation. */static inline Elf32_Addrelf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, Elf32_Addr value){ return value + reloc->r_addend;}#endif /* dl_machine_h */#define ARCH_LA_PLTENTER sparc32_gnu_pltenter#define ARCH_LA_PLTEXIT sparc32_gnu_pltexit#ifdef RESOLVE_MAP/* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */auto inline void__attribute__ ((always_inline))elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, const Elf32_Sym *sym, const struct r_found_version *version, void *const reloc_addr_arg){ Elf32_Addr *const reloc_addr = reloc_addr_arg; const Elf32_Sym *const refsym = sym; Elf32_Addr value; const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); struct link_map *sym_map = NULL;#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC /* This is defined in rtld.c, but nowhere in the static libc.a; make the reference weak so static programs can still link. This declaration cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the common defn for _dl_rtld_map, which is incompatible with a weak decl in the same file. */ weak_extern (_dl_rtld_map);#endif if (__builtin_expect (r_type == R_SPARC_NONE, 0)) return;#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0)) {# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC if (map != &_dl_rtld_map) /* Already done in rtld itself. */# endif *reloc_addr += map->l_addr + reloc->r_addend; return; }#endif#ifndef RESOLVE_CONFLICT_FIND_MAP if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0) && sym->st_shndx != SHN_UNDEF) { value = map->l_addr; } else { sym_map = RESOLVE_MAP (&sym, version, r_type); value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; }#else value = 0;#endif value += reloc->r_addend; /* Assume copy relocs have zero addend. */ switch (r_type) {#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP case R_SPARC_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be found. */ break; if (sym->st_size > refsym->st_size || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) { const char *strtab; strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); _dl_error_printf ("\%s: Symbol `%s' has different size in shared object, consider re-linking\n", rtld_progname ?: "<program name unknown>", strtab + refsym->st_name); } memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break;#endif case R_SPARC_GLOB_DAT: case R_SPARC_32: *reloc_addr = value; break; case R_SPARC_JMP_SLOT: {#if !defined RTLD_BOOTSTRAP && !defined __sparc_v9__ /* Note that we don't mask the hwcap here, as the flush is essential to functionality on those cpu's that implement it. For sparcv9 we can assume flush is present. */ const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH;#else /* Unfortunately, this is necessary, so that we can ensure ld.so will not execute corrupt PLT entry instructions. */ const int do_flush = 1;#endif /* At this point we don't need to bother with thread safety, so we can optimize the first instruction of .plt out. */ sparc_fixup_plt (reloc, reloc_addr, value, 0, do_flush); } break;#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD32: /* Get the information from the link map returned by the resolv function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; break; case R_SPARC_TLS_DTPOFF32: /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend; break; case R_SPARC_TLS_TPOFF32: /* The offset is negative, forward from the thread pointer. */ /* We know the offset of object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ if (sym != NULL) { CHECK_STATIC_TLS (map, sym_map); *reloc_addr = sym->st_value - sym_map->l_tls_offset + reloc->r_addend; } break;# ifndef RTLD_BOOTSTRAP case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: if (sym != NULL) { CHECK_STATIC_TLS (map, sym_map); value = sym->st_value - sym_map->l_tls_offset + reloc->r_addend; if (r_type == R_SPARC_TLS_LE_HIX22) *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10); else *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff) | 0x1c00; } break;# endif#endif#ifndef RTLD_BOOTSTRAP case R_SPARC_8: *(char *) reloc_addr = value; break; case R_SPARC_16: *(short *) reloc_addr = value; break; case R_SPARC_DISP8: *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr); break; case R_SPARC_DISP16: *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr); break; case R_SPARC_DISP32: *reloc_addr = (value - (Elf32_Addr) reloc_addr); break; case R_SPARC_LO10: *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff); break; case R_SPARC_WDISP30: *reloc_addr = ((*reloc_addr & 0xc0000000) | ((value - (unsigned int) reloc_addr) >> 2)); break; case R_SPARC_HI22: *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10); break; case R_SPARC_UA16: ((unsigned char *) reloc_addr_arg) [0] = value >> 8; ((unsigned char *) reloc_addr_arg) [1] = value; break; case R_SPARC_UA32: ((unsigned char *) reloc_addr_arg) [0] = value >> 24; ((unsigned char *) reloc_addr_arg) [1] = value >> 16; ((unsigned char *) reloc_addr_arg) [2] = value >> 8; ((unsigned char *) reloc_addr_arg) [3] = value; break;#endif#if !defined RTLD_BOOTSTRAP || defined _NDEBUG default: _dl_reloc_bad_type (map, r_type, 0); break;#endif }}auto inline void__attribute__ ((always_inline))elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, void *const reloc_addr_arg){ Elf32_Addr *const reloc_addr = reloc_addr_arg; *reloc_addr += l_addr + reloc->r_addend;}auto inline void__attribute__ ((always_inline))elf_machine_lazy_rel (struct link_map *map, Elf32_Addr l_addr, const Elf32_Rela *reloc){ switch (ELF32_R_TYPE (reloc->r_info)) { case R_SPARC_NONE: break; case R_SPARC_JMP_SLOT: break; default: _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1); break; }}#endif /* RESOLVE_MAP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -