diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2025-04-14 08:03:20 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2025-04-15 08:30:57 +0000 |
| commit | 93db339b43e883b4f87a3b0617e2f8a3f8eb313b (patch) | |
| tree | 62049346be7e8564c06ec42186a57f3dfd1d0819 | |
| parent | eb2144e822c56abb85860646d22d7ce4656fcdb1 (diff) | |
tools/syz-declextract: extract enums declared with a typedef
| -rw-r--r-- | tools/syz-declextract/clangtool/declextract.cpp | 22 | ||||
| -rw-r--r-- | tools/syz-declextract/testdata/arch/x86/syscalls.tbl | 9 | ||||
| -rw-r--r-- | tools/syz-declextract/testdata/types.c | 14 | ||||
| -rw-r--r-- | tools/syz-declextract/testdata/types.c.info | 1 | ||||
| -rw-r--r-- | tools/syz-declextract/testdata/types.c.json | 79 | ||||
| -rw-r--r-- | tools/syz-declextract/testdata/types.c.txt | 7 |
6 files changed, 120 insertions, 12 deletions
diff --git a/tools/syz-declextract/clangtool/declextract.cpp b/tools/syz-declextract/clangtool/declextract.cpp index 3b9769069..f1f1ad0a7 100644 --- a/tools/syz-declextract/clangtool/declextract.cpp +++ b/tools/syz-declextract/clangtool/declextract.cpp @@ -124,7 +124,7 @@ private: void run(const MatchFinder::MatchResult& Result, MatchFunc Action); template <typename T> const T* getResult(StringRef ID) const; FieldType extractRecord(QualType QT, const RecordType* Typ, const std::string& BackupName); - std::string extractEnum(const EnumDecl* Decl); + std::string extractEnum(QualType QT, const EnumDecl* Decl); void emitConst(const std::string& Name, int64_t Val, SourceLocation Loc); std::string getDeclName(const Expr* Expr); const ValueDecl* getValueDecl(const Expr* Expr); @@ -223,7 +223,7 @@ FieldType Extractor::genType(QualType QT, const std::string& BackupName) { return IntType{.ByteSize = sizeofType(T), .Name = TypeName(QT), .Base = QualType(T, 0).getAsString()}; } if (auto* Typ = llvm::dyn_cast<EnumType>(T)) { - return IntType{.ByteSize = sizeofType(T), .Enum = extractEnum(Typ->getDecl())}; + return IntType{.ByteSize = sizeofType(T), .Enum = extractEnum(QT, Typ->getDecl())}; } if (llvm::isa<FunctionProtoType>(T)) { return PtrType{.Elem = TodoType(), .IsConst = true}; @@ -330,8 +330,22 @@ FieldType Extractor::extractRecord(QualType QT, const RecordType* Typ, const std return Name; } -std::string Extractor::extractEnum(const EnumDecl* Decl) { - const std::string& Name = Decl->getNameAsString(); +std::string Extractor::extractEnum(QualType QT, const EnumDecl* Decl) { + std::string Name = Decl->getNameAsString(); + if (Name.empty()) { + // This is an unnamed enum declared with a typedef: + // typedef enum {...} enum_name; + auto Elaborated = dyn_cast<ElaboratedType>(QT.getTypePtr()); + if (Elaborated) { + auto Typedef = dyn_cast<TypedefType>(Elaborated->getNamedType().getTypePtr()); + if (Typedef) + Name = Typedef->getDecl()->getNameAsString(); + } + if (Name.empty()) { + QT.dump(); + llvm::report_fatal_error("enum with empty name"); + } + } if (EnumDedup[Name]) return Name; EnumDedup[Name] = true; diff --git a/tools/syz-declextract/testdata/arch/x86/syscalls.tbl b/tools/syz-declextract/testdata/arch/x86/syscalls.tbl index 3a290f3ba..e8e79d7e7 100644 --- a/tools/syz-declextract/testdata/arch/x86/syscalls.tbl +++ b/tools/syz-declextract/testdata/arch/x86/syscalls.tbl @@ -4,8 +4,9 @@ 1 64 open sys_open 2 64 chmod sys_chmod 3 64 types_syscall sys_types_syscall -4 64 align_syscall sys_align_syscall -5 64 functions sys_functions -6 64 scopes0 sys_scopes0 -7 64 cover sys_cover +4 64 types_syscall2 sys_types_syscall2 +5 64 align_syscall sys_align_syscall +6 64 functions sys_functions +7 64 scopes0 sys_scopes0 +8 64 cover sys_cover diff --git a/tools/syz-declextract/testdata/types.c b/tools/syz-declextract/testdata/types.c index be88269eb..1b7f3fb96 100644 --- a/tools/syz-declextract/testdata/types.c +++ b/tools/syz-declextract/testdata/types.c @@ -56,6 +56,20 @@ SYSCALL_DEFINE1(types_syscall, struct anon_struct* p, struct empty_struct* y, return 0; } +enum enum_foo { + enum_foo_a, + enum_foo_b, +}; + +typedef const enum { + enum_bar_a, + enum_bar_b, +} enum_bar; + +SYSCALL_DEFINE1(types_syscall2, const enum enum_foo foo, const enum_bar bar) { + return 0; +} + void anon_flow(int x) { struct anon_struct s; s.a.x = x; diff --git a/tools/syz-declextract/testdata/types.c.info b/tools/syz-declextract/testdata/types.c.info index 286282395..560b38f1a 100644 --- a/tools/syz-declextract/testdata/types.c.info +++ b/tools/syz-declextract/testdata/types.c.info @@ -1,2 +1,3 @@ SYSCALL align_syscall func:__do_sys_align_syscall loc:1 coverage:0 access:unknown manual_desc:false auto_desc:true file:types.c subsystem:kernel SYSCALL types_syscall func:__do_sys_types_syscall loc:3 coverage:0 access:unknown manual_desc:false auto_desc:true file:types.c subsystem:kernel +SYSCALL types_syscall2 func:__do_sys_types_syscall2 loc:1 coverage:0 access:unknown manual_desc:false auto_desc:true file:types.c subsystem:kernel diff --git a/tools/syz-declextract/testdata/types.c.json b/tools/syz-declextract/testdata/types.c.json index 558d0d5f4..58469c703 100644 --- a/tools/syz-declextract/testdata/types.c.json +++ b/tools/syz-declextract/testdata/types.c.json @@ -3,8 +3,8 @@ { "name": "__do_sys_align_syscall", "file": "types.c", - "start_line": 97, - "end_line": 99, + "start_line": 111, + "end_line": 113, "scopes": [ { "arg": -1 @@ -23,10 +23,21 @@ ] }, { + "name": "__do_sys_types_syscall2", + "file": "types.c", + "start_line": 69, + "end_line": 71, + "scopes": [ + { + "arg": -1 + } + ] + }, + { "name": "anon_flow", "file": "types.c", - "start_line": 59, - "end_line": 68, + "start_line": 73, + "end_line": 82, "scopes": [ { "arg": -1, @@ -172,6 +183,26 @@ "name": "c", "filename": "types.c", "value": 2 + }, + { + "name": "enum_bar_a", + "filename": "types.c", + "value": 0 + }, + { + "name": "enum_bar_b", + "filename": "types.c", + "value": 1 + }, + { + "name": "enum_foo_a", + "filename": "types.c", + "value": 0 + }, + { + "name": "enum_foo_b", + "filename": "types.c", + "value": 1 } ], "enums": [ @@ -182,6 +213,20 @@ "b", "c" ] + }, + { + "name": "enum_bar", + "values": [ + "enum_bar_a", + "enum_bar_b" + ] + }, + { + "name": "enum_foo", + "values": [ + "enum_foo_a", + "enum_foo_b" + ] } ], "structs": [ @@ -1000,6 +1045,32 @@ } ], "source_file": "types.c" + }, + { + "func": "__do_sys_types_syscall2", + "args": [ + { + "name": "foo", + "counted_by": -1, + "type": { + "int": { + "byte_size": 4, + "enum": "enum_foo" + } + } + }, + { + "name": "bar", + "counted_by": -1, + "type": { + "int": { + "byte_size": 4, + "enum": "enum_bar" + } + } + } + ], + "source_file": "types.c" } ] }
\ No newline at end of file diff --git a/tools/syz-declextract/testdata/types.c.txt b/tools/syz-declextract/testdata/types.c.txt index 216200384..d9c0a843a 100644 --- a/tools/syz-declextract/testdata/types.c.txt +++ b/tools/syz-declextract/testdata/types.c.txt @@ -9,9 +9,12 @@ type auto_aligner[N] { } [align[N]] bitfield_enum$auto = a, b, c +enum_bar$auto = enum_bar_a, enum_bar_b +enum_foo$auto = enum_foo_a, enum_foo_b align_syscall$auto(a1 ptr[inout, align1$auto], a2 ptr[inout, align2$auto], a3 ptr[inout, align3$auto], a4 ptr[inout, align4$auto]) types_syscall$auto(p ptr[inout, anon_struct$auto], y ptr[inout, auto_aligner[1]], b ptr[inout, bitfields$auto], pid pid, f int32, v ptr[inout, various$auto], pi ptr[inout, int32], pu ptr[inout, int32]) +types_syscall2$auto(foo flags[enum_foo$auto], bar flags[enum_bar$auto]) align1$auto { f1 int8 @@ -110,3 +113,7 @@ various$auto { define a 0 define b 1 define c 2 +define enum_bar_a 0 +define enum_bar_b 1 +define enum_foo_a 0 +define enum_foo_b 1 |
