Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

sbtools: more work on sbtoelf and elftosb, support more attributes

Now handle timestamp, sb minor version, component/product versions,
section flags.

Change-Id: I35313efe60c28f04ea3732b36e5e01be3213cf9e

+106 -85
+18 -38
utils/imxtools/sbtools/dbparser.c
··· 419 419 420 420 #define INVALID_SB_SUBVERSION 0xffff 421 421 422 - static uint16_t parse_sb_subversion(char *str) 422 + static const char *parse_sb_subversion(const char *str, uint16_t *v) 423 423 { 424 - int len = strlen(str); 425 - uint16_t n = 0; 426 - if(len == 0 || len > 4) 427 - return INVALID_SB_SUBVERSION; 428 - for(int i = 0; i < len; i++) 429 - { 430 - if(!isdigit(str[i])) 431 - return INVALID_SB_SUBVERSION; 432 - n = n << 4 | (str[i] - '0'); 433 - } 434 - return n; 424 + int len = 0; 425 + *v = 0; 426 + while(isdigit(str[len]) && len < 3) 427 + *v = (*v) << 4 | (str[len++] - '0'); 428 + if(len == 0) 429 + *v = INVALID_SB_SUBVERSION; 430 + return str + len; 435 431 } 436 432 437 - bool db_parse_sb_version(struct sb_version_t *ver, char *str) 433 + bool db_parse_sb_version(struct sb_version_t *ver, const char *str) 438 434 { 439 - int len = strlen(str); 440 - int cnt = 0; 441 - int pos[2]; 442 - 443 - for(int i = 0; i < len; i++) 444 - { 445 - if(str[i] != '.') 446 - continue; 447 - if(cnt == 2) 448 - return false; 449 - pos[cnt++] = i + 1; 450 - str[i] = 0; 451 - } 452 - if(cnt != 2) 435 + str = parse_sb_subversion(str, &ver->major); 436 + if(ver->major == INVALID_SB_SUBVERSION || *str != '.') 437 + return false; 438 + str = parse_sb_subversion(str + 1, &ver->minor); 439 + if(ver->minor == INVALID_SB_SUBVERSION || *str != '.') 440 + return false; 441 + str = parse_sb_subversion(str + 1, &ver->revision); 442 + if(ver->revision == INVALID_SB_SUBVERSION || *str != 0) 453 443 return false; 454 - ver->major = parse_sb_subversion(str); 455 - ver->minor = parse_sb_subversion(str + pos[0]); 456 - ver->revision = parse_sb_subversion(str + pos[1]); 457 - return ver->major != INVALID_SB_SUBVERSION && 458 - ver->minor != INVALID_SB_SUBVERSION && 459 - ver->revision != INVALID_SB_SUBVERSION; 444 + return true; 460 445 } 461 446 462 447 static bool db_generate_sb_subversion(uint16_t subver, char *str) ··· 829 814 830 815 free(buf); 831 816 return cmd_file; 832 - } 833 - 834 - void db_generate_default_sb_version(struct sb_version_t *ver) 835 - { 836 - ver->major = ver->minor = ver->revision = 0x999; 837 817 } 838 818 839 819 void db_free_option_list(struct cmd_option_t *opt_list)
+1 -1
utils/imxtools/sbtools/dbparser.h
··· 111 111 112 112 struct cmd_source_t *db_find_source_by_id(struct cmd_file_t *cmd_file, const char *id); 113 113 struct cmd_option_t *db_find_option_by_id(struct cmd_option_t *opt, const char *name); 114 - bool db_parse_sb_version(struct sb_version_t *ver, char *str); 114 + bool db_parse_sb_version(struct sb_version_t *ver, const char *str); 115 115 bool db_generate_sb_version(struct sb_version_t *ver, char *str, int size); 116 116 void db_generate_default_sb_version(struct sb_version_t *ver); 117 117 struct cmd_file_t *db_parse_file(const char *file);
+48 -32
utils/imxtools/sbtools/elftosb.c
··· 118 118 src->loaded = true; 119 119 } 120 120 121 + static const char *get_str_opt(struct cmd_option_t *opt_list, const char *id, const char *dflt) 122 + { 123 + struct cmd_option_t *opt = db_find_option_by_id(opt_list, id); 124 + if(!opt) 125 + return dflt; 126 + if(!opt->is_string) 127 + bug("'%s' option must be a string\n", id); 128 + return opt->str; 129 + } 130 + 131 + static uint32_t get_int_opt(struct cmd_option_t *opt_list, const char *id, uint32_t dflt) 132 + { 133 + struct cmd_option_t *opt = db_find_option_by_id(opt_list, id); 134 + if(!opt) 135 + return dflt; 136 + if(opt->is_string) 137 + bug("'%s' option must be an integer\n", id); 138 + return opt->val; 139 + } 140 + 121 141 static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file) 122 142 { 123 143 struct sb_file_t *sb = xmalloc(sizeof(struct sb_file_t)); 124 144 memset(sb, 0, sizeof(struct sb_file_t)); 145 + sb_build_default_image(sb); 125 146 126 - db_generate_default_sb_version(&sb->product_ver); 127 - db_generate_default_sb_version(&sb->component_ver); 147 + if(db_find_option_by_id(cmd_file->opt_list, "componentVersion") && 148 + !db_parse_sb_version(&sb->component_ver, get_str_opt(cmd_file->opt_list, "componentVersion", ""))) 149 + bug("Invalid 'componentVersion' format\n"); 150 + if(db_find_option_by_id(cmd_file->opt_list, "productVersion") && 151 + !db_parse_sb_version(&sb->product_ver, get_str_opt(cmd_file->opt_list, "productVersion", ""))) 152 + bug("Invalid 'productVersion' format\n"); 153 + if(db_find_option_by_id(cmd_file->opt_list, "sbMinorVersion")) 154 + sb->minor_version = get_int_opt(cmd_file->opt_list, "sbMinorVersion", 0); 155 + if(db_find_option_by_id(cmd_file->opt_list, "flags")) 156 + sb->flags = get_int_opt(cmd_file->opt_list, "flags", 0); 157 + if(db_find_option_by_id(cmd_file->opt_list, "driveTag")) 158 + sb->drive_tag = get_int_opt(cmd_file->opt_list, "driveTag", 0); 159 + if(db_find_option_by_id(cmd_file->opt_list, "timestampLow")) 160 + { 161 + if(!db_find_option_by_id(cmd_file->opt_list, "timestampHigh")) 162 + bug("Option 'timestampLow' and 'timestampHigh' must both specified\n"); 163 + sb->timestamp = (uint64_t)get_int_opt(cmd_file->opt_list, "timestampHigh", 0) << 32 | 164 + get_int_opt(cmd_file->opt_list, "timestampLow", 0); 165 + } 128 166 129 167 if(g_debug) 130 168 printf("Applying command file...\n"); ··· 149 187 do 150 188 { 151 189 /* cleartext */ 152 - struct cmd_option_t *opt = db_find_option_by_id(csec->opt_list, "cleartext"); 153 - if(opt != NULL) 154 - { 155 - if(opt->is_string) 156 - bug("Cleartext section attribute must be an integer\n"); 157 - if(opt->val != 0 && opt->val != 1) 158 - bug("Cleartext section attribute must be 0 or 1\n"); 159 - sec->is_cleartext = opt->val; 160 - } 190 + sec->is_cleartext = get_int_opt(csec->opt_list, "cleartext", false); 161 191 /* alignment */ 162 - opt = db_find_option_by_id(csec->opt_list, "alignment"); 163 - if(opt != NULL) 164 - { 165 - if(opt->is_string) 166 - bug("Cleartext section attribute must be an integer\n"); 167 - // n is a power of 2 iff n & (n - 1) = 0 168 - // alignement cannot be lower than block size 169 - if((opt->val & (opt->val - 1)) != 0) 170 - bug("Cleartext section attribute must be a power of two\n"); 171 - if(opt->val < BLOCK_SIZE) 172 - sec->alignment = BLOCK_SIZE; 173 - else 174 - sec->alignment = opt->val; 175 - } 176 - else 192 + sec->alignment = get_int_opt(csec->opt_list, "alignment", BLOCK_SIZE); 193 + // alignement cannot be lower than block size 194 + if((sec->alignment & (sec->alignment - 1)) != 0) 195 + bug("Alignment section attribute must be a power of two\n"); 196 + if(sec->alignment < BLOCK_SIZE) 177 197 sec->alignment = BLOCK_SIZE; 198 + /* other flags */ 199 + sec->other_flags = get_int_opt(csec->opt_list, "sectionFlags", 0) & ~SECTION_STD_MASK; 178 200 }while(0); 179 201 180 202 if(csec->is_data) ··· 423 445 sb_file->override_crypto_iv = true; 424 446 memcpy(sb_file->crypto_iv, crypto_iv.u.key, 16); 425 447 } 426 - 427 - /* fill with default parameters since there is no command file support for them */ 428 - sb_file->drive_tag = 0; 429 - sb_file->first_boot_sec_id = sb_file->sections[0].identifier; 430 - sb_file->flags = 0; 431 - sb_file->minor_version = 1; 432 448 433 449 sb_write_file(sb_file, output_filename, 0, generic_std_printf); 434 450 sb_free(sb_file);
+32 -10
utils/imxtools/sbtools/sb.c
··· 186 186 #undef printf 187 187 } 188 188 189 - static uint64_t generate_timestamp() 189 + uint64_t sb_generate_timestamp(void) 190 190 { 191 191 struct tm tm_base; 192 192 memset(&tm_base, 0, sizeof(tm_base)); ··· 218 218 sb_hdr->signature[2] = 'M'; 219 219 sb_hdr->signature[3] = 'P'; 220 220 sb_hdr->major_ver = IMAGE_MAJOR_VERSION; 221 - sb_hdr->minor_ver = IMAGE_MINOR_VERSION; 222 - sb_hdr->flags = 0; 221 + sb_hdr->minor_ver = sb->minor_version; 222 + sb_hdr->flags = sb->flags; 223 223 sb_hdr->image_size = sb->image_size; 224 224 sb_hdr->header_size = sizeof(struct sb_header_t) / BLOCK_SIZE; 225 - sb_hdr->first_boot_sec_id = sb->first_boot_sec_id; 225 + sb_hdr->first_boot_sec_id = sb->sections[0].identifier; 226 226 sb_hdr->nr_keys = g_nr_keys; 227 227 sb_hdr->nr_sections = sb->nr_sections; 228 228 sb_hdr->sec_hdr_size = sizeof(struct sb_section_header_t) / BLOCK_SIZE; ··· 237 237 if(sb->minor_version >= 1) 238 238 memcpy(&sb_hdr->rand_pad0[2], "sgtl", 4); 239 239 240 - if(sb->override_timestamp) 241 - sb_hdr->timestamp = sb->timestamp; 242 - else 243 - sb_hdr->timestamp = generate_timestamp(); 240 + sb_hdr->timestamp = sb->timestamp; 244 241 sb_hdr->product_ver = sb->product_ver; 245 242 fix_version(&sb_hdr->product_ver); 246 243 sb_hdr->component_ver = sb->component_ver; ··· 261 258 sec_hdr->offset = sec->file_offset; 262 259 sec_hdr->size = sec->sec_size; 263 260 sec_hdr->flags = (sec->is_data ? 0 : SECTION_BOOTABLE) 264 - | (sec->is_cleartext ? SECTION_CLEARTEXT : 0); 261 + | (sec->is_cleartext ? SECTION_CLEARTEXT : 0) 262 + | sec->other_flags; 265 263 } 266 264 267 265 static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr) ··· 281 279 tag->identifier = sec->identifier; 282 280 tag->len = sec->sec_size; 283 281 tag->flags = (sec->is_data ? 0 : SECTION_BOOTABLE) 284 - | (sec->is_cleartext ? SECTION_CLEARTEXT : 0); 282 + | (sec->is_cleartext ? SECTION_CLEARTEXT : 0) 283 + | sec->other_flags; 285 284 tag->hdr.checksum = instruction_checksum(&tag->hdr); 286 285 } 287 286 ··· 333 332 memset(cbc_macs[i], 0, 16); 334 333 335 334 fill_gaps(sb); 335 + if(sb->nr_sections == 0 || sb->sections[0].is_data) 336 + { 337 + cprintf(u, true, GREY, "First section of the image is not bootable, I cannot handle that.\n"); 338 + return SB_ERROR; 339 + } 336 340 compute_sb_offsets(sb, u, cprintf); 337 341 338 342 generate_random_data(real_key.u.key, 16); ··· 983 987 sec, size, " ", u, cprintf, err); 984 988 if(s) 985 989 { 990 + s->other_flags = sec_hdr->flags & ~SECTION_STD_MASK; 986 991 s->is_cleartext = !encrypted; 987 992 s->alignment = guess_alignment(pos); 988 993 memcpy(&sb_file->sections[i], s, sizeof(struct sb_section_t)); ··· 1073 1078 sec, size, " ", u, cprintf, err); 1074 1079 if(s) 1075 1080 { 1081 + s->other_flags = tag->flags & ~SECTION_STD_MASK; 1076 1082 s->is_cleartext = !encrypted; 1077 1083 s->alignment = guess_alignment(pos); 1078 1084 sb_file->sections = augment_array(sb_file->sections, ··· 1138 1144 #undef print_hex 1139 1145 } 1140 1146 1147 + void sb_generate_default_version(struct sb_version_t *ver) 1148 + { 1149 + ver->major = ver->minor = ver->revision = 0x999; 1150 + } 1151 + 1152 + void sb_build_default_image(struct sb_file_t *sb) 1153 + { 1154 + sb->minor_version = IMAGE_MINOR_VERSION; 1155 + sb->timestamp = sb_generate_timestamp(); 1156 + sb_generate_default_version(&sb->product_ver); 1157 + sb_generate_default_version(&sb->component_ver); 1158 + } 1159 + 1141 1160 void sb_free_instruction(struct sb_inst_t inst) 1142 1161 { 1143 1162 free(inst.padding); ··· 1245 1264 printf(TREE, "| +-"); 1246 1265 printf(HEADER, "Alignment: "); 1247 1266 printf(TEXT, "%d (bytes)\n", sec->alignment); 1267 + printf(TREE, "| +-"); 1268 + printf(HEADER, "Other Flags: "); 1269 + printf(TEXT, "%#x\n", sec->other_flags); 1248 1270 printf(TREE, "| +-"); 1249 1271 printf(HEADER, "Instructions\n"); 1250 1272 for(int j = 0; j < sec->nr_insts; j++)
+6 -3
utils/imxtools/sbtools/sb.h
··· 81 81 82 82 #define SECTION_BOOTABLE (1 << 0) 83 83 #define SECTION_CLEARTEXT (1 << 1) 84 + #define SECTION_STD_MASK (3 << 0) 84 85 85 86 #define SB_INST_NOP 0x0 86 87 #define SB_INST_TAG 0x1 ··· 187 188 uint32_t identifier; 188 189 bool is_data; 189 190 bool is_cleartext; 191 + uint32_t other_flags; 190 192 uint32_t alignment; 191 193 // data sections are handled as one or more SB_INST_DATA virtual instruction 192 194 int nr_insts; ··· 204 206 /* override crypto IV, use with caution ! Use NULL to generate it */ 205 207 bool override_crypto_iv; 206 208 uint8_t crypto_iv[16]; 207 - /* override timestamp */ 208 - bool override_timestamp; 209 209 uint64_t timestamp; /* In microseconds since 2000/1/1 00:00:00 */ 210 + uint8_t minor_version; 210 211 211 212 int nr_sections; 212 213 uint16_t drive_tag; 213 214 uint32_t first_boot_sec_id; 214 215 uint16_t flags; 215 - uint8_t minor_version; 216 216 struct sb_section_t *sections; 217 217 struct sb_version_t product_ver; 218 218 struct sb_version_t component_ver; ··· 244 244 struct sb_file_t *sb_read_memory(void *buffer, size_t size, bool raw_mode, void *u, 245 245 generic_printf_t printf, enum sb_error_t *err); 246 246 247 + uint64_t sb_generate_timestamp(void); 248 + void sb_generate_default_version(struct sb_version_t *ver); 249 + void sb_build_default_image(struct sb_file_t *file); 247 250 void sb_fill_section_name(char name[5], uint32_t identifier); 248 251 void sb_dump(struct sb_file_t *file, void *u, generic_printf_t printf); 249 252 void sb_free_instruction(struct sb_inst_t inst);
+1 -1
utils/imxtools/sbtools/sbtoelf.c
··· 96 96 struct cmd_section_t *db_sec = db_add_section(cmd_file, sec->identifier, sec->is_data); 97 97 db_add_int_opt(&db_sec->opt_list, "alignment", sec->alignment); 98 98 db_add_int_opt(&db_sec->opt_list, "cleartext", sec->is_cleartext); 99 + db_add_int_opt(&db_sec->opt_list, "sectionFlags", sec->other_flags); 99 100 100 101 if(sec->is_data) 101 102 { ··· 413 414 * garbage */ 414 415 file->override_real_key = false; 415 416 file->override_crypto_iv = false; 416 - file->override_timestamp = true; 417 417 sb_write_file(file, loopback, 0, generic_std_printf); 418 418 } 419 419 sb_free(file);