mirror of
https://github.com/gentoo-mirror/gentoo-zh.git
synced 2025-04-17 23:18:49 -04:00
dev-util/patchelf-liblol: new package, add 0.1.4
Signed-off-by: WANG Xuerui <xen0n@gentoo.org>
This commit is contained in:
parent
a4e49d6aab
commit
ce44d844d0
1
dev-util/patchelf-liblol/Manifest
Normal file
1
dev-util/patchelf-liblol/Manifest
Normal file
@ -0,0 +1 @@
|
||||
DIST patchelf-0.18.0.tar.gz 331312 BLAKE2B e6ce4ec3bd89c280bb37230dbeb566b803f09900006e79f7dba74f138f66e17746d331baea4def6a43163024b3d86aa8dbac9b2c6545ac146298a8b84373d03b SHA512 6a917d7336b1e8c59f42d4cd1dc725df1378d77657fce13cb31547da1d4805b9df8a834a7b8408fda8aa1dbeb37d0cdca74d8698844ea2f44149f800b802dea6
|
29
dev-util/patchelf-liblol/files/patchelf-0.18.0-alpha.patch
Normal file
29
dev-util/patchelf-liblol/files/patchelf-0.18.0-alpha.patch
Normal 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:
|
@ -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
|
||||
|
10
dev-util/patchelf-liblol/metadata.xml
Normal file
10
dev-util/patchelf-liblol/metadata.xml
Normal 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>
|
50
dev-util/patchelf-liblol/patchelf-liblol-0.1.4.ebuild
Normal file
50
dev-util/patchelf-liblol/patchelf-liblol-0.1.4.ebuild
Normal 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"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user