From 58166321a5e801d25deb98e53aeb266a9e3f4cfa Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 29 May 2024 14:21:23 -0300 Subject: [PATCH 1/6] ArgvParser: Detect when IBT is being used Current upstream kernel relies on IBT security feature. When this is activated we can't rely on kallsyms to access private symbols. For now only propagate the information if IBT is enabled or anot to places where it can be used. Signed-off-by: Marcos Paulo de Souza --- libcextract/ArgvParser.cpp | 6 ++++++ libcextract/ArgvParser.hh | 7 +++++++ libcextract/Passes.cpp | 2 +- libcextract/Passes.hh | 4 ++++ libcextract/SymbolExternalizer.hh | 8 ++++++-- 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/libcextract/ArgvParser.cpp b/libcextract/ArgvParser.cpp index 990c75e..c0272ba 100644 --- a/libcextract/ArgvParser.cpp +++ b/libcextract/ArgvParser.cpp @@ -65,6 +65,7 @@ ArgvParser::ArgvParser(int argc, char **argv) DumpPasses(false), RenameSymbols(false), Kernel(false), + Ibt(false), DebuginfoPath(nullptr), IpaclonesPath(nullptr), SymversPath(nullptr), @@ -166,6 +167,11 @@ bool ArgvParser::Handle_Clang_Extract_Arg(const char *str) return false; } + if (!strcmp("-D__USE_IBT__", str)) { + Ibt = true; + return false; + } + if (prefix("-DCE_EXTRACT_FUNCTIONS=", str)) { FunctionsToExtract = Extract_Args(str); diff --git a/libcextract/ArgvParser.hh b/libcextract/ArgvParser.hh index 81b912e..83e48b7 100644 --- a/libcextract/ArgvParser.hh +++ b/libcextract/ArgvParser.hh @@ -84,6 +84,11 @@ class ArgvParser return Kernel; } + inline bool Has_Ibt(void) + { + return Ibt; + } + inline const char *Get_Debuginfo_Path(void) { return DebuginfoPath; @@ -140,6 +145,8 @@ class ArgvParser bool DumpPasses; bool RenameSymbols; bool Kernel; + /* If the file was compiled with IBT support */ + bool Ibt; const char *DebuginfoPath; const char *IpaclonesPath; diff --git a/libcextract/Passes.cpp b/libcextract/Passes.cpp index ca6ffa9..ecb8385 100644 --- a/libcextract/Passes.cpp +++ b/libcextract/Passes.cpp @@ -437,7 +437,7 @@ class FunctionExternalizerPass : public Pass virtual bool Run_Pass(PassManager::Context *ctx) { /* Issue externalization. */ - SymbolExternalizer externalizer(ctx->AST.get(), ctx->IA, ctx->DumpPasses); + SymbolExternalizer externalizer(ctx->AST.get(), ctx->IA, ctx->Ibt, ctx->DumpPasses); externalizer.Externalize_Symbols(ctx->Externalize); if (ctx->RenameSymbols) { /* The FuncExtractNames will be modified, as the function will be diff --git a/libcextract/Passes.hh b/libcextract/Passes.hh index 41a5ccb..06d5f56 100644 --- a/libcextract/Passes.hh +++ b/libcextract/Passes.hh @@ -53,6 +53,7 @@ class PassManager { DumpPasses(args.Should_Dump_Passes()), RenameSymbols(args.Should_Rename_Symbols()), Kernel(args.Is_Kernel()), + Ibt(args.Has_Ibt()), HeadersToExpand(args.Get_Headers_To_Expand()), ClangArgs(args.Get_Args_To_Clang()), DebuginfoPath(args.Get_Debuginfo_Path()), @@ -102,6 +103,9 @@ class PassManager { /** If the source code comes from Linux Kernel */ bool Kernel; + /** If the code was compiled with IBT support */ + bool Ibt; + /** Which includes we must expand? */ std::vector HeadersToExpand; diff --git a/libcextract/SymbolExternalizer.hh b/libcextract/SymbolExternalizer.hh index 9ba2234..4eb2172 100644 --- a/libcextract/SymbolExternalizer.hh +++ b/libcextract/SymbolExternalizer.hh @@ -182,11 +182,12 @@ class TextModifications class SymbolExternalizer { public: - SymbolExternalizer(ASTUnit *ast, InlineAnalysis &ia, bool dump = false) + SymbolExternalizer(ASTUnit *ast, InlineAnalysis &ia, bool ibt, bool dump = false) : AST(ast), MW(ast->getPreprocessor()), TM(ast, dump), - IA(ia) + IA(ia), + Ibt(ibt) { } @@ -284,4 +285,7 @@ class SymbolExternalizer /** Log of changed names. */ std::vector Log; + + /** Defines the method that a private symbol will be searched. */ + bool Ibt; }; From f2fd635f68e8c33d6492884652ebc0b686ce96e7 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Tue, 4 Jun 2024 17:15:00 -0300 Subject: [PATCH 2/6] Read KBUILD_MODNAME and pass it to SymbolExternalizer Signed-off-by: Marcos Paulo de Souza --- libcextract/ArgvParser.cpp | 9 +++++++++ libcextract/ArgvParser.hh | 6 ++++++ libcextract/Passes.cpp | 2 +- libcextract/Passes.hh | 4 ++++ libcextract/SymbolExternalizer.hh | 8 ++++++-- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/libcextract/ArgvParser.cpp b/libcextract/ArgvParser.cpp index c0272ba..617b503 100644 --- a/libcextract/ArgvParser.cpp +++ b/libcextract/ArgvParser.cpp @@ -172,6 +172,15 @@ bool ArgvParser::Handle_Clang_Extract_Arg(const char *str) return false; } + if (prefix("-DKBUILD_MODNAME=", str)) { + /* Avoid storing double quotes */ + PatchObject = Extract_Single_Arg(str); + PatchObject.erase(std::remove(PatchObject.begin(), PatchObject.end(), '\"' ), + PatchObject.end()); + + return false; + } + if (prefix("-DCE_EXTRACT_FUNCTIONS=", str)) { FunctionsToExtract = Extract_Args(str); diff --git a/libcextract/ArgvParser.hh b/libcextract/ArgvParser.hh index 83e48b7..02ddc04 100644 --- a/libcextract/ArgvParser.hh +++ b/libcextract/ArgvParser.hh @@ -89,6 +89,11 @@ class ArgvParser return Ibt; } + inline std::string Get_PatchObject(void) + { + return PatchObject; + } + inline const char *Get_Debuginfo_Path(void) { return DebuginfoPath; @@ -147,6 +152,7 @@ class ArgvParser bool Kernel; /* If the file was compiled with IBT support */ bool Ibt; + std::string PatchObject; const char *DebuginfoPath; const char *IpaclonesPath; diff --git a/libcextract/Passes.cpp b/libcextract/Passes.cpp index ecb8385..f1b6c34 100644 --- a/libcextract/Passes.cpp +++ b/libcextract/Passes.cpp @@ -437,7 +437,7 @@ class FunctionExternalizerPass : public Pass virtual bool Run_Pass(PassManager::Context *ctx) { /* Issue externalization. */ - SymbolExternalizer externalizer(ctx->AST.get(), ctx->IA, ctx->Ibt, ctx->DumpPasses); + SymbolExternalizer externalizer(ctx->AST.get(), ctx->IA, ctx->Ibt, ctx->PatchObject, ctx->DumpPasses); externalizer.Externalize_Symbols(ctx->Externalize); if (ctx->RenameSymbols) { /* The FuncExtractNames will be modified, as the function will be diff --git a/libcextract/Passes.hh b/libcextract/Passes.hh index 06d5f56..f60bf79 100644 --- a/libcextract/Passes.hh +++ b/libcextract/Passes.hh @@ -54,6 +54,7 @@ class PassManager { RenameSymbols(args.Should_Rename_Symbols()), Kernel(args.Is_Kernel()), Ibt(args.Has_Ibt()), + PatchObject(args.Get_PatchObject()), HeadersToExpand(args.Get_Headers_To_Expand()), ClangArgs(args.Get_Args_To_Clang()), DebuginfoPath(args.Get_Debuginfo_Path()), @@ -106,6 +107,9 @@ class PassManager { /** If the code was compiled with IBT support */ bool Ibt; + /** Object that will be patched. */ + std::string PatchObject; + /** Which includes we must expand? */ std::vector HeadersToExpand; diff --git a/libcextract/SymbolExternalizer.hh b/libcextract/SymbolExternalizer.hh index 4eb2172..a8e4609 100644 --- a/libcextract/SymbolExternalizer.hh +++ b/libcextract/SymbolExternalizer.hh @@ -182,12 +182,13 @@ class TextModifications class SymbolExternalizer { public: - SymbolExternalizer(ASTUnit *ast, InlineAnalysis &ia, bool ibt, bool dump = false) + SymbolExternalizer(ASTUnit *ast, InlineAnalysis &ia, bool ibt, std::string patch_object, bool dump = false) : AST(ast), MW(ast->getPreprocessor()), TM(ast, dump), IA(ia), - Ibt(ibt) + Ibt(ibt), + PatchObject(patch_object) { } @@ -288,4 +289,7 @@ class SymbolExternalizer /** Defines the method that a private symbol will be searched. */ bool Ibt; + + /* Name of the object that will be patched. */ + std::string PatchObject; }; From 51dab0e861762735efead5bba8b9d1385628b940 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Tue, 4 Jun 2024 17:16:43 -0300 Subject: [PATCH 3/6] SymbolExternalizer: Include livepatch.h if IBT was set This is necessary due to kernel requirements. Signed-off-by: Marcos Paulo de Souza --- libcextract/SymbolExternalizer.cpp | 13 +++++++++++++ libcextract/SymbolExternalizer.hh | 1 + 2 files changed, 14 insertions(+) diff --git a/libcextract/SymbolExternalizer.cpp b/libcextract/SymbolExternalizer.cpp index 80036a9..d41eb26 100644 --- a/libcextract/SymbolExternalizer.cpp +++ b/libcextract/SymbolExternalizer.cpp @@ -520,6 +520,11 @@ void SymbolExternalizer::Remove_Text(const SourceRange &range, int prio) Replace_Text(range, "", prio); } +void SymbolExternalizer::Insert_Text(const SourceRange &range, StringRef text, int prio) +{ + Replace_Text(range, text, prio); +} + VarDecl *SymbolExternalizer::Create_Externalized_Var(DeclaratorDecl *decl, const std::string &name) { /* Hack a new Variable Declaration node in which holds the address of our @@ -892,6 +897,14 @@ void SymbolExternalizer::Externalize_Symbol(const std::string &to_externalize) void SymbolExternalizer::Externalize_Symbols(std::vector const &to_externalize_array) { + if (Ibt) { + SourceManager &sm = AST->getSourceManager(); + FileID fi = sm.getMainFileID(); + SourceLocation sl = sm.getLocForStartOfFile(fi); + SourceRange sr(sl, sl); + Insert_Text(sr, "#include ", 1000); + } + for (const std::string &to_externalize : to_externalize_array) { Externalize_Symbol(to_externalize); } diff --git a/libcextract/SymbolExternalizer.hh b/libcextract/SymbolExternalizer.hh index a8e4609..b2e943e 100644 --- a/libcextract/SymbolExternalizer.hh +++ b/libcextract/SymbolExternalizer.hh @@ -271,6 +271,7 @@ class SymbolExternalizer used in case that there are two replacements to the same piece of text. */ void Replace_Text(const SourceRange &range, StringRef new_name, int priority); void Remove_Text(const SourceRange &range, int priority); + void Insert_Text(const SourceRange &range, StringRef text, int priority); /** AST in analysis. */ ASTUnit *AST; From e83d41ee50f0ddca7ff2654a5275e7804d48da09 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Tue, 4 Jun 2024 15:06:36 -0300 Subject: [PATCH 4/6] SymbolExternalizer: Apply transformations needed by IBT For IBT enabled kernels, private symbols need a special macro that to allow klp-convert to create relocations to them. Signed-off-by: Marcos Paulo de Souza --- libcextract/SymbolExternalizer.cpp | 35 +++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/libcextract/SymbolExternalizer.cpp b/libcextract/SymbolExternalizer.cpp index d41eb26..682a42a 100644 --- a/libcextract/SymbolExternalizer.cpp +++ b/libcextract/SymbolExternalizer.cpp @@ -553,6 +553,10 @@ VarDecl *SymbolExternalizer::Create_Externalized_Var(DeclaratorDecl *decl, const /* Create a type that is a pointer to the externalized object's type. */ QualType pointer_to = astctx.getPointerType(decl->getType()); + /* For IBT, create an extern variable with the same type from the original */ + if (Ibt) + pointer_to = decl->getType(); + /* Get context of decl. */ DeclContext *decl_ctx; @@ -563,13 +567,22 @@ VarDecl *SymbolExternalizer::Create_Externalized_Var(DeclaratorDecl *decl, const decl_ctx = decl->getDeclContext(); } + /* + * For normal externalization, create a static variable. When dealing with IBT + * restrictions, create an extern variable that will be sorted out later by + * the code that is using it, like Linux for example. + */ + StorageClass sc = SC_Static; + if (Ibt) + sc = SC_Extern; + VarDecl *ret = VarDecl::Create(astctx, decl_ctx, decl->getBeginLoc(), decl->getEndLoc(), id, pointer_to, nullptr, - SC_Static + sc ); /* return node. */ @@ -753,7 +766,7 @@ bool SymbolExternalizer::_Externalize_Symbol(const std::string &to_externalize, TypeUpdaterVisitor(*this, new_decl, to_externalize, wrap) .TraverseDecl(decl); - FunctionUpdater(*this, new_decl, to_externalize, wrap) + FunctionUpdater(*this, new_decl, to_externalize, wrap || Ibt) .Update_References_To_Symbol(decl); } @@ -763,9 +776,10 @@ bool SymbolExternalizer::_Externalize_Symbol(const std::string &to_externalize, /* If we found the first instance of the function we want to externalize, then proceed to create and replace the function declaration node with a variable declaration node of proper type. */ - std::string new_name = EXTERNALIZED_PREFIX + decl->getName().str(); + std::string old_name = decl->getName().str(); + std::string new_name = EXTERNALIZED_PREFIX + old_name; new_decl = Create_Externalized_Var(decl, new_name); - Log.push_back({.OldName = decl->getName().str(), + Log.push_back({.OldName = old_name, .NewName = new_name, .Type = ExternalizationType::STRONG}); @@ -773,6 +787,10 @@ bool SymbolExternalizer::_Externalize_Symbol(const std::string &to_externalize, std::string o; llvm::raw_string_ostream outstr(o); new_decl->print(outstr, AST->getLangOpts()); + if (Ibt) { + outstr << " \\\n" << "\tKLP_RELOC_SYMBOL(" << PatchObject << ", " << + IA.Get_Symbol_Module(old_name) << ", " << old_name << ")"; + } outstr << ";\n"; Replace_Text(decl->getSourceRange(), outstr.str(), 1000); @@ -780,8 +798,15 @@ bool SymbolExternalizer::_Externalize_Symbol(const std::string &to_externalize, must_update = true; wrap = false; - /* Update any macros that may reference the symbol. */ std::string replacement = "(*" + new_decl->getName().str() + ")"; + /* + * IBT uses extern variables, so we need to use the same type from the + * private symbol. + */ + if (Ibt) + replacement = new_decl->getName().str(); + + /* Update any macros that may reference the symbol. */ Rewrite_Macros(to_externalize, replacement); /* Slaps the new node into the position of where was the function From 459bb1dae6f9a16dde4531d5ffd442ad0c7557b3 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 5 Jun 2024 10:03:55 -0300 Subject: [PATCH 5/6] Test IBT externalization method Signed-off-by: Marcos Paulo de Souza --- testsuite/small/Modules.symvers | 1 + testsuite/small/ibt-1.c | 21 +++++++++++++++++++++ testsuite/small/linux/livepatch.h | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 testsuite/small/Modules.symvers create mode 100644 testsuite/small/ibt-1.c create mode 100644 testsuite/small/linux/livepatch.h diff --git a/testsuite/small/Modules.symvers b/testsuite/small/Modules.symvers new file mode 100644 index 0000000..141e99d --- /dev/null +++ b/testsuite/small/Modules.symvers @@ -0,0 +1 @@ +0x00000000 crc32c lib/libcrc32c EXPORT_SYMBOL diff --git a/testsuite/small/ibt-1.c b/testsuite/small/ibt-1.c new file mode 100644 index 0000000..e022953 --- /dev/null +++ b/testsuite/small/ibt-1.c @@ -0,0 +1,21 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_RENAME_SYMBOLS -I ../testsuite/small/ -DCE_SYMVERS_PATH=../testsuite/small/Modules.symvers -DKBUILD_MODNAME=crc32c -D__USE_IBT__ -D__KERNEL__" } */ + +typedef unsigned int u32; + +u32 crc32c(u32 crc, const void *address, unsigned int length); + +#include "linux/livepatch.h" + +int f(void) +{ + u32 lcrc = 0; + void *addr = 0; + unsigned int len = 0; + + (void)crc32c(lcrc, addr, len); + return 0; +} + +/* { dg-final { scan-tree-dump "u32 klpe_crc32c" } } */ +/* { dg-final { scan-tree-dump "KLP_RELOC_SYMBOL\(crc32c, crc32c, crc32c\)" } } */ +/* { dg-final { scan-tree-dump-not "\(\*klpe_crc32c\)" } } */ diff --git a/testsuite/small/linux/livepatch.h b/testsuite/small/linux/livepatch.h new file mode 100644 index 0000000..b2d0166 --- /dev/null +++ b/testsuite/small/linux/livepatch.h @@ -0,0 +1,18 @@ +/** + * KLP_RELOC_SYMBOL_POS - define relocation for external symbols + * + * @LP_OBJ_NAME: name of the livepatched object where the symbol is needed + * @SYM_OBJ_NAME: name of the object where the symbol exists + * @SYM_NAME: symbol name + * @SYM_POS: position of the symbol in SYM_OBJ when there are more + * symbols of the same name. + * + * Use for annotating external symbols used in livepatches which are + * not exported in vmlinux or are in livepatched modules, see + * Documentation/livepatch/module-elf-format.rst + */ +#define KLP_RELOC_SYMBOL_POS(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME, SYM_POS) \ + asm("\".klp.sym.rela." #LP_OBJ_NAME "." #SYM_OBJ_NAME "." #SYM_NAME "," #SYM_POS "\"") + +#define KLP_RELOC_SYMBOL(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME) \ + KLP_RELOC_SYMBOL_POS(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME, 0) From 671796654911d620ad371fa4a82fc23eff49777e Mon Sep 17 00:00:00 2001 From: Giuliano Belinassi Date: Wed, 5 Jun 2024 14:04:01 -0300 Subject: [PATCH 6/6] Fix externalization in command line macros, IBT tests This commit fixes a weird case where the SymbolExternalizer attempts to rewrite a macro that was defined in the command line. This also fixes the first IBT testcase, as well as add new ones that are currently failing so we mark them as XFAIL. linux tests are now in testsuite/linux. Signed-off-by: Giuliano Belinassi --- libcextract/SymbolExternalizer.cpp | 15 ++++++++++++- testsuite/{small => linux}/Modules.symvers | 0 testsuite/linux/ibt-1.c | 19 ++++++++++++++++ testsuite/linux/ibt-2.c | 23 ++++++++++++++++++++ testsuite/linux/ibt-3.c | 22 +++++++++++++++++++ testsuite/{small => linux}/linux/livepatch.h | 0 testsuite/linux/meson.build | 0 testsuite/meson.build | 2 +- testsuite/small/ibt-1.c | 21 ------------------ 9 files changed, 79 insertions(+), 23 deletions(-) rename testsuite/{small => linux}/Modules.symvers (100%) create mode 100644 testsuite/linux/ibt-1.c create mode 100644 testsuite/linux/ibt-2.c create mode 100644 testsuite/linux/ibt-3.c rename testsuite/{small => linux}/linux/livepatch.h (100%) create mode 100644 testsuite/linux/meson.build delete mode 100644 testsuite/small/ibt-1.c diff --git a/libcextract/SymbolExternalizer.cpp b/libcextract/SymbolExternalizer.cpp index 682a42a..9f94ebf 100644 --- a/libcextract/SymbolExternalizer.cpp +++ b/libcextract/SymbolExternalizer.cpp @@ -326,6 +326,19 @@ void TextModifications::Commit(void) /* Insert into the list of FileIDs. */ const FileEntry *fentry = SM.getFileEntryForID(begin_id); + + /* There are some cases where the fentry is known to return NULL. Check if + those are the cases we already acknownledged. */ + if (fentry == nullptr) { + PresumedLoc ploc = SM.getPresumedLoc(a.ToChange.getBegin()); + if (ploc.getFilename() == StringRef("")) { + /* Locations comming from the command line can be ignored. */ + continue; + } + + /* Crash with assertion. */ + assert(fentry && "FileEntry is NULL on a non-acknowledged case"); + } /* Insert the FileEntry if we don't have one. */ if (FileEntryMap.find(fentry) == FileEntryMap.end()) { /* Insert it. */ @@ -927,7 +940,7 @@ void SymbolExternalizer::Externalize_Symbols(std::vector const &to_ FileID fi = sm.getMainFileID(); SourceLocation sl = sm.getLocForStartOfFile(fi); SourceRange sr(sl, sl); - Insert_Text(sr, "#include ", 1000); + Insert_Text(sr, "#include \n", 1000); } for (const std::string &to_externalize : to_externalize_array) { diff --git a/testsuite/small/Modules.symvers b/testsuite/linux/Modules.symvers similarity index 100% rename from testsuite/small/Modules.symvers rename to testsuite/linux/Modules.symvers diff --git a/testsuite/linux/ibt-1.c b/testsuite/linux/ibt-1.c new file mode 100644 index 0000000..bbe9ee9 --- /dev/null +++ b/testsuite/linux/ibt-1.c @@ -0,0 +1,19 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_SYMVERS_PATH=../testsuite/linux/Modules.symvers -DCE_RENAME_SYMBOLS -nostdinc -I../testsuite/linux -DKBUILD_MODNAME=libcrc32c -D__USE_IBT__ -D__KERNEL__ -DCE_KEEP_INCLUDES" } */ + +typedef unsigned int u32; + +u32 crc32c(u32 crc, const void *address, unsigned int length); + +int f(void) +{ + u32 lcrc = 0; + void *addr = 0; + unsigned int len = 0; + + (void)crc32c(lcrc, addr, len); + return 0; +} + +/* { dg-final { scan-tree-dump "u32 klpe_crc32c|u32 \(klpe_crc32c\)" } } */ +/* { dg-final { scan-tree-dump "KLP_RELOC_SYMBOL\(libcrc32c, libcrc32c, crc32c\)" } } */ +/* { dg-final { scan-tree-dump-not "\(\*klpe_crc32c\)" } } */ diff --git a/testsuite/linux/ibt-2.c b/testsuite/linux/ibt-2.c new file mode 100644 index 0000000..a47acae --- /dev/null +++ b/testsuite/linux/ibt-2.c @@ -0,0 +1,23 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_SYMVERS_PATH=../testsuite/linux/Modules.symvers -DCE_RENAME_SYMBOLS -nostdinc -I../testsuite/linux -DKBUILD_MODNAME=libcrc32c -D__USE_IBT__ -D__KERNEL__ -DCE_KEEP_INCLUDES" } */ + +/* Check why the include is not being output. */ +/* { dg-xfail }*/ + +typedef unsigned int u32; + +u32 crc32c(u32 crc, const void *address, unsigned int length); + +int f(void) +{ + u32 lcrc = 0; + void *addr = 0; + unsigned int len = 0; + + (void)crc32c(lcrc, addr, len); + return 0; +} + +/* { dg-final { scan-tree-dump "#include " } } */ +/* { dg-final { scan-tree-dump "u32 klpe_crc32c|u32 \(klpe_crc32c\)" } } */ +/* { dg-final { scan-tree-dump "KLP_RELOC_SYMBOL\(libcrc32c, libcrc32c, crc32c\)" } } */ +/* { dg-final { scan-tree-dump-not "\(\*klpe_crc32c\)" } } */ diff --git a/testsuite/linux/ibt-3.c b/testsuite/linux/ibt-3.c new file mode 100644 index 0000000..66e706c --- /dev/null +++ b/testsuite/linux/ibt-3.c @@ -0,0 +1,22 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_SYMVERS_PATH=../testsuite/linux/Modules.symvers -DCE_RENAME_SYMBOLS -nostdinc -I../testsuite/linux -DKBUILD_MODNAME=libcrc32c -D__USE_IBT__ -D__KERNEL__ -DCE_KEEP_INCLUDES" } */ +/* { dg-xfail } */ + +/* Check why parenthesis are being output in the redeclaration. */ + +typedef unsigned int u32; + +u32 crc32c(u32 crc, const void *address, unsigned int length); + +int f(void) +{ + u32 lcrc = 0; + void *addr = 0; + unsigned int len = 0; + + (void)crc32c(lcrc, addr, len); + return 0; +} + +/* { dg-final { scan-tree-dump "u32 klpe_crc32c" } } */ +/* { dg-final { scan-tree-dump "KLP_RELOC_SYMBOL\(libcrc32c, libcrc32c, crc32c\)" } } */ +/* { dg-final { scan-tree-dump-not "\(\*klpe_crc32c\)" } } */ diff --git a/testsuite/small/linux/livepatch.h b/testsuite/linux/linux/livepatch.h similarity index 100% rename from testsuite/small/linux/livepatch.h rename to testsuite/linux/linux/livepatch.h diff --git a/testsuite/linux/meson.build b/testsuite/linux/meson.build new file mode 100644 index 0000000..e69de29 diff --git a/testsuite/meson.build b/testsuite/meson.build index ed5dcd0..ffbcbee 100644 --- a/testsuite/meson.build +++ b/testsuite/meson.build @@ -14,7 +14,7 @@ # Author: Giuliano Belinassi runtest = find_program('lib/runtest.py') -ordinary_test_dirs = [ 'small/', 'includes/', 'ccp/' ] +ordinary_test_dirs = [ 'small/', 'includes/', 'ccp/', 'linux' ] returncode_to_bool = [ true, false ] diff --git a/testsuite/small/ibt-1.c b/testsuite/small/ibt-1.c deleted file mode 100644 index e022953..0000000 --- a/testsuite/small/ibt-1.c +++ /dev/null @@ -1,21 +0,0 @@ -/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_RENAME_SYMBOLS -I ../testsuite/small/ -DCE_SYMVERS_PATH=../testsuite/small/Modules.symvers -DKBUILD_MODNAME=crc32c -D__USE_IBT__ -D__KERNEL__" } */ - -typedef unsigned int u32; - -u32 crc32c(u32 crc, const void *address, unsigned int length); - -#include "linux/livepatch.h" - -int f(void) -{ - u32 lcrc = 0; - void *addr = 0; - unsigned int len = 0; - - (void)crc32c(lcrc, addr, len); - return 0; -} - -/* { dg-final { scan-tree-dump "u32 klpe_crc32c" } } */ -/* { dg-final { scan-tree-dump "KLP_RELOC_SYMBOL\(crc32c, crc32c, crc32c\)" } } */ -/* { dg-final { scan-tree-dump-not "\(\*klpe_crc32c\)" } } */