📄 dl-machine.h
字号:
sll %r1,2\n\ ar %r15,%r1\n\ # Set the back chain to zero again\n\ xc 0(4,%r15),0(%r15)\n\ # Store back the modified argument count.\n\ st %r0,96(%r15)\n\ # The special initializer gets called with the stack just\n\ # as the application's entry point will see it; it can\n\ # switch stacks if it moves these contents over.\n\" RTLD_START_SPECIAL_INIT "\n\ # Call the function to run the initializers.\n\ # Load the parameters:\n\ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\ l %r2,_rtld_local@GOT(%r12)\n\ l %r2,0(%r2)\n\ l %r3,96(%r15)\n\ la %r4,100(%r15)\n\ lr %r5,%r3\n\ sll %r5,2\n\ la %r5,104(%r5,%r15)\n\ l %r1,.Ladr4-.Llit(%r13)\n\ bas %r14,0(%r1,%r13)\n\ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\ l %r14,_dl_fini@GOT(%r12)\n\ # Free stack frame\n\ ahi %r15,96\n\ # Jump to the user's entry point (saved in %r8).\n\ br %r8\n\.Llit:\n\.Ladr0: .long _GLOBAL_OFFSET_TABLE_-.Llit\n\.Ladr1: .long _dl_start-.Llit\n\.Ladr4: .long _dl_init_internal@PLT-.Llit\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 S390 never uses Elf32_Rel relocations. */#define ELF_MACHINE_NO_REL 1/* The S390 overlaps DT_RELA and DT_PLTREL. */#define ELF_MACHINE_PLTREL_OVERLAP 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 Elf32_Addrelf_machine_fixup_plt (struct link_map *map, lookup_t t, const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, Elf32_Addr value){ return *reloc_addr = value;}/* 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;}#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 Elf32_Rela *reloc, const Elf32_Sym *sym, const struct r_found_version *version, Elf32_Addr *const reloc_addr){ const unsigned int r_type = ELF32_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 Elf32_Sym *const refsym = sym;#if defined USE_TLS && !defined RTLD_BOOTSTRAP struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;#else Elf32_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_32: *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_PC32: *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; break; case R_390_PC16DBL: case R_390_PLT16DBL: *(unsigned short *) reloc_addr = (unsigned short) ((short) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1); break; case R_390_PC16: *(unsigned short *) reloc_addr = value + reloc->r_addend - (Elf32_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 (Elf32_Addr l_addr, const Elf32_Rela *reloc, Elf32_Addr *const reloc_addr){ *reloc_addr = l_addr + reloc->r_addend;}static inline voidelf_machine_lazy_rel (struct link_map *map, Elf32_Addr l_addr, const Elf32_Rela *reloc){ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); const unsigned int r_type = ELF32_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 + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8; } else _dl_reloc_bad_type (map, r_type, 1);}#endif /* RESOLVE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -