📄 boot1.c
字号:
_dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpnt); _dl_exit(16);#ifdef DL_TRACE }#endif } else {#ifdef DL_TRACE if (_dl_trace_loaded_objects && !tpnt1->usage_count) _dl_dprintf(1, "\t%s => %s (0x%x)\n", lpnt, tpnt1->libname, (unsigned) tpnt1->loadaddr);#endif rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next))); rpnt = rpnt->next; tpnt1->usage_count++; tpnt1->symbol_scope = _dl_symbol_tables; tpnt1->libtype = elf_lib; rpnt->dyn = tpnt1; } } } } }#ifdef USE_CACHE _dl_unmap_cache();#endif /* ldd uses uses this. I am not sure how you pick up the other flags */#ifdef DL_TRACE if (_dl_trace_loaded_objects) { char *_dl_warn = 0; _dl_warn = _dl_getenv("LD_WARN", envp); if (!_dl_warn) _dl_exit(0); }#endif /* * If the program interpreter is not in the module chain, add it. This will * be required for dlopen to be able to access the internal functions in the * dynamic linker. */ if (tpnt) { struct elf_resolve *tcurr; tcurr = _dl_loaded_modules; if (tcurr) while (tcurr->next) tcurr = tcurr->next; tpnt->next = NULL; tpnt->usage_count++; if (tcurr) { tcurr->next = tpnt; tpnt->prev = tcurr; } else { _dl_loaded_modules = tpnt; tpnt->prev = NULL; } if (rpnt) { rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next))); rpnt = rpnt->next; } else { rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); _dl_memset(rpnt, 0, sizeof(*(rpnt->next))); } rpnt->dyn = tpnt; tpnt = NULL; } /* * OK, now all of the kids are tucked into bed in their proper addresses. * Now we go through and look for REL and RELA records that indicate fixups * to the GOT tables. We need to do this in reverse order so that COPY * directives work correctly */ goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0; /* Some flavors of SVr4 do not generate the R_*_COPY directive, and we have to manually search for entries that require fixups. Solaris gets this one right, from what I understand. */ if (_dl_symbol_tables) goof += _dl_copy_fixups(_dl_symbol_tables);#ifdef DL_TRACE if (goof || _dl_trace_loaded_objects) _dl_exit(0);#endif /* OK, at this point things are pretty much ready to run. Now we need to touch up a few items that are required, and then we can let the user application have at it. Note that the dynamic linker itself is not guaranteed to be fully dynamicly linked if we are using ld.so.1, so we have to look up each symbol individually. */ _dl_brkp = (unsigned long *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0); if (_dl_brkp) *_dl_brkp = brk_addr; _dl_envp = (unsigned long *) _dl_find_hash("__environ", NULL, 1, NULL, 0); if (_dl_envp) *_dl_envp = (unsigned long) envp; { int i; elf_phdr *ppnt; /* We had to set the protections of all pages to R/W for dynamic linking. Set text pages back to R/O */ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) for (ppnt = tpnt->ppnt, i = 0; i < tpnt->n_phent; i++, ppnt++) if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) _dl_mprotect((void *) (tpnt->loadaddr + (ppnt->p_vaddr & 0xfffff000)), (ppnt->p_vaddr & 0xfff) + (unsigned long) ppnt->p_filesz, LXFLAGS(ppnt->p_flags)); } _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0); /* * OK, fix one more thing - set up the debug_addr structure to point * to our chain. Later we may need to fill in more fields, but this * should be enough for now. */ debug_addr->r_map = (struct link_map *) _dl_loaded_modules; debug_addr->r_version = 1; debug_addr->r_ldbase = load_addr; debug_addr->r_brk = (unsigned long) &_dl_debug_state; _dl_debug_addr = debug_addr; debug_addr->r_state = RT_CONSISTENT; /* This is written in this funny way to keep gcc from inlining the function call. */ ((void (*)(void)) debug_addr->r_brk) (); for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { /* Apparently crt1 for the application is responsible for handling this. * We only need to run the init/fini for shared libraries */ if (tpnt->libtype == program_interpreter || tpnt->libtype == elf_executable) continue; if (tpnt->init_flag & INIT_FUNCS_CALLED) continue; tpnt->init_flag |= INIT_FUNCS_CALLED; if (tpnt->dynamic_info[DT_INIT]) { _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]); (*_dl_elf_init) (); } if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) { (*_dl_atexit) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); }#undef DL_DEBUG#ifdef DL_DEBUG else { _dl_dprintf(2, tpnt->libname); _dl_dprintf(2, ": "); if (!_dl_atexit) _dl_dprintf(2, "The address is atexit () is 0x0."); if (!tpnt->dynamic_info[DT_FINI]) _dl_dprintf(2, "Invalid .fini section."); _dl_dprintf(2, "\n"); }#endif#undef DL_DEBUG } /* OK we are done here. Turn out the lights, and lock up. */ _dl_elf_main = (int (*)(int, char **, char **)) auxv_t[AT_ENTRY].a_un.a_fcn; /* * Transfer control to the application. */ status = 0; /* Used on x86, but not on other arches */ START();}/* * This stub function is used by some debuggers. The idea is that they * can set an internal breakpoint on it, so that we are notified when the * address mapping is changed in some way. */void _dl_debug_state(){ return;}int _dl_fixup(struct elf_resolve *tpnt){ int goof = 0; if (tpnt->next) goof += _dl_fixup(tpnt->next); if (tpnt->dynamic_info[DT_REL]) {#ifdef ELF_USES_RELOCA _dl_dprintf(2, "%s: can't handle REL relocation records\n", _dl_progname); _dl_exit(17);#else if (tpnt->init_flag & RELOCS_DONE) return goof; tpnt->init_flag |= RELOCS_DONE; goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_REL], tpnt->dynamic_info[DT_RELSZ], 0);#endif } if (tpnt->dynamic_info[DT_RELA]) {#ifdef ELF_USES_RELOCA if (tpnt->init_flag & RELOCS_DONE) return goof; tpnt->init_flag |= RELOCS_DONE; goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);#else _dl_dprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname); _dl_exit(18);#endif } if (tpnt->dynamic_info[DT_JMPREL]) { if (tpnt->init_flag & JMP_RELOCS_DONE) return goof; tpnt->init_flag |= JMP_RELOCS_DONE; if (!_dl_not_lazy || *_dl_not_lazy == 0) _dl_parse_lazy_relocation_information(tpnt, tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0); else goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0); } return goof;}void *_dl_malloc(int size){ void *retval;#ifdef DL_DEBUG SEND_STDERR("malloc: request for "); SEND_NUMBER_STDERR(size, 0); SEND_STDERR(" bytes\n");#endif if (_dl_malloc_function) return (*_dl_malloc_function) (size); if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {#ifdef DL_DEBUG SEND_STDERR("malloc: mmapping more memory\n");#endif _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (_dl_mmap_check_error(_dl_mmap_zero)) { _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname); _dl_exit(20); } } retval = _dl_malloc_addr; _dl_malloc_addr += size; /* * Align memory to 4 byte boundary. Some platforms require this, others * simply get better performance. */ _dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3)); return retval;}char *_dl_getenv(char *symbol, char **envp){ char *pnt; char *pnt1; while ((pnt = *envp++)) { pnt1 = symbol; while (*pnt && *pnt == *pnt1) pnt1++, pnt++; if (!*pnt || *pnt != '=' || *pnt1) continue; return pnt + 1; } return 0;}void _dl_unsetenv(char *symbol, char **envp){ char *pnt; char *pnt1; char **newenvp = envp; for (pnt = *envp; pnt; pnt = *++envp) { pnt1 = symbol; while (*pnt && *pnt == *pnt1) pnt1++, pnt++; if (!*pnt || *pnt != '=' || *pnt1) *newenvp++ = *envp; } *newenvp++ = *envp; return;}char *_dl_strdup(const char *string){ char *retval; int len; len = _dl_strlen(string); retval = _dl_malloc(len + 1); _dl_strcpy(retval, string); return retval;}/* Minimum printf which handles only characters, %d's and %s's */void _dl_dprintf(int fd, const char *fmt, ...){ int num; va_list args; char *start, *ptr, *string; char buf[2048]; start = ptr = buf; if (!fmt) return; if (_dl_strlen(fmt) >= (sizeof(buf)-1)) _dl_write(fd, "(overflow)\n", 10); _dl_strcpy(buf, fmt); va_start(args, fmt); while(start) { while(*ptr != '%' && *ptr) { ptr++; } if(*ptr == '%') { *ptr++ = '\0'; _dl_write(fd, start, _dl_strlen(start)); switch(*ptr++) { case 's': string = va_arg(args, char *); if (!string) _dl_write(fd, "(null)", 6); else _dl_write(fd, string, _dl_strlen(string)); break; case 'i': case 'd': { char tmp[13]; num = va_arg(args, int); string = _dl_simple_ltoa(tmp, num); _dl_write(fd, string, _dl_strlen(string)); break; } case 'x': case 'X': { char tmp[13]; num = va_arg(args, int); string = _dl_simple_ltoahex(tmp, num); _dl_write(fd, string, _dl_strlen(string)); break; } default: _dl_write(fd, "(null)", 6); break; } start = ptr; } else { _dl_write(fd, start, _dl_strlen(start)); start = NULL; } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -