Skip to content

Commit 75e4daa

Browse files
committed
Add infrastructure to iterate on all objects that are string indexes
1 parent c749f67 commit 75e4daa

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

src/patchelf.cc

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,42 @@ void ElfFile<ElfFileParamNames>::modifyExecstack(ExecstackMode op)
22932293
printf("execstack: %c\n", result);
22942294
}
22952295

2296+
template<ElfFileParams>
2297+
template<class StrIdxCallback>
2298+
void ElfFile<ElfFileParamNames>::forAllStringReferences(Elf_Shdr& strTabHdr, StrIdxCallback&& fn)
2299+
{
2300+
for (auto& sym : tryGetSectionSpan<Elf_Sym>(".dynsym"))
2301+
fn(sym.st_name);
2302+
2303+
for (auto& dyn : tryGetSectionSpan<Elf_Dyn>(".dynamic"))
2304+
switch (rdi(dyn.d_tag))
2305+
{
2306+
case DT_NEEDED:
2307+
case DT_SONAME:
2308+
case DT_RPATH:
2309+
case DT_RUNPATH: fn(dyn.d_un.d_val);
2310+
default:;
2311+
}
2312+
2313+
if (auto verdHdr = tryFindSectionHeader(".gnu.version_d"))
2314+
{
2315+
if (&shdrs.at(rdi(verdHdr->get().sh_link)) == &strTabHdr)
2316+
forAll_ElfVer(getSectionSpan<Elf_Verdef>(*verdHdr),
2317+
[] (auto& /*vd*/) {},
2318+
[&] (auto& vda) { fn(vda.vda_name); }
2319+
);
2320+
}
2321+
2322+
if (auto vernHdr = tryFindSectionHeader(".gnu.version_r"))
2323+
{
2324+
if (&shdrs.at(rdi(vernHdr->get().sh_link)) == &strTabHdr)
2325+
forAll_ElfVer(getSectionSpan<Elf_Verneed>(*vernHdr),
2326+
[&] (auto& vn) { fn(vn.vn_file); },
2327+
[&] (auto& vna) { fn(vna.vna_name); }
2328+
);
2329+
}
2330+
}
2331+
22962332
static bool printInterpreter = false;
22972333
static bool printOsAbi = false;
22982334
static bool setOsAbi = false;
@@ -2397,9 +2433,9 @@ static void patchElf()
23972433
const std::string & outputFileName2 = outputFileName.empty() ? fileName : outputFileName;
23982434

23992435
if (getElfType(fileContents).is32Bit)
2400-
patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed, Elf32_Versym, Elf32_Rel, Elf32_Rela, 32>(fileContents), fileContents, outputFileName2);
2436+
patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Versym, Elf32_Verdef, Elf32_Verdaux, Elf32_Verneed, Elf32_Vernaux, Elf32_Rel, Elf32_Rela, 32>(fileContents), fileContents, outputFileName2);
24012437
else
2402-
patchElf2(ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, Elf64_Versym, Elf64_Rel, Elf64_Rela, 64>(fileContents), fileContents, outputFileName2);
2438+
patchElf2(ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Versym, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64>(fileContents), fileContents, outputFileName2);
24032439
}
24042440
}
24052441

src/patchelf.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

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

13-
#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, class Elf_Rel, class Elf_Rela, unsigned ElfClass
14-
#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed, Elf_Versym, Elf_Rel, Elf_Rela, ElfClass
13+
#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_Versym, class Elf_Verdef, class Elf_Verdaux, class Elf_Verneed, class Elf_Vernaux, class Elf_Rel, class Elf_Rela, unsigned ElfClass
14+
#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Versym, Elf_Verdef, Elf_Verdaux, Elf_Verneed, Elf_Vernaux, Elf_Rel, Elf_Rela, ElfClass
1515

1616
template<class T>
1717
struct span
@@ -237,6 +237,40 @@ class ElfFile
237237
}
238238
}
239239

240+
template<class StrIdxCallback>
241+
void forAllStringReferences(const Elf_Shdr& strTabHdr, StrIdxCallback&& fn);
242+
243+
template<class T, class U>
244+
auto follow(U* ptr, size_t offset) -> T* {
245+
return offset ? (T*)(((char*)ptr)+offset) : nullptr;
246+
};
247+
248+
template<class VdFn, class VaFn>
249+
void forAll_ElfVer(span<Elf_Verdef> vdspan, VdFn&& vdfn, VaFn&& vafn)
250+
{
251+
auto* vd = vdspan.begin();
252+
for (; vd; vd = follow<Elf_Verdef>(vd, rdi(vd->vd_next)))
253+
{
254+
vdfn(*vd);
255+
auto va = follow<Elf_Verdaux>(vd, rdi(vd->vd_aux));
256+
for (; va; va = follow<Elf_Verdaux>(va, rdi(va->vda_next)))
257+
vafn(*va);
258+
}
259+
}
260+
261+
template<class VnFn, class VaFn>
262+
void forAll_ElfVer(span<Elf_Verneed> vnspan, VnFn&& vnfn, VaFn&& vafn)
263+
{
264+
auto* vn = vnspan.begin();
265+
for (; vn; vn = follow<Elf_Verneed>(vn, rdi(vn->vn_next)))
266+
{
267+
vnfn(*vn);
268+
auto va = follow<Elf_Vernaux>(vn, rdi(vn->vn_aux));
269+
for (; va; va = follow<Elf_Vernaux>(va, rdi(va->vna_next)))
270+
vafn(*va);
271+
}
272+
}
273+
240274
/* Convert an integer in big or little endian representation (as
241275
specified by the ELF header) to this platform's integer
242276
representation. */

0 commit comments

Comments
 (0)