Skip to content

Instantly share code, notes, and snippets.

@ytoshima
Created March 12, 2012 04:40
Show Gist options
  • Save ytoshima/2019857 to your computer and use it in GitHub Desktop.
Save ytoshima/2019857 to your computer and use it in GitHub Desktop.
Prints address map with gap size between segment within a core file
/**
* Prints address map with gap size between segment
* within a core file. This program uses readelf
* command and expects the output is same as the
* readelf on Linux.
*/
object CoreAmap {
def main(args: Array[String]) {
for (a <- args) doAmapCore(a)
}
def extractPhdrs(input: String) = {
val lns = input.split("\\n").toList
lns.dropWhile(! _.startsWith("Program Headers:")).
drop(1).takeWhile(_.length > 0).map(_.trim).
filter(_.startsWith("LOAD")).
map(_.split("\\s+")).
map(e => Seg(hexToLong(e(2)), hexToLong(e(5))))
}
case class Seg(va: Long, sz: Long) {
require(sz > 0)
val end = va + sz
override def toString =
"[0x%x, 0x%x), sz 0x%x".format(va, end, sz)
}
def hexToLong(str: String) = {
val ts = "^0[xX][0-9a-fA-F]+".r.findFirstIn(str) match {
case Some(s) => str.drop(2)
case None => str
}
java.lang.Long.parseLong(ts, 16)
}
def doAmapCore(path: String) {
import scala.sys.process._
val phdrs = extractPhdrs(Process("readelf -l " + path) !!)
def doAna(segs: List[Seg], prev: Option[Seg]) : List[String] = {
segs match {
case Nil => List("")
case x::xs => {
prev match {
case None => x.toString :: doAna(xs, Some(x))
case Some(ps) => {
(x.va - ps.end) match {
case 0 => x.toString :: doAna(xs, Some(x))
case diff if diff > 0 =>
" <<< GAP %dk >>>\n%s".
format(diff/1024L, x.toString) ::
doAna(xs, Some(x))
case diff =>
"E: unexpected diff %d".format(diff) ::
doAna(xs, Some(x))
}
} // Some(ps)
} // prev match
} // x::xs
} // segs match
}
println(doAna(phdrs, None).mkString("\n"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment