blob: d0fbfb3e3e302a1fe15db9bff6695c633ebad3a1 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_LIB_ELFLIB_ELFLIB_H_
#define GARNET_LIB_ELFLIB_ELFLIB_H_
#include <map>
#include <memory>
#include <optional>
#include <vector>
#include "garnet/public/lib/fxl/macros.h"
#include "garnet/third_party/llvm/include/llvm/BinaryFormat/ELF.h"
namespace elflib {
using namespace llvm::ELF;
class ElfLib {
public:
// Proxy object for whatever address space we're exploring.
class MemoryAccessor {
public:
virtual ~MemoryAccessor() = default;
// Get memory from the process relative to the base of this lib. That means
// offset 0 should point to the Elf64_Ehdr. The vector should be cleared and
// filled. Return true unless the memory could not be read.
virtual std::optional<std::vector<uint8_t>> GetMemory(uint64_t offset,
size_t size) = 0;
// Get memory for a mapped area. This is the same as GetMemory except we
// are also given the target address of the memory we want according to the
// ELF file, and the expected mapped size. If we're reading ELF structures
// that have been mapped into a running process already we may want to
// check the mapped address instead.
virtual std::optional<std::vector<uint8_t>> GetMappedMemory(
uint64_t offset, uint64_t mapped_address, size_t file_size,
size_t mapped_size) {
return GetMemory(offset, file_size);
}
};
// Do not use. See Create.
explicit ElfLib(std::unique_ptr<MemoryAccessor>&& memory);
virtual ~ElfLib();
// Get the contents of a section by its name. Return nullptr if there is no
// section by that name.
const std::vector<uint8_t>* GetSectionData(const std::string& name);
// Get a note from the notes section.
const std::optional<std::vector<uint8_t>> GetNote(const std::string& name,
uint64_t type);
// Get the stored value of a given symbol. Returns nullopt if the lookup
// failed.
std::optional<uint64_t> GetSymbolValue(const std::string& name);
// Get a map of all symbols and their string names. Returns nullopt if the
// symbols could not be loaded.
std::optional<std::map<std::string, Elf64_Sym>> GetAllSymbols();
// Create a new ElfLib object.
static std::unique_ptr<ElfLib> Create(
std::unique_ptr<MemoryAccessor>&& memory);
private:
// Get the header for a section by its index. Return nullptr if the index is
// invalid.
const Elf64_Shdr* GetSectionHeader(size_t section);
// Load the program header table into the cache in segments_. Return true
// unless a read error occurred.
bool LoadProgramHeaders();
// Get the contents of a section by its index. Return nullptr if the index is
// invalid.
const std::vector<uint8_t>* GetSectionData(size_t section);
// Get the contents of a segment by its index. Return nullptr if the index is
// invalid.
const std::vector<uint8_t>* GetSegmentData(size_t segment);
// Get a string from the .strtab section. Return nullptr if the index is
// invalid.
std::optional<std::string> GetString(size_t index);
// Get a symbol from the symbol table. Return nullptr if there is no such
// symbol.
const Elf64_Sym* GetSymbol(const std::string& name);
// Load all symbols from the target. Returns true unless an error occurred.
bool LoadSymbols();
// Load symbols from the dynamic segment of the target. We only do this when
// the section data isn't available and we can't use the regular .symtab
// information. Returns true unless an error occurred.
bool LoadDynamicSymbols();
std::unique_ptr<MemoryAccessor> memory_;
Elf64_Ehdr header_;
size_t dynamic_strtab_size_;
size_t dynamic_symtab_size_;
std::optional<uint64_t> dynamic_strtab_offset_;
std::optional<uint64_t> dynamic_symtab_offset_;
std::vector<Elf64_Shdr> sections_;
std::vector<Elf64_Phdr> segments_;
std::vector<Elf64_Sym> symbols_;
std::map<size_t, std::vector<uint8_t>> section_data_;
std::map<size_t, std::vector<uint8_t>> segment_data_;
std::map<std::string, size_t> section_names_;
FXL_DISALLOW_COPY_AND_ASSIGN(ElfLib);
};
} // namespace elflib
#endif // GARNET_LIB_ELFLIB_ELFLIB_H_