Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of structural analysis by sacrificing some precision #29

Merged
merged 3 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name := "chen"
ThisBuild / organization := "io.appthreat"
ThisBuild / version := "0.5.4"
ThisBuild / version := "0.6.0"
ThisBuild / scalaVersion := "3.3.1"

val cpgVersion = "1.4.22"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
"enum",
"struct",
"interface",
"class"
"class",
"naked",
"export",
"module",
"import"
)

protected def cleanType(rawType: String, stripKeywords: Boolean = true): String = {
Expand Down Expand Up @@ -485,6 +489,10 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
}

protected def astForNode(node: IASTNode): Ast = {
if (config.includeFunctionBodies) astForNodeFull(node) else astForNodePartial(node)
}

protected def astForNodeFull(node: IASTNode): Ast = {
node match {
case expr: IASTExpression => astForExpression(expr)
case name: IASTName => astForIdentifier(name)
Expand All @@ -505,6 +513,16 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
}
}

protected def astForNodePartial(node: IASTNode): Ast = {
node match {
case expr: IASTExpression => astForExpression(expr)
case name: IASTName => astForIdentifier(name)
case decl: IASTDeclSpecifier => astForIdentifier(decl)
case decl: ICPPASTDecltypeSpecifier => astForDecltypeSpecifier(decl)
case _ => notHandledYet(node)
}
}

protected def typeForDeclSpecifier(spec: IASTNode, stripKeywords: Boolean = true, index: Int = 0): String = {
val tpe = spec match {
case s: IASTSimpleDeclSpecifier if s.getParent.isInstanceOf[IASTParameterDeclaration] =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) {
astForExpression(packExpansionExpression.getPattern)

protected def astForExpression(expression: IASTExpression): Ast = {
if (config.includeFunctionBodies)
astForExpressionFull(expression)
else astForExpressionPartial(expression)
}

protected def astForExpressionFull(expression: IASTExpression): Ast = {
val r = expression match {
case lit: IASTLiteralExpression => astForLiteral(lit)
case un: IASTUnaryExpression => astForUnaryExpression(un)
Expand All @@ -295,6 +301,19 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) {
asChildOfMacroCall(expression, r)
}

protected def astForExpressionPartial(expression: IASTExpression): Ast = {
val r = expression match {
case call: IASTFunctionCallExpression => astForCallExpression(call)
case typeId: IASTTypeIdExpression => astForTypeIdExpression(typeId)
case fieldRef: IASTFieldReference => astForFieldReference(fieldRef)
case newExpression: ICPPASTNewExpression => astForNewExpression(newExpression)
case typeIdInit: IASTTypeIdInitializerExpression => astForTypeIdInitExpression(typeIdInit)
case c: ICPPASTSimpleTypeConstructorExpression => astForConstructorExpression(c)
case _ => notHandledYet(expression)
}
asChildOfMacroCall(expression, r)
}

private def astForIdExpression(idExpression: IASTIdExpression): Ast = idExpression.getName match {
case name: CPPASTQualifiedName => astForQualifiedName(name)
case _ => astForIdentifier(idExpression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ class CdtParser(config: Config) extends ParseProblemsLogger with PreprocessorSta
private val includePaths = parserConfig.userIncludePaths
private val log = new DefaultLogService

private var stayCpp: Boolean = false;

private val cScannerInfo: ExtendedScannerInfo = new ExtendedScannerInfo(
definedSymbols,
(includePaths ++ parserConfig.systemIncludePathsC).map(_.toString).toArray,
parserConfig.macroFiles.map(_.toString).toArray,
parserConfig.includeFiles.map(_.toString).toArray
)

private val cppScannerInfo: ExtendedScannerInfo = new ExtendedScannerInfo(
definedSymbols,
(includePaths ++ parserConfig.systemIncludePathsCPP).map(_.toString).toArray,
parserConfig.macroFiles.map(_.toString).toArray,
parserConfig.includeFiles.map(_.toString).toArray
)

// Setup indexing
var index: Option[IIndex] = Option(EmptyCIndex.INSTANCE)
if (config.useProjectIndex) {
Expand All @@ -71,17 +87,11 @@ class CdtParser(config: Config) extends ParseProblemsLogger with PreprocessorSta
}
}

private def createScannerInfo(file: Path): ExtendedScannerInfo = {
val additionalIncludes =
if (FileDefaults.isCPPFile(file.toString)) parserConfig.systemIncludePathsCPP
else parserConfig.systemIncludePathsC
new ExtendedScannerInfo(
definedSymbols,
(includePaths ++ additionalIncludes).map(_.toString).toArray,
parserConfig.macroFiles.map(_.toString).toArray,
parserConfig.includeFiles.map(_.toString).toArray
)
}
private def createScannerInfo(file: Path): ExtendedScannerInfo =
if (stayCpp || FileDefaults.isCPPFile(file.toString)) {
stayCpp = true
cppScannerInfo
} else cScannerInfo

private def parseInternal(file: Path): ParseResult = {
val realPath = File(file)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,34 @@ package io.appthreat.c2cpg.parser

object DefaultDefines {
val DEFAULT_CALL_CONVENTIONS: Map[String, String] = Map(
"__fastcall" -> "__attribute((fastcall))",
"__cdecl" -> "__attribute((cdecl))",
"__pascal" -> "__attribute((pascal))"
"__fastcall" -> "__attribute((fastcall))",
"__cdecl" -> "__attribute((cdecl))",
"__pascal" -> "__attribute((pascal))",
"__vectorcall" -> "__attribute((vectorcall))",
"__clrcall" -> "__attribute((clrcall))",
"__stdcall" -> "__attribute((stdcall))",
"__thiscall" -> "__attribute((thiscall))",
"__declspec" -> "__attribute((declspec))",
"__restrict" -> "__attribute((restrict))",
"__sptr" -> "__attribute((sptr))",
"__uptr" -> "__attribute((uptr))",
"__syscall" -> "__attribute((syscall))",
"__oldcall" -> "__attribute((oldcall))",
"__unaligned" -> "__attribute((unaligned))",
"__w64" -> "__attribute((w64))",
"__asm" -> "__attribute((asm))",
"__based" -> "__attribute((based))",
"__interface" -> "__attribute((interface))",
"__event" -> "__attribute((event))",
"__hook" -> "__attribute((hook))",
"__unhook" -> "__attribute((unhook))",
"__raise" -> "__attribute((raise))",
"__try" -> "__attribute((try))",
"__except" -> "__attribute((except))",
"__finally" -> "__attribute((finally))",
"__m128" -> "__attribute((m128))",
"__m128d" -> "__attribute((m128d))",
"__m128i" -> "__attribute((m128i))",
"__m64" -> "__attribute((m64))"
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class AstCreationPass(cpg: Cpg, config: Config, report: Report = new Report())
FileDefaults.SOURCE_FILE_EXTENSIONS ++ FileDefaults.HEADER_FILE_EXTENSIONS,
config.withDefaultIgnoredFilesRegex(DefaultIgnoredFolders)
)
.sortWith(_.compareToIgnoreCase(_) > 0)
.toArray

override def runOnPart(diffGraph: DiffGraphBuilder, filename: String): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ class HeaderAstCreationPassTests extends CCodeToCpgSuite {
// second time for the actual implementation in the source file
// We do not de-duplicate this as line/column numbers differ
m1.fullName shouldBe "main"
m1.filename shouldBe "main.c"
m1.filename shouldBe "main.h"
m2.fullName shouldBe "main"
m2.filename shouldBe "main.h"
m2.filename shouldBe "main.c"
printf.fullName shouldBe "printf"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ProgramStructureTests extends CCodeToCpgSuite {

"create one NamespaceBlock per file" in {
val cpg = code("", "foo.c").moreCode("", "woo.c")
val expectedFilenames = Seq("foo.c", "woo.c")
val expectedFilenames = Seq("woo.c", "foo.c")
val expectedNamespaceFullNames = expectedFilenames.map(f => s"$f:${NamespaceTraversal.globalNamespaceName}")
val allNamespaceBlockFullNames = cpg.namespaceBlock.fullNameNot(NamespaceTraversal.globalNamespaceName).fullName.l
allNamespaceBlockFullNames.zip(expectedNamespaceFullNames).foreach { case (actual, expected) =>
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "appthreat-chen"
version = "0.5.4"
version = "0.6.0"
description = "Code Hierarchy Exploration Net (chen)"
authors = ["Team AppThreat <cloud@appthreat.com>"]
license = "Apache-2.0"
Expand Down