diff --git a/src/binfmt_rto/binfmt_rto.c b/src/binfmt_rto/binfmt_rto.c index 8d7836605ef6520a3d9d803b5eb12e9e061f4b97..cd511d88e8da0f8cdaa7c327bd9e8a81155a3547 100644 --- a/src/binfmt_rto/binfmt_rto.c +++ b/src/binfmt_rto/binfmt_rto.c @@ -1243,8 +1243,11 @@ load_rto: printk("replace rto file fail, %d\n", ret); goto out; } - } else if (debug) { + } + if (!is_rto_format) goto out; + if (debug) { + printk("exec in rto mode, is_rto_format %d\n", is_rto_format); } #endif diff --git a/src/elf_hugepage.c b/src/elf_hugepage.c index be59dbd83b496f02818ee512e25f5c207c51ddaa..f670f3862da4862cac86331b9442df00fb02848a 100644 --- a/src/elf_hugepage.c +++ b/src/elf_hugepage.c @@ -51,20 +51,31 @@ #define OS_SPECIFIC_FLAG_HUGEPAGE EF_X86_64_HUGEPAGE #define OS_SPECIFIC_FLAG_RTO EF_X86_64_RTO #endif -#define OS_SPECIFIC_MASK (0xffffffffU ^ OS_SPECIFIC_FLAG_SYMBOLIC_LINK ^ OS_SPECIFIC_FLAG_HUGEPAGE) +#define OS_SPECIFIC_MASK (0xffffffffU ^ OS_SPECIFIC_FLAG_SYMBOLIC_LINK ^ OS_SPECIFIC_FLAG_HUGEPAGE ^ OS_SPECIFIC_FLAG_RTO) -static void _elf_set_symbolic_link(elf_file_t *ef, bool state) +static int _elf_set_flags(char *path, unsigned int flags) { - if (state) { - ef->hdr->e_flags |= OS_SPECIFIC_FLAG_SYMBOLIC_LINK; - } else { - ef->hdr->e_flags &= OS_SPECIFIC_MASK; + elf_file_t *ef = malloc(sizeof(elf_file_t)); + if (ef == NULL) { + SI_LOG_ERR("malloc fail\n"); + return -1; } + + int ret = elf_read_file(path, ef, false); + if (ret != 0) { + return -1; + } + + ef->hdr->e_flags |= flags; + + elf_close_file(ef); + free(ef); + ef = NULL; + return 0; } -int elf_set_symbolic_link(char *path, bool state) +static int _elf_unset_flags(char *path, unsigned int flags) { - // this memory will free by process exit elf_file_t *ef = malloc(sizeof(elf_file_t)); if (ef == NULL) { SI_LOG_ERR("malloc fail\n"); @@ -76,14 +87,30 @@ int elf_set_symbolic_link(char *path, bool state) return -1; } - _elf_set_symbolic_link(ef, state); + ef->hdr->e_flags &= (0xffffffffU ^ flags); - close(ef->fd); - // This process is a oneshot process. The release of variable ef depends - // on the process exit. + elf_close_file(ef); + free(ef); + ef = NULL; return 0; } +int elf_set_symbolic_link(char *path, bool state) +{ + if (state) { + return _elf_set_flags(path, OS_SPECIFIC_FLAG_SYMBOLIC_LINK); + } + return _elf_unset_flags(path, OS_SPECIFIC_FLAG_SYMBOLIC_LINK); +} + +int elf_set_rto(char *path, bool state) +{ + if (state) { + return _elf_set_flags(path, OS_SPECIFIC_FLAG_RTO); + } + return _elf_unset_flags(path, OS_SPECIFIC_FLAG_RTO); +} + void elf_set_hugepage(elf_link_t *elf_link) { int i, exec_only = 1; @@ -103,4 +130,3 @@ void elf_set_hugepage(elf_link_t *elf_link) ef->hdr->e_flags |= OS_SPECIFIC_FLAG_HUGEPAGE; } - diff --git a/src/elf_hugepage.h b/src/elf_hugepage.h index 94f1b909ebec0cbab836c7c262ef501dde6c0da5..7e7d7d83aa6666f246726872b5ad2591a057978b 100644 --- a/src/elf_hugepage.h +++ b/src/elf_hugepage.h @@ -6,5 +6,6 @@ void elf_set_hugepage(elf_link_t *elf_link); int elf_set_symbolic_link(char *path, bool state); +int elf_set_rto(char *path, bool state); #endif /* _ELF_HUGEPAGE_H */ diff --git a/src/elf_read_elf.c b/src/elf_read_elf.c index 2179227889ab6ca2d6072c41adaca2dc90fd21e7..7d9ecab56b34c3ebf16e79a0310d60e9cbdf7769 100644 --- a/src/elf_read_elf.c +++ b/src/elf_read_elf.c @@ -538,7 +538,7 @@ int elf_read_file(char *file_name, elf_file_t *ef, bool is_readonly) return 0; } -static void _elf_close_file(elf_file_t *ef) +void elf_close_file(elf_file_t *ef) { close(ef->fd); if (ef->file_name != NULL) { @@ -563,7 +563,7 @@ static int read_relocation_file(char *file_name, elf_file_t *ef) // save old build id memcpy(old_build_id, ef->build_id, BUILD_ID_LEN); - _elf_close_file(ef); + elf_close_file(ef); SI_LOG_DEBUG("read extern relocations\n"); diff --git a/src/elf_read_elf.h b/src/elf_read_elf.h index c90ccda350289730798b0cac4c39db11fd3e957f..c270a710a4a6c582ebd16a4eddf4d637fa94901f 100644 --- a/src/elf_read_elf.h +++ b/src/elf_read_elf.h @@ -99,6 +99,7 @@ void elf_read_elf_phdr(elf_file_t *ef); void elf_read_elf_sections(elf_file_t *ef); int elf_read_file(char *file_name, elf_file_t *elf, bool is_readonly); int elf_read_file_relocation(char *file_name, elf_file_t *ef); +void elf_close_file(elf_file_t *ef); // debug void elf_show_dynsym(elf_file_t *ef); diff --git a/src/main.c b/src/main.c index d276985d46692eaef53039dfae63a8f17ad4e8bc..cde1e5ae4abdad409b14b67bf04e78c59071eebf 100644 --- a/src/main.c +++ b/src/main.c @@ -32,6 +32,8 @@ int main(int argc, char *argv[]) {"debug", no_argument, NULL, 'd'}, {"set", required_argument, NULL, 's'}, {"unset", required_argument, NULL, 'u'}, + {"set-rto", required_argument, NULL, '1'}, + {"unset-rto", required_argument, NULL, '0'}, {"hook", no_argument, NULL, 'h'}, {ELF_LINK_STATIC_S, no_argument, NULL, 'S'}, {ELF_LINK_STATIC_NOLIBC_S, no_argument, NULL, 'N'}, @@ -59,6 +61,20 @@ int main(int argc, char *argv[]) return -1; } return elf_set_symbolic_link(tmp, false); + case '1': + str_ret = realpath(optarg, tmp); + if (!str_ret) { + SI_LOG_ERR("get realpath fail: %s\n", optarg); + return -1; + } + return elf_set_rto(tmp, true); + case '0': + str_ret = realpath(optarg, tmp); + if (!str_ret) { + SI_LOG_ERR("get realpath fail: %s\n", optarg); + return -1; + } + return elf_set_rto(tmp, false); case 'h': elf_link->hook_func = true; SI_LOG_INFO("hook func\n"); diff --git a/tests/test_binfmt_rto/Makefile b/tests/test_binfmt_rto/Makefile index 09ae11ea9389db31702ce81775bc3cb5ed92b048..3a1a023b76709279570f7b3d7b8549f2e8e8b984 100644 --- a/tests/test_binfmt_rto/Makefile +++ b/tests/test_binfmt_rto/Makefile @@ -9,13 +9,18 @@ KO_DIR=$(ROOT_DIR)src/binfmt_rto all: test_ko link: - cp /usr/bin/bash bash_test_link + cp -f /usr/bin/bash bash_test_link $(SYSBOOST) --set bash_test_link readelf -W -a bash_test_link > bash_test_link.link.elf test_ko: link make -C $(KO_DIR) install - cp /usr/bin/bash bash_test_link.rto + @echo ===test link=== + cp -f /usr/bin/bash bash_test_link.rto + ./bash_test_link -c "echo 1" + @echo ===test rto=== + $(SYSBOOST) --set-rto bash_test_link.rto + readelf -W -a bash_test_link.rto > bash_test_link.rto.elf ./bash_test_link -c "echo 1" env: