use of com.facebook.buck.cxx.elf.ElfSection in project buck by facebook.
the class AbstractElfDynamicSectionScrubberStep method execute.
@Override
public StepExecutionResult execute(ExecutionContext context) throws IOException {
try (FileChannel channel = FileChannel.open(getFilesystem().resolve(getPath()), StandardOpenOption.READ, StandardOpenOption.WRITE)) {
MappedByteBuffer buffer = channel.map(READ_WRITE, 0, channel.size());
Elf elf = new Elf(buffer);
Optional<ElfSection> section = elf.getSectionByName(SECTION).map(Pair::getSecond);
if (!section.isPresent()) {
throw new IOException(String.format("Error parsing ELF file %s: no such section \"%s\"", getPath(), SECTION));
}
for (ByteBuffer body = section.get().body; body.hasRemaining(); ) {
ElfDynamicSection.DTag dTag = ElfDynamicSection.DTag.valueOf(elf.header.ei_class == ElfHeader.EIClass.ELFCLASS32 ? Elf.Elf32.getElf32Sword(body) : (int) Elf.Elf64.getElf64Sxword(body));
if (!WHITELISTED_TAGS.contains(dTag)) {
if (elf.header.ei_class == ElfHeader.EIClass.ELFCLASS32) {
// d_ptr
Elf.Elf32.putElf32Addr(body, 0);
} else {
// d_ptr
Elf.Elf64.putElf64Addr(body, 0);
}
} else {
if (elf.header.ei_class == ElfHeader.EIClass.ELFCLASS32) {
// d_ptr
Elf.Elf32.getElf32Addr(body);
} else {
// d_ptr
Elf.Elf64.getElf64Addr(body);
}
}
}
}
return StepExecutionResult.SUCCESS;
}
use of com.facebook.buck.cxx.elf.ElfSection in project buck by facebook.
the class AbstractElfExtractSectionsStep method getNewSectionAddresses.
// We want to compact the sections into the new ELF file, so find out the new addresses of each
// section.
private ImmutableMap<String, Long> getNewSectionAddresses() throws IOException {
ImmutableMap.Builder<String, Long> addresses = ImmutableMap.builder();
try (FileChannel channel = FileChannel.open(getFilesystem().resolve(getInput()), StandardOpenOption.READ)) {
MappedByteBuffer buffer = channel.map(READ_ONLY, 0, channel.size());
Elf elf = new Elf(buffer);
// We start placing sections right after the program headers.
long end = elf.header.e_phoff + elf.header.e_phnum * elf.header.e_phentsize;
for (int index = 0; index < elf.getNumberOfSections(); index++) {
ElfSection section = elf.getSectionByIndex(index);
String name = elf.getSectionName(section.header);
// address by this sections size.
if (getSections().contains(name)) {
addresses.put(name, end);
end += section.header.sh_size;
}
}
}
return addresses.build();
}
use of com.facebook.buck.cxx.elf.ElfSection in project buck by facebook.
the class AbstractElfSymbolTableScrubberStep method execute.
@Override
public StepExecutionResult execute(ExecutionContext context) throws IOException {
try (FileChannel channel = FileChannel.open(getFilesystem().resolve(getPath()), StandardOpenOption.READ, StandardOpenOption.WRITE)) {
MappedByteBuffer buffer = channel.map(READ_WRITE, 0, channel.size());
Elf elf = new Elf(buffer);
// Locate the symbol table section.
Optional<ElfSection> section = elf.getSectionByName(getSection()).map(Pair::getSecond);
if (!section.isPresent()) {
if (isAllowMissing()) {
return StepExecutionResult.SUCCESS;
} else {
throw new IOException(String.format("Error parsing ELF file %s: no such section \"%s\"", getPath(), getSection()));
}
}
// Read in and fixup the symbol table then write it back out.
ElfSymbolTable table = ElfSymbolTable.parse(elf.header.ei_class, section.get().body);
ElfSymbolTable fixedUpTable = fixUpSymbolTable(table);
Preconditions.checkState(table.entries.size() == fixedUpTable.entries.size());
section.get().body.rewind();
fixedUpTable.write(elf.header.ei_class, section.get().body);
}
return StepExecutionResult.SUCCESS;
}
use of com.facebook.buck.cxx.elf.ElfSection in project buck by facebook.
the class DebugSectionFinder method findElf.
// Locate, if any, the debug sections in the ELF file represented by the given buffer.
private ImmutableMap<String, DebugSection> findElf(ByteBuffer buffer) {
ImmutableMap.Builder<String, DebugSection> debugSectionsBuilder = ImmutableMap.builder();
Elf elf = new Elf(buffer);
for (int i = 0; i < elf.getNumberOfSections(); i++) {
ElfSection section = elf.getSectionByIndex(i);
String name = elf.getSectionName(section.header);
ImmutableSet<DebugSectionProperty> properties = ELF_DEBUG_SECTIONS.get(name);
if (properties != null) {
buffer.position((int) section.header.sh_off);
ByteBuffer body = buffer.slice();
body.limit((int) section.header.sh_size);
debugSectionsBuilder.put(name, new DebugSection(properties, body));
}
}
return debugSectionsBuilder.build();
}
use of com.facebook.buck.cxx.elf.ElfSection in project buck by facebook.
the class ElfDynamicSectionScrubberStepTest method test.
@Test
public void test() throws IOException {
ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "elf_shared_lib", tmp);
workspace.setUp();
ElfDynamicSectionScrubberStep step = ElfDynamicSectionScrubberStep.of(new ProjectFilesystem(tmp.getRoot()), tmp.getRoot().getFileSystem().getPath("libfoo.so"));
step.execute(TestExecutionContext.newInstance());
// Verify that the relevant dynamic section tag have been zero'd out.
try (FileChannel channel = FileChannel.open(step.getFilesystem().resolve(step.getPath()), StandardOpenOption.READ)) {
MappedByteBuffer buffer = channel.map(READ_ONLY, 0, channel.size());
Elf elf = new Elf(buffer);
Optional<ElfSection> section = elf.getSectionByName(ElfDynamicSectionScrubberStep.SECTION).map(Pair::getSecond);
for (ByteBuffer body = section.get().body; body.hasRemaining(); ) {
ElfDynamicSection.DTag dTag = ElfDynamicSection.DTag.valueOf(elf.header.ei_class == ElfHeader.EIClass.ELFCLASS32 ? Elf.Elf32.getElf32Sword(body) : (int) Elf.Elf64.getElf64Sxword(body));
long dPtr = elf.header.ei_class == ElfHeader.EIClass.ELFCLASS32 ? Elf.Elf32.getElf32Addr(body) : Elf.Elf64.getElf64Addr(body);
if (!ElfDynamicSectionScrubberStep.WHITELISTED_TAGS.contains(dTag)) {
assertThat(dPtr, Matchers.equalTo(0L));
}
}
}
}
Aggregations