/* * Copyright 2014-present Facebook, Inc. * * 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. */ package com.facebook.buck.cxx.elf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import com.facebook.buck.model.Pair; import com.facebook.buck.testutil.integration.ProjectWorkspace; import com.facebook.buck.testutil.integration.TemporaryPaths; import com.facebook.buck.testutil.integration.TestDataHelper; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; public class ElfTest { @Rule public TemporaryPaths tmp = new TemporaryPaths(); @Test public void le64() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "samples", tmp); workspace.setUp(); Path elfPath = workspace.resolve(Paths.get("le64.o")); try (FileChannel channel = FileChannel.open(elfPath)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); Elf elf = new Elf(buffer); assertEquals(ElfHeader.EIClass.ELFCLASS64, elf.header.ei_class); assertEquals(ElfHeader.EIData.ELFDATA2LSB, elf.header.ei_data); assertEquals(11, elf.getNumberOfSections()); assertTrue(elf.getSectionByName(".text").isPresent()); } } @Test public void le32() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "samples", tmp); workspace.setUp(); Path elfPath = workspace.resolve(Paths.get("le32.o")); try (FileChannel channel = FileChannel.open(elfPath)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); Elf elf = new Elf(buffer); assertEquals(ElfHeader.EIClass.ELFCLASS32, elf.header.ei_class); assertEquals(ElfHeader.EIData.ELFDATA2LSB, elf.header.ei_data); assertEquals(9, elf.getNumberOfSections()); assertTrue(elf.getSectionByName(".text").isPresent()); } } @Test public void be32() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "samples", tmp); workspace.setUp(); Path elfPath = workspace.resolve(Paths.get("be32.o")); try (FileChannel channel = FileChannel.open(elfPath)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); Elf elf = new Elf(buffer); assertEquals(ElfHeader.EIClass.ELFCLASS32, elf.header.ei_class); assertEquals(ElfHeader.EIData.ELFDATA2MSB, elf.header.ei_data); assertEquals(14, elf.getNumberOfSections()); assertTrue(elf.getSectionByName(".text").isPresent()); } } @Test public void sectionTypes() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "samples", tmp); workspace.setUp(); Path elfPath = workspace.resolve(Paths.get("section_types.o")); try (FileChannel channel = FileChannel.open(elfPath)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); Elf elf = new Elf(buffer); Optional<ElfSection> section; section = elf.getSectionByName(".text").map(Pair::getSecond); assertTrue(section.isPresent()); assertEquals(ElfSectionHeader.SHType.SHT_PROGBITS, section.get().header.sh_type); section = elf.getSectionByName(".bss").map(Pair::getSecond); assertTrue(section.isPresent()); assertEquals(ElfSectionHeader.SHType.SHT_NOBITS, section.get().header.sh_type); section = elf.getSectionByName(".strtab").map(Pair::getSecond); assertTrue(section.isPresent()); assertEquals(ElfSectionHeader.SHType.SHT_STRTAB, section.get().header.sh_type); section = elf.getSectionByName(".symtab").map(Pair::getSecond); assertTrue(section.isPresent()); assertEquals(ElfSectionHeader.SHType.SHT_SYMTAB, section.get().header.sh_type); } } @Test public void lotsOfSectionHeaders() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "samples", tmp); workspace.setUp(); Path elfPath = workspace.resolve(Paths.get("has43664sections.o")); try (FileChannel channel = FileChannel.open(elfPath)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); Elf elf = new Elf(buffer); assertThat(elf.getNumberOfSections(), Matchers.equalTo(43664)); } } @Test public void isElfEmptyBuffer() throws IOException { assertFalse(Elf.isElf(ByteBuffer.allocate(0))); } }