866 #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr) |
866 #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr) |
867 #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name) |
867 #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name) |
868 #define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld) |
868 #define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld) |
869 #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next) |
869 #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next) |
870 |
870 |
|
871 #define INVALID_LOAD_ADDRESS -1L |
|
872 #define ZERO_LOAD_ADDRESS 0x0L |
|
873 |
871 // Calculate the load address of shared library |
874 // Calculate the load address of shared library |
872 // on prelink-enabled environment. |
875 // on prelink-enabled environment. |
873 // |
876 // |
874 // In case of GDB, it would be calculated by offset of link_map.l_ld |
877 // In case of GDB, it would be calculated by offset of link_map.l_ld |
875 // and the address of .dynamic section. |
878 // and the address of .dynamic section. |
882 int i; |
885 int i; |
883 |
886 |
884 phbuf = read_program_header_table(lib_fd, elf_ehdr); |
887 phbuf = read_program_header_table(lib_fd, elf_ehdr); |
885 if (phbuf == NULL) { |
888 if (phbuf == NULL) { |
886 print_debug("can't read program header of shared object\n"); |
889 print_debug("can't read program header of shared object\n"); |
887 return 0L; |
890 return INVALID_LOAD_ADDRESS; |
888 } |
891 } |
889 |
892 |
890 // Get the address of .dynamic section from shared library. |
893 // Get the address of .dynamic section from shared library. |
891 for (i = 0; i < elf_ehdr->e_phnum; i++) { |
894 for (i = 0; i < elf_ehdr->e_phnum; i++) { |
892 if (phbuf[i].p_type == PT_DYNAMIC) { |
895 if (phbuf[i].p_type == PT_DYNAMIC) { |
898 free(phbuf); |
901 free(phbuf); |
899 |
902 |
900 if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET, |
903 if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET, |
901 &lib_ld, sizeof(uintptr_t)) != PS_OK) { |
904 &lib_ld, sizeof(uintptr_t)) != PS_OK) { |
902 print_debug("can't read address of dynamic section in shared object\n"); |
905 print_debug("can't read address of dynamic section in shared object\n"); |
903 return 0L; |
906 return INVALID_LOAD_ADDRESS; |
904 } |
907 } |
905 |
908 |
906 // Return the load address which is calculated by the address of .dynamic |
909 // Return the load address which is calculated by the address of .dynamic |
907 // and link_map.l_ld . |
910 // and link_map.l_ld . |
908 load_addr = lib_ld - lib_dyn_addr; |
911 load_addr = lib_ld - lib_dyn_addr; |
1009 if (lib_fd < 0) { |
1012 if (lib_fd < 0) { |
1010 print_debug("can't open shared object %s\n", lib_name); |
1013 print_debug("can't open shared object %s\n", lib_name); |
1011 // continue with other libraries... |
1014 // continue with other libraries... |
1012 } else { |
1015 } else { |
1013 if (read_elf_header(lib_fd, &elf_ehdr)) { |
1016 if (read_elf_header(lib_fd, &elf_ehdr)) { |
1014 if (lib_base_diff == 0x0L) { |
1017 if (lib_base_diff == ZERO_LOAD_ADDRESS) { |
1015 lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr); |
1018 lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr); |
1016 if (lib_base_diff == 0x0L) { |
1019 if (lib_base_diff == INVALID_LOAD_ADDRESS) { |
1017 close(lib_fd); |
1020 close(lib_fd); |
1018 return false; |
1021 return false; |
1019 } |
1022 } |
1020 } |
1023 } |
1021 |
1024 |