| 108 | }; |
| 109 | |
| 110 | void Patch(const TString& path, const TString& library, IOutputStream& verboseOut) { |
| 111 | TElf elf(path); |
| 112 | |
| 113 | TVerneedSection verneedSect(&elf); |
| 114 | if (verneedSect.IsNull()) { |
| 115 | verboseOut << "No symbol versions section" << Endl; |
| 116 | return; |
| 117 | } |
| 118 | |
| 119 | TSection verStrings(&elf, elf.GetSection(verneedSect.GetLink())); |
| 120 | |
| 121 | TStringBuf skipFrom("GLIBC_2.14"); |
| 122 | TStringBuf patchFrom("GLIBC_2.2.5"); |
| 123 | |
| 124 | TVector<Elf64_Vernaux*> patchAux; |
| 125 | |
| 126 | Elf64_Vernaux* patchFromAux = nullptr; |
| 127 | |
| 128 | Elf64_Verneed* verneed = verneedSect.GetFirstVerneed(); |
| 129 | while (verneed) { |
| 130 | |
| 131 | TStringBuf file = verStrings.GetStr(verneed->vn_file); |
| 132 | verboseOut << file; |
| 133 | |
| 134 | if (file != library) { |
| 135 | verboseOut << " skipped" << Endl; |
| 136 | |
| 137 | } else { |
| 138 | verboseOut << Endl; |
| 139 | |
| 140 | Elf64_Vernaux* vernaux = verneedSect.GetFirstVernaux(verneed); |
| 141 | while (vernaux) { |
| 142 | |
| 143 | TStringBuf name = verStrings.GetStr(vernaux->vna_name); |
| 144 | verboseOut << "\t" << name; |
| 145 | |
| 146 | if (!patchFromAux && name == patchFrom) { |
| 147 | verboseOut << " taken as patch source" << Endl; |
| 148 | patchFromAux = vernaux; |
| 149 | |
| 150 | } else { |
| 151 | |
| 152 | if (NumericStrCmp(name, skipFrom) < 0) { |
| 153 | verboseOut << " skipped" << Endl; |
| 154 | |
| 155 | } else { |
| 156 | verboseOut << " will be patched" << Endl; |
| 157 | patchAux.push_back(vernaux); |
| 158 | } |
| 159 | } |
| 160 | vernaux = verneedSect.GetNextVernaux(vernaux); |
| 161 | } |
| 162 | } |
| 163 | verneed = verneedSect.GetNextVerneed(verneed); |
| 164 | } |
| 165 | |
| 166 | if (patchAux.empty()) { |
| 167 | verboseOut << "Nothing to patch" << Endl; |
no test coverage detected