📄 dl-machine.h
字号:
/* Undo the sub %sp, 6*8, %sp; add %sp, STACK_BIAS + 22*8, %o0 below to get at the value we want in __libc_stack_end. */#define DL_STACK_END(cookie) \ ((void *) (((long) (cookie)) - (22 - 6) * 8 - STACK_BIAS))/* Initial entry point code for the dynamic linker. The C function `_dl_start' is the real entry point; its return value is the user program's entry point. */#define __S1(x) #x#define __S(x) __S1(x)#define RTLD_START __asm__ ( "\n" \" .text\n" \" .global _start\n" \" .type _start, @function\n" \" .align 32\n" \"_start:\n" \" /* Make room for functions to drop their arguments on the stack. */\n" \" sub %sp, 6*8, %sp\n" \" /* Pass pointer to argument block to _dl_start. */\n" \" call _dl_start\n" \" add %sp," __S(STACK_BIAS) "+22*8,%o0\n" \" /* FALLTHRU */\n" \" .size _start, .-_start\n" \"\n" \" .global _dl_start_user\n" \" .type _dl_start_user, @function\n" \"_dl_start_user:\n" \" /* Load the GOT register. */\n" \"1: call 11f\n" \" sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \"11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \" sethi %hi(_dl_skip_args), %g5\n" \" add %l7, %o7, %l7\n" \" or %g5, %lo(_dl_skip_args), %g5\n" \" /* Save the user entry point address in %l0. */\n" \" mov %o0, %l0\n" \" /* See if we were run as a command with the executable file name as an\n" \" extra leading argument. If so, we must shift things around since we\n" \" must keep the stack doubleword aligned. */\n" \" ldx [%l7 + %g5], %i0\n" \" ld [%i0], %i0\n" \" brz,pt %i0, 2f\n" \" ldx [%sp + " __S(STACK_BIAS) " + 22*8], %i5\n" \" /* Find out how far to shift. */\n" \" sethi %hi(_dl_argv), %l4\n" \" sub %i5, %i0, %i5\n" \" or %l4, %lo(_dl_argv), %l4\n" \" sllx %i0, 3, %l6\n" \" ldx [%l7 + %l4], %l4\n" \" stx %i5, [%sp + " __S(STACK_BIAS) " + 22*8]\n" \" add %sp, " __S(STACK_BIAS) " + 23*8, %i1\n" \" add %i1, %l6, %i2\n" \" ldx [%l4], %l5\n" \" /* Copy down argv. */\n" \"12: ldx [%i2], %i3\n" \" add %i2, 8, %i2\n" \" stx %i3, [%i1]\n" \" brnz,pt %i3, 12b\n" \" add %i1, 8, %i1\n" \" sub %l5, %l6, %l5\n" \" /* Copy down envp. */\n" \"13: ldx [%i2], %i3\n" \" add %i2, 8, %i2\n" \" stx %i3, [%i1]\n" \" brnz,pt %i3, 13b\n" \" add %i1, 8, %i1\n" \" /* Copy down auxiliary table. */\n" \"14: ldx [%i2], %i3\n" \" ldx [%i2 + 8], %i4\n" \" add %i2, 16, %i2\n" \" stx %i3, [%i1]\n" \" stx %i4, [%i1 + 8]\n" \" brnz,pt %i3, 14b\n" \" add %i1, 16, %i1\n" \" stx %l5, [%l4]\n" \" /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n" \"2: sethi %hi(_rtld_local), %o0\n" \" add %sp, " __S(STACK_BIAS) " + 23*8, %o2\n" \" orcc %o0, %lo(_rtld_local), %o0\n" \" sllx %i5, 3, %o3\n" \" ldx [%l7 + %o0], %o0\n" \" add %o3, 8, %o3\n" \" mov %i5, %o1\n" \" add %o2, %o3, %o3\n" \" call _dl_init_internal\n" \" ldx [%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" \" ldx [%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*8, %sp\n" \" .size _dl_start_user, . - _dl_start_user\n" \" .previous\n");#endif /* dl_machine_h */#define ARCH_LA_PLTENTER sparc64_gnu_pltenter#define ARCH_LA_PLTEXIT sparc64_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 Elf64_Rela *reloc, const Elf64_Sym *sym, const struct r_found_version *version, void *const reloc_addr_arg){ Elf64_Addr *const reloc_addr = reloc_addr_arg;#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP const Elf64_Sym *const refsym = sym;#endif Elf64_Addr value; const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);#if !defined RESOLVE_CONFLICT_FIND_MAP struct link_map *sym_map = NULL;#endif#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 (ELF64_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_64: case R_SPARC_GLOB_DAT: *reloc_addr = value; break; case R_SPARC_JMP_SLOT:#ifdef RESOLVE_CONFLICT_FIND_MAP /* R_SPARC_JMP_SLOT conflicts against .plt[32768+] relocs should be turned into R_SPARC_64 relocs in .gnu.conflict section. r_addend non-zero does not mean it is a .plt[32768+] reloc, instead it is the actual address of the function to call. */ sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0);#else sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0);#endif break;#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD64: /* 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_DTPOFF64: /* 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_TPOFF64: /* 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) & 0x3fffff); 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_32: *(unsigned int *) reloc_addr = value; break; case R_SPARC_DISP8: *(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr); break; case R_SPARC_DISP16: *(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr); break; case R_SPARC_DISP32: *(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr); break; case R_SPARC_WDISP30: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & 0xc0000000) | (((value - (Elf64_Addr) reloc_addr) >> 2) & 0x3fffffff)); break; /* MEDLOW code model relocs */ case R_SPARC_LO10: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & ~0x3ff) | (value & 0x3ff)); break; case R_SPARC_HI22: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & 0xffc00000) | ((value >> 10) & 0x3fffff)); break; case R_SPARC_OLO10: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & ~0x1fff) | (((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff)); break; /* MEDMID code model relocs */ case R_SPARC_H44: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & 0xffc00000) | ((value >> 22) & 0x3fffff)); break; case R_SPARC_M44: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & ~0x3ff) | ((value >> 12) & 0x3ff)); break; case R_SPARC_L44: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & ~0xfff) | (value & 0xfff)); break; /* MEDANY code model relocs */ case R_SPARC_HH22: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & 0xffc00000) | (value >> 42)); break; case R_SPARC_HM10: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & ~0x3ff) | ((value >> 32) & 0x3ff)); break; case R_SPARC_LM22: *(unsigned int *) reloc_addr = ((*(unsigned int *)reloc_addr & 0xffc00000) | ((value >> 10) & 0x003fffff)); 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; case R_SPARC_UA64: if (! ((long) reloc_addr_arg & 3)) { /* Common in .eh_frame */ ((unsigned int *) reloc_addr_arg) [0] = value >> 32; ((unsigned int *) reloc_addr_arg) [1] = value; break; } ((unsigned char *) reloc_addr_arg) [0] = value >> 56; ((unsigned char *) reloc_addr_arg) [1] = value >> 48; ((unsigned char *) reloc_addr_arg) [2] = value >> 40; ((unsigned char *) reloc_addr_arg) [3] = value >> 32; ((unsigned char *) reloc_addr_arg) [4] = value >> 24; ((unsigned char *) reloc_addr_arg) [5] = value >> 16; ((unsigned char *) reloc_addr_arg) [6] = value >> 8; ((unsigned char *) reloc_addr_arg) [7] = 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 (Elf64_Addr l_addr, const Elf64_Rela *reloc, void *const reloc_addr_arg){ Elf64_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, Elf64_Addr l_addr, const Elf64_Rela *reloc){ switch (ELF64_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 + -