1

与 linux gcc 编译器相比,我看到读取 bin 文件并映射到 windows 中的结构的奇怪行为。

下面是我的c代码:

#include <inttypes.h>
#include <stdio.h>
#include <fcntl.h>

#define IV_MAX_LEN              32
#define HASH_MAX_LEN            64
#define MAX_NUM_IMGS            8
#define MAX_NUM_SRK_RECORDS     4
#define SKIP_OFFSET_1K          0x400

typedef struct {
    uint8_t version;
    uint16_t length;
    uint8_t tag;
    uint16_t srk_table_offset;
    uint16_t cert_offset;
    uint16_t blob_offset;
    uint16_t signature_offset;
    uint32_t reserved;
} __attribute__((packed)) blk_hdr_t;

typedef struct {
    uint32_t offset;
    uint32_t size;
    uint64_t dst;
    uint64_t entry;
    uint32_t hab_flags;
    uint32_t meta;
    uint8_t hash[HASH_MAX_LEN];
    uint8_t iv[IV_MAX_LEN];
} __attribute__((packed)) boot_t;
typedef struct {
    uint8_t version;
    uint16_t length;
    uint8_t tag;
    uint32_t flags;
    uint16_t sw_version;
    uint8_t fuse_version;
    uint8_t num_images;
    uint16_t sig_blk_offset;
    uint16_t reserved;
    boot_t img[MAX_NUM_IMGS];
    blk_hdr_t blk_hdr;
    uint32_t sigblk_size;
    uint32_t padding;
} __attribute__((packed)) headerMain_t;

int main()
{
    int ofd =1;
    char filename[] = "sample.bin";
    int readSizes= 0;
    int headerSizes= 0;
    headerMain_t header;
    uint8_t *byte;

    ofd = open(filename, O_RDONLY);
    printf("\nOPENING File: %s!\n", filename);
    printf("\n STRUCT sizes: %d, %d, %d,\n", sizeof(headerMain_t), sizeof(boot_t), sizeof(blk_hdr_t));
#if 0
    if(lseek(ofd, SKIP_OFFSET_1K, SEEK_SET) < 0) {
        printf("Error Read \n");
    }
#endif    
    readSizes = read(ofd, &header, sizeof(header)) ;
    headerSizes = sizeof(header);
    printf("\n Read SIZE: %d / %d !",readSizes,headerSizes);
    
    printf("\n Read Bytes: \n");
    byte = (uint8_t*)&header;
    for(int i=0; i<readSizes; i++)
    {
        printf("0x%02x, ",*byte);
        byte++;
        if(0 ==i%20 )
            printf("\n");
    }
    
    return 0;
}

这是它读取的输入二进制文件。(此示例 bin 文件为0x01(20 次)... 0xFF(20 次) = 所以255 x 20 = 5100 字节)相同的代码在 windows mingW-gcc 和 linux gcc 中编译和运行。

以下是在 windows 运行中看到的奇怪观察: 在此处输入图像描述

  1. blk_hdr_tstruct 虽然 4 字节对齐,总共 16 字节:22 字节(更新:我发现这个解决方案与 -mno-ms-bitfields 选项一起使用)
  2. 尽管有 5100 字节可用,但 read() 函数只能读取 1000 字节。是什么让它进一步阅读?
  3. read() 还会将具有“0x00”字节值的“孔”放入其中。我不明白这种奇怪的行为。
  4. 启用 lseek 跳过前 1024 个字节应到达文件末尾。

linux 结果上的一切看起来都很完美(尽管第 3 点)在 linux 端也确实存在:虽然这对我来说微不足道,但我对这种行为很好奇)

所以最后,如何在 windows gcc 上使用与linux gcc 中的精确结果一样的代码?谁能启发我?(结构中的参数不能重新洗牌)

4

0 回答 0