| // Copyright 2019 The Cobalt Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "starboard/elf_loader/elf_header.h" |
| |
| #include "starboard/common/scoped_ptr.h" |
| #include "starboard/elf_loader/file.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| #if SB_API_VERSION >= 12 && (SB_API_VERSION >= 12 || SB_HAS(MMAP)) && \ |
| SB_CAN(MAP_EXECUTABLE_MEMORY) |
| namespace starboard { |
| namespace elf_loader { |
| |
| namespace { |
| |
| class DummyFile : public File { |
| public: |
| DummyFile(const char* buffer, int size) : buffer_(buffer), size_(size) {} |
| |
| bool Open(const char* name) { return true; } |
| bool ReadFromOffset(int64_t offset, char* buffer, int size) { |
| SB_LOG(INFO) << "ReadFromOffset"; |
| if (offset != 0) { |
| SB_LOG(ERROR) << "ReadFromOffset: Invalid offset " << offset; |
| return false; |
| } |
| if (size < size_) { |
| SB_LOG(ERROR) << "ReadFromOffset: Invalid size " << size; |
| return false; |
| } |
| SbMemoryCopy(buffer, buffer_, size); |
| return true; |
| } |
| void Close() {} |
| |
| private: |
| const char* buffer_; |
| int size_; |
| }; |
| |
| class ElfHeaderTest : public ::testing::Test { |
| protected: |
| ElfHeaderTest() { |
| elf_header_.reset(new ElfHeader()); |
| SbMemorySet(reinterpret_cast<char*>(&ehdr_data_), 0, sizeof(ehdr_data_)); |
| ehdr_data_.e_machine = ELF_MACHINE; |
| ehdr_data_.e_ident[0] = 0x7F; |
| ehdr_data_.e_ident[1] = 'E'; |
| ehdr_data_.e_ident[2] = 'L'; |
| ehdr_data_.e_ident[3] = 'F'; |
| ehdr_data_.e_ident[EI_CLASS] = ELF_CLASS_VALUE; |
| ehdr_data_.e_ident[EI_DATA] = ELFDATA2LSB; |
| ehdr_data_.e_type = ET_DYN; |
| ehdr_data_.e_version = EV_CURRENT; |
| ehdr_data_.e_machine = ELF_MACHINE; |
| |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| } |
| ~ElfHeaderTest() {} |
| |
| scoped_ptr<ElfHeader> elf_header_; |
| Ehdr ehdr_data_; |
| scoped_ptr<DummyFile> dummy_file_; |
| }; |
| |
| TEST_F(ElfHeaderTest, Initialize) { |
| EXPECT_TRUE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeBadImage) { |
| ehdr_data_.e_ident[1] = 'F'; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeBadClass) { |
| ehdr_data_.e_ident[EI_CLASS] = 0; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeWrongGulliverLilliput) { |
| ehdr_data_.e_type = 2; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeBadType) { |
| ehdr_data_.e_type = 2; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeBadVersion) { |
| ehdr_data_.e_version = 2; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| |
| TEST_F(ElfHeaderTest, NegativeBadMachine) { |
| ehdr_data_.e_machine = 0; |
| dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_), |
| sizeof(ehdr_data_))); |
| EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get())); |
| } |
| } // namespace |
| } // namespace elf_loader |
| } // namespace starboard |
| #endif // SB_API_VERSION >= 12 && (SB_API_VERSION >= 12 |
| // || SB_HAS(MMAP)) && SB_CAN(MAP_EXECUTABLE_MEMORY) |