first update in 2020

update gradle managed modules
update gradle to 6
refactor directory for aosp modules
pull/41/head
cfig 5 years ago
parent 4d1a3912d0
commit c1d4133f79
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -95,9 +95,6 @@ We now support both VB 1.0 and AVB 2.0 layouts.
boot\_signer
https://android.googlesource.com/platform/system/extras
bouncycastle
https://android.googlesource.com/platform/external/bouncycastle
cpio / fs\_config
https://android.googlesource.com/platform/system/core
@ -105,7 +102,7 @@ AVB
https://android.googlesource.com/platform/external/avb/
mkbootimg
https://android.googlesource.com/platform/system/core/+/master/mkbootimg/
https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/master/
Android version list
https://source.android.com/source/build-numbers.html

File diff suppressed because it is too large Load Diff

@ -77,6 +77,12 @@ public class BootSignature extends ASN1Object
* or equal to 1.
*/
private static final int BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET = 1632;
/**
* Offset of DTB length in a boot image header of version greater than
* or equal to 2.
*/
private static final int BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET = 1648;
/**
* Initializes the object for signing an image file
@ -221,12 +227,16 @@ public class BootSignature extends ASN1Object
length += ((recoveryDtboLength + pageSize - 1) / pageSize) * pageSize;
image.getLong(); // recovery_dtbo address
if (headerVersion == 1) {
int headerSize = image.getInt();
if (image.position() != headerSize) {
throw new IllegalArgumentException(
"Invalid image header: invalid header length");
}
int headerSize = image.getInt();
if (headerVersion == 2) {
image.position(BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET);
int dtbLength = image.getInt();
length += ((dtbLength + pageSize - 1) / pageSize) * pageSize;
image.getLong(); // dtb address
}
if (image.position() != headerSize) {
throw new IllegalArgumentException(
"Invalid image header: invalid header length");
}
}

@ -187,7 +187,7 @@ def main():
args.output_configs.write(o)
else:
sys.stderr.write(
"Cannot extract kernel configs in {}\n".format(args.input.name))
"Cannot extract kernel configs in {}".format(args.input.name))
ret = 1
if args.output_version is not None:
o = decompress_dump(dump_version, input_bytes)
@ -195,7 +195,7 @@ def main():
args.output_version.write(o)
else:
sys.stderr.write(
"Cannot extract kernel versions in {}\n".format(args.input.name))
"Cannot extract kernel versions in {}".format(args.input.name))
ret = 1
return ret

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python
# Copyright 2015, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -14,13 +14,15 @@
# limitations under the License.
from __future__ import print_function
from sys import argv, exit, stderr
from argparse import ArgumentParser, FileType, Action
from os import fstat
from struct import pack
from hashlib import sha1
import sys
from os import fstat
import re
from struct import pack
BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
def filesize(f):
if f is None:
@ -61,18 +63,61 @@ def get_recovery_dtbo_offset(args):
return dtbo_offset
def write_header_v3(args):
BOOT_IMAGE_HEADER_V3_SIZE = 1596
BOOT_MAGIC = 'ANDROID!'.encode()
args.output.write(pack('8s', BOOT_MAGIC))
args.output.write(pack(
'4I',
filesize(args.kernel), # kernel size in bytes
filesize(args.ramdisk), # ramdisk size in bytes
(args.os_version << 11) | args.os_patch_level, # os version and patch level
BOOT_IMAGE_HEADER_V3_SIZE))
args.output.write(pack('4I', 0, 0, 0, 0)) # reserved
args.output.write(pack('I', args.header_version)) # version of bootimage header
args.output.write(pack('1536s', args.cmdline.encode()))
pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)
def write_vendor_boot_header(args):
VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2108
BOOT_MAGIC = 'VNDRBOOT'.encode()
args.vendor_boot.write(pack('8s', BOOT_MAGIC))
args.vendor_boot.write(pack(
'5I',
args.header_version, # version of header
args.pagesize, # flash page size we assume
args.base + args.kernel_offset, # kernel physical load addr
args.base + args.ramdisk_offset, # ramdisk physical load addr
filesize(args.vendor_ramdisk))) # vendor ramdisk size in bytes
args.vendor_boot.write(pack('2048s', args.vendor_cmdline.encode()))
args.vendor_boot.write(pack('I', args.base + args.tags_offset)) # physical addr for kernel tags
args.vendor_boot.write(pack('16s', args.board.encode())) # asciiz product name
args.vendor_boot.write(pack('I', VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) # header size in bytes
if filesize(args.dtb) == 0:
raise ValueError("DTB image must not be empty.")
args.vendor_boot.write(pack('I', filesize(args.dtb))) # size in bytes
args.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
pad_file(args.vendor_boot, args.pagesize)
def write_header(args):
BOOT_IMAGE_HEADER_V1_SIZE = 1648
BOOT_IMAGE_HEADER_V2_SIZE = 1660
BOOT_MAGIC = 'ANDROID!'.encode()
if (args.header_version > 2):
if args.header_version > 3:
raise ValueError('Boot header version %d not supported' % args.header_version)
elif args.header_version == 3:
return write_header_v3(args)
args.output.write(pack('8s', BOOT_MAGIC))
final_ramdisk_offset = (args.base + args.ramdisk_offset) if filesize(args.ramdisk) > 0 else 0
final_second_offset = (args.base + args.second_offset) if filesize(args.second) > 0 else 0
args.output.write(pack('10I',
args.output.write(pack(
'10I',
filesize(args.kernel), # size in bytes
args.base + args.kernel_offset, # physical load addr
filesize(args.ramdisk), # size in bytes
@ -135,8 +180,8 @@ class ValidateStrLenAction(Action):
def __call__(self, parser, namespace, values, option_string=None):
if len(values) > self.maxlen:
raise ValueError('String argument too long: max {0:d}, got {1:d}'.
format(self.maxlen, len(values)))
raise ValueError(
'String argument too long: max {0:d}, got {1:d}'.format(self.maxlen, len(values)))
setattr(namespace, self.dest, values)
@ -150,6 +195,7 @@ def write_padded_file(f_out, f_in, padding):
def parse_int(x):
return int(x, 0)
def parse_os_version(x):
match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)
if match:
@ -166,33 +212,40 @@ def parse_os_version(x):
return (a << 14) | (b << 7) | c
return 0
def parse_os_patch_level(x):
match = re.search(r'^(\d{4})-(\d{2})-(\d{2})', x)
if match:
y = int(match.group(1)) - 2000
m = int(match.group(2))
# 7 bits allocated for the year, 4 bits for the month
assert y >= 0 and y < 128
assert m > 0 and m <= 12
assert 0 <= y < 128
assert 0 < m <= 12
return (y << 4) | m
return 0
def parse_cmdline():
parser = ArgumentParser()
parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'),
required=True)
parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))
parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))
recovery_dtbo_group = parser.add_mutually_exclusive_group()
recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO', type=FileType('rb'))
recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',
type=FileType('rb'))
recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',
type=FileType('rb'), metavar='RECOVERY_ACPIO', dest='recovery_dtbo')
type=FileType('rb'), metavar='RECOVERY_ACPIO',
dest='recovery_dtbo')
parser.add_argument('--cmdline', help='extra arguments to be passed on the '
'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
parser.add_argument('--vendor_cmdline',
help='kernel command line arguments contained in vendor boot',
default='', action=ValidateStrLenAction, maxlen=2048)
parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int, default=0x01000000)
parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,
default=0x01000000)
parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
default=0x00f00000)
parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)
@ -205,34 +258,59 @@ def parse_cmdline():
parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
maxlen=16)
parser.add_argument('--pagesize', help='page size', type=parse_int,
choices=[2**i for i in range(11,15)], default=2048)
choices=[2**i for i in range(11, 15)], default=2048)
parser.add_argument('--id', help='print the image ID on standard output',
action='store_true')
parser.add_argument('--header_version', help='boot image header version', type=parse_int, default=0)
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'),
required=True)
parser.add_argument('--header_version', help='boot image header version', type=parse_int,
default=0)
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))
parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))
parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))
return parser.parse_args()
def write_data(args):
write_padded_file(args.output, args.kernel, args.pagesize)
write_padded_file(args.output, args.ramdisk, args.pagesize)
write_padded_file(args.output, args.second, args.pagesize)
def write_data(args, pagesize):
write_padded_file(args.output, args.kernel, pagesize)
write_padded_file(args.output, args.ramdisk, pagesize)
write_padded_file(args.output, args.second, pagesize)
if args.header_version > 0 and args.header_version < 3:
write_padded_file(args.output, args.recovery_dtbo, pagesize)
if args.header_version == 2:
write_padded_file(args.output, args.dtb, pagesize)
def write_vendor_boot_data(args):
write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)
write_padded_file(args.vendor_boot, args.dtb, args.pagesize)
if args.header_version > 0:
write_padded_file(args.output, args.recovery_dtbo, args.pagesize)
if args.header_version > 1:
write_padded_file(args.output, args.dtb, args.pagesize)
def main():
args = parse_cmdline()
img_id = write_header(args)
write_data(args)
if args.id:
if isinstance(img_id, str):
if args.vendor_boot is not None:
if args.header_version < 3:
raise ValueError('--vendor_boot not compatible with given header version')
if args.vendor_ramdisk is None:
raise ValueError('--vendor_ramdisk missing or invalid')
write_vendor_boot_header(args)
write_vendor_boot_data(args)
if args.output is not None:
if args.kernel is None:
raise ValueError('kernel must be supplied when creating a boot image')
if args.second is not None and args.header_version > 2:
raise ValueError('--second not compatible with given header version')
img_id = write_header(args)
if args.header_version > 2:
write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)
else:
write_data(args, args.pagesize)
if args.id and img_id is not None:
# Python 2's struct.pack returns a string, but py3 returns bytes.
img_id = [ord(x) for x in img_id]
print('0x' + ''.join('{:02x}'.format(c) for c in img_id))
if isinstance(img_id, str):
img_id = [ord(x) for x in img_id]
print('0x' + ''.join('{:02x}'.format(c) for c in img_id))
if __name__ == '__main__':
main()

@ -1,5 +1,5 @@
plugins {
id("org.jetbrains.kotlin.jvm").version("1.3.41")
id("org.jetbrains.kotlin.jvm").version("1.3.61")
application
}
@ -11,10 +11,10 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.slf4j:slf4j-simple:1.7.25")
implementation("org.slf4j:slf4j-api:1.7.25")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.9.4")
implementation("com.fasterxml.jackson.core:jackson-databind:2.9.4")
implementation("org.slf4j:slf4j-simple:1.7.29")
implementation("org.slf4j:slf4j-api:1.7.29")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.10.1")
implementation("com.fasterxml.jackson.core:jackson-databind:2.10.1")
implementation("com.google.guava:guava:18.0")
implementation("org.apache.commons:commons-exec:1.3")
implementation("org.apache.commons:commons-compress:1.16.1")

@ -83,18 +83,6 @@ class Helper {
return data
}
//similar to this.toString(StandardCharsets.UTF_8).replace("${Character.MIN_VALUE}", "")
@Deprecated("by 1.3.41 experimental api: String.decodeToString()")
fun toCString(ba: ByteArray): String {
val str = ba.toString(StandardCharsets.UTF_8)
val nullPos = str.indexOf(Character.MIN_VALUE)
return if (nullPos >= 0) {
str.substring(0, nullPos)
} else {
str
}
}
@Throws(IOException::class)
fun gnuZipFile(compressedFile: String, decompressedFile: String) {
val buffer = ByteArray(1024)
@ -302,7 +290,7 @@ class Helper {
}
fun String.check_call(): Boolean {
var ret = false
val ret: Boolean
try {
val cmd = CommandLine.parse(this)
log.info(cmd.toString())

@ -9,4 +9,5 @@ data class ParamConfig(
var dtbo: String? = UnifiedConfig.workDir + "recoveryDtbo",
var dtb: String? = UnifiedConfig.workDir + "dtb",
var cfg: String = UnifiedConfig.workDir + "bootimg.json",
val mkbootimg: String = "./external/mkbootimg")
val mkbootimg: String = "./aosp/system/tools/mkbootimg/mkbootimg.py")

@ -36,7 +36,7 @@ class Algorithms {
intArrayOf(0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20)),
defaultKey = "avb/avb_test_data/testkey_rsa2048.pem")
defaultKey = "aosp/avb/avb_test_data/testkey_rsa2048.pem")
val SHA256_RSA4096 = Algorithm(
name = "SHA256_RSA4096",
@ -53,7 +53,7 @@ class Algorithms {
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20)
),
defaultKey = "avb/avb_test_data/testkey_rsa4096.pem"
defaultKey = "aosp/avb/avb_test_data/testkey_rsa4096.pem"
)
val SHA256_RSA8192 = Algorithm(
@ -70,7 +70,7 @@ class Algorithms {
intArrayOf(0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20)),
defaultKey = "avb/avb_test_data/testkey_rsa8192.pem")
defaultKey = "aosp/avb/avb_test_data/testkey_rsa8192.pem")
val SHA512_RSA2048 = Algorithm(
name = "SHA512_RSA2048",
@ -86,7 +86,7 @@ class Algorithms {
intArrayOf(0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40)),
defaultKey = "avb/avb_test_data/testkey_rsa2048.pem")
defaultKey = "aosp/avb/avb_test_data/testkey_rsa2048.pem")
val SHA512_RSA4096 = Algorithm(
name = "SHA512_RSA4096",
@ -102,7 +102,7 @@ class Algorithms {
intArrayOf(0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40)),
defaultKey = "avb/avb_test_data/testkey_rsa4096.pem")
defaultKey = "aosp/avb/avb_test_data/testkey_rsa4096.pem")
val SHA512_RSA8192 = Algorithm(
name = "SHA512_RSA8192",
@ -119,7 +119,7 @@ class Algorithms {
intArrayOf(0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40)),
defaultKey = "avb/avb_test_data/testkey_rsa8192.pem")
defaultKey = "aosp/avb/avb_test_data/testkey_rsa8192.pem")
algMap[NONE.name] = NONE

@ -40,7 +40,7 @@ class ChainPartitionDescriptor(
}
constructor(data: InputStream, seq: Int = 0) : this() {
if (SIZE - RESERVED != Struct3(FORMAT_STRING).calcSize()!!.toLong()) {
if (SIZE - RESERVED != Struct3(FORMAT_STRING).calcSize().toLong()) {
throw RuntimeException()
}
this.sequence = seq

@ -9,7 +9,7 @@ class PropertyDescriptor(
var key: String = "",
var value: String = "") : Descriptor(TAG, 0U, 0) {
override fun encode(): ByteArray {
if (SIZE != Struct3(FORMAT_STRING).calcSize()!!.toUInt()) {
if (SIZE != Struct3(FORMAT_STRING).calcSize().toUInt()) {
throw RuntimeException()
}
this.num_bytes_following = (SIZE + this.key.length.toUInt() + this.value.length.toUInt() + 2U - 16U).toULong()

@ -32,7 +32,7 @@ data class ImgInfo(
data class VeritySignature(
var type: String = "dm-verity",
var path: String = "/boot",
var verity_pk8: String = "security/verity.pk8",
var verity_pem: String = "security/verity.x509.pem",
var verity_pk8: String = "aosp/security/verity.pk8",
var verity_pem: String = "aosp/security/verity.x509.pem",
var jarPath: String = "aosp/boot_signer/build/libs/boot_signer.jar")
}

@ -1,14 +1,36 @@
package cfig.io
import cfig.Helper
import cfig.io.Struct3.ByteArrayExt.Companion.toCString
import cfig.io.Struct3.ByteArrayExt.Companion.toInt
import cfig.io.Struct3.ByteArrayExt.Companion.toLong
import cfig.io.Struct3.ByteArrayExt.Companion.toShort
import cfig.io.Struct3.ByteArrayExt.Companion.toUInt
import cfig.io.Struct3.ByteArrayExt.Companion.toULong
import cfig.io.Struct3.ByteArrayExt.Companion.toUShort
import cfig.io.Struct3.ByteBufferExt.Companion.appendByteArray
import cfig.io.Struct3.ByteBufferExt.Companion.appendPadding
import cfig.io.Struct3.ByteBufferExt.Companion.appendUByteArray
import cfig.io.Struct3.InputStreamExt.Companion.getByteArray
import cfig.io.Struct3.InputStreamExt.Companion.getCString
import cfig.io.Struct3.InputStreamExt.Companion.getChar
import cfig.io.Struct3.InputStreamExt.Companion.getInt
import cfig.io.Struct3.InputStreamExt.Companion.getLong
import cfig.io.Struct3.InputStreamExt.Companion.getPadding
import cfig.io.Struct3.InputStreamExt.Companion.getShort
import cfig.io.Struct3.InputStreamExt.Companion.getUByteArray
import cfig.io.Struct3.InputStreamExt.Companion.getUInt
import cfig.io.Struct3.InputStreamExt.Companion.getULong
import cfig.io.Struct3.InputStreamExt.Companion.getUShort
import org.junit.Assert
import org.slf4j.LoggerFactory
import java.io.IOException
import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.charset.StandardCharsets
import java.util.*
import java.util.regex.Pattern
import kotlin.random.Random
@ExperimentalUnsignedTypes
class Struct3 {
@ -17,85 +39,44 @@ class Struct3 {
private var byteOrder = ByteOrder.LITTLE_ENDIAN
private val formats = ArrayList<Array<Any?>>()
enum class Type {
Padding,
}
constructor(inFormatString: String) {
Assert.assertTrue("FORMAT_STRING must not be empty",
inFormatString.isNotEmpty())
formatString = inFormatString
val m = Pattern.compile("(\\d*)([a-zA-Z])").matcher(formatString)
if (formatString.startsWith(">") || formatString.startsWith("!")) {
this.byteOrder = ByteOrder.BIG_ENDIAN
log.debug("Parsing BIG_ENDIAN format: $formatString")
} else if (formatString.startsWith("@") || formatString.startsWith("=")) {
this.byteOrder = ByteOrder.nativeOrder()
log.debug("Parsing native ENDIAN format: $formatString")
} else {
log.debug("Parsing LITTLE_ENDIAN format: $formatString")
when (formatString[0]) {
'>', '!' -> this.byteOrder = ByteOrder.BIG_ENDIAN
'@', '=' -> this.byteOrder = ByteOrder.nativeOrder()
else -> this.byteOrder = ByteOrder.LITTLE_ENDIAN
}
while (m.find()) {
var bExploded = false
val multiple = if (m.group(1).isEmpty()) 1 else Integer.decode(m.group(1))
//item[0]: Type, item[1]: multiple
// if need to expand format items, explode it
// eg: "4L" will be exploded to "1L 1L 1L 1L"
// eg: "10x" won't be exploded, it's still "10x"
val item = arrayOfNulls<Any?>(2)
when (m.group(2)) {
//exploded types
"x" -> {//byte 1
item[0] = Type.Padding
bExploded = true
}
"b" -> {//byte 1
item[0] = Byte
bExploded = true
}
"B" -> {//UByte 1
item[0] = UByte
bExploded = true
}
"s" -> {//string
item[0] = String
bExploded = true
}
//combo types, which need to be exploded with multiple=1
"c" -> {//char 1
item[0] = Char
bExploded = false
}
"h" -> {//2
item[0] = Short
}
"H" -> {//2
item[0] = UShort
}
"i", "l" -> {//4
item[0] = Int
}
"I", "L" -> {//4
item[0] = UInt
}
"q" -> {//8
item[0] = Long
}
"Q" -> {//8
item[0] = ULong
}
else -> {
throw IllegalArgumentException("type [" + m.group(2) + "] not supported")
}
// eg: "4L" will be exploded to "1L 1L 1L 1L", so it's treated as primitive
// eg: "10x" won't be exploded, it's still "10x", so it's treated as non-primitive
val typeName: Any = when (m.group(2)) {
//primitive types
"x" -> Random //byte 1 (exploded)
"b" -> Byte //byte 1 (exploded)
"B" -> UByte //UByte 1 (exploded)
"s" -> String //string (exploded)
//zippable types, which need to be exploded with multiple=1
"c" -> Char
"h" -> Short //2
"H" -> UShort //2
"i", "l" -> Int //4
"I", "L" -> UInt //4
"q" -> Long //8
"Q" -> ULong //8
else -> throw IllegalArgumentException("type [" + m.group(2) + "] not supported")
}
if (bExploded) {
item[1] = multiple
formats.add(item)
val bPrimitive = m.group(2) in listOf("x", "b", "B", "s")
val multiple = if (m.group(1).isEmpty()) 1 else Integer.decode(m.group(1))
if (bPrimitive) {
formats.add(arrayOf<Any?>(typeName, multiple))
} else {
item[1] = 1
for (i in 0 until multiple) {
formats.add(item)
formats.add(arrayOf<Any?>(typeName, 1))
}
}
}
@ -105,25 +86,39 @@ class Struct3 {
return ("type=" + formats.get(inCursor)[0] + ", value=" + formats.get(inCursor)[1])
}
fun calcSize(): Int? {
override fun toString(): String {
val formatStr = mutableListOf<String>()
formats.forEach {
val fs = StringBuilder()
when (it[0]) {
Random -> fs.append("x")
Byte -> fs.append("b")
UByte -> fs.append("B")
String -> fs.append("s")
Char -> fs.append("c")
Short -> fs.append("h")
UShort -> fs.append("H")
Int -> fs.append("i")
UInt -> fs.append("I")
Long -> fs.append("q")
ULong -> fs.append("Q")
else -> throw IllegalArgumentException("type [" + it[0] + "] not supported")
}
fs.append(":" + it[1])
formatStr.add(fs.toString())
}
return "Struct3(formatString='$formatString', byteOrder=$byteOrder, formats=$formatStr)"
}
fun calcSize(): Int {
var ret = 0
for (format in formats) {
when (val formatType = format[0]) {
Byte, UByte, Char, String, Type.Padding -> {
ret += format[1] as Int
}
Short, UShort -> {
ret += 2 * format[1] as Int
}
Int, UInt -> {
ret += 4 * format[1] as Int
}
Long, ULong -> {
ret += 8 * format[1] as Int
}
else -> {
throw IllegalArgumentException("Class [" + formatType + "] not supported")
}
ret += when (val formatType = format[0]) {
Random, Byte, UByte, Char, String -> format[1] as Int
Short, UShort -> 2 * format[1] as Int
Int, UInt -> 4 * format[1] as Int
Long, ULong -> 8 * format[1] as Int
else -> throw IllegalArgumentException("Class [$formatType] not supported")
}
}
return ret
@ -133,129 +128,88 @@ class Struct3 {
if (args.size != this.formats.size) {
throw IllegalArgumentException("argument size " + args.size +
" doesn't match format size " + this.formats.size)
} else {
log.debug("byte buffer size: " + this.calcSize()!!)
}
val bf = ByteBuffer.allocate(this.calcSize()!!)
val bf = ByteBuffer.allocate(this.calcSize())
bf.order(this.byteOrder)
var formatCursor = -1 //which format item to handle
for (i in args.indices) {
formatCursor++
val arg = args[i]
val format2 = formats[i][0]
val size = formats[i][1] as Int
val typeName = formats[i][0]
val multiple = formats[i][1] as Int
if (typeName !in arrayOf(Random, Byte, String, UByte)) {
Assert.assertEquals(1, multiple)
}
//x: padding:
// arg == null:
// arg is Byte.class
// arg is Integer.class
if (Type.Padding == format2) {
val b = ByteArray(size)
if (Random == typeName) {
when (arg) {
null -> Arrays.fill(b, 0.toByte())
is Byte -> Arrays.fill(b, arg)
is Int -> Arrays.fill(b, arg.toByte())
null -> bf.appendPadding(0, multiple)
is Byte -> bf.appendPadding(arg, multiple)
is Int -> bf.appendPadding(arg.toByte(), multiple)
else -> throw IllegalArgumentException("Index[" + i + "] Unsupported arg ["
+ arg + "] with type [" + formats[i][0] + "]")
}
bf.put(b)
continue
}
//c: character
if (Char == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of Character.class",
if (Char == typeName) {
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT Char",
arg is Char)
bf.put(getLowerByte(arg as Char))
if ((arg as Char) !in '\u0000'..'\u00ff') {
throw IllegalArgumentException("arg[${arg.toInt()}] exceeds 8-bit bound")
}
bf.put(arg.toByte())
continue
}
//b: byte array
if (Byte == format2) {
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of ByteArray/IntArray",
arg is ByteArray || arg is IntArray)
val argInternal = if (arg is IntArray) {
val arg2: MutableList<Byte> = mutableListOf()
for (item in arg) {
Assert.assertTrue("$item is not valid Byte",
item in Byte.MIN_VALUE..Byte.MAX_VALUE)
arg2.add(item.toByte())
}
arg2.toByteArray()
} else {
arg as ByteArray
}
val paddingSize = size - argInternal.size
Assert.assertTrue("argument size overflow: " + argInternal.size + " > " + size,
paddingSize >= 0)
bf.put(argInternal)
if (paddingSize > 0) {
val padBytes = ByteArray(paddingSize)
Arrays.fill(padBytes, 0.toByte())
bf.put(padBytes)
log.debug("paddingSize $paddingSize")
} else {
log.debug("paddingSize is zero, perfect match")
if (Byte == typeName) {
when (arg) {
is IntArray -> bf.appendByteArray(arg, multiple)
is ByteArray -> bf.appendByteArray(arg, multiple)
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT ByteArray/IntArray")
}
continue
}
//B: UByte array
if (UByte == format2) {
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of ByteArray/IntArray",
arg is ByteArray || arg is IntArray || arg is UByteArray)
val argInternal = if (arg is IntArray) {
val arg2: MutableList<Byte> = mutableListOf()
for (item in arg) {
Assert.assertTrue("$item is not valid UByte",
item in UByte.MIN_VALUE.toInt()..UByte.MAX_VALUE.toInt())
arg2.add(item.toByte())
}
arg2.toByteArray()
} else if (arg is UByteArray) {
arg as ByteArray
} else {
arg as ByteArray
if (UByte == typeName) {
when (arg) {
is ByteArray -> bf.appendByteArray(arg, multiple)
is UByteArray -> bf.appendUByteArray(arg, multiple)
is IntArray -> bf.appendUByteArray(arg, multiple)
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT ByteArray/IntArray")
}
continue
}
val paddingSize = size - argInternal.size
Assert.assertTrue("argument size overflow: " + argInternal.size + " > " + size,
paddingSize >= 0)
bf.put(argInternal)
if (paddingSize > 0) {
val padBytes = ByteArray(paddingSize)
Arrays.fill(padBytes, 0.toByte())
bf.put(padBytes)
log.debug("paddingSize $paddingSize")
} else {
log.debug("paddingSize is zero, perfect match")
}
//s: String
if (String == typeName) {
Assert.assertNotNull("arg can not be NULL for String, formatString=$formatString, ${getFormatInfo(i)}", arg)
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT String, ${getFormatInfo(i)}",
arg is String)
bf.appendByteArray((arg as String).toByteArray(), multiple)
continue
}
//h: Short
if (Short == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of Short/Int",
arg is Short || arg is Int)
if (Short == typeName) {
when (arg) {
is Int -> {
Assert.assertTrue("[$arg] is truncated as type Short.class",
arg in java.lang.Short.MIN_VALUE..java.lang.Short.MAX_VALUE)
arg in Short.MIN_VALUE..Short.MAX_VALUE)
bf.putShort(arg.toShort())
}
is Short -> //instance Short
bf.putShort(arg)
is Short -> bf.putShort(arg) //instance Short
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Short/Int")
}
continue
}
//H: UShort
if (UShort == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of UShort/UInt/Int",
if (UShort == typeName) {
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT UShort/UInt/Int",
arg is UShort || arg is UInt || arg is Int)
when (arg) {
is Int -> {
@ -274,18 +228,14 @@ class Struct3 {
}
//i, l: Int
if (Int == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of Int", arg is Int)
if (Int == typeName) {
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT Int", arg is Int)
bf.putInt(arg as Int)
continue
}
//I, L: UInt
if (UInt == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of UInt/Int/Long",
arg is UInt || arg is Int || arg is Long)
if (UInt == typeName) {
when (arg) {
is Int -> {
Assert.assertTrue("[$arg] is invalid as type UInt", arg >= 0)
@ -296,30 +246,23 @@ class Struct3 {
Assert.assertTrue("[$arg] is invalid as type UInt", arg >= 0)
bf.putInt(arg.toInt())
}
else -> {
Assert.fail("program bug")
}
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT UInt/Int/Long")
}
continue
}
//q: Long
if (Long == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of Long/Int",
arg is Long || arg is Int)
if (Long == typeName) {
when (arg) {
is Long -> bf.putLong(arg)
is Int -> bf.putLong(arg.toLong())
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Long/Int")
}
continue
}
//Q: ULong
if (ULong == format2) {
Assert.assertEquals(1, size.toLong())
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of Int/Long/ULong",
arg is Int || arg is Long || arg is ULong)
if (ULong == typeName) {
when (arg) {
is Int -> {
Assert.assertTrue("[$arg] is invalid as type ULong", arg >= 0)
@ -329,36 +272,14 @@ class Struct3 {
Assert.assertTrue("[$arg] is invalid as type ULong", arg >= 0)
bf.putLong(arg)
}
is ULong -> {
bf.putLong(arg.toLong())
}
}
continue
}
//s: String
if (String == format2) {
Assert.assertNotNull("arg can not be NULL for String, formatString=$formatString, ${getFormatInfo(formatCursor)}", arg)
Assert.assertTrue("[$arg](${arg!!::class.java}) is NOT instance of String.class, ${getFormatInfo(formatCursor)}",
arg is String)
val paddingSize = size - (arg as String).length
Assert.assertTrue("argument size overflow: " + arg.length + " > " + size,
paddingSize >= 0)
bf.put(arg.toByteArray())
if (paddingSize > 0) {
val padBytes = ByteArray(paddingSize)
Arrays.fill(padBytes, 0.toByte())
bf.put(padBytes)
log.debug("paddingSize $paddingSize")
} else {
log.debug("paddingSize is zero, perfect match")
is ULong -> bf.putLong(arg.toLong())
else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Int/Long/ULong")
}
continue
}
throw java.lang.IllegalArgumentException("unrecognized format $format2")
throw IllegalArgumentException("unrecognized format $typeName")
}
log.debug("Pack Result:" + Helper.toHexString(bf.array()))
return bf.array()
}
@ -366,143 +287,251 @@ class Struct3 {
fun unpack(iS: InputStream): List<*> {
val ret = ArrayList<Any>()
for (format in this.formats) {
//x: padding
//return padding byte
if (format[0] === Type.Padding) {
val multip = format[1] as Int
val data = ByteArray(1)
iS.read(data)//sample the 1st byte
val skipped = iS.skip(multip.toLong() - 1)//skip remaining
Assert.assertEquals(multip.toLong() - 1, skipped)
ret.add(data[0])
continue
when (format[0]) {
Random -> ret.add(iS.getPadding(format[1] as Int)) //return padding byte
Byte -> ret.add(iS.getByteArray(format[1] as Int)) //b: byte array
UByte -> ret.add(iS.getUByteArray(format[1] as Int)) //B: ubyte array
Char -> ret.add(iS.getChar()) //char: 1
String -> ret.add(iS.getCString(format[1] as Int)) //c string
Short -> ret.add(iS.getShort(this.byteOrder)) //h: short
UShort -> ret.add(iS.getUShort(this.byteOrder)) //H: UShort
Int -> ret.add(iS.getInt(this.byteOrder)) //i, l: Int
UInt -> ret.add(iS.getUInt(this.byteOrder)) //I, L: UInt
Long -> ret.add(iS.getLong(this.byteOrder)) //q: Long
ULong -> ret.add(iS.getULong(this.byteOrder)) //Q: ULong
else -> throw IllegalArgumentException("Class [" + format[0] + "] not supported")
}//end-of-when
}//end-of-for
return ret
}
class ByteBufferExt {
companion object {
private val log = LoggerFactory.getLogger(ByteBufferExt::class.java)
fun ByteBuffer.appendPadding(b: Byte, bufSize: Int) {
when {
bufSize == 0 -> {
log.debug("paddingSize is zero, perfect match")
return
}
bufSize < 0 -> {
throw IllegalArgumentException("illegal padding size: $bufSize")
}
else -> {
log.debug("paddingSize $bufSize")
}
}
val padding = ByteArray(bufSize)
Arrays.fill(padding, b)
this.put(padding)
}
//b: byte array
if (format[0] === Byte) {
val data = ByteArray(format[1] as Int)
Assert.assertEquals(format[1] as Int, iS.read(data))
ret.add(data)
continue
fun ByteBuffer.appendByteArray(inIntArray: IntArray, bufSize: Int) {
val arg2 = mutableListOf<Byte>()
inIntArray.toMutableList().mapTo(arg2, {
if (it in Byte.MIN_VALUE..Byte.MAX_VALUE)
it.toByte()
else
throw IllegalArgumentException("$it is not valid Byte")
})
appendByteArray(arg2.toByteArray(), bufSize)
}
//B: ubyte array
if (format[0] === UByte) {
val data = ByteArray(format[1] as Int)
Assert.assertEquals(format[1] as Int, iS.read(data))
val innerData = UByteArray(data.size)
for (i in 0 until data.size) {
innerData[i] = data[i].toUByte()
}
ret.add(innerData)
continue
fun ByteBuffer.appendByteArray(inByteArray: ByteArray, bufSize: Int) {
val paddingSize = bufSize - inByteArray.size
if (paddingSize < 0) throw IllegalArgumentException("arg length [${inByteArray.size}] exceeds limit: $bufSize")
//data
this.put(inByteArray)
//padding
this.appendPadding(0.toByte(), paddingSize)
log.debug("paddingSize $paddingSize")
}
//char: 1
if (format[0] === Char) {
val data = ByteArray(format[1] as Int)//now its size is fixed at 1
Assert.assertEquals(format[1] as Int, iS.read(data))
ret.add(data[0].toChar())
continue
fun ByteBuffer.appendUByteArray(inIntArray: IntArray, bufSize: Int) {
val arg2 = mutableListOf<UByte>()
inIntArray.toMutableList().mapTo(arg2, {
if (it in UByte.MIN_VALUE.toInt()..UByte.MAX_VALUE.toInt())
it.toUByte()
else
throw IllegalArgumentException("$it is not valid Byte")
})
appendUByteArray(arg2.toUByteArray(), bufSize)
}
//string
if (format[0] === String) {
val data = ByteArray(format[1] as Int)
Assert.assertEquals(format[1] as Int, iS.read(data))
ret.add(Helper.toCString(data))
continue
fun ByteBuffer.appendUByteArray(inUByteArray: UByteArray, bufSize: Int) {
val bl = mutableListOf<Byte>()
inUByteArray.toMutableList().mapTo(bl, { it.toByte() })
this.appendByteArray(bl.toByteArray(), bufSize)
}
}
}
class InputStreamExt {
companion object {
fun InputStream.getChar(): Char {
val data = ByteArray(Byte.SIZE_BYTES)
Assert.assertEquals(Byte.SIZE_BYTES, this.read(data))
return data[0].toChar()
}
fun InputStream.getShort(inByteOrder: ByteOrder): Short {
val data = ByteArray(Short.SIZE_BYTES)
Assert.assertEquals(Short.SIZE_BYTES, this.read(data))
return data.toShort(inByteOrder)
}
fun InputStream.getInt(inByteOrder: ByteOrder): Int {
val data = ByteArray(Int.SIZE_BYTES)
Assert.assertEquals(Int.SIZE_BYTES, this.read(data))
return data.toInt(inByteOrder)
}
//h: short
if (format[0] === Short) {
val data = ByteArray(2)
Assert.assertEquals(2, iS.read(data).toLong())
ByteBuffer.allocate(2).let {
it.order(this.byteOrder)
it.put(data)
fun InputStream.getLong(inByteOrder: ByteOrder): Long {
val data = ByteArray(Long.SIZE_BYTES)
Assert.assertEquals(Long.SIZE_BYTES, this.read(data))
return data.toLong(inByteOrder)
}
fun InputStream.getUShort(inByteOrder: ByteOrder): UShort {
val data = ByteArray(UShort.SIZE_BYTES)
Assert.assertEquals(UShort.SIZE_BYTES, this.read(data))
return data.toUShort(inByteOrder)
}
fun InputStream.getUInt(inByteOrder: ByteOrder): UInt {
val data = ByteArray(UInt.SIZE_BYTES)
Assert.assertEquals(UInt.SIZE_BYTES, this.read(data))
return data.toUInt(inByteOrder)
}
fun InputStream.getULong(inByteOrder: ByteOrder): ULong {
val data = ByteArray(ULong.SIZE_BYTES)
Assert.assertEquals(ULong.SIZE_BYTES, this.read(data))
return data.toULong(inByteOrder)
}
fun InputStream.getByteArray(inSize: Int): ByteArray {
val data = ByteArray(inSize)
Assert.assertEquals(inSize, this.read(data))
return data
}
fun InputStream.getUByteArray(inSize: Int): UByteArray {
val data = ByteArray(inSize)
Assert.assertEquals(inSize, this.read(data))
val innerData2 = mutableListOf<UByte>()
data.toMutableList().mapTo(innerData2, { it.toUByte() })
return innerData2.toUByteArray()
}
fun InputStream.getCString(inSize: Int): String {
val data = ByteArray(inSize)
Assert.assertEquals(inSize, this.read(data))
return data.toCString()
}
fun InputStream.getPadding(inSize: Int): Byte {
val data = ByteArray(Byte.SIZE_BYTES)
Assert.assertEquals(Byte.SIZE_BYTES, this.read(data)) //sample the 1st byte
val skipped = this.skip(inSize.toLong() - Byte.SIZE_BYTES)//skip remaining to save memory
Assert.assertEquals(inSize.toLong() - Byte.SIZE_BYTES, skipped)
return data[0]
}
}
}
class ByteArrayExt {
companion object {
fun ByteArray.toShort(inByteOrder: ByteOrder): Short {
val typeSize = Short.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("Short must have $typeSize bytes", typeSize, this.size)
var ret: Short
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.short)
ret = it.getShort()
}
continue
return ret
}
//H: UShort
if (format[0] === UShort) {
val data = ByteArray(2)
Assert.assertEquals(2, iS.read(data).toLong())
ByteBuffer.allocate(2).let {
it.order(this.byteOrder)
it.put(data)
fun ByteArray.toInt(inByteOrder: ByteOrder): Int {
val typeSize = Int.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("Int must have $typeSize bytes", typeSize, this.size)
var ret: Int
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.short.toUShort())
ret = it.getInt()
}
continue
return ret
}
//i, l: Int
if (format[0] === Int) {
val data = ByteArray(4)
Assert.assertEquals(4, iS.read(data).toLong())
ByteBuffer.allocate(4).let {
it.order(this.byteOrder)
it.put(data)
fun ByteArray.toLong(inByteOrder: ByteOrder): Long {
val typeSize = Long.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("Long must have $typeSize bytes", typeSize, this.size)
var ret: Long
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.int)
ret = it.getLong()
}
continue
return ret
}
//I, L: UInt
if (format[0] === UInt) {
val data = ByteArray(4)
Assert.assertEquals(4, iS.read(data).toLong())
ByteBuffer.allocate(4).let {
it.order(this.byteOrder)
it.put(data)
fun ByteArray.toUShort(inByteOrder: ByteOrder): UShort {
val typeSize = UShort.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("UShort must have $typeSize bytes", typeSize, this.size)
var ret: UShort
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.int.toUInt())
ret = it.getShort().toUShort()
}
continue
return ret
}
//q: Long
if (format[0] === Long) {
val data = ByteArray(8)
Assert.assertEquals(8, iS.read(data).toLong())
ByteBuffer.allocate(8).let {
it.order(this.byteOrder)
it.put(data)
fun ByteArray.toUInt(inByteOrder: ByteOrder): UInt {
val typeSize = UInt.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("UInt must have $typeSize bytes", typeSize, this.size)
var ret: UInt
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.long)
ret = it.getInt().toUInt()
}
continue
return ret
}
//Q: ULong
if (format[0] === ULong) {
val data = ByteArray(8)
Assert.assertEquals(8, iS.read(data).toLong())
ByteBuffer.allocate(8).let {
it.order(this.byteOrder)
it.put(data)
fun ByteArray.toULong(inByteOrder: ByteOrder): ULong {
val typeSize = ULong.SIZE_BYTES / Byte.SIZE_BYTES
Assert.assertEquals("ULong must have $typeSize bytes", typeSize, this.size)
var ret: ULong
ByteBuffer.allocate(typeSize).let {
it.order(inByteOrder)
it.put(this)
it.flip()
ret.add(it.long.toULong())
ret = it.getLong().toULong()
}
continue
return ret
}
throw IllegalArgumentException("Class [" + format[0] + "] not supported")
//similar to this.toString(StandardCharsets.UTF_8).replace("${Character.MIN_VALUE}", "")
// not Deprecated for now, "1.3.41 experimental api: ByteArray.decodeToString()") is a little different
fun ByteArray.toCString(): String {
val str = this.toString(StandardCharsets.UTF_8)
val nullPos = str.indexOf(Character.MIN_VALUE)
return if (nullPos >= 0) {
str.substring(0, nullPos)
} else {
str
}
}
}
return ret
}
//get lower 1 byte
private fun getLowerByte(obj: Char?): Byte {
val bf2 = ByteBuffer.allocate(Character.SIZE / 8) //aka. 16/8
bf2.putChar(obj!!)
bf2.flip()
bf2.get()
return bf2.get()
}
}

@ -20,7 +20,7 @@ class KernelExtractor {
val baseDir = "build/unzip_boot"
val kernelVersionFile = "$baseDir/kernel_version.txt"
val kernelConfigFile = "$baseDir/kernel_configs.txt"
val cmd = CommandLine.parse("external/extract_kernel.py").let {
val cmd = CommandLine.parse("aosp/build/tools/extract_kernel.py").let {
it.addArgument("--input")
it.addArgument(fileName)
it.addArgument("--output-configs")

@ -33,7 +33,7 @@ class BootImgParser() : IPackable {
if (File(UnifiedConfig.workDir).exists()) File(UnifiedConfig.workDir).deleteRecursively()
File(UnifiedConfig.workDir).mkdirs()
try {
val info = Parser().parseBootImgHeader(fileName, avbtool = "avb/avbtool")
val info = Parser().parseBootImgHeader(fileName, avbtool = "aosp/avb/avbtool")
InfoTable.instance.addRule()
InfoTable.instance.addRow("image info", ParamConfig().cfg)
if (info.signatureType == BootImgInfo.VerifyType.AVB) {
@ -69,7 +69,7 @@ class BootImgParser() : IPackable {
override fun pack(fileName: String) {
Packer().pack(mkbootfsBin = "./aosp/mkbootfs/build/exe/mkbootfs/mkbootfs")
Signer.sign(avbtool = "avb/avbtool", bootSigner = "aosp/boot_signer/build/libs/boot_signer.jar")
Signer.sign(avbtool = "aosp/avb/avbtool", bootSigner = "aosp/boot_signer/build/libs/boot_signer.jar")
if (File("vbmeta.img").exists()) {
val partitionName = ObjectMapper().readValue(File(Avb.getJsonFileName(fileName)), AVBInfo::class.java).let {
it.auxBlob!!.hashDescriptors.get(0).partition_name

@ -5,6 +5,7 @@ import cfig.Helper.Companion.check_output
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@ExperimentalUnsignedTypes
interface IPackable {
val loopNo: Int
fun capabilities(): List<String> {

@ -46,6 +46,11 @@ class Struct3Test {
Assert.assertEquals(9, Struct3("9c").calcSize())
}
@Test
fun toStringTest() {
println(Struct3("!4s2L2QL11QL4x47sx80x"))
}
//x
@Test
fun paddingTest() {
@ -189,7 +194,7 @@ class Struct3Test {
Struct3("3s").pack("abcd")
Assert.fail("should throw exception here")
} catch (e: Throwable) {
Assert.assertTrue(e is AssertionError || e is IllegalArgumentException)
Assert.assertTrue(e.toString(), e is AssertionError || e is IllegalArgumentException)
}
//unpack

Binary file not shown.

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

51
gradlew vendored

@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@ -138,19 +154,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@ -159,14 +175,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

18
gradlew.bat vendored

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

@ -8,4 +8,4 @@ include("aosp:libsparse:simg2img")
include("aosp:libsparse:simg2simg")
include("aosp:libsparse:append2simg")
include("aosp:libavb")
include("avbImpl")
//include("avbImpl")

Loading…
Cancel
Save