Skip to content

Commit

Permalink
frontend fixes (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
ailrst authored Oct 2, 2024
1 parent 4fb69f1 commit 5aa5c6f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/main/antlr4/ReadELF.g4
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ syms : NEWLINE* relocationTable+ symbolTable+ ;
Sym value is the addend to be added to the symbol resolution
Sym name and addend - a pretty printing of the symbol name + addend.
*/
relocationTable : relocationTableHeader NEWLINE relocationTableRow* NEWLINE*;
relocationTable : (empty='There are no relocations in this file.') NEWLINE* | (relocationTableHeader NEWLINE relocationTableRow* NEWLINE*);
relocationTableHeader :
'Relocation section' tableName 'at offset 0x' HEX 'contains' HEX 'entries:' NEWLINE
'Offset' 'Info' 'Type' ('Sym. Value' | 'Symbol\'s Value') ('Symbol\'s Name + Addend' | 'Sym. Name + Addend')
Expand Down
20 changes: 13 additions & 7 deletions src/main/scala/translating/ReadELFLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum ELFSymType:
case FILE
case OBJECT
case FUNC /* code function */
case TLS /* ??? */


enum ELFBind:
Expand All @@ -26,6 +27,7 @@ enum ELFBind:
enum ELFVis:
case HIDDEN
case DEFAULT
case PROTECTED

enum ELFNDX:
case Section(num: Int) /* Section containing the symbol */
Expand All @@ -43,8 +45,8 @@ case class ELFSymbol(num: Int, /* symbol number */

object ReadELFLoader {
def visitSyms(ctx: SymsContext, config: ILLoadingConfig): (List[ELFSymbol], Set[ExternalFunction], Set[SpecGlobal], Map[BigInt, BigInt], BigInt) = {
val externalFunctions = ctx.relocationTable.asScala.flatMap(r => visitRelocationTableExtFunc(r)).toSet
val relocationOffsets = ctx.relocationTable.asScala.flatMap(r => visitRelocationTableOffsets(r)).toMap
val externalFunctions = ctx.relocationTable.asScala.filter(_.relocationTableHeader != null).flatMap(r => visitRelocationTableExtFunc(r)).toSet
val relocationOffsets = ctx.relocationTable.asScala.filter(_.relocationTableHeader != null).flatMap(r => visitRelocationTableOffsets(r)).toMap
val mainAddress = ctx.symbolTable.asScala.flatMap(s => getFunctionAddress(s, config.mainProcedureName))

val symbolTable = ctx.symbolTable.asScala.flatMap(s => visitSymbolTable(s)).toList
Expand All @@ -59,12 +61,16 @@ object ReadELFLoader {
}

def visitRelocationTableExtFunc(ctx: RelocationTableContext): Set[ExternalFunction] = {
val sectionName = ctx.relocationTableHeader.tableName.STRING.getText
if (sectionName == ".rela.plt" || sectionName == ".rela.dyn") {
val rows = ctx.relocationTableRow.asScala
rows.filter(r => r.name != null).map(r => visitRelocationTableRowExtFunc(r)).toSet
} else {
if (ctx.relocationTableHeader == null) {
Set()
} else {
val sectionName = ctx.relocationTableHeader.tableName.STRING.getText
if (sectionName == ".rela.plt" || sectionName == ".rela.dyn") {
val rows = ctx.relocationTableRow.asScala
rows.filter(r => r.name != null).map(r => visitRelocationTableRowExtFunc(r)).toSet
} else {
Set()
}
}
}

Expand Down
67 changes: 40 additions & 27 deletions src/main/scala/translating/SemanticsLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,21 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]

// LittleEndian is an assumption
if (index.isDefined && value.isDefined) {
Some(MemoryAssign(mem, index.get, value.get, Endian.LittleEndian, size, label))
Some(MemoryAssign(mem, index.get, value.get, Endian.LittleEndian, size.toInt, label))
} else {
None
}

case "unsupported_opcode.0" => {
val op = args.headOption.flatMap(visitExpr) match {
case Some(IntLiteral(s)) => Some("%08x".format(s))
case c => c.map(_.toString)
}
val comment = " unsupported opcode" + op.map(": " + _).getOrElse("")
Some(Assert(FalseLiteral, Some(comment)))
}
case _ =>
Logger.debug(s"Unidentified function call $function: ${ctx.getText}")
None
Logger.error(s"Unidentified function call $function: ${ctx.getText}")
Some(Assert(FalseLiteral, Some( " unsupported: " + ctx.getText)))
}
}

Expand Down Expand Up @@ -173,11 +180,11 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]

private def visitType(ctx: TypeContext): IRType = {
ctx match
case e: TypeBitsContext => BitVecType(parseInt(e.size))
case e: TypeBitsContext => BitVecType(parseInt(e.size).toInt)
case r: TypeRegisterContext =>
// this is a special register - not the same as a register in the IR
// ignoring the register's fields for now
BitVecType(visitInteger(r.size))
BitVecType(visitInteger(r.size).toInt)
case c: TypeConstructorContext => visitIdent(c.str).match {
case "FPRounding" => BitVecType(3)
case "integer" => BitVecType(64)
Expand Down Expand Up @@ -212,6 +219,8 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case "__BranchTaken" => None
case "BTypeNext" => None
case "BTypeCompatible" => None
case "TPIDR_EL0" => Some(Register(name, 64))
// case ov => Some(LocalVar(ov, BitVecType(1)))
case _ => throw Exception(s"could not identify variable '$name'")
}
}
Expand Down Expand Up @@ -243,7 +252,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]

if (index.isDefined) {
// LittleEndian is assumed
Some(MemoryLoad(mem, index.get, Endian.LittleEndian, size))
Some(MemoryLoad(mem, index.get, Endian.LittleEndian, size.toInt))
} else {
None
}
Expand All @@ -255,6 +264,8 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
val e = expr.get
e match {
case b: BinaryExpr if b.op == BVEQ => Some(BinaryExpr(BVCOMP, b.arg1, b.arg2))
case FalseLiteral => Some(BitVecLiteral(0, 1))
case TrueLiteral => Some(BitVecLiteral(1, 1))
case _ => throw Exception(s"unhandled conversion from bool to bitvector: ${ctx.getText}")
}
} else {
Expand Down Expand Up @@ -289,7 +300,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case "replicate_bits.0" =>
checkArgs(function, 2, 2, typeArgs.size, args.size, ctx.getText)
val oldSize = parseInt(typeArgs(0))
val replications = parseInt(typeArgs(1))
val replications = parseInt(typeArgs(1)).toInt
val arg0 = visitExpr(args(0))
val arg1 = parseInt(args(1))
val newSize = oldSize * replications
Expand All @@ -312,7 +323,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
Exception(s"inconsistent size parameters in ZeroExtend.0: ${ctx.getText}")
}
if (arg0.isDefined) {
Some(ZeroExtend(newSize - oldSize, arg0.get))
Some(ZeroExtend((newSize - oldSize).toInt, arg0.get))
} else {
None
}
Expand All @@ -327,7 +338,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
Exception(s"inconsistent size parameters in SignExtend.0: ${ctx.getText}")
}
if (arg0.isDefined) {
Some(SignExtend(newSize - oldSize, arg0.get))
Some(SignExtend((newSize - oldSize).toInt, arg0.get))
} else {
None
}
Expand All @@ -342,7 +353,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case "FPAdd.0" | "FPMul.0" | "FPDiv.0" | "FPMulX.0" | "FPMax.0" | "FPMin.0" | "FPMaxNum.0" | "FPMinNum.0" | "FPSub.0" =>
checkArgs(function, 1, 3, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val size = parseInt(typeArgs(0))
val size = parseInt(typeArgs(0)).toInt
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + size, argsIR, BitVecType(size)))

Expand All @@ -351,15 +362,15 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
"FPRoundIntN.0" =>
checkArgs(function, 1, 4, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val size = parseInt(typeArgs(0))
val size = parseInt(typeArgs(0)).toInt
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + size, argsIR, BitVecType(size)))

case "FPRecpX.0" | "FPSqrt.0" | "FPRecipEstimate.0" |
"FPRSqrtStepFused.0" | "FPRecipStepFused.0" =>
checkArgs(function, 1, 2, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val size = parseInt(typeArgs(0))
val size = parseInt(typeArgs(0)).toInt
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + size, argsIR, BitVecType(size)))

Expand All @@ -373,15 +384,15 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case "FPConvert.0" =>
checkArgs(function, 2, 3, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val outSize = parseInt(typeArgs(0))
val outSize = parseInt(typeArgs(0)).toInt
val inSize = parseInt(typeArgs(1))
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + outSize + "$" + inSize, argsIR, BitVecType(outSize)))

case "FPToFixed.0" =>
checkArgs(function, 2, 5, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val outSize = parseInt(typeArgs(0))
val outSize = parseInt(typeArgs(0)).toInt
val inSize = parseInt(typeArgs(1))
// need to specifically handle the integer parameter
val argsIR = args.flatMap(visitExpr).toSeq
Expand All @@ -391,7 +402,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
checkArgs(function, 2, 5, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val inSize = parseInt(typeArgs(0))
val outSize = parseInt(typeArgs(1))
val outSize = parseInt(typeArgs(1)).toInt
// need to specifically handle the integer parameter
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + outSize + "$" + inSize, argsIR, BitVecType(outSize)))
Expand All @@ -406,7 +417,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
checkArgs(function, 2, 3, typeArgs.size, args.size, ctx.getText)
val name = function.stripSuffix(".0")
val inSize = parseInt(typeArgs(0))
val outSize = parseInt(typeArgs(1))
val outSize = parseInt(typeArgs(1)).toInt
val argsIR = args.flatMap(visitExpr).toSeq
Some(UninterpretedFunction(name + "$" + outSize + "$" + inSize, argsIR, BitVecType(outSize)))

Expand Down Expand Up @@ -478,7 +489,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
if (size0 == size1) {
Some(BinaryExpr(operator, arg0.get, arg1.get))
} else {
Some(BinaryExpr(operator, arg0.get, ZeroExtend(size0 - size1, arg1.get)))
Some(BinaryExpr(operator, arg0.get, ZeroExtend((size0 - size1).toInt, arg1.get)))
}
} else {
None
Expand All @@ -503,12 +514,12 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
private def visitSliceContext(ctx: SliceContext): (Int, Int) = {
ctx match {
case s: Slice_HiLoContext =>
val hi = parseInt(s.hi)
val lo = parseInt(s.lo)
val hi = parseInt(s.hi).toInt
val lo = parseInt(s.lo).toInt
(hi + 1, lo)
case s: Slice_LoWdContext =>
val lo = parseInt(s.lo)
val wd = parseInt(s.wd)
val lo = parseInt(s.lo).toInt
val wd = parseInt(s.wd).toInt
(lo + wd, lo)
}
}
Expand All @@ -528,7 +539,7 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case e: ExprVarContext => visitIdent(e.ident)
case _ => throw Exception(s"expected ${ctx.getText} to have an Expr_Var as first parameter")
}
val index = parseInt(ctx.index)
val index = parseInt(ctx.index).toInt

resolveArrayExpr(name, index)
}
Expand Down Expand Up @@ -558,6 +569,8 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case "__BranchTaken" => None
case "BTypeNext" => None
case "BTypeCompatible" => None
case "TPIDR_EL0" => Some(Register(name, 64))
// case ov => Some(LocalVar(ov, BitVecType(1)))
case _ => throw Exception(s"could not identify variable '$name' in ${ctx.getText}")
}
}
Expand All @@ -579,15 +592,15 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
}
val index = parseInt(ctx.index)

resolveArrayExpr(name, index)
resolveArrayExpr(name, index.toInt)
}

private def visitIdent(ctx: IdentContext): String = {
ctx.ID.getText.stripPrefix("\"").stripSuffix("\"")
}

private def visitInteger(ctx: IntegerContext): Int = {
ctx.DEC.getText.toInt
private def visitInteger(ctx: IntegerContext): BigInt = {
BigInt(ctx.DEC.getText, 10)
}

private def visitBits(ctx: BitsContext): BitVecLiteral = {
Expand Down Expand Up @@ -615,4 +628,4 @@ class SemanticsLoader(parserMap: immutable.Map[String, Array[Array[StmtContext]]
case _ => throw Exception(s"unidentified Expr_Array ($name, $index)")
}
}
}
}
7 changes: 7 additions & 0 deletions src/main/scala/util/RunUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ object IRTransform {
Logger.debug(
s"[!] Removed ${before - ctx.program.procedures.size} functions (${ctx.program.procedures.size} remaining)"
)
val dupProcNames = (ctx.program.procedures.groupBy(_.name).filter((n,p) => p.size > 1)).toList.flatMap(_._2)

var dupCounter = 0
for (p <- dupProcNames) {
dupCounter += 1
p.name = p.name + "$" + p.address.map(_.toString).getOrElse(dupCounter.toString)
}

val stackIdentification = StackSubstituter()
stackIdentification.visitProgram(ctx.program)
Expand Down

0 comments on commit 5aa5c6f

Please sign in to comment.