30 std::optional<std::vector<std::string>>
31 try_get_dt_needed(std::string_view filename)
33 std::vector<std::string> libraries;
35 m_file.open(std::string(filename), std::ios::binary);
40 unsigned char e_ident[EI_NIDENT];
41 m_file.read(
reinterpret_cast<char*
>(e_ident), EI_NIDENT);
45 if(e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1
46 || e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3)
49 if(e_ident[EI_CLASS] != ELFCLASS64)
54 process_elf64(libraries);
67 std::vector<std::string> get_dt_needed(std::string_view filename)
69 if(
auto res = try_get_dt_needed(filename))
70 return *std::move(res);
72 std::cerr << filename <<
" is not a readable, valid 64-bit ELF file\n";
78 T read_at(std::streampos pos)
82 m_file.read(
reinterpret_cast<char*
>(&value),
sizeof(T));
84 throw std::runtime_error(
"Failed to read from file");
88 std::string read_string_at(std::streampos pos)
93 while(m_file.get(c) && c !=
'\0')
98 void process_elf64(std::vector<std::string>& libraries)
101 Elf64_Ehdr ehdr = read_at<Elf64_Ehdr>(0);
104 auto phdrs = std::unique_ptr<Elf64_Phdr[]>(
new Elf64_Phdr[ehdr.e_phnum]);
105 m_file.seekg(ehdr.e_phoff);
106 m_file.read(
reinterpret_cast<char*
>(phdrs.get()), ehdr.e_phnum *
sizeof(Elf64_Phdr));
108 throw std::runtime_error(
"Failed to read program headers");
110 Elf64_Phdr* dynamic_phdr =
nullptr;
111 for(
int i = 0; i < ehdr.e_phnum; ++i)
113 if(phdrs[i].p_type == PT_DYNAMIC)
115 dynamic_phdr = &phdrs[i];
124 std::vector<Elf64_Dyn> dyns(dynamic_phdr->p_filesz /
sizeof(Elf64_Dyn));
125 m_file.seekg(dynamic_phdr->p_offset);
126 m_file.read(
reinterpret_cast<char*
>(dyns.data()), dynamic_phdr->p_filesz);
128 throw std::runtime_error(
"Failed to read dynamic section");
131 Elf64_Addr strtab_addr = 0;
132 for(
const auto& dyn : dyns)
134 if(dyn.d_tag == DT_STRTAB)
136 strtab_addr = dyn.d_un.d_ptr;
145 Elf64_Off strtab_offset = 0;
146 for(
int i = 0; i < ehdr.e_phnum; ++i)
148 if(phdrs[i].p_type == PT_LOAD && strtab_addr >= phdrs[i].p_vaddr
149 && strtab_addr < phdrs[i].p_vaddr + phdrs[i].p_filesz)
151 strtab_offset = strtab_addr - phdrs[i].p_vaddr + phdrs[i].p_offset;
160 for(
const auto& dyn : dyns)
162 if(dyn.d_tag == DT_NEEDED)
164 libraries.push_back(read_string_at(strtab_offset + dyn.d_un.d_val));
169 std::ifstream m_file;
Base toolkit upon which the software is built.
Definition Application.cpp:117