dev-util/patchelf-liblol: new package, add 0.1.4

Signed-off-by: WANG Xuerui <xen0n@gentoo.org>
This commit is contained in:
WANG Xuerui 2024-03-14 16:16:06 +08:00 committed by 梁永祥
parent a4e49d6aab
commit ce44d844d0
5 changed files with 562 additions and 0 deletions

View File

@ -0,0 +1 @@
DIST patchelf-0.18.0.tar.gz 331312 BLAKE2B e6ce4ec3bd89c280bb37230dbeb566b803f09900006e79f7dba74f138f66e17746d331baea4def6a43163024b3d86aa8dbac9b2c6545ac146298a8b84373d03b SHA512 6a917d7336b1e8c59f42d4cd1dc725df1378d77657fce13cb31547da1d4805b9df8a834a7b8408fda8aa1dbeb37d0cdca74d8698844ea2f44149f800b802dea6

View File

@ -0,0 +1,29 @@
https://bugs.gentoo.org/909738
https://github.com/NixOS/patchelf/pull/529
Note this has removed the unit test changes because it involves adding a binary
file which is not supported in portage for now, see
https://bugs.gentoo.org/835964
commit dbc9aeaadfd982b2d8a04eb74cbcecb83208844d
Author: matoro <matoro@users.noreply.github.com>
Date: Sat Nov 4 20:01:22 2023 -0400
Fix page size on Alpha
All tests pass.
Also explicitly specifies -no-pie for executables which should have it
disabled, to be compatible with gccs built with --enable-default-pie.
diff --git a/src/patchelf.cc b/src/patchelf.cc
index b42111d..b4d4a7d 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -367,6 +367,7 @@ unsigned int ElfFile<ElfFileParamNames>::getPageSize() const noexcept
// requirements. There is no authoritative list of these values. The
// current list is extracted from GNU gold's source code (abi_pagesize).
switch (rdi(hdr()->e_machine)) {
+ case EM_ALPHA:
case EM_IA_64:
case EM_MIPS:
case EM_PPC:

View File

@ -0,0 +1,472 @@
https://github.com/AOSC-Dev/liblol/blob/v0.1.4/autobuild/patches/patchelf/0001-add-remap-symvers.patch
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Fri, 12 Jan 2024 16:56:07 +0800
Subject: [PATCH] add remap-symvers
--- a/src/elf.h
+++ b/src/elf.h
@@ -55,6 +55,8 @@ typedef uint16_t Elf64_Section;
typedef Elf32_Half Elf32_Versym;
typedef Elf64_Half Elf64_Versym;
+#define VERSYM_HIDDEN 0x8000
+#define VERSYM_VERSION 0x7fff
/* The ELF file header. This appears at the start of every ELF file. */
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -1234,8 +1234,14 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
}
else if (d_tag == DT_VERNEED)
dyn->d_un.d_ptr = findSectionHeader(".gnu.version_r").sh_addr;
+ else if (d_tag == DT_VERNEEDNUM)
+ dyn->d_un.d_val = findSectionHeader(".gnu.version_r").sh_info;
else if (d_tag == DT_VERSYM)
dyn->d_un.d_ptr = findSectionHeader(".gnu.version").sh_addr;
+ else if (d_tag == DT_VERDEF)
+ dyn->d_un.d_ptr = findSectionHeader(".gnu.version_d").sh_addr;
+ else if (d_tag == DT_VERDEFNUM)
+ dyn->d_un.d_val = findSectionHeader(".gnu.version_d").sh_info;
else if (d_tag == DT_MIPS_RLD_MAP_REL) {
/* the MIPS_RLD_MAP_REL tag stores the offset to the debug
pointer, relative to the address of the tag */
@@ -2016,7 +2022,7 @@ auto ElfFile<ElfFileParamNames>::parseGnuHashTable(span<char> sectionData) -> Gn
}
template<ElfFileParams>
-void ElfFile<ElfFileParamNames>::rebuildGnuHashTable(span<char> strTab, span<Elf_Sym> dynsyms)
+void ElfFile<ElfFileParamNames>::rebuildGnuHashTable(span<char> strTab, span<Elf_Sym> dynsyms, span<Elf_Versym> versyms)
{
auto sectionData = tryGetSectionSpan<char>(".gnu.hash");
if (!sectionData)
@@ -2028,12 +2034,20 @@ void ElfFile<ElfFileParamNames>::rebuildGnuHashTable(span<char> strTab, span<Elf
if (ght.m_table.size() == 0)
return;
+ if (ght.m_table.size() + rdi(ght.m_hdr.symndx) < dynsyms.size()){
+ debug("gnuhash table is too small, rebuilding\n");
+ auto & newSection = replaceSection(".gnu.hash", sectionData.size() + (dynsyms.size() - ght.m_table.size() - rdi(ght.m_hdr.symndx)) * sizeof(uint32_t));
+ sectionData = span<char>(newSection.data(), newSection.size());
+ ght = parseGnuHashTable(sectionData);
+ }
+
// The hash table includes only a subset of dynsyms
auto firstSymIdx = rdi(ght.m_hdr.symndx);
dynsyms = span(&dynsyms[firstSymIdx], dynsyms.end());
// Only use the range of symbol versions that will be changed
- auto versyms = tryGetSectionSpan<Elf_Versym>(".gnu.version");
+ if (!versyms)
+ versyms = tryGetSectionSpan<Elf_Versym>(".gnu.version");
if (versyms)
versyms = span(&versyms[firstSymIdx], versyms.end());
@@ -2148,7 +2162,7 @@ auto ElfFile<ElfFileParamNames>::parseHashTable(span<char> sectionData) -> HashT
}
template<ElfFileParams>
-void ElfFile<ElfFileParamNames>::rebuildHashTable(span<char> strTab, span<Elf_Sym> dynsyms)
+void ElfFile<ElfFileParamNames>::rebuildHashTable(span<char> strTab, span<Elf_Sym> dynsyms, int moreSyms)
{
auto sectionData = tryGetSectionSpan<char>(".hash");
if (!sectionData)
@@ -2156,6 +2170,15 @@ void ElfFile<ElfFileParamNames>::rebuildHashTable(span<char> strTab, span<Elf_Sy
auto ht = parseHashTable(sectionData);
+ if(moreSyms > 0)
+ {
+ auto & newSection = replaceSection(".hash", sectionData.size() + moreSyms * sizeof(uint32_t));
+ sectionData = span<char>(newSection.data(), newSection.size());
+ auto hdr = (typename HashTable::Header*)sectionData.begin();
+ wri(hdr->nchain, rdi(hdr->nchain) + moreSyms);
+ ht = parseHashTable(sectionData);
+ }
+
std::fill(ht.m_buckets.begin(), ht.m_buckets.end(), 0);
std::fill(ht.m_chain.begin(), ht.m_chain.end(), 0);
@@ -2320,6 +2343,281 @@ void ElfFile<ElfFileParamNames>::modifyExecstack(ExecstackMode op)
printf("execstack: %c\n", result);
}
+template<ElfFileParams>
+void ElfFile<ElfFileParamNames>::remapSymvers(const std::string & mapTo, const std::vector<std::string> & mapFrom, bool alsoPatchVerNeed)
+{
+ auto shdrDynStr = findSectionHeader(".dynstr");
+ auto shdrDynsym = findSectionHeader(".dynsym");
+ auto shdrVersym = findSectionHeader(".gnu.version");
+
+ auto strTab = (char *)fileContents->data() + rdi(shdrDynStr.sh_offset);
+ auto strTabSize = rdi(shdrDynStr.sh_size);
+ auto dynsyms = (Elf_Sym *)(fileContents->data() + rdi(shdrDynsym.sh_offset));
+ auto versyms = (Elf_Versym *)(fileContents->data() + rdi(shdrVersym.sh_offset));
+ const size_t count = rdi(shdrDynsym.sh_size) / sizeof(Elf_Sym);
+
+ if (count != rdi(shdrVersym.sh_size) / sizeof(Elf_Versym))
+ error("versym size mismatch");
+
+ auto &shdrVerdef = findSectionHeader(".gnu.version_d");
+ auto verdef = (char *)(fileContents->data() + rdi(shdrVerdef.sh_offset));
+
+ std::map<int, std::string> verdefMap;
+
+ debug("Parsing .gnu.version_d\n");
+
+ int verdef_entries = rdi(shdrVerdef.sh_info);
+ debug(".gnu.version_d: %d entries\n", verdef_entries);
+
+ auto verdef_end = verdef + rdi(shdrVerdef.sh_size);
+ off_t curoff = 0;
+
+ int map_to_ndx = -1;
+ int max_ndx = 0;
+ off_t last_verdef_off = 0;
+ off_t mapToStrOff = 0;
+ bool mapToAdded = false;
+
+ for(int i = 0; i < verdef_entries; i++){
+ Elf_Verdef *vd = (Elf_Verdef *) (verdef + curoff);
+ if ((char *)vd + sizeof(Elf_Verdef) > verdef_end)
+ error(fmt("verdef entry overflow: idx=", i));
+ auto ndx = rdi(vd->vd_ndx);
+ if ((char *)vd + rdi(vd->vd_aux) >= verdef_end)
+ error(fmt("verdef entry aux out of bounds: idx=", i));
+ auto aux = (Elf_Verdaux *) ((char *)vd + rdi(vd->vd_aux));
+ if ((char *)aux + sizeof(Elf_Verdaux) > verdef_end)
+ error(fmt("verdef entry aux overflow: idx=", i));
+ std::string_view name = &strTab[rdi(aux->vda_name)];
+ debug("verdef entry %d: %s, ndx=%d\n", i, name.data(), ndx);
+ if (ndx > max_ndx)
+ max_ndx = ndx;
+ if (name == mapTo) {
+ map_to_ndx = ndx;
+ mapToStrOff = rdi(aux->vda_name);
+ }
+ if(ndx != 0 && ndx != 1){
+ verdefMap[ndx] = name;
+ }
+
+ if(rdi(vd->vd_next) == 0){
+ if(i == verdef_entries - 1){
+ last_verdef_off = curoff;
+ break;
+ }
+ else
+ error(fmt("verdef entry should have next entry: idx=", i));
+ }
+ if((char *)vd + rdi(vd->vd_next) >= verdef_end)
+ error(fmt("verdef entry next out of bounds: idx=", i));
+ curoff += rdi(vd->vd_next);
+ }
+ if (map_to_ndx == -1){
+ debug("no version index for %s, adding\n", mapTo.c_str());
+ auto & newDynStr = replaceSection(".dynstr", rdi(shdrDynStr.sh_size) + mapTo.size() + 1);
+ mapToStrOff = rdi(shdrDynStr.sh_size);
+ setSubstr(newDynStr, mapToStrOff, mapTo + '\0');
+ strTab = newDynStr.data();
+ strTabSize = newDynStr.size();
+ }
+ debug("parsing verneed entries\n", mapTo.c_str());
+ auto verneedhdr = tryFindSectionHeader(".gnu.version_r");
+ std::map<int, int> verneedMap;
+ if(verneedhdr){
+ auto &shdrVerNeed = verneedhdr->get();
+ auto verneed = (char *)(fileContents->data() + rdi(shdrVerNeed.sh_offset));
+
+ debug("found .gnu.version_r, parsing\n");
+ int verneed_entries = rdi(shdrVerNeed.sh_info);
+ debug(".gnu.version_r: %d entries\n", verdef_entries);
+
+ auto verneed_end = verneed + rdi(shdrVerNeed.sh_size);
+ off_t curoff = 0;
+ for(int i = 0; i < verneed_entries; i++){
+ Elf_Verneed *vn = (Elf_Verneed *) (verneed + curoff);
+ if ((char *)vn + sizeof(Elf_Verneed) > verneed_end)
+ error(fmt("verneed entry overflow: idx=", i));
+ auto aux_cnt = rdi(vn->vn_cnt);
+ debug("file: %s, %d versions\n", &strTab[rdi(vn->vn_file)], aux_cnt);
+ off_t aux_off = rdi(vn->vn_aux);
+ if ((char *)vn + aux_off >= verneed_end)
+ error(fmt("verneed entry aux out of bounds: idx=", i));
+ for(int j = 0; j < aux_cnt; j++){
+ auto aux = (Elf_Vernaux *) ((char *)vn + aux_off);
+ if ((char *)aux + sizeof(Elf_Vernaux) > verneed_end)
+ error(fmt("verneed entry aux overflow: idx=", i, "aux idx=", j));
+ auto ndx = rdi(aux->vna_other) & VERSYM_VERSION;
+ debug(" %s, ndx=%d\n", &strTab[rdi(aux->vna_name)], ndx);
+ if(alsoPatchVerNeed){
+ for (auto it : mapFrom){
+ if (it == &strTab[rdi(aux->vna_name)]){
+ debug(" found %s, changing to %s\n", it.c_str(), mapTo.c_str());
+ wri(aux->vna_name, mapToStrOff);
+ wri(aux->vna_hash, sysvHash(mapTo));
+ break;
+ }
+ }
+ }
+ if(map_to_ndx == -1 && ndx >= max_ndx + 1){
+ verneedMap[ndx] = ndx + 1;
+ ndx = ndx + 1;
+ wri(aux->vna_other, (rdi(aux->vna_other) & ~VERSYM_VERSION) | (ndx & VERSYM_VERSION));
+ debug(" changing ndx to %d\n", ndx);
+ }
+ if (rdi(aux->vna_next) == 0){
+ if (j == aux_cnt - 1)
+ break;
+ else
+ error(fmt("verneed entry should have next entry: idx=", i, "aux idx=", j));
+ }
+ if ((char *)aux + rdi(aux->vna_next) >= verneed_end)
+ error(fmt("verneed entry next out of bounds: idx=", i, "aux idx=", j));
+ aux_off += rdi(aux->vna_next);
+ }
+ if (rdi(vn->vn_next) == 0){
+ if (i == verneed_entries - 1)
+ break;
+ else
+ error(fmt("verneed entry should have next entry: idx=", i));
+ }
+ if ((char *)vn + rdi(vn->vn_next) >= verneed_end)
+ error(fmt("verneed entry next out of bounds: idx=", i));
+ curoff += rdi(vn->vn_next);
+ }
+ }else{
+ debug("no .gnu.version_r found\n");
+ }
+ if (map_to_ndx == -1){
+ map_to_ndx = max_ndx + 1;
+ debug("decided to use %d for %s\n", map_to_ndx, mapTo.c_str());
+ if(map_to_ndx > VERSYM_VERSION){
+ error(fmt("version index %d is too large", map_to_ndx));
+ }
+ verdefMap[map_to_ndx] = mapTo;
+ auto & newVerdef = replaceSection(".gnu.version_d", rdi(shdrVerdef.sh_size) + sizeof(Elf_Verdef) + sizeof(Elf_Verdaux));
+ char * newVerdefData = newVerdef.data();
+ Elf_Verdef *lastVd = (Elf_Verdef *)(newVerdefData + last_verdef_off);
+ Elf_Verdef *newVd = (Elf_Verdef *)(newVerdefData + rdi(shdrVerdef.sh_size));
+ wri(lastVd->vd_next, (char *)newVd - (char *)lastVd);
+ wri(newVd->vd_version, 1);
+ wri(newVd->vd_flags, 0);
+ wri(newVd->vd_ndx, map_to_ndx);
+ wri(newVd->vd_cnt, 1);
+ wri(newVd->vd_hash, sysvHash(mapTo));
+ wri(newVd->vd_aux, sizeof(Elf_Verdef));
+ wri(newVd->vd_next, 0);
+ Elf_Verdaux *newVda = (Elf_Verdaux *)((char *)newVd + sizeof(Elf_Verdef));
+ wri(newVda->vda_next, 0);
+ wri(((Elf_Shdr *)(&shdrVerdef))->sh_info, rdi(shdrVerdef.sh_info) + 1);
+ verdef_entries += 1;
+
+ wri(newVda->vda_name, mapToStrOff);
+ mapToAdded = true;
+ }else{
+ debug("verdef entry for %s found at ndx=%d\n", mapTo.c_str(), map_to_ndx);
+ }
+ std::map<std::string, std::map<std::string, int>> symVersionMap;
+
+ debug("Parsing .dynsym\n");
+ for(size_t i = 0; i < count; i++){
+ auto dynsym = &dynsyms[i];
+ std::string name = strTab + rdi(dynsym->st_name);
+ auto verndx = rdi(versyms[i]);
+ auto verdef_ndx = verndx & VERSYM_VERSION;
+
+ if(verneedMap.find(verdef_ndx) != verneedMap.end()){
+ debug("verneed entry remapping for %s found at ndx=%d\n", name.c_str(), verdef_ndx);
+ verdef_ndx = verneedMap[verdef_ndx];
+ wri(versyms[i], (verndx & ~VERSYM_VERSION) | (verdef_ndx & VERSYM_VERSION));
+ }
+
+ if(name.empty())
+ continue;
+ debug("dynsym entry %d: %s ", i, name.c_str());
+ auto shndx = rdi(dynsym->st_shndx);
+ if(shndx == SHN_UNDEF){
+ debug("(undefined)\n");
+ continue;
+ }else if(shndx == SHN_ABS){
+ debug("(absolute)\n");
+ continue;
+ }else if(shndx == SHN_COMMON){
+ debug("(common)\n");
+ continue;
+ }
+ if(verndx == 0){
+ debug("(local)\n");
+ continue;
+ }else if(verndx == 1){
+ debug("(global)\n");
+ continue;
+ }
+ if(verdefMap.find(verdef_ndx) == verdefMap.end()){
+ debug("(verdef %d not found)\n", verdef_ndx);
+ continue;
+ }
+ debug("(ver: %s)\n", verdefMap[verdef_ndx].c_str());
+ symVersionMap[verdefMap[verdef_ndx]][name] = i;
+ }
+
+ debug("Generating new dsyms list\n");
+ std::map<std::string, int> newDsyms;
+ for(const auto &fromVer : mapFrom){
+ if(symVersionMap.find(fromVer) == symVersionMap.end()){
+ debug("No symbols with version %s found\n", fromVer.c_str());
+ continue;
+ }
+ for(auto sym : symVersionMap[fromVer]){
+ debug("Adding %s@%s to new dsyms list\n", sym.first.c_str(), fromVer.c_str());
+ newDsyms[sym.first] = sym.second;
+ }
+ }
+ for(const auto &syms : symVersionMap[mapTo]){
+ debug("removing %s@%s from new dsyms list\n", syms.first.c_str(), mapTo.c_str());
+ newDsyms.erase(syms.first);
+ }
+ auto newDynsymSize = (newDsyms.size() + (mapToAdded ? 1 : 0)) * sizeof(Elf_Sym) + rdi(shdrDynsym.sh_size);
+ auto newVersymSize = (newDsyms.size() + (mapToAdded ? 1 : 0)) * sizeof(Elf_Versym) + rdi(shdrVersym.sh_size);
+
+ auto& newDynsym = replaceSection(".dynsym", newDynsymSize);
+ auto& newVersym = replaceSection(".gnu.version", newVersymSize);
+
+ auto newDynsymSpan = span<Elf_Sym>((Elf_Sym *)newDynsym.data(), newDynsymSize / sizeof(Elf_Sym));
+ auto newVersymSpan = span<Elf_Versym>((Elf_Versym *)newVersym.data(), newVersymSize / sizeof(Elf_Versym));
+
+ {
+ int i = count;
+ for(auto it = newDsyms.cbegin(); it != newDsyms.cend(); ++it){
+ auto sym = it->second;
+ debug("Adding %s@%s to dynsym list\n", it->first.c_str(), mapTo.c_str());
+ newDynsymSpan[i] = dynsyms[sym];
+ bool is_hidden = rdi(newVersymSpan[sym]) & VERSYM_HIDDEN;
+ wri(newVersymSpan[i], map_to_ndx | (is_hidden ? VERSYM_HIDDEN : 0));
+ wri(newVersymSpan[sym], rdi(newVersymSpan[sym]) | VERSYM_HIDDEN);
+ i += 1;
+ }
+ if(mapToAdded){
+ debug("Adding %s@%s to dynsym list\n", mapTo.c_str(), mapTo.c_str());
+ wri(newDynsymSpan[i].st_name, mapToStrOff);
+ wri(newDynsymSpan[i].st_info, STB_GLOBAL << 4 | STT_OBJECT);
+ wri(newDynsymSpan[i].st_other, STV_DEFAULT);
+ wri(newDynsymSpan[i].st_shndx, SHN_ABS);
+ wri(newDynsymSpan[i].st_value, 0);
+ wri(newDynsymSpan[i].st_size, 0);
+ wri(newVersymSpan[i], map_to_ndx);
+ }
+ }
+
+ debug("Rebuilding hash tables\n");
+
+ rebuildGnuHashTable(span(strTab, strTabSize), newDynsymSpan, newVersymSpan);
+ rebuildHashTable(span(strTab, strTabSize), newDynsymSpan, newDsyms.size() + (mapToAdded ? 1 : 0));
+
+ this->rewriteSections();
+
+ changed = true;
+}
+
template<ElfFileParams>
template<class StrIdxCallback>
void ElfFile<ElfFileParamNames>::forAllStringReferences(const Elf_Shdr& strTabHdr, StrIdxCallback&& fn)
@@ -2384,6 +2682,10 @@ static bool noDefaultLib = false;
static bool printExecstack = false;
static bool clearExecstack = false;
static bool setExecstack = false;
+static bool remapSymvers = false;
+static bool remapVerneed = false;
+static std::string symverMapTo;
+static std::vector<std::string> symverMapFrom;
template<class ElfFile>
static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, const std::string & fileName)
@@ -2441,6 +2743,9 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
if (renameDynamicSymbols)
elfFile.renameDynamicSymbols(symbolsToRename);
+ if (remapSymvers)
+ elfFile.remapSymvers(symverMapTo, symverMapFrom, remapVerneed);
+
if (elfFile.isChanged()){
writeFile(fileName, elfFile.fileContents);
} else if (alwaysWrite) {
@@ -2505,6 +2810,8 @@ static void showHelp(const std::string & progName)
[--clear-execstack]\n\
[--set-execstack]\n\
[--rename-dynamic-symbols NAME_MAP_FILE]\tRenames dynamic symbols. The map file should contain two symbols (old_name new_name) per line\n\
+ [--remap-symvers TO=FROM1,FROM2...]\n\
+ [--also-remap-verneed]\n\
[--output FILE]\n\
[--debug]\n\
[--version]\n\
@@ -2661,6 +2968,44 @@ static int mainWrapped(int argc, char * * argv)
symbolsToRename[*symbolsToRenameKeys.insert(from).first] = to;
}
}
+ else if (arg == "--remap-symvers") {
+ remapSymvers = true;
+ if (++i == argc) error("missing argument");
+
+ const char* mapping = argv[i];
+ for(int i = 0; mapping[i]; ++i)
+ {
+ if (mapping[i] == '=')
+ {
+ char *mapto = strndup(mapping, i);
+ symverMapTo = mapto;
+ free(mapto);
+ mapping += i + 1;
+ break;
+ }
+ }
+ if (symverMapTo.empty())
+ error(fmt("Invalid symver mapping, must contains =: ", mapping));
+ for(int i = 0; mapping[i]; ++i)
+ {
+ if (mapping[i] == ',')
+ {
+ char *mapfrom = strndup(mapping, i);
+ if(strlen(mapfrom) != 0)
+ symverMapFrom.push_back(mapfrom);
+ free(mapfrom);
+ mapping += i + 1;
+ i = -1;
+ }
+ }
+ if (strlen(mapping) != 0)
+ symverMapFrom.push_back(mapping);
+ if (symverMapFrom.empty())
+ error(fmt("Invalid symver mapping, must contains at least one from: ", mapping));
+ }
+ else if (arg == "--also-remap-verneed") {
+ remapVerneed = true;
+ }
else if (arg == "--help" || arg == "-h" ) {
showHelp(argv[0]);
return 0;
--- a/src/patchelf.h
+++ b/src/patchelf.h
@@ -175,6 +175,8 @@ public:
void modifyExecstack(ExecstackMode op);
+ void remapSymvers(const std::string & mapTo, const std::vector<std::string> & mapFrom, bool alsoRemapVerneed);
+
private:
struct GnuHashTable {
using BloomWord = Elf_Addr;
@@ -194,8 +196,8 @@ private:
};
HashTable parseHashTable(span<char> gh);
- void rebuildGnuHashTable(span<char> strTab, span<Elf_Sym> dynsyms);
- void rebuildHashTable(span<char> strTab, span<Elf_Sym> dynsyms);
+ void rebuildGnuHashTable(span<char> strTab, span<Elf_Sym> dynsyms, span<Elf_Versym> versyms = {nullptr, nullptr});
+ void rebuildHashTable(span<char> strTab, span<Elf_Sym> dynsyms, int moreSyms = 0);
using Elf_Rel_Info = decltype(Elf_Rel::r_info);
--
2.43.0

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<maintainer type="person">
<email>xen0n@gentoo.org</email>
</maintainer>
<upstream>
<remote-id type="github">AOSC-Dev/liblol</remote-id>
</upstream>
</pkgmetadata>

View File

@ -0,0 +1,50 @@
# Copyright 2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
inherit autotools
PATCHELF_PN=patchelf
PATCHELF_PV=0.18.0
PATCHELF_P="${PATCHELF_PN}-${PATCHELF_PV}"
DESCRIPTION="patchelf patched for building libLoL only"
HOMEPAGE="https://github.com/NixOS/patchelf https://github.com/AOSC-Dev/liblol"
SRC_URI="https://github.com/NixOS/${PATCHELF_PN}/archive/${PATCHELF_PV}.tar.gz -> ${PATCHELF_P}.tar.gz"
S="${WORKDIR}/${PATCHELF_P}"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~ppc ~ppc64 ~riscv ~s390 ~x86 ~amd64-linux ~riscv-linux ~x86-linux"
PATCHES=(
# "${FILESDIR}"/${PATCHELF_PN}-glibc-dt-mips-xhash.patch # conflicts with liblol
"${FILESDIR}"/${PATCHELF_PN}-0.18.0-alpha.patch
"${FILESDIR}"/${PATCHELF_P}-liblol-${PV}.patch
)
src_prepare() {
# rm src/elf.h || die # this file is touched by the liblol patch
default
sed -i \
-e 's:-Werror::g' \
configure.ac || die
eautoreconf
}
src_configure() {
local myeconfargs=(
--program-suffix=-liblol
)
econf "${myeconfargs[@]}"
}
src_install() {
default
# prevent collision with the vanilla patchelf
rm -rf "${D}/usr/share/zsh"
}