Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170904746
D59377.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D59377.diff
View Options
Index: mkimg/mkimg.c
===================================================================
--- mkimg/mkimg.c
+++ mkimg/mkimg.c
@@ -492,15 +492,19 @@
offset = NULL;
}
}
- if (offset != NULL) {
- if (*offset != '+')
- abs_offset = true;
- else
- offset++;
- if (expand_number(offset, &byteoffset) == -1)
- error = errno;
- }
break;
+ default:
+ offset = NULL;
+ break;
+ }
+
+ if (offset != NULL) {
+ if (*offset != '+')
+ abs_offset = true;
+ else
+ offset++;
+ if (expand_number(offset, &byteoffset) == -1)
+ error = errno;
}
/* Work out exactly where the partition starts. */
Index: mkimg/tests/Makefile
===================================================================
--- mkimg/tests/Makefile
+++ mkimg/tests/Makefile
@@ -4,6 +4,7 @@
_REBASE_SCRIPT= mkimg_test
ATF_TESTS_SH= ${_REBASE_SCRIPT}
+ATF_TESTS_SH+= mkimg_offset_test
SOURCES!= cd ${.CURDIR}; echo *.hex
${PACKAGE}FILES+= ${SOURCES:S,.hex,,g}
Index: mkimg/tests/mkimg_offset_test.sh
===================================================================
--- /dev/null
+++ mkimg/tests/mkimg_offset_test.sh
@@ -0,0 +1,227 @@
+#
+# Regression tests for partition offsets in mkimg(1) partition specifications.
+#
+# mkimg(1) documents an optional offset for a partition specification:
+#
+# <t>[/<l>]::<size>[:[+]<offset>] - SIZE form
+# <t>[/<l>]:=<file>[:[+]<offset>] - FILE form
+#
+# An offset without a "+" prefix is absolute from the start of the image; with
+# a "+" prefix it is relative to the end of the preceding partition. Both
+# forms must honour both kinds of offset.
+#
+# These tests assert the resulting start LBA rather than comparing a hexdump
+# baseline, so a failure reports the address that was actually produced.
+#
+
+# Start LBA of partition $2 (1-based) in GPT image $1, for an image whose
+# logical sector size is $3 (default 512).
+#
+# The GPT entry array starts at LBA 2, so its byte offset scales with the
+# sector size. Entries are 128 bytes and the starting LBA is a little-endian
+# 64-bit value at offset 32 within an entry; both are fixed by the spec. Only
+# the low 32 bits are read, which is ample for these images and keeps the
+# arithmetic inside what expr(1) handles portably.
+gpt_start_lba()
+{
+ local image index secsz off byte shift value
+
+ image=$1
+ index=$2
+ secsz=${3:-512}
+
+ off=$(((2 * secsz) + (index - 1) * 128 + 32))
+
+ value=0
+ shift=1
+ # Little-endian: least significant byte first.
+ for byte in $(od -A n -t u1 -j $off -N 4 "$image"); do
+ value=$((value + byte * shift))
+ shift=$((shift * 256))
+ done
+ echo $value
+}
+
+# Build a 512-byte-sector GPT image whose second partition is requested at an
+# offset, then check where that partition actually landed.
+#
+# $1 partition specification for partition 2
+# $2 expected start LBA of partition 2
+check_second_partition()
+{
+ local spec want got
+
+ spec=$1
+ want=$2
+
+ # Partition 1 is 25 blocks, so without offset handling partition 2
+ # would be packed at LBA 34 + 25 = 59. The expected offsets below are
+ # all beyond that, which is what makes the failure observable.
+ atf_check -s exit:0 -o empty -e empty \
+ mkimg -s gpt -S 512 -P 512 --capacity 16m \
+ -p freebsd-boot::12800 \
+ -p "$spec" \
+ -o image.raw
+
+ got=$(gpt_start_lba image.raw 2)
+ if test "$got" != "$want"; then
+ atf_fail "partition 2 starts at LBA $got, expected $want"
+ fi
+}
+
+# As check_second_partition(), but for a 4096-byte logical sector image.
+#
+# Note that -S sets the logical sector size that determines the GPT layout;
+# -P only sets the physical block size used for alignment. Partition 1 is 2m,
+# which at this sector size spans LBA 6 through 517, so the offsets used below
+# have to reach past that to avoid an overlap.
+#
+# $1 partition specification for partition 2
+# $2 expected start LBA of partition 2
+check_second_partition_4k()
+{
+ local spec want got
+
+ spec=$1
+ want=$2
+
+ atf_check -s exit:0 -o empty -e empty \
+ mkimg -s gpt -S 4096 -P 4096 --capacity 64m \
+ -p freebsd-boot::2m \
+ -p "$spec" \
+ -o image4k.raw
+
+ got=$(gpt_start_lba image4k.raw 2 4096)
+ if test "$got" != "$want"; then
+ atf_fail "partition 2 starts at LBA $got, expected $want"
+ fi
+}
+
+atf_test_case size_absolute_offset
+size_absolute_offset_head()
+{
+ atf_set "descr" "SIZE form honours an absolute offset"
+}
+size_absolute_offset_body()
+{
+ # 40960 bytes / 512 = LBA 80. This is the specification form and the
+ # offset used by release/amd64/mkisoimages.sh for the ESP.
+ check_second_partition "efi::2m:40960" 80
+}
+
+atf_test_case size_relative_offset
+size_relative_offset_head()
+{
+ atf_set "descr" "SIZE form honours a relative offset"
+}
+size_relative_offset_body()
+{
+ # Partition 1 ends at LBA 58, so +10752 bytes (21 blocks) is LBA 80.
+ check_second_partition "efi::2m:+10752" 80
+}
+
+atf_test_case file_absolute_offset
+file_absolute_offset_head()
+{
+ atf_set "descr" "FILE form honours an absolute offset"
+}
+file_absolute_offset_body()
+{
+ check_second_partition \
+ "efi:=$(atf_get_srcdir)/partition_data_4M.bin:40960" 80
+}
+
+atf_test_case file_relative_offset
+file_relative_offset_head()
+{
+ atf_set "descr" "FILE form honours a relative offset"
+}
+file_relative_offset_body()
+{
+ check_second_partition \
+ "efi:=$(atf_get_srcdir)/partition_data_4M.bin:+10752" 80
+}
+
+atf_test_case size_no_offset
+size_no_offset_head()
+{
+ atf_set "descr" "SIZE form without an offset packs after the previous partition"
+}
+size_no_offset_body()
+{
+ # Guards against a fix that treats a missing offset as an absolute 0.
+ check_second_partition "efi::2m" 59
+}
+
+atf_test_case file_colon_in_name
+file_colon_in_name_head()
+{
+ atf_set "descr" "FILE form accepts a filename containing a colon"
+}
+file_colon_in_name_body()
+{
+ # An existing file wins over the offset interpretation, so a colon in
+ # the name must not be parsed as an offset separator. This is the
+ # behaviour the parser rework was written to provide; keep it covered
+ # so restoring offsets to the SIZE form cannot regress it.
+ atf_check -s exit:0 -o empty -e empty \
+ cp "$(atf_get_srcdir)/partition_data_4M.bin" "odd:name.bin"
+ check_second_partition "efi:=odd:name.bin" 59
+}
+
+atf_test_case size_absolute_offset_4k
+size_absolute_offset_4k_head()
+{
+ atf_set "descr" "SIZE form honours an absolute offset with 4K sectors"
+}
+size_absolute_offset_4k_body()
+{
+ # 2621440 bytes / 4096 = LBA 640.
+ check_second_partition_4k "efi::2m:2621440" 640
+}
+
+atf_test_case size_relative_offset_4k
+size_relative_offset_4k_head()
+{
+ atf_set "descr" "SIZE form honours a relative offset with 4K sectors"
+}
+size_relative_offset_4k_body()
+{
+ # Partition 1 ends at LBA 517, so +512000 bytes (125 blocks) is LBA 643.
+ check_second_partition_4k "efi::2m:+512000" 643
+}
+
+atf_test_case file_absolute_offset_4k
+file_absolute_offset_4k_head()
+{
+ atf_set "descr" "FILE form honours an absolute offset with 4K sectors"
+}
+file_absolute_offset_4k_body()
+{
+ check_second_partition_4k \
+ "efi:=$(atf_get_srcdir)/partition_data_4M.bin:2621440" 640
+}
+
+atf_test_case size_no_offset_4k
+size_no_offset_4k_head()
+{
+ atf_set "descr" "SIZE form without an offset packs after the previous partition with 4K sectors"
+}
+size_no_offset_4k_body()
+{
+ check_second_partition_4k "efi::2m" 518
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case size_absolute_offset
+ atf_add_test_case size_relative_offset
+ atf_add_test_case file_absolute_offset
+ atf_add_test_case file_relative_offset
+ atf_add_test_case size_no_offset
+ atf_add_test_case file_colon_in_name
+ atf_add_test_case size_absolute_offset_4k
+ atf_add_test_case size_relative_offset_4k
+ atf_add_test_case file_absolute_offset_4k
+ atf_add_test_case size_no_offset_4k
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 8, 11:36 AM (3 h, 22 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38514388
Default Alt Text
D59377.diff (7 KB)
Attached To
Mode
D59377: mkimg: Restore offset support for the SIZE partition form
Attached
Detach File
Event Timeline
Log In to Comment