aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-declextract/clangtool/declextract.cpp22
-rw-r--r--tools/syz-declextract/testdata/arch/x86/syscalls.tbl9
-rw-r--r--tools/syz-declextract/testdata/types.c14
-rw-r--r--tools/syz-declextract/testdata/types.c.info1
-rw-r--r--tools/syz-declextract/testdata/types.c.json79
-rw-r--r--tools/syz-declextract/testdata/types.c.txt7
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