Skip to content

Commit 907c020

Browse files
committed
Small cleanups to replaceNeeded
No semantic changes, but I noticed some small errors in the DT_NEEDED handling loop while I was adding the .gnu.version_r handling, so might as well fix them while I'm here.
1 parent 25cb97c commit 907c020

File tree

1 file changed

+37
-14
lines changed

1 file changed

+37
-14
lines changed

src/patchelf.cc

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,13 +1274,13 @@ void ElfFile<ElfFileParamNames>::replaceNeeded(map<string, string>& libs)
12741274

12751275
// technically, the string referred by d_val could be used otherwise, too (although unlikely)
12761276
// we'll therefore add a new string
1277-
debug("resizing .dynstr ...");
1277+
debug("resizing .dynstr ...\n");
12781278

12791279
string & newDynStr = replaceSection(".dynstr",
12801280
rdi(shdrDynStr.sh_size) + replacement.size() + 1 + dynStrAddedBytes);
12811281
setSubstr(newDynStr, rdi(shdrDynStr.sh_size) + dynStrAddedBytes, replacement + '\0');
12821282

1283-
dyn->d_un.d_val = shdrDynStr.sh_size + dynStrAddedBytes;
1283+
wri(dyn->d_un.d_val, rdi(shdrDynStr.sh_size) + dynStrAddedBytes);
12841284

12851285
dynStrAddedBytes += replacement.size() + 1;
12861286

@@ -1299,23 +1299,46 @@ void ElfFile<ElfFileParamNames>::replaceNeeded(map<string, string>& libs)
12991299
// be replaced.
13001300

13011301
if (verNeedNum) {
1302-
Elf_Shdr & shdrVersionR = findSection3(".gnu.version_r");
1303-
// The filename strings in the .gnu.version_r aren't necessarily in
1304-
// .dynstr -- we have to look at ->sh_link to find the section with
1305-
// the strings in it.
1306-
Elf_Shdr & shdrVersionRStrings = *shdrs[rdi(shdrVersionR->sh_link)];
1302+
Elf_Shdr & shdrVersionR = findSection(".gnu.version_r");
1303+
// The filename strings in the .gnu.version_r are different from the
1304+
// ones in .dynamic: instead of being in .dynstr, they're in some
1305+
// arbitrary section and we have to look in ->sh_link to figure out
1306+
// which one.
1307+
Elf_Shdr & shdrVersionRStrings = shdrs[rdi(shdrVersionR.sh_link)];
1308+
// this is where we find the actual filename strings
1309+
char * verStrTab = (char *) contents + rdi(shdrVersionRStrings.sh_offset);
1310+
// and we also need the name of the section containing the strings, so
1311+
// that we can pass it to replaceSection
1312+
string versionRStringsSName = getSectionName(shdrVersionRStrings);
1313+
1314+
debug("found .gnu.version_r with %i entries, strings in %s\n", verNeedNum, versionRStringsSName.c_str());
1315+
1316+
unsigned int verStrAddedBytes = 0;
13071317

13081318
Elf_Verneed * need = (Elf_Verneed *) (contents + rdi(shdrVersionR.sh_offset));
13091319
while (verNeedNum > 0) {
1320+
char * file = verStrTab + rdi(need->vn_file);
1321+
if (libs.find(file) != libs.end()) {
1322+
const string & replacement = libs[file];
13101323

1311-
// XX check need->vn_file, which is an offset into the
1312-
// shdrVersionRStrings section
1313-
// if if matches one of the entries in `libs`, then use
1314-
// replaceSection logic like that above to add the new string to
1315-
// this section and change vn_file
1324+
debug("replacing .gnu.version_r entry `%s' with `%s'\n", file, replacement.c_str());
1325+
debug("resizing string section %s ...\n", versionRStringsSName.c_str());
13161326

1317-
need = (Elf_Verneed *) (contents + rdi(need->vn_next));
1318-
verNeedNum--;
1327+
string & newVerDynStr = replaceSection(versionRStringsSName,
1328+
rdi(shdrVersionRStrings.sh_size) + replacement.size() + 1 + verStrAddedBytes);
1329+
setSubstr(newVerDynStr, rdi(shdrVersionRStrings.sh_size) + verStrAddedBytes, replacement + '\0');
1330+
1331+
wri(need->vn_file, rdi(shdrVersionRStrings.sh_size) + verStrAddedBytes);
1332+
1333+
verStrAddedBytes += replacement.size() + 1;
1334+
1335+
changed = true;
1336+
} else {
1337+
debug("keeping .gnu.version_r entry `%s'\n", file);
1338+
}
1339+
// the Elf_Verneed structures form a linked list, so jump to next entry
1340+
need = (Elf_Verneed *) (contents + rdi(shdrVersionR.sh_offset) + rdi(need->vn_next));
1341+
--verNeedNum;
13191342
}
13201343
}
13211344
}

0 commit comments

Comments
 (0)