-
- void map() {
- if (library[library_index].is_mapped == 0) {
- library[library_index]._elf_header = (Elf64_Ehdr *) library[library_index].array;
- library[library_index]._elf_program_header = (Elf64_Phdr *)((unsigned long)library[library_index]._elf_header + library[library_index]._elf_header->e_phoff);
-
- /*
- the very first thing we do is obtain the base address
-
- Base Address
- The virtual addresses in the program headers might not represent the actual virtual addresses
- of the program's memory image. Executable files typically contain absolute code. To let the
- process execute correctly, the segments must reside at the virtual addresses used to build the
- executable file. On the other hand, shared object segments typically contain
- position-independent code. This lets a segment's virtual address change from one process to
- another, without invalidating execution behavior. Though the system chooses virtual addresses
- for individual processes, it maintains the segments’ relative positions. Because
- position-independent code uses relative addressing between segments, the difference between
- virtual addresses in memory must match the difference between virtual addresses in the file.
-
- The difference between the virtual address of any segment in memory and the corresponding
- virtual address in the file is thus a single constant value for any one executable or shared object
- in a given process. This difference is the base address. One use of the base address is to relocate
- the memory image of the program during dynamic linking.
-
- An executable or shared object file's base address is calculated during execution from three
- values: the virtual memory load address, the maximum page size, and the lowest virtual address
- of a program's loadable segment. To compute the base address, one determines the memory
- address associated with the lowest p_vaddr value for a PT_LOAD segment. This address is
- truncated to the nearest multiple of the maximum page size. The corresponding p_vaddr value
- itself is also truncated to the nearest multiple of the maximum page size. The base address is
- the difference between the truncated memory address and the truncated p_vaddr value.
- */
-
- // aquire the first and last PT_LOAD'S
- int PT_LOADS=0;
- for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
- switch(library[library_index]._elf_program_header[i].p_type)
- {
- case PT_LOAD:
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "i = %d\n", i);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "PT_LOADS = %d\n", PT_LOADS);
- if (!PT_LOADS) {
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "saving first load\n");
- library[library_index].First_Load_Header_index = i;
- }
- if (PT_LOADS) {
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "saving last load\n");
- library[library_index].Last_Load_Header_index = i;
- }
- PT_LOADS=PT_LOADS+1;
- break;
- }
- }
- size_t span = library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr + library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_memsz - library[library_index]._elf_program_header[library[library_index].First_Load_Header_index].p_vaddr;
-
-
- read_fast_verifyb(library[library_index].array, library[library_index].len, &library[library_index].mapping_start, span, library[library_index]._elf_program_header[library[library_index].First_Load_Header_index], library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index]);
-
- fprintf(stderr, "library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr = %014p\n", library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr);
-
- // aquire the lowest PT_LOAD'S
- Elf64_Addr lowest_p_vaddr = 0;
- int lowest_idx = -1;
- for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
- switch(library[library_index]._elf_program_header[i].p_type)
- {
- case PT_LOAD:
- if (!lowest_p_vaddr) {
- lowest_p_vaddr = library[library_index]._elf_program_header[i].p_vaddr;
- lowest_idx = i;
- }
- if (lowest_p_vaddr < library[library_index]._elf_program_header[i].p_memsz) {
- lowest_p_vaddr = library[library_index]._elf_program_header[i].p_vaddr;
- lowest_idx = i;
- }
- break;
- }
- }
- size_t pagesize = 0x1000;
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "library[library_index]._elf_program_header[lowest_idx].p_paddr = %014p\nlibrary[library_index]._elf_program_header[lowest_idx].p_vaddr = %014p\n",library[library_index]._elf_program_header[lowest_idx].p_paddr, library[library_index]._elf_program_header[lowest_idx].p_vaddr);
- Elf64_Addr truncated_physical_address = round_down(library[library_index]._elf_program_header[lowest_idx].p_paddr, pagesize);
- Elf64_Addr truncated_virtual_address = round_down(library[library_index]._elf_program_header[lowest_idx].p_vaddr, pagesize);
- library[library_index].base_address = truncated_physical_address - truncated_virtual_address;
-
- library[library_index].align = round_nearest(library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr, pagesize);
- library[library_index].mapping_end = library[library_index].mapping_start+span;
-
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "base address range = %014p - %014p\nmapping = %014p\nbase address = %014p\n", library[library_index].mapping_start, library[library_index].mapping_end, library[library_index].mapping_start, library[library_index].base_address);
-
- // abort_();
- // base address aquired, map all PT_LOAD segments adjusting by base address then continue with the rest
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\n\n\nfind %014p, %014p, (int) 1239\n\n\n\n", library[library_index].mapping_start, library[library_index].mapping_end);
-
- if (library[library_index].mapping_start == 0x00000000) abort_();
- int PT_LOADS_CURRENT = 0;
- for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
- switch(library[library_index]._elf_program_header[i].p_type)
- {
- case PT_LOAD:
- PT_LOADS_CURRENT = PT_LOADS_CURRENT + 1;
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mapping PT_LOAD number %d\n", PT_LOADS_CURRENT);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_flags: %014p\n", library[library_index]._elf_program_header[i].p_flags);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_offset: %014p\n", library[library_index]._elf_program_header[i].p_offset);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_vaddr: %014p\n", library[library_index]._elf_program_header[i].p_vaddr+library[library_index].mapping_start);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_paddr: %014p\n", library[library_index]._elf_program_header[i].p_paddr);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_filesz: %014p\n", library[library_index]._elf_program_header[i].p_filesz);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_memsz: %014p\n", library[library_index]._elf_program_header[i].p_memsz);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_align: %014p\n\n", library[library_index]._elf_program_header[i].p_align);
- //
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\tp_flags: %014p", library[library_index]._elf_program_header[i].p_flags);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_offset: %014p", library[library_index]._elf_program_header[i].p_offset);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_vaddr: %014p", library[library_index]._elf_program_header[i].p_vaddr+library[library_index].mapping_start);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_paddr: %014p", library[library_index]._elf_program_header[i].p_paddr);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_filesz: %014p", library[library_index]._elf_program_header[i].p_filesz);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_memsz: %014p", library[library_index]._elf_program_header[i].p_memsz);
- // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_align: %014p\n\n\n", library[library_index]._elf_program_header[i].p_align);
-
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect(%014p+round_down(%014p, %014p), %014p, ", library[library_index].mapping_start, library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align, library[library_index]._elf_program_header[i].p_memsz);
- prot_from_phdr(library[library_index]._elf_program_header[i].p_flags);
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, ");\n");
- errno = 0;
- int check_mprotect_success = mprotect(library[library_index].mapping_start+round_down(library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align), round_up(library[library_index]._elf_program_header[i].p_memsz, library[library_index]._elf_program_header[i].p_align), library[library_index]._elf_program_header[i].p_flags);
- if (errno == 0)
- {
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect on %014p succeded with size: %014p\n", library[library_index].mapping_start+round_down(library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align), round_up(library[library_index]._elf_program_header[i].p_memsz, library[library_index]._elf_program_header[i].p_align));
- print_maps();
- }
- else
- {
- if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect failed with: %s (errno: %d, check_mprotect_success = %d)\n", strerror(errno), errno, check_mprotect_success);
- print_maps();
- abort_();
- }
- break;
- }
- }
- library[library_index].is_mapped = 1;
- }
- }
-