Skip to content

Commit

Permalink
libmbcommon: Remove concept of fatal state from mb::File
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Gunnerson <[email protected]>
  • Loading branch information
chenxiaolong committed Nov 25, 2018
1 parent fa1bbfb commit 779c44c
Show file tree
Hide file tree
Showing 20 changed files with 89 additions and 400 deletions.
51 changes: 14 additions & 37 deletions libmbbootimg/src/format/android_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,20 +246,13 @@ AndroidFormatReader::find_header(Reader &reader, File &file,
return AndroidError::InvalidArgument;
}

auto seek_ret = file.seek(0, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(0, SEEK_SET));

auto n = file_read_retry(file, buf, static_cast<size_t>(max_header_offset)
+ sizeof(AndroidHeader));
if (!n) {
if (file.is_fatal()) { reader.set_fatal(); }
return n.as_failure();
}
OUTCOME_TRY(n, file_read_retry(file, buf,
static_cast<size_t>(max_header_offset)
+ sizeof(AndroidHeader)));

auto buf_end = buf + n.value();
auto buf_end = buf + n;
auto it = std2::search(
buf, buf_end, std2::boyer_moore_searcher<const unsigned char *>(
BOOT_MAGIC, BOOT_MAGIC + BOOT_MAGIC_SIZE));
Expand All @@ -271,7 +264,7 @@ AndroidFormatReader::find_header(Reader &reader, File &file,

offset = static_cast<size_t>(it - buf);

if (n.value() - offset < sizeof(AndroidHeader)) {
if (n - offset < sizeof(AndroidHeader)) {
//DEBUG("Android header at %" MB_PRIzu " exceeds file size", offset);
return AndroidError::HeaderOutOfBounds;
}
Expand Down Expand Up @@ -329,20 +322,12 @@ AndroidFormatReader::find_samsung_seandroid_magic(Reader &reader, File &file,
pos += hdr.dt_size;
pos += align_page_size<uint64_t>(pos, hdr.page_size);

auto seek_ret = file.seek(static_cast<int64_t>(pos), SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(static_cast<int64_t>(pos), SEEK_SET));

auto n = file_read_retry(file, buf, sizeof(buf));
if (!n) {
if (file.is_fatal()) { reader.set_fatal(); }
return n.as_failure();
}
OUTCOME_TRY(n, file_read_retry(file, buf, sizeof(buf)));

if (n.value() != SAMSUNG_SEANDROID_MAGIC_SIZE
|| memcmp(buf, SAMSUNG_SEANDROID_MAGIC, n.value()) != 0) {
if (n != SAMSUNG_SEANDROID_MAGIC_SIZE
|| memcmp(buf, SAMSUNG_SEANDROID_MAGIC, n) != 0) {
//DEBUG("SEAndroid magic not found in last %" MB_PRIzu " bytes",
// SAMSUNG_SEANDROID_MAGIC_SIZE);
return AndroidError::SamsungMagicNotFound;
Expand Down Expand Up @@ -397,20 +382,12 @@ AndroidFormatReader::find_bump_magic(Reader &reader, File &file,
pos += hdr.dt_size;
pos += align_page_size<uint64_t>(pos, hdr.page_size);

auto seek_ret = file.seek(static_cast<int64_t>(pos), SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(static_cast<int64_t>(pos), SEEK_SET));

auto n = file_read_retry(file, buf, sizeof(buf));
if (!n) {
if (file.is_fatal()) { reader.set_fatal(); }
return n.as_failure();
}
OUTCOME_TRY(n, file_read_retry(file, buf, sizeof(buf)));

if (n.value() != bump::BUMP_MAGIC_SIZE
|| memcmp(buf, bump::BUMP_MAGIC, n.value()) != 0) {
if (n != bump::BUMP_MAGIC_SIZE
|| memcmp(buf, bump::BUMP_MAGIC, n) != 0) {
//DEBUG("Bump magic not found in last %" MB_PRIzu " bytes",
// bump::BUMP_MAGIC_SIZE);
return AndroidError::BumpMagicNotFound;
Expand Down
24 changes: 4 additions & 20 deletions libmbbootimg/src/format/android_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,7 @@ oc::result<void> AndroidFormatWriter::close(File &file)
? bump::BUMP_MAGIC_SIZE
: SAMSUNG_SEANDROID_MAGIC_SIZE;

auto ret = file_write_exact(file, magic, magic_size);
if (!ret) {
if (file.is_fatal()) { m_writer.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_write_exact(file, magic, magic_size));

// Set ID
unsigned char digest[SHA_DIGEST_LENGTH];
Expand All @@ -126,18 +122,10 @@ oc::result<void> AndroidFormatWriter::close(File &file)
android_fix_header_byte_order(m_hdr);

// Seek back to beginning to write header
auto seek_ret = file.seek(0, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { m_writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(0, SEEK_SET));

// Write header
ret = file_write_exact(file, &m_hdr, sizeof(m_hdr));
if (!ret) {
if (file.is_fatal()) { m_writer.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_write_exact(file, &m_hdr, sizeof(m_hdr)));
}
}

Expand Down Expand Up @@ -223,11 +211,7 @@ oc::result<void> AndroidFormatWriter::write_header(File &file,
OUTCOME_TRYV(m_seg->set_entries(std::move(entries)));

// Start writing after first page
auto seek_ret = file.seek(m_hdr.page_size, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { m_writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(m_hdr.page_size, SEEK_SET));

return oc::success();
}
Expand Down
50 changes: 10 additions & 40 deletions libmbbootimg/src/format/loki.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,9 @@ static oc::result<void>
_loki_read_android_header(Writer &writer, File &file,
android::AndroidHeader &ahdr)
{
auto seek_ret = file.seek(0, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(0, SEEK_SET));

auto ret = file_read_exact(file, &ahdr, sizeof(ahdr));
if (!ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_read_exact(file, &ahdr, sizeof(ahdr)));

android_fix_header_byte_order(ahdr);

Expand All @@ -171,17 +163,9 @@ _loki_write_android_header(Writer &writer, File &file,

android_fix_header_byte_order(dup);

auto seek_ret = file.seek(0, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(0, SEEK_SET));

auto ret = file_write_exact(file, &dup, sizeof(dup));
if (!ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_write_exact(file, &dup, sizeof(dup)));

return oc::success();
}
Expand All @@ -194,17 +178,9 @@ _loki_write_loki_header(Writer &writer, File &file,

loki_fix_header_byte_order(dup);

auto seek_ret = file.seek(LOKI_MAGIC_OFFSET, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(LOKI_MAGIC_OFFSET, SEEK_SET));

auto ret = file_write_exact(file, &dup, sizeof(dup));
if (!ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_write_exact(file, &dup, sizeof(dup)));

return oc::success();
}
Expand All @@ -214,11 +190,9 @@ _loki_move_dt_image(Writer &writer, File &file,
uint64_t aboot_offset, uint32_t fake_size, uint32_t dt_size)
{
// Move DT image
auto n = file_move(file, aboot_offset, aboot_offset + fake_size, dt_size);
if (!n) {
if (file.is_fatal()) { writer.set_fatal(); }
return n.as_failure();
} else if (n.value() != dt_size) {
OUTCOME_TRY(n, file_move(file, aboot_offset, aboot_offset + fake_size,
dt_size));
if (n != dt_size) {
// Non-recoverable
writer.set_fatal();
return FileError::UnexpectedEof;
Expand All @@ -239,11 +213,7 @@ _loki_write_aboot(Writer &writer, File &file,
return LokiError::AbootFunctionOutOfRange;
}

auto seek_ret = file.seek(static_cast<int64_t>(aboot_offset), SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { writer.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(static_cast<int64_t>(aboot_offset), SEEK_SET));

auto ret = file_write_exact(file, aboot + aboot_func_offset, fake_size);
if (!ret) {
Expand Down
73 changes: 15 additions & 58 deletions libmbbootimg/src/format/loki_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,18 +216,13 @@ oc::result<void> LokiFormatReader::find_loki_header(Reader &reader, File &file,
{
LokiHeader header;

auto seek_ret = file.seek(LOKI_MAGIC_OFFSET, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(LOKI_MAGIC_OFFSET, SEEK_SET));

auto ret = file_read_exact(file, &header, sizeof(header));
if (!ret) {
if (ret.error() == FileError::UnexpectedEof) {
return LokiError::LokiHeaderTooSmall;
} else {
if (file.is_fatal()) { reader.set_fatal(); }
return ret.as_failure();
}
}
Expand Down Expand Up @@ -282,31 +277,18 @@ LokiFormatReader::find_ramdisk_address(Reader &reader, File &file,
return FileSearchAction::Continue;
};

auto ret = file_search(file, {}, {}, 0, LOKI_SHELLCODE,
LOKI_SHELLCODE_SIZE - 9, 1, result_cb);
if (!ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_search(file, {}, {}, 0, LOKI_SHELLCODE,
LOKI_SHELLCODE_SIZE - 9, 1, result_cb));

if (offset == 0) {
return LokiError::ShellcodeNotFound;
}

offset += LOKI_SHELLCODE_SIZE - 5;

auto seek_ret = file.seek(static_cast<int64_t>(offset), SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(static_cast<int64_t>(offset), SEEK_SET));

auto read_ret = file_read_exact(file, &ramdisk_addr,
sizeof(ramdisk_addr));
if (!read_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return read_ret.as_failure();
}
OUTCOME_TRYV(file_read_exact(file, &ramdisk_addr, sizeof(ramdisk_addr)));

ramdisk_addr = mb_le32toh(ramdisk_addr);
} else {
Expand Down Expand Up @@ -409,12 +391,8 @@ LokiFormatReader::find_gzip_offset_old(Reader &reader, File &file,
return FileSearchAction::Continue;
};

auto ret = file_search(file, start_offset, {}, 0, gzip_deflate_magic,
sizeof(gzip_deflate_magic), {}, result_cb);
if (!ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_search(file, start_offset, {}, 0, gzip_deflate_magic,
sizeof(gzip_deflate_magic), {}, result_cb));

// Prefer gzip header with original filename flag since most loki'd boot
// images will have been compressed manually with the gzip tool
Expand Down Expand Up @@ -468,43 +446,30 @@ LokiFormatReader::find_ramdisk_size_old(Reader &reader, File &file,
aboot_size = 0x200;
}

auto aboot_offset = file.seek(-aboot_size, SEEK_END);
if (!aboot_offset) {
if (file.is_fatal()) { reader.set_fatal(); }
return aboot_offset.as_failure();
}
OUTCOME_TRY(aboot_offset, file.seek(-aboot_size, SEEK_END));

if (ramdisk_offset > aboot_offset.value()) {
if (ramdisk_offset > aboot_offset) {
return LokiError::RamdiskOffsetGreaterThanAbootOffset;
}

// Ignore zero padding as we might strip away too much
#if 1
ramdisk_size_out = static_cast<uint32_t>(
aboot_offset.value() - ramdisk_offset);
ramdisk_size_out = static_cast<uint32_t>(aboot_offset - ramdisk_offset);
return oc::success();
#else
char buf[1024];
// Search backwards to find non-zero byte
uint64_t cur_offset = aboot_offset.value();
uint64_t cur_offset = aboot_offset;
while (cur_offset > ramdisk_offset) {
size_t to_read = std::min<uint64_t>(
sizeof(buf), cur_offset - ramdisk_offset);
cur_offset -= to_read;
auto seek_ret = file.seek(cur_offset, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(cur_offset, SEEK_SET));
auto ret = file_read_exact(file, buf, to_read);
if (!ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_read_exact(file, buf, to_read));
for (size_t i = to_read; i-- > 0; ) {
if (buf[i] != '\0') {
Expand Down Expand Up @@ -548,17 +513,9 @@ LokiFormatReader::find_linux_kernel_size(Reader &reader,File &file,
// shellcode). The size is stored in the kernel image's header though, so
// we'll use that.
// http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e309
auto seek_ret = file.seek(kernel_offset + 0x2c, SEEK_SET);
if (!seek_ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return seek_ret.as_failure();
}
OUTCOME_TRYV(file.seek(kernel_offset + 0x2c, SEEK_SET));

auto ret = file_read_exact(file, &kernel_size, sizeof(kernel_size));
if (!ret) {
if (file.is_fatal()) { reader.set_fatal(); }
return ret.as_failure();
}
OUTCOME_TRYV(file_read_exact(file, &kernel_size, sizeof(kernel_size)));

kernel_size_out = mb_le32toh(kernel_size);
return oc::success();
Expand Down
Loading

0 comments on commit 779c44c

Please sign in to comment.