Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernizations and strictness improvements #464

Merged
merged 17 commits into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include <optional>
Expand Down Expand Up @@ -69,14 +70,18 @@ static int forcedPageSize = -1;
#define EM_LOONGARCH 258
#endif


static std::vector<std::string> splitColonDelimitedString(const char * s)
[[nodiscard]] static std::vector<std::string> splitColonDelimitedString(std::string_view s)
{
std::string item;
std::vector<std::string> parts;
std::stringstream ss(s);
while (std::getline(ss, item, ':'))
parts.push_back(item);

size_t pos;
while ((pos = s.find(':')) != std::string_view::npos) {
parts.emplace_back(s.substr(0, pos));
s = s.substr(pos + 1);
}

if (!s.empty())
parts.emplace_back(s);

return parts;
}
Expand Down Expand Up @@ -104,7 +109,7 @@ static std::string downcase(std::string s)
why... */
template<ElfFileParams>
template<class I>
I ElfFile<ElfFileParamNames>::rdi(I i) const
constexpr I ElfFile<ElfFileParamNames>::rdi(I i) const noexcept
{
I r = 0;
if (littleEndian) {
Expand All @@ -131,7 +136,7 @@ static void debug(const char * format, ...)
}


void fmt2(std::ostringstream & out)
static void fmt2([[maybe_unused]] std::ostringstream & out)
{
}

Expand Down Expand Up @@ -191,11 +196,11 @@ static FileContents readFile(const std::string & fileName,
while ((portion = read(fd, contents->data() + bytesRead, size - bytesRead)) > 0)
bytesRead += portion;

close(fd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be even autoclosed later on.


if (bytesRead != size)
throw SysError(fmt("reading '", fileName, "'"));

close(fd);

return contents;
}

Expand Down Expand Up @@ -309,7 +314,7 @@ ElfFile<ElfFileParamNames>::ElfFile(FileContents fContents)


template<ElfFileParams>
unsigned int ElfFile<ElfFileParamNames>::getPageSize() const
unsigned int ElfFile<ElfFileParamNames>::getPageSize() const noexcept
{
if (forcedPageSize > 0)
return forcedPageSize;
Expand Down Expand Up @@ -555,7 +560,7 @@ std::optional<std::reference_wrapper<Elf_Shdr>> ElfFile<ElfFileParamNames>::tryF


template<ElfFileParams>
unsigned int ElfFile<ElfFileParamNames>::getSectionIndex(const SectionName & sectionName)
unsigned int ElfFile<ElfFileParamNames>::getSectionIndex(const SectionName & sectionName) const
{
for (unsigned int i = 1; i < rdi(hdr()->e_shnum); ++i)
if (getSectionName(shdrs.at(i)) == sectionName) return i;
Expand Down
49 changes: 27 additions & 22 deletions src/patchelf.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "elf.h"

using FileContents = std::shared_ptr<std::vector<unsigned char>>;

#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym, class Elf_Verneed, class Elf_Versym
Expand Down Expand Up @@ -30,14 +39,14 @@ class ElfFile

/* Align on 4 or 8 bytes boundaries on 32- or 64-bit platforms
respectively. */
size_t sectionAlignment = sizeof(Elf_Off);
static constexpr size_t sectionAlignment = sizeof(Elf_Off);

std::vector<SectionName> sectionsByOldIndex;

public:
explicit ElfFile(FileContents fileContents);

bool isChanged()
[[nodiscard]] bool isChanged() const noexcept
{
return changed;
}
Expand All @@ -46,8 +55,8 @@ class ElfFile

struct CompPhdr
{
ElfFile * elfFile;
bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y)
const ElfFile * elfFile;
bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y) const noexcept
{
// A PHDR comes before everything else.
if (elfFile->rdi(y.p_type) == PT_PHDR) return false;
Expand All @@ -58,39 +67,35 @@ class ElfFile
}
};

friend struct CompPhdr;

void sortPhdrs();

struct CompShdr
{
ElfFile * elfFile;
bool operator ()(const Elf_Shdr & x, const Elf_Shdr & y)
const ElfFile * elfFile;
bool operator ()(const Elf_Shdr & x, const Elf_Shdr & y) const noexcept
{
return elfFile->rdi(x.sh_offset) < elfFile->rdi(y.sh_offset);
}
};

friend struct CompShdr;

unsigned int getPageSize() const;
[[nodiscard]] unsigned int getPageSize() const noexcept;

void sortShdrs();

void shiftFile(unsigned int extraPages, size_t sizeOffset, size_t extraBytes);

std::string getSectionName(const Elf_Shdr & shdr) const;
[[nodiscard]] std::string getSectionName(const Elf_Shdr & shdr) const;

Elf_Shdr & findSectionHeader(const SectionName & sectionName);

std::optional<std::reference_wrapper<Elf_Shdr>> tryFindSectionHeader(const SectionName & sectionName);
[[nodiscard]] std::optional<std::reference_wrapper<Elf_Shdr>> tryFindSectionHeader(const SectionName & sectionName);

unsigned int getSectionIndex(const SectionName & sectionName);
[[nodiscard]] unsigned int getSectionIndex(const SectionName & sectionName) const;

std::string & replaceSection(const SectionName & sectionName,
unsigned int size);

bool haveReplacedSection(const SectionName & sectionName) const;
[[nodiscard]] bool haveReplacedSection(const SectionName & sectionName) const;

void writeReplacedSections(Elf_Off & curOff,
Elf_Addr startAddr, Elf_Off startOffset);
Expand All @@ -107,7 +112,7 @@ class ElfFile

void rewriteSections(bool force = false);

std::string getInterpreter();
[[nodiscard]] std::string getInterpreter();

typedef enum { printOsAbi, replaceOsAbi } osAbiMode;

Expand Down Expand Up @@ -149,21 +154,21 @@ class ElfFile
specified by the ELF header) to this platform's integer
representation. */
template<class I>
I rdi(I i) const;
constexpr I rdi(I i) const noexcept;

/* Convert back to the ELF representation. */
template<class I>
I wri(I & t, unsigned long long i) const
constexpr I wri(I & t, unsigned long long i) const
{
t = rdi((I) i);
return i;
}

Elf_Ehdr *hdr() {
return (Elf_Ehdr *)fileContents->data();
[[nodiscard]] Elf_Ehdr *hdr() noexcept {
return reinterpret_cast<Elf_Ehdr *>(fileContents->data());
}

const Elf_Ehdr *hdr() const {
return (const Elf_Ehdr *)fileContents->data();
[[nodiscard]] const Elf_Ehdr *hdr() const noexcept {
return reinterpret_cast<const Elf_Ehdr *>(fileContents->data());
}
};