#define CBFS_HEADER_PTR 0xfffffffc #define CBFS_HEADER_MAGIC 0 #define CBFS_HEADER_VERSION (CBFS_HEADER_MAGIC + 4) #define CBFS_HEADER_ROMSIZE (CBFS_HEADER_VERSION + 4) #define CBFS_HEADER_BOOTBLOCKSIZE (CBFS_HEADER_ROMSIZE + 4) #define CBFS_HEADER_ALIGN (CBFS_HEADER_BOOTBLOCKSIZE + 4) #define CBFS_HEADER_OFFSET (CBFS_HEADER_ALIGN + 4) #define CBFS_FILE_MAGIC 0 #define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8) #define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4) #define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4) #define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4) #define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4) #define CBFS_STAGE_COMPRESSION 0 #define CBFS_STAGE_ENTRY (CBFS_STAGE_COMPRESSION + 4) #define CBFS_STAGE_LOAD (CBFS_STAGE_ENTRY + 8) #define CBFS_STAGE_LEN (CBFS_STAGE_LOAD + 8) #define CBFS_STAGE_MEMLEN (CBFS_STAGE_LEN + 4) /* input %esi: filename input %esp: return address (not pointer to return address!) output %eax: entry point clobbers %ebx, %ecx, %edi */ walkcbfs: mov CBFS_HEADER_PTR, %eax mov CBFS_HEADER_ROMSIZE(%eax), %ecx bswap %ecx mov $0, %ebx sub %ecx, %ebx mov CBFS_HEADER_OFFSET(%eax), %ecx bswap %ecx add %ecx, %ebx /* determine filename length */ mov $0, %eax 1: cmpb $0, (%eax,%esi) jz 2f add $1, %eax jmp 1b 2: add $1, %eax walker: mov %ebx, %edi add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */ mov %eax, %ecx repe cmpsb # zero flag set if strings are equal jnz tryharder # we found it! mov CBFS_FILE_OFFSET(%ebx), %eax bswap %eax add %ebx, %eax add $CBFS_STAGE_ENTRY, %eax /* eax = ((cbfs_stage* (cbfs_file* ebx)->offset)->entry) */ mov 0(%eax), %eax jmp *%esp tryharder: sub %ebx, %edi /* edi = # of walked bytes */ sub %edi, %esi /* esi = start of filename */ /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */ mov CBFS_FILE_OFFSET(%ebx), %ecx bswap %ecx add %ebx, %ecx mov CBFS_FILE_LEN(%ebx), %edi bswap %edi add %edi, %ecx mov CBFS_HEADER_PTR, %ebx mov CBFS_HEADER_ALIGN(%ebx), %ebx bswap %ebx sub $1, %ebx add %ebx, %ecx mov %ebx, %edi not %edi and %edi, %ecx mov %ecx, %ebx /* look if we should exit */ mov CBFS_HEADER_PTR, %ecx mov CBFS_HEADER_ROMSIZE(%ecx), %ecx bswap %ecx not %ecx add $1, %ecx cmp %ebx, %ecx /* if we're still inside the ROM area, jump back */ jbe walker mov $0, %eax jmp *%esp