@@ -1668,66 +1668,67 @@ void Monkeypatcher::patch_after_mmap(RecordTask* t, remote_ptr<void> start,
16681668 return ;
16691669 }
16701670 }
1671+
16711672 ElfFileReader reader (open_fd, t->arch ());
1672- // Check for symbols first in the library itself, regardless of whether
1673- // there is a debuglink. For example, on Fedora 26, the .symtab and
1674- // .strtab sections are stripped from the debuginfo file for
1675- // libpthread.so.
1676- SymbolTable syms = reader.read_symbols (" .symtab" , " .strtab" );
1677- if (syms.size () == 0 ) {
1678- ScopedFd debug_fd = reader.open_debug_file (map.map .fsname ());
1679- if (debug_fd.is_open ()) {
1680- ElfFileReader debug_reader (debug_fd, t->arch ());
1681- syms = debug_reader.read_symbols (" .symtab" , " .strtab" );
1682- }
1683- }
1684- switch (t->arch ()) {
1685- case x86:
1686- case x86_64:
1687- for (size_t i = 0 ; i < syms.size (); ++i) {
1688- if (syms.is_name (i, " __elision_aconf" )) {
1689- static const int zero = 0 ;
1690- // Setting __elision_aconf.retry_try_xbegin to zero means that
1691- // pthread rwlocks don't try to use elision at all. See ELIDE_LOCK
1692- // in glibc's elide.h.
1693- set_and_record_bytes (t, reader, syms.addr (i) + 8 , &zero, sizeof (zero),
1694- start, size, offset_bytes, prot);
1695- }
1696- if (syms.is_name (i, " elision_init" )) {
1697- // Make elision_init return without doing anything. This means
1698- // the __elision_available and __pthread_force_elision flags will
1699- // remain zero, disabling elision for mutexes. See glibc's
1700- // elision-conf.c.
1701- static const uint8_t ret = 0xC3 ;
1702- set_and_record_bytes (t, reader, syms.addr (i), &ret, sizeof (ret), start,
1703- size, offset_bytes, prot);
1704- }
1705- // The following operations can only be applied once because after the
1706- // patch is applied the code no longer matches the expected template.
1707- // For replaying a replay to work, we need to only apply these changes
1708- // during a real exec, not during the mmap operations performed when rr
1709- // replays an exec.
1710- if (mode == MMAP_EXEC &&
1711- (syms.is_name (i, " _dl_runtime_resolve_fxsave" ) ||
1712- syms.is_name (i, " _dl_runtime_resolve_xsave" ) ||
1713- syms.is_name (i, " _dl_runtime_resolve_xsavec" ))) {
1714- patch_dl_runtime_resolve (t, reader, syms.addr (i), start, size,
1715- offset_bytes, prot);
1673+ auto patch_with_symbols = [&](ElfFileReader& sym_reader) -> void {
1674+ SymbolTable syms = sym_reader.read_symbols (" .symtab" , " .strtab" );
1675+ switch (t->arch ()) {
1676+ case x86:
1677+ case x86_64:
1678+ for (size_t i = 0 ; i < syms.size (); ++i) {
1679+ if (syms.is_name (i, " __elision_aconf" )) {
1680+ static const int zero = 0 ;
1681+ // Setting __elision_aconf.retry_try_xbegin to zero means that
1682+ // pthread rwlocks don't try to use elision at all. See ELIDE_LOCK
1683+ // in glibc's elide.h.
1684+ set_and_record_bytes (t, reader, syms.addr (i) + 8 , &zero, sizeof (zero),
1685+ start, size, offset_bytes, prot);
1686+ }
1687+ if (syms.is_name (i, " elision_init" )) {
1688+ // Make elision_init return without doing anything. This means
1689+ // the __elision_available and __pthread_force_elision flags will
1690+ // remain zero, disabling elision for mutexes. See glibc's
1691+ // elision-conf.c.
1692+ static const uint8_t ret = 0xC3 ;
1693+ set_and_record_bytes (t, reader, syms.addr (i), &ret, sizeof (ret), start,
1694+ size, offset_bytes, prot);
1695+ }
1696+ // The following operations can only be applied once because after the
1697+ // patch is applied the code no longer matches the expected template.
1698+ // For replaying a replay to work, we need to only apply these changes
1699+ // during a real exec, not during the mmap operations performed when rr
1700+ // replays an exec.
1701+ if (mode == MMAP_EXEC &&
1702+ (syms.is_name (i, " _dl_runtime_resolve_fxsave" ) ||
1703+ syms.is_name (i, " _dl_runtime_resolve_xsave" ) ||
1704+ syms.is_name (i, " _dl_runtime_resolve_xsavec" ))) {
1705+ patch_dl_runtime_resolve (t, reader, syms.addr (i), start, size,
1706+ offset_bytes, prot);
1707+ }
17161708 }
1717- }
1718- break ;
1719- case aarch64:
1720- for ( size_t i = 0 ; i < syms.size (); ++i ) {
1721- if (syms. is_name (i, " __aarch64_have_lse_atomics" )) {
1722- // Patch the __aarch64_have_lse_atomics variable to ensure that LSE
1723- // atomics are always used even if init_lse_atomics hasn't been called
1724- // yet (or at all).
1725- static const char one = 1 ;
1726- set_and_record_bytes (t, reader, syms. addr (i), &one, sizeof (one),
1727- start, size, offset_bytes, prot);
1709+ break ;
1710+ case aarch64:
1711+ for ( size_t i = 0 ; i < syms. size (); ++i) {
1712+ if ( syms.is_name (i, " __aarch64_have_lse_atomics " ) ) {
1713+ // Patch the __aarch64_have_lse_atomics variable to ensure that LSE
1714+ // atomics are always used even if init_lse_atomics hasn't been called
1715+ // yet (or at all).
1716+ static const char one = 1 ;
1717+ set_and_record_bytes (t, reader, syms. addr (i), &one, sizeof (one),
1718+ start, size, offset_bytes, prot);
1719+ }
17281720 }
1729- }
1730- break ;
1721+ break ;
1722+ }
1723+ };
1724+ // Check for symbols in the library itself as well as in debuginfo.
1725+ // For example, on Fedora 26, the .symtab and .strtab sections are stripped
1726+ // from the debuginfo file for libpthread.so.
1727+ patch_with_symbols (reader);
1728+ ScopedFd debug_fd = reader.open_debug_file (map.map .fsname ());
1729+ if (debug_fd.is_open ()) {
1730+ ElfFileReader debug_reader (debug_fd, t->arch ());
1731+ patch_with_symbols (debug_reader);
17311732 }
17321733}
17331734
0 commit comments