@@ -2228,7 +2228,7 @@ void ElfFile<ElfFileParamNames>::removeNeededVersion(const std::map<std::string,
2228
2228
auto & shdrVersionR = shdrs.at (idxVersionR);
2229
2229
Elf_Shdr & shdrVersionRStrings = shdrs.at (rdi (shdrVersionR.sh_link ));
2230
2230
2231
- auto spanVersyms = tryGetSectionSpan<Elf_Versym>( " .gnu.version " );
2231
+ auto mapOffset = rdi (shdrVersionR. sh_addr ) - rdi (shdrVersionR. sh_offset );
2232
2232
2233
2233
size_t verNeedNum = rdi (shdrVersionR.sh_info );
2234
2234
std::set<size_t > removedVersionIds;
@@ -2238,6 +2238,8 @@ void ElfFile<ElfFileParamNames>::removeNeededVersion(const std::map<std::string,
2238
2238
2239
2239
debug (" found .gnu.version_r with %i entries\n " , verNeedNum);
2240
2240
2241
+ bool removeEntireSection = false ;
2242
+
2241
2243
auto vn = (Elf_Verneed *)(fileContents->data () + rdi (shdrVersionR.sh_offset ));
2242
2244
Elf_Verneed * prevVn = nullptr ;
2243
2245
for (size_t i = 0 ; i < verNeedNum; ++i) {
@@ -2296,9 +2298,9 @@ void ElfFile<ElfFileParamNames>::removeNeededVersion(const std::map<std::string,
2296
2298
if (next) {
2297
2299
wri (shdrVersionR.sh_offset , rdi (shdrVersionR.sh_offset ) + next);
2298
2300
} else {
2299
- // FIXME: remove entire section?
2300
- wri (shdrVersionR.sh_offset , 0 );
2301
2301
wri (shdrVersionR.sh_size , 0 );
2302
+
2303
+ removeEntireSection = true ;
2302
2304
}
2303
2305
}
2304
2306
wri (shdrVersionR.sh_info , rdi (shdrVersionR.sh_info ) - 1 );
@@ -2313,20 +2315,40 @@ void ElfFile<ElfFileParamNames>::removeNeededVersion(const std::map<std::string,
2313
2315
vn = follow<Elf_Verneed>(vn, next);
2314
2316
}
2315
2317
}
2316
- // virtual address and file offset need to be the same for .gnu.version_r
2317
- shdrVersionR.sh_addr = shdrVersionR.sh_offset ;
2318
+
2319
+ // virtual address and file offset need to be the same
2320
+ if (!removeEntireSection) {
2321
+ wri (shdrVersionR.sh_addr , mapOffset + rdi (shdrVersionR.sh_offset ));
2322
+ }
2318
2323
2319
2324
if (auto shdrDynamic = tryFindSectionHeader (" .dynamic" )) {
2320
2325
auto dyn = (Elf_Dyn *)(fileContents->data () + rdi (shdrDynamic->get ().sh_offset ));
2321
2326
2322
- // keep DT_VERNEED and DT_VERNEEDNUM in sync, DT_VERNEEDNUM handled by rewriteHeaders
2327
+ // keep DT_VERNEED and DT_VERNEEDNUM in sync, DT_VERNEED handled by rewriteHeaders
2328
+ Elf_Dyn * last = dyn;
2323
2329
for ( ; rdi (dyn->d_tag ) != DT_NULL; dyn++) {
2324
2330
if (rdi (dyn->d_tag ) == DT_VERNEEDNUM) {
2325
- dyn->d_un .d_val = shdrVersionR.sh_info ;
2331
+ if (!removeEntireSection) {
2332
+ dyn->d_un .d_val = shdrVersionR.sh_info ;
2333
+ *last++ = *dyn;
2334
+ }
2335
+ } else if (rdi (dyn->d_tag ) == DT_VERNEED) {
2336
+ if (!removeEntireSection) {
2337
+ *last++ = *dyn;
2338
+ }
2339
+ } else if (rdi (dyn->d_tag ) == DT_VERSYM) {
2340
+ if (!removeEntireSection) {
2341
+ *last++ = *dyn;
2342
+ }
2343
+ } else {
2344
+ *last++ = *dyn;
2326
2345
}
2327
2346
}
2347
+ memset (last, 0 , sizeof (Elf_Dyn) * (dyn - last));
2328
2348
}
2329
2349
2350
+ auto spanVersyms = tryGetSectionSpan<Elf_Versym>(" .gnu.version" );
2351
+
2330
2352
if (spanVersyms) {
2331
2353
for (auto & versym : spanVersyms) {
2332
2354
if (removedVersionIds.count (versym)) {
@@ -2335,8 +2357,30 @@ void ElfFile<ElfFileParamNames>::removeNeededVersion(const std::map<std::string,
2335
2357
}
2336
2358
}
2337
2359
2338
- debug (" remaining entries in .gnu.version_r: %i\n " , rdi (shdrVersionR.sh_info ));
2339
- this ->rewriteSections (true );
2360
+ if (removeEntireSection) {
2361
+ debug (" removing .gnu.version_r and .gnu.version section\n " );
2362
+ wri (shdrVersionR.sh_type , SHT_NULL);
2363
+ auto idxVersion = getSectionIndex (" .gnu.version" );
2364
+ if (idxVersion) {
2365
+ auto & shdrVersion = shdrs.at (idxVersion);
2366
+ wri (shdrVersion.sh_type , SHT_NULL);
2367
+ memset (fileContents->data () + rdi (shdrVersion.sh_offset ), 0 , rdi (shdrVersion.sh_size ));
2368
+ wri (shdrVersion.sh_size , 0 );
2369
+ }
2370
+ } else {
2371
+ debug (" remaining entries in .gnu.version_r: %i\n " , rdi (shdrVersionR.sh_info ));
2372
+ }
2373
+
2374
+ // we did not change phdrAddress, rewrite it in place
2375
+ Elf_Addr phdrAddress;
2376
+ for (auto & phdr : phdrs) {
2377
+ if (rdi (phdr.p_type ) == PT_PHDR) {
2378
+ phdrAddress = rdi (phdr.p_vaddr );
2379
+ break ;
2380
+ }
2381
+ }
2382
+
2383
+ rewriteHeaders (phdrAddress);
2340
2384
}
2341
2385
2342
2386
template <ElfFileParams>
0 commit comments