1+ // -*-C++-*-
12// This file is a part of the IncludeOS unikernel - www.includeos.org
23//
34// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
2021template <typename Arch>
2122const typename Arch::Ehdr& Elf_binary<Arch>::elf_header() const {
2223 Expects (data_.size () >= (long ) sizeof (typename Arch::Ehdr));
23- return *reinterpret_cast <typename Arch::Ehdr *>(data_.data ());
24+ return *reinterpret_cast <Elf_header *>(data_.data ());
2425}
2526
2627template <typename Arch>
27- const typename Arch::Phdr& Elf_binary<Arch>::program_header() const {
28+ typename Arch::Phdr& Elf_binary<Arch>::program_header() const {
2829 auto hdr = elf_header ();
2930 Expects (data_.size () >= (long )(hdr.e_phoff + sizeof (typename Arch::Phdr)));
30- return *reinterpret_cast <typename Arch::Phdr*>(data_.data () + hdr.e_phoff );
31+ return *reinterpret_cast <Program_header*>(data_.data () + hdr.e_phoff );
32+ }
33+
34+
35+ template <typename Arch>
36+ const typename Elf_binary<Arch>::Program_headers Elf_binary<Arch>::program_headers() const {
37+ return {reinterpret_cast <Program_header*>(&program_header ()), elf_header ().e_phnum };
3138}
3239
3340
3441template <typename Arch>
3542void Elf_binary<Arch>::print_summary() {
3643
37- auto hdr = elf_header ();
44+ auto hdr = elf_header ();
3845
3946 for (int i {0 }; i < EI_NIDENT; ++i) {
4047 std::cout << hdr.e_ident [i];
4148 }
42-
49+
4350 std::cout << " \n Type: "
4451 << ((hdr.e_type == ET_EXEC) ? " ELF Executable\n " : " Non-executable\n " );
4552 std::cout << " Machine: " ;
@@ -52,34 +59,34 @@ void Elf_binary<Arch>::print_summary() {
5259 break ;
5360 default :
5461 std::cout << " Other (" << hdr.e_machine << " )\n " ;
55- break ;
62+ break ;
5663 }
57-
64+
5865 std::cout << " Version: " << hdr.e_version << ' \n ' ;
5966 std::cout << " Entry point: 0x" << std::hex << hdr.e_entry << ' \n ' ;
6067 std::cout << " Number of program headers: " << std::dec << hdr.e_phnum << ' \n ' ;
6168 std::cout << " Program header offset: " << hdr.e_phoff << ' \n ' ;
6269 std::cout << " Number of section headers: " << hdr.e_shnum << ' \n ' ;
6370 std::cout << " Section header offset: " << hdr.e_shoff << ' \n ' ;
64- std::cout << " Size of ELF-header: " << hdr.e_ehsize << " bytes\n " ;
71+ std::cout << " Size of ELF-header: " << hdr.e_ehsize << " bytes\n " ;
6572}
6673
6774
6875template <typename Arch>
6976bool Elf_binary<Arch>::is_executable(){
70- return elf_header ().e_type == ET_EXEC;
77+ return elf_header ().e_type == ET_EXEC;
7178}
7279
7380template <typename Arch>
7481bool Elf_binary<Arch>::is_bootable(){
7582
7683 bool has_multiboot = false ;
77-
84+
7885 try {
7986 section_header (" .multiboot" );
8087 has_multiboot = true ;
8188 }catch (...) {}
82-
89+
8390 return is_executable () and has_multiboot;
8491}
8592
@@ -90,24 +97,36 @@ bool Elf_binary<Arch>::is_ELF(){
9097 data_[EI_MAG0] == ELFMAG0 and
9198 data_[EI_MAG1] == ELFMAG1 and
9299 data_[EI_MAG2] == ELFMAG2 and
93- data_[EI_MAG3] == ELFMAG3;
94-
100+ data_[EI_MAG3] == ELFMAG3;
101+
95102}
96103
97104
98105template <typename Arch>
99106void Elf_binary<Arch>::validate(){
100-
107+
101108 if (not is_ELF () or not is_bootable () or not is_executable ())
102- throw Elf_exception (" Not a bootable ELF binary." );
103-
109+ throw Elf_exception (" Not a bootable and executable ELF binary." );
110+
104111}
105112
106113template <typename Arch>
107114typename Arch::Addr Elf_binary<Arch>::entry() {
108115 return elf_header ().e_entry ;
109116}
110117
118+
119+ template <typename Arch>
120+ std::vector<const typename Arch::Phdr*> Elf_binary<Arch>::loadable_segments() {
121+ std::vector<const Program_header*> hdrs;
122+ for (auto & phdr : program_headers ()) {
123+ if (phdr.p_type == PT_LOAD)
124+ hdrs.push_back (&phdr);
125+ }
126+ return hdrs;
127+ };
128+
129+
111130template <typename Arch>
112131const typename Elf_binary<Arch>::Section_headers Elf_binary<Arch>::section_headers() const {
113132 return {reinterpret_cast <Section_header*>(data_.data () + elf_header ().e_shoff ),
0 commit comments