DF-5833 / parse2.c
#include <sys/types.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma pack(1) typedef struct { unsigned char e_ident[16]; uint16_t e_type,e_machine; uint32_t e_version; uint64_t e_entry,e_phoff,e_shoff; uint32_t e_flags; uint16_t e_ehsize,e_phentsize,e_phnum,e_shentsize,e_shnum,e_shstrndx; } Ehdr; typedef struct { uint32_t p_type,p_flags; uint64_t p_offset,p_vaddr,p_paddr,p_filesz,p_memsz,p_align; } Phdr; #pragma pack() int main(int argc,char**argv){ FILE*f=fopen(argv[1],"rb"); Ehdr eh; fread(&eh,sizeof eh,1,f); Phdr*ph=calloc(eh.e_phnum,56); fseek(f,eh.e_phoff,SEEK_SET); fread(ph,56,eh.e_phnum,f); uint64_t no=0,ns=0,p1off=0; for(int i=0;i<eh.e_phnum;i++) if(ph[i].p_type==4){no=ph[i].p_offset;ns=ph[i].p_filesz;} for(int i=0;i<eh.e_phnum;i++) if(ph[i].p_type==1){p1off=ph[i].p_offset;break;} printf("phnum=%u note_off=%llu note_sz=%llu seg1_off=%llu\n",eh.e_phnum,(unsigned long long)no,(unsigned long long)ns,(unsigned long long)p1off); /* expected WRITE end raw = 64 + phnum*56 + note_sz + 100 + C + 4320 + 40 + nfileinfo*80 */ /* inspect the region after the notes: vminfo(96) vn_count(4) vn_hdrs... sigs(4320) filehdr(40)... */ unsigned char *b=malloc(ns+6000); fseek(f,no,SEEK_SET); fread(b,1,ns+6000,f); uint64_t p=no+ns; /* absolute file offset of vminfo */ printf("vminfo region at %llu:\n",(unsigned long long)p); /* ckpt_vminfo: cvm_dsize.. 6 segsz + 6 caddr — dump first 96 bytes */ for(int r=0;r<6;r++){ for(int c=0;c<16;c++) printf("%02x ", b[(p-no)+r*16+c]); printf("\n"); } int vnc; memcpy(&vnc, b+(p-no)+96, 4); printf("vn_count=%d\n", vnc); /* after vn_hdrs: siginfo: csi_ckptpisz = sizeof(struct ckpt_siginfo)=4320 */ uint64_t sigp = p + 100 + (uint64_t)vnc*120; int pisz; memcpy(&pisz, b+(sigp-no), 4); printf("siginfo at %llu csi_ckptpisz=%d (expect 4320)\n",(unsigned long long)sigp,pisz); uint64_t fh = sigp + 4320; int magic=0,nfiles=0; memcpy(&magic,b+(fh-no),4); memcpy(&nfiles,b+(fh-no)+4,4); printf("filehdr at %llu magic=%x nfiles=%d\n",(unsigned long long)fh,magic,nfiles); /* WRITE_end_raw = fh + 40 + nfiles*80 ; check rounding vs seg1_off */ uint64_t wer = fh + 40 + (uint64_t)nfiles*80; printf("WRITE_end_raw=%llu round_page=%llu seg1_off=%llu %s\n", (unsigned long long)wer,(unsigned long long)((wer+4095)&~4095ULL), (unsigned long long)p1off, (((wer+4095)&~4095ULL)==p1off)?"CONSISTENT":"INCONSISTENT"); return 0; } |