diff options
author | somov <somov@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
commit | a5950576e397b1909261050b8c7da16db58f10b1 (patch) | |
tree | 7ba7677f6a4c3e19e2cefab34d16df2c8963b4d4 /tools | |
parent | 81eddc8c0b55990194e112b02d127b87d54164a9 (diff) | |
download | ydb-a5950576e397b1909261050b8c7da16db58f10b1.tar.gz |
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/archiver/main.cpp | 2 | ||||
-rw-r--r-- | tools/archiver/ya.make | 6 | ||||
-rw-r--r-- | tools/fix_elf/patch.cpp | 452 | ||||
-rw-r--r-- | tools/fix_elf/patch.h | 294 | ||||
-rw-r--r-- | tools/fix_elf/ya.make | 8 | ||||
-rw-r--r-- | tools/ya.make | 2 |
6 files changed, 382 insertions, 382 deletions
diff --git a/tools/archiver/main.cpp b/tools/archiver/main.cpp index 6cda54c1ea..0b794e86d3 100644 --- a/tools/archiver/main.cpp +++ b/tools/archiver/main.cpp @@ -2,7 +2,7 @@ #include <library/cpp/deprecated/mapped_file/mapped_file.h> #include <library/cpp/digest/md5/md5.h> #include <library/cpp/getopt/small/last_getopt.h> - + #include <util/folder/dirut.h> #include <util/folder/filelist.h> #include <util/folder/path.h> diff --git a/tools/archiver/ya.make b/tools/archiver/ya.make index 757378c1b3..da322b3e3d 100644 --- a/tools/archiver/ya.make +++ b/tools/archiver/ya.make @@ -5,12 +5,12 @@ OWNER( mvel ) -PEERDIR( +PEERDIR( library/cpp/archive library/cpp/digest/md5 library/cpp/getopt/small -) - +) + SRCS( main.cpp ) diff --git a/tools/fix_elf/patch.cpp b/tools/fix_elf/patch.cpp index d49ebab307..88d997d17b 100644 --- a/tools/fix_elf/patch.cpp +++ b/tools/fix_elf/patch.cpp @@ -1,15 +1,15 @@ -#include "patch.h" - +#include "patch.h" + #include <library/cpp/getopt/last_getopt.h> - -#include <util/generic/algorithm.h> -#include <util/generic/hash.h> -#include <util/stream/null.h> -#include <util/string/cast.h> + +#include <util/generic/algorithm.h> +#include <util/generic/hash.h> +#include <util/stream/null.h> +#include <util/string/cast.h> #include <util/system/defaults.h> - -namespace NElf { - + +namespace NElf { + bool IsElf(const TString& path) { TUnbufferedFileInput in(path); char buffer[EI_NIDENT]; @@ -43,227 +43,227 @@ bool IsElf(const TString& path) { } return true; -} - -} // namespace NElf - -using namespace NElf; - -void ReadNum(TStringBuf& src, TStringBuf& dst) { - const char* c = src.data(); - while (isdigit(*c)) { - ++c; - } - size_t len = c - src.data(); - - dst = TStringBuf(src.data(), len); - src.Skip(len); -} - -int NumericStrCmp(TStringBuf s1, TStringBuf s2) { +} + +} // namespace NElf + +using namespace NElf; + +void ReadNum(TStringBuf& src, TStringBuf& dst) { + const char* c = src.data(); + while (isdigit(*c)) { + ++c; + } + size_t len = c - src.data(); + + dst = TStringBuf(src.data(), len); + src.Skip(len); +} + +int NumericStrCmp(TStringBuf s1, TStringBuf s2) { while (!s1.empty() || !s2.empty()) { - char c1 = *s1.data(); - char c2 = *s2.data(); - - if (isdigit(c1) && isdigit(c2)) { - TStringBuf num1, num2; - ReadNum(s1, num1); - ReadNum(s2, num2); - - int c = FromString<int>(num1) - FromString<int>(num2); - if (c) { - return c; - } - - } else { - int c = int(c1) - int(c2); - if (c) { - return c; - } - } - + char c1 = *s1.data(); + char c2 = *s2.data(); + + if (isdigit(c1) && isdigit(c2)) { + TStringBuf num1, num2; + ReadNum(s1, num1); + ReadNum(s2, num2); + + int c = FromString<int>(num1) - FromString<int>(num2); + if (c) { + return c; + } + + } else { + int c = int(c1) - int(c2); + if (c) { + return c; + } + } + s1.Skip(1); s2.Skip(1); - } - - return 0; -} - -class TVernauxCmp { -public: - TVernauxCmp(TSection strSect) - : StrSect(strSect) - { - } - - bool operator()(Elf64_Vernaux* v1, Elf64_Vernaux* v2) { - TStringBuf s1 = StrSect.GetStr(v1->vna_name); - TStringBuf s2 = StrSect.GetStr(v2->vna_name); - - return NumericStrCmp(s1, s2) < 0; - } - -private: - TSection StrSect; -}; - + } + + return 0; +} + +class TVernauxCmp { +public: + TVernauxCmp(TSection strSect) + : StrSect(strSect) + { + } + + bool operator()(Elf64_Vernaux* v1, Elf64_Vernaux* v2) { + TStringBuf s1 = StrSect.GetStr(v1->vna_name); + TStringBuf s2 = StrSect.GetStr(v2->vna_name); + + return NumericStrCmp(s1, s2) < 0; + } + +private: + TSection StrSect; +}; + void Patch(const TString& path, const TString& library, IOutputStream& verboseOut) { - TElf elf(path); - - TVerneedSection verneedSect(&elf); - if (verneedSect.IsNull()) { - verboseOut << "No symbol versions section" << Endl; - return; - } - - TSection verStrings(&elf, elf.GetSection(verneedSect.GetLink())); - - TStringBuf skipFrom("GLIBC_2.14"); - TStringBuf patchFrom("GLIBC_2.2.5"); - + TElf elf(path); + + TVerneedSection verneedSect(&elf); + if (verneedSect.IsNull()) { + verboseOut << "No symbol versions section" << Endl; + return; + } + + TSection verStrings(&elf, elf.GetSection(verneedSect.GetLink())); + + TStringBuf skipFrom("GLIBC_2.14"); + TStringBuf patchFrom("GLIBC_2.2.5"); + TVector<Elf64_Vernaux*> patchAux; - + Elf64_Vernaux* patchFromAux = nullptr; - - Elf64_Verneed* verneed = verneedSect.GetFirstVerneed(); - while (verneed) { - - TStringBuf file = verStrings.GetStr(verneed->vn_file); - verboseOut << file; - - if (file != library) { - verboseOut << " skipped" << Endl; - - } else { - verboseOut << Endl; - - Elf64_Vernaux* vernaux = verneedSect.GetFirstVernaux(verneed); - while (vernaux) { - - TStringBuf name = verStrings.GetStr(vernaux->vna_name); - verboseOut << "\t" << name; - - if (!patchFromAux && name == patchFrom) { - verboseOut << " taken as patch source" << Endl; - patchFromAux = vernaux; - - } else { - - if (NumericStrCmp(name, skipFrom) < 0) { - verboseOut << " skipped" << Endl; - - } else { - verboseOut << " will be patched" << Endl; - patchAux.push_back(vernaux); - } - } - vernaux = verneedSect.GetNextVernaux(vernaux); - } - } - verneed = verneedSect.GetNextVerneed(verneed); - } - - if (patchAux.empty()) { - verboseOut << "Nothing to patch" << Endl; - return; - } - - if (!patchFromAux) { - ythrow yexception() << path << ": no ELF64_Vernaux source to patch from"; - } - - TSection dynsymSect(&elf, elf.GetSectionByType(SHT_DYNSYM)); - TSection symstrSect(&elf, elf.GetSection(dynsymSect.GetLink())); - TSection dynverSect(&elf, elf.GetSectionByType(SHT_GNU_versym)); - - for (size_t i = 0, c = dynsymSect.GetEntryCount(); i < c; ++i) { - Elf64_Sym* sym = dynsymSect.GetEntry<Elf64_Sym>(i); - Elf64_Half* ver = dynverSect.GetEntry<Elf64_Half>(i); - for (auto aux : patchAux) { - if (*ver == aux->vna_other) { - *ver = 0; - verboseOut << "Symbol " << i << ": " << symstrSect.GetStr(sym->st_name) - << "@" << verStrings.GetStr(aux->vna_name) << " version removed" << Endl; - } - } - } - - for (auto aux : patchAux) { - TStringBuf name = verStrings.GetStr(aux->vna_name); - aux->vna_name = patchFromAux->vna_name; - aux->vna_hash = patchFromAux->vna_hash; - verboseOut << "Version dependence " << name << " [" << aux->vna_other - << "] patched from " << patchFrom << " [" << patchFromAux->vna_other << "]" << Endl; - } -} - -void PatchGnuUnique(const TString& path, IOutputStream& verboseOut) { - TElf elf(path); - - for (Elf64_Shdr* it = elf.GetSectionBegin(), *end = elf.GetSectionEnd(); it != end; ++it) { - if (it->sh_type == SHT_SYMTAB) { - - TSection section{&elf, it}; - verboseOut << "Found symbol section [" << section.GetName() << ']' << Endl; - - for (size_t i = 0, count = section.GetEntryCount(); i < count; ++i) { - Elf64_Sym* symbol = section.GetEntry<Elf64_Sym>(i); - auto& info = symbol->st_info; - - if (ELF64_ST_BIND(info) == STB_GNU_UNIQUE) { - verboseOut << "Found GNU unique symbol #" << i << Endl; - info = ELF64_ST_INFO(STB_GLOBAL, ELF64_ST_TYPE(info)); - } - } - } - } -} - -int main(int argc, char* argv[]) { - bool verbose = false; - bool rewrite_unique = false; - - using namespace NLastGetopt; - - TOpts opts = NLastGetopt::TOpts::Default(); - opts.AddHelpOption(); - - opts.AddLongOption('v', "verbose").NoArgument().StoreValue(&verbose, true); - opts.AddLongOption('u', "rewrite-gnu-unique", "Change STB_GNU_UNIQUE to STB_GLOBAL").NoArgument().StoreValue(&rewrite_unique, true); - - opts.SetFreeArgsMin(1); - opts.SetFreeArgTitle(0, "<file>", "File"); - - TOptsParseResult res(&opts, argc, argv); + + Elf64_Verneed* verneed = verneedSect.GetFirstVerneed(); + while (verneed) { + + TStringBuf file = verStrings.GetStr(verneed->vn_file); + verboseOut << file; + + if (file != library) { + verboseOut << " skipped" << Endl; + + } else { + verboseOut << Endl; + + Elf64_Vernaux* vernaux = verneedSect.GetFirstVernaux(verneed); + while (vernaux) { + + TStringBuf name = verStrings.GetStr(vernaux->vna_name); + verboseOut << "\t" << name; + + if (!patchFromAux && name == patchFrom) { + verboseOut << " taken as patch source" << Endl; + patchFromAux = vernaux; + + } else { + + if (NumericStrCmp(name, skipFrom) < 0) { + verboseOut << " skipped" << Endl; + + } else { + verboseOut << " will be patched" << Endl; + patchAux.push_back(vernaux); + } + } + vernaux = verneedSect.GetNextVernaux(vernaux); + } + } + verneed = verneedSect.GetNextVerneed(verneed); + } + + if (patchAux.empty()) { + verboseOut << "Nothing to patch" << Endl; + return; + } + + if (!patchFromAux) { + ythrow yexception() << path << ": no ELF64_Vernaux source to patch from"; + } + + TSection dynsymSect(&elf, elf.GetSectionByType(SHT_DYNSYM)); + TSection symstrSect(&elf, elf.GetSection(dynsymSect.GetLink())); + TSection dynverSect(&elf, elf.GetSectionByType(SHT_GNU_versym)); + + for (size_t i = 0, c = dynsymSect.GetEntryCount(); i < c; ++i) { + Elf64_Sym* sym = dynsymSect.GetEntry<Elf64_Sym>(i); + Elf64_Half* ver = dynverSect.GetEntry<Elf64_Half>(i); + for (auto aux : patchAux) { + if (*ver == aux->vna_other) { + *ver = 0; + verboseOut << "Symbol " << i << ": " << symstrSect.GetStr(sym->st_name) + << "@" << verStrings.GetStr(aux->vna_name) << " version removed" << Endl; + } + } + } + + for (auto aux : patchAux) { + TStringBuf name = verStrings.GetStr(aux->vna_name); + aux->vna_name = patchFromAux->vna_name; + aux->vna_hash = patchFromAux->vna_hash; + verboseOut << "Version dependence " << name << " [" << aux->vna_other + << "] patched from " << patchFrom << " [" << patchFromAux->vna_other << "]" << Endl; + } +} + +void PatchGnuUnique(const TString& path, IOutputStream& verboseOut) { + TElf elf(path); + + for (Elf64_Shdr* it = elf.GetSectionBegin(), *end = elf.GetSectionEnd(); it != end; ++it) { + if (it->sh_type == SHT_SYMTAB) { + + TSection section{&elf, it}; + verboseOut << "Found symbol section [" << section.GetName() << ']' << Endl; + + for (size_t i = 0, count = section.GetEntryCount(); i < count; ++i) { + Elf64_Sym* symbol = section.GetEntry<Elf64_Sym>(i); + auto& info = symbol->st_info; + + if (ELF64_ST_BIND(info) == STB_GNU_UNIQUE) { + verboseOut << "Found GNU unique symbol #" << i << Endl; + info = ELF64_ST_INFO(STB_GLOBAL, ELF64_ST_TYPE(info)); + } + } + } + } +} + +int main(int argc, char* argv[]) { + bool verbose = false; + bool rewrite_unique = false; + + using namespace NLastGetopt; + + TOpts opts = NLastGetopt::TOpts::Default(); + opts.AddHelpOption(); + + opts.AddLongOption('v', "verbose").NoArgument().StoreValue(&verbose, true); + opts.AddLongOption('u', "rewrite-gnu-unique", "Change STB_GNU_UNIQUE to STB_GLOBAL").NoArgument().StoreValue(&rewrite_unique, true); + + opts.SetFreeArgsMin(1); + opts.SetFreeArgTitle(0, "<file>", "File"); + + TOptsParseResult res(&opts, argc, argv); TVector<TString> files = res.GetFreeArgs(); - + IOutputStream& verboseOut = verbose ? Cout : Cnull; - - bool first = true; - for (auto path : files) { - - if (!IsElf(path)) { - continue; - } - - if (!first) { - verboseOut << Endl; - } - first = false; - - verboseOut << "Patching " << path << Endl; - - try { - if (rewrite_unique) { - PatchGnuUnique(path, verboseOut); - } else { - Patch(path, "libc.so.6", verboseOut); - Patch(path, "libm.so.6", verboseOut); - } - } catch (const yexception& e) { - Cerr << "Patching failed: " << e.what() << Endl; - } - } - - return 0; -} + + bool first = true; + for (auto path : files) { + + if (!IsElf(path)) { + continue; + } + + if (!first) { + verboseOut << Endl; + } + first = false; + + verboseOut << "Patching " << path << Endl; + + try { + if (rewrite_unique) { + PatchGnuUnique(path, verboseOut); + } else { + Patch(path, "libc.so.6", verboseOut); + Patch(path, "libm.so.6", verboseOut); + } + } catch (const yexception& e) { + Cerr << "Patching failed: " << e.what() << Endl; + } + } + + return 0; +} diff --git a/tools/fix_elf/patch.h b/tools/fix_elf/patch.h index c3dcd24224..6a30aba4ea 100644 --- a/tools/fix_elf/patch.h +++ b/tools/fix_elf/patch.h @@ -1,175 +1,175 @@ -#pragma once - +#pragma once + #include "elf.h" - + #include <util/generic/string.h> -#include <util/stream/file.h> -#include <util/system/filemap.h> - -namespace NElf { - -template<typename TTo, typename TFrom> -inline TTo Offset(TFrom from, size_t off) { - return reinterpret_cast<TTo>(reinterpret_cast<char*>(from) + off); -} - +#include <util/stream/file.h> +#include <util/system/filemap.h> + +namespace NElf { + +template<typename TTo, typename TFrom> +inline TTo Offset(TFrom from, size_t off) { + return reinterpret_cast<TTo>(reinterpret_cast<char*>(from) + off); +} + bool IsElf(const TString& path); - -class TElf { -public: + +class TElf { +public: TElf(const TString& path) - : Map(path, TFileMap::oRdWr) - { - Map.Map(0, Map.Length()); - Begin = reinterpret_cast<char*>(Map.Ptr()); - + : Map(path, TFileMap::oRdWr) + { + Map.Map(0, Map.Length()); + Begin = reinterpret_cast<char*>(Map.Ptr()); + if (Map.Length() < static_cast<i64>(sizeof(Elf64_Ehdr)) || TStringBuf(Begin, SELFMAG) != ELFMAG) { - ythrow yexception() << path << " is not an ELF file"; - } - } - + ythrow yexception() << path << " is not an ELF file"; + } + } + Elf64_Ehdr* GetHeader() const noexcept { - return reinterpret_cast<Elf64_Ehdr*>(Begin); - } - + return reinterpret_cast<Elf64_Ehdr*>(Begin); + } + char* GetPtr(size_t offset = 0) const noexcept { - return Begin + offset; - } - - Elf64_Shdr* GetSectionByType(Elf64_Word type) const { + return Begin + offset; + } + + Elf64_Shdr* GetSectionByType(Elf64_Word type) const { Elf64_Shdr* r = nullptr; - - for (Elf64_Shdr* p = GetSectionBegin(), *end = GetSectionEnd(); p != end; ++p) { - if (p->sh_type == type) { - if (r) { - ythrow yexception() << "More than one section of type " << type << Endl; - } - - r = p; - } - } - - return r; - } - + + for (Elf64_Shdr* p = GetSectionBegin(), *end = GetSectionEnd(); p != end; ++p) { + if (p->sh_type == type) { + if (r) { + ythrow yexception() << "More than one section of type " << type << Endl; + } + + r = p; + } + } + + return r; + } + size_t GetSectionCount() const noexcept { - size_t count = GetHeader()->e_shnum; - if (count == 0) { - count = GetSection(0)->sh_size; - } - - return count; - } - + size_t count = GetHeader()->e_shnum; + if (count == 0) { + count = GetSection(0)->sh_size; + } + + return count; + } + Elf64_Shdr* GetSectionBegin() const noexcept { - return reinterpret_cast<Elf64_Shdr*>(Begin + GetHeader()->e_shoff); - } - + return reinterpret_cast<Elf64_Shdr*>(Begin + GetHeader()->e_shoff); + } + Elf64_Shdr* GetSectionEnd() const noexcept { - return reinterpret_cast<Elf64_Shdr*>(Begin + GetHeader()->e_shoff) + GetSectionCount(); - } - + return reinterpret_cast<Elf64_Shdr*>(Begin + GetHeader()->e_shoff) + GetSectionCount(); + } + Elf64_Shdr* GetSection(size_t i) const noexcept { - return GetSectionBegin() + i; - } - - Elf64_Shdr* GetSectionsNameSection() const noexcept { - size_t index = GetHeader()->e_shstrndx; - if (index == SHN_XINDEX) { - index = GetSection(0)->sh_link; - } - return GetSection(index); - } - -private: - TFileMap Map; - char* Begin; -}; - -class TSection { -public: - TSection(TElf* elf, Elf64_Shdr* this_) - : Elf(elf) - , This(this_) - { - } - + return GetSectionBegin() + i; + } + + Elf64_Shdr* GetSectionsNameSection() const noexcept { + size_t index = GetHeader()->e_shstrndx; + if (index == SHN_XINDEX) { + index = GetSection(0)->sh_link; + } + return GetSection(index); + } + +private: + TFileMap Map; + char* Begin; +}; + +class TSection { +public: + TSection(TElf* elf, Elf64_Shdr* this_) + : Elf(elf) + , This(this_) + { + } + bool IsNull() const noexcept { - return !This; - } - + return !This; + } + char* GetPtr(size_t offset = 0) const noexcept { - return Elf->GetPtr(This->sh_offset) + offset; - } - + return Elf->GetPtr(This->sh_offset) + offset; + } + TStringBuf GetStr(size_t offset) const noexcept { - return GetPtr(offset); - } - + return GetPtr(offset); + } + TStringBuf GetName() const noexcept { - return TSection{Elf, Elf->GetSectionsNameSection()}.GetPtr(This->sh_name); - } - + return TSection{Elf, Elf->GetSectionsNameSection()}.GetPtr(This->sh_name); + } + size_t GetLink() const noexcept { - return This->sh_link; - } - + return This->sh_link; + } + size_t GetSize() const noexcept { - return This->sh_size; - } - + return This->sh_size; + } + size_t GetEntryCount() const noexcept { - return GetSize() / This->sh_entsize; - } - - template<typename TTo = char> + return GetSize() / This->sh_entsize; + } + + template<typename TTo = char> TTo* GetEntry(size_t i) const noexcept { - return reinterpret_cast<TTo*>(GetPtr(i * This->sh_entsize)); - } - -private: - TElf* Elf; - Elf64_Shdr* This; -}; - -class TVerneedSection : public TSection { -public: - TVerneedSection(TElf* elf) - : TSection(elf, elf->GetSectionByType(SHT_GNU_verneed)) - { - } - + return reinterpret_cast<TTo*>(GetPtr(i * This->sh_entsize)); + } + +private: + TElf* Elf; + Elf64_Shdr* This; +}; + +class TVerneedSection : public TSection { +public: + TVerneedSection(TElf* elf) + : TSection(elf, elf->GetSectionByType(SHT_GNU_verneed)) + { + } + Elf64_Verneed* GetFirstVerneed() const noexcept { - if (!GetSize()) { + if (!GetSize()) { return nullptr; - } - - return reinterpret_cast<Elf64_Verneed*>(GetPtr()); - } - + } + + return reinterpret_cast<Elf64_Verneed*>(GetPtr()); + } + Elf64_Verneed* GetNextVerneed(Elf64_Verneed* v) const noexcept { - if (!v->vn_next) { + if (!v->vn_next) { return nullptr; - } - - return Offset<Elf64_Verneed*>(v, v->vn_next); - } - + } + + return Offset<Elf64_Verneed*>(v, v->vn_next); + } + Elf64_Vernaux* GetFirstVernaux(Elf64_Verneed* v) const noexcept { - if (!v->vn_cnt) { + if (!v->vn_cnt) { return nullptr; - } - - return Offset<Elf64_Vernaux*>(v, v->vn_aux); - } - + } + + return Offset<Elf64_Vernaux*>(v, v->vn_aux); + } + Elf64_Vernaux* GetNextVernaux(Elf64_Vernaux* v) const noexcept { - if (!v->vna_next) { + if (!v->vna_next) { return nullptr; - } - - return Offset<Elf64_Vernaux*>(v, v->vna_next); - } -}; - -} + } + + return Offset<Elf64_Vernaux*>(v, v->vna_next); + } +}; + +} diff --git a/tools/fix_elf/ya.make b/tools/fix_elf/ya.make index 747323d868..16f9514f7b 100644 --- a/tools/fix_elf/ya.make +++ b/tools/fix_elf/ya.make @@ -1,13 +1,13 @@ -OWNER(somov) - +OWNER(somov) + IF (USE_PREBUILT_TOOLS) INCLUDE(${ARCADIA_ROOT}/build/prebuilt/tools/fix_elf/ya.make.prebuilt) ENDIF() - + IF (NOT PREBUILT) INCLUDE(${ARCADIA_ROOT}/tools/fix_elf/bin/ya.make) ENDIF() - + RECURSE( bin ) diff --git a/tools/ya.make b/tools/ya.make index 51a6b8b426..73a5f27426 100644 --- a/tools/ya.make +++ b/tools/ya.make @@ -40,7 +40,7 @@ RECURSE( fast_diff fastcksum filter_nonucs2 - fix_elf + fix_elf fml_sweeper_api frq_index_print geo |