2019-07-29 17:14:53 +00:00
|
|
|
#pragma once
|
|
|
|
|
2022-06-10 08:22:31 +00:00
|
|
|
#if defined(__ELF__) && !defined(OS_FREEBSD)
|
2019-08-21 00:48:34 +00:00
|
|
|
|
2019-07-29 17:14:53 +00:00
|
|
|
#include <IO/MMapReadBufferFromFile.h>
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <optional>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
#include <elf.h>
|
|
|
|
#include <link.h>
|
|
|
|
|
|
|
|
|
|
|
|
using ElfAddr = ElfW(Addr);
|
|
|
|
using ElfEhdr = ElfW(Ehdr);
|
|
|
|
using ElfOff = ElfW(Off);
|
|
|
|
using ElfPhdr = ElfW(Phdr);
|
|
|
|
using ElfShdr = ElfW(Shdr);
|
2020-06-14 03:10:35 +00:00
|
|
|
using ElfNhdr = ElfW(Nhdr);
|
2019-07-29 17:14:53 +00:00
|
|
|
using ElfSym = ElfW(Sym);
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-07-29 18:06:39 +00:00
|
|
|
/** Allow to navigate sections in ELF.
|
|
|
|
*/
|
|
|
|
class Elf final
|
2019-07-29 17:14:53 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct Section
|
|
|
|
{
|
|
|
|
const ElfShdr & header;
|
|
|
|
const char * name() const;
|
|
|
|
|
|
|
|
const char * begin() const;
|
|
|
|
const char * end() const;
|
2019-07-29 18:06:39 +00:00
|
|
|
size_t size() const;
|
2019-07-29 17:14:53 +00:00
|
|
|
|
2019-08-03 11:02:40 +00:00
|
|
|
Section(const ElfShdr & header_, const Elf & elf_);
|
2019-07-29 17:14:53 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
const Elf & elf;
|
|
|
|
};
|
|
|
|
|
2019-07-29 18:38:04 +00:00
|
|
|
explicit Elf(const std::string & path);
|
2019-07-29 17:14:53 +00:00
|
|
|
|
|
|
|
bool iterateSections(std::function<bool(const Section & section, size_t idx)> && pred) const;
|
2019-07-29 18:06:39 +00:00
|
|
|
std::optional<Section> findSection(std::function<bool(const Section & section, size_t idx)> && pred) const;
|
|
|
|
std::optional<Section> findSectionByName(const char * name) const;
|
2019-07-29 17:14:53 +00:00
|
|
|
|
2019-07-29 18:38:04 +00:00
|
|
|
const char * begin() const { return mapped; }
|
|
|
|
const char * end() const { return mapped + elf_size; }
|
|
|
|
size_t size() const { return elf_size; }
|
2019-07-29 17:14:53 +00:00
|
|
|
|
2021-11-20 12:52:00 +00:00
|
|
|
/// Obtain build id from SHT_NOTE of section headers (fallback to PT_NOTES section of program headers).
|
|
|
|
/// Return empty string if does not exist.
|
2020-06-14 03:10:35 +00:00
|
|
|
/// The string is returned in binary. Note that "readelf -n ./clickhouse-server" prints it in hex.
|
|
|
|
String getBuildID() const;
|
|
|
|
static String getBuildID(const char * nhdr_pos, size_t size);
|
|
|
|
|
2021-01-07 02:56:57 +00:00
|
|
|
/// Hash of the binary for integrity checks.
|
2022-06-14 08:50:53 +00:00
|
|
|
String getStoredBinaryHash() const;
|
2021-01-07 02:56:57 +00:00
|
|
|
|
2019-07-29 17:14:53 +00:00
|
|
|
private:
|
|
|
|
MMapReadBufferFromFile in;
|
2019-07-29 18:38:04 +00:00
|
|
|
size_t elf_size;
|
2019-07-29 17:14:53 +00:00
|
|
|
const char * mapped;
|
|
|
|
const ElfEhdr * header;
|
|
|
|
const ElfShdr * section_headers;
|
2020-06-14 03:10:35 +00:00
|
|
|
const ElfPhdr * program_headers;
|
2019-07-29 17:14:53 +00:00
|
|
|
const char * section_names = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
2019-08-21 00:48:34 +00:00
|
|
|
|
|
|
|
#endif
|