📄 dl-machine.h
字号:
lg %r2,0(%r2)\n\ lg %r3,160(%r15)\n\ la %r4,168(%r15)\n\ lgr %r5,%r3\n\ sllg %r5,%r5,3\n\ la %r5,176(%r5,%r15)\n\ brasl %r14,_dl_init_internal@PLT\n\ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\ lghi %r14,_dl_fini@GOT\n\ lg %r14,0(%r14,%r12)\n\ # Free stack frame\n\ aghi %r15,160\n\ # Jump to the user's entry point (saved in %r8).\n\ br %r8\n\");#ifndef RTLD_START_SPECIAL_INIT#define RTLD_START_SPECIAL_INIT /* nothing */#endif/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable, so undefined references should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */#ifdef USE_TLS# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))#else# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))#endif/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT/* The 64 bit S/390 never uses Elf64_Rel relocations. */#define ELF_MACHINE_NO_REL 1/* We define an initialization functions. This is called very early in _dl_sysdep_start. */#define DL_PLATFORM_INIT dl_platform_init ()static inline void __attribute__ ((unused))dl_platform_init (void){ if (GL(dl_platform) != NULL && *GL(dl_platform) == '\0') /* Avoid an empty string which would disturb us. */ GL(dl_platform) = NULL;}static inline Elf64_Addrelf_machine_fixup_plt (struct link_map *map, lookup_t t, const Elf64_Rela *reloc, Elf64_Addr *reloc_addr, Elf64_Addr value){ return *reloc_addr = value;}/* Return the final value of a plt relocation. */static inline Elf64_Addrelf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, Elf64_Addr value){ return value;}#endif /* !dl_machine_h */#ifdef RESOLVE/* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */static inline voidelf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, const Elf64_Sym *sym, const struct r_found_version *version, Elf64_Addr *const reloc_addr){ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_390_RELATIVE, 0)) {# 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. */# ifndef SHARED weak_extern (GL(dl_rtld_map));# endif if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */# endif *reloc_addr = map->l_addr + reloc->r_addend; } else#endif if (__builtin_expect (r_type == R_390_NONE, 0)) return; else { const Elf64_Sym *const refsym = sym;#if defined USE_TLS && !defined RTLD_BOOTSTRAP struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;#else Elf64_Addr value = RESOLVE (&sym, version, r_type);# ifndef RTLD_BOOTSTRAP if (sym)# endif value += sym->st_value;#endif /* use TLS and !RTLD_BOOTSTRAP */ switch (r_type) { case R_390_GLOB_DAT: case R_390_JMP_SLOT: *reloc_addr = value + reloc->r_addend; break;#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) case R_390_TLS_DTPMOD:# ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module with index 1. XXX If this relocation is necessary move before RESOLVE call. */ *reloc_addr = 1;# else /* Get the information from the link map returned by the resolv function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid;# endif break; case R_390_TLS_DTPOFF:# ifndef RTLD_BOOTSTRAP /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) *reloc_addr = sym->st_value + reloc->r_addend;# endif break; case R_390_TLS_TPOFF: /* The offset is negative, forward from the thread pointer. */# ifdef RTLD_BOOTSTRAP *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;# else /* We know the offset of the 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 + reloc->r_addend - sym_map->l_tls_offset); }#endif break;#endif /* use TLS */#ifndef RTLD_BOOTSTRAP case R_390_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be found. */ break; if (__builtin_expect (sym->st_size > refsym->st_size, 0) || (__builtin_expect (sym->st_size < refsym->st_size, 0) && __builtin_expect (GL(dl_verbose), 0))) { const char *strtab; strtab = (const char *) 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, (void *) value, MIN (sym->st_size, refsym->st_size)); break; case R_390_64: *reloc_addr = value + reloc->r_addend; break; case R_390_32: *(unsigned int *) reloc_addr = value + reloc->r_addend; break; case R_390_16: *(unsigned short *) reloc_addr = value + reloc->r_addend; break; case R_390_8: *(char *) reloc_addr = value + reloc->r_addend; break; case R_390_PC64: *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; break; case R_390_PC32DBL: case R_390_PLT32DBL: *(unsigned int *) reloc_addr = (unsigned int) ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); break; case R_390_PC32: *(unsigned int *) reloc_addr = value + reloc->r_addend - (Elf64_Addr) reloc_addr; break; case R_390_PC16DBL: case R_390_PLT16DBL: *(unsigned short *) reloc_addr = (unsigned short) ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); break; case R_390_PC16: *(unsigned short *) reloc_addr = value + reloc->r_addend - (Elf64_Addr) reloc_addr; break; case R_390_NONE: break;#endif#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) default: /* We add these checks in the version to relocate ld.so only if we are still debugging. */ _dl_reloc_bad_type (map, r_type, 0); break;#endif } }}static inline voidelf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, Elf64_Addr *const reloc_addr){ *reloc_addr = l_addr + reloc->r_addend;}static inline voidelf_machine_lazy_rel (struct link_map *map, Elf64_Addr l_addr, const Elf64_Rela *reloc){ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); /* Check for unexpected PLT reloc type. */ if (__builtin_expect (r_type == R_390_JMP_SLOT, 1)) { if (__builtin_expect (map->l_mach.plt, 0) == 0) *reloc_addr += l_addr; else *reloc_addr = map->l_mach.plt + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4; } else _dl_reloc_bad_type (map, r_type, 1);}#endif /* RESOLVE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -