struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) { struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); uint i; /* allocate storage for program inputs/outputs, aligned to 16 bytes */ qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16); qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16); qss->machine.Inputs = align16(qss->inputs); qss->machine.Outputs = align16(qss->outputs); qss->stage.softpipe = softpipe; qss->stage.begin = shade_begin; qss->stage.run = shade_quad; qss->stage.destroy = shade_destroy; /* set TGSI sampler state that's constant */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { assert(softpipe->tex_cache[i]); qss->samplers[i].get_samples = sp_get_samples; qss->samplers[i].pipe = &softpipe->pipe; qss->samplers[i].cache = softpipe->tex_cache[i]; } tgsi_exec_machine_init( &qss->machine ); return &qss->stage; }
void q_atomic_lock(int *lock) { // ldcw requires a 16-byte aligned address volatile int *x = align16(lock); while (q_ldcw(x) == 0) ; }
static char *portaddr2str(struct PortAddress *addr) { static char buf[BIN_BUF_SIZE]; switch(align16(&addr->networkProtocol)) { case TRANS_UDP_IPV4: if (align16(&addr->addressLength) == 4 && inet_ntop(AF_INET, addr->address, buf, sizeof(buf))) return buf; break; case TRANS_UDP_IPV6: if (align16(&addr->addressLength) == 16 && inet_ntop(AF_INET6, addr->address, buf, sizeof(buf))) return buf; break; } bin2str_impl(addr->address, align16(&addr->addressLength), buf, sizeof(buf)); return buf; }
static ucell *aligncell(ucell *v) { if (pc_cellsize==2) return align16(v); if (pc_cellsize==4) return align32(v); #if PAWN_CELL_SIZE>=64 if (pc_cellsize==8) return align64(v); #endif assert(0); }
int SavedataParam::UpdateHash(u8* sfoData, int sfoSize, int sfoDataParamsOffset, int encryptmode) { int alignedLen = align16(sfoSize); memset(sfoData+sfoDataParamsOffset, 0, 128); u8 filehash[16]; int ret = 0; /* Compute 11D0 hash over entire file */ if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, (encryptmode & 2) ? 4 : 2, NULL)) < 0) { // Not sure about "2" return ret - 400; } /* Copy 11D0 hash to param.sfo and set flag indicating it's there */ memcpy(sfoData+sfoDataParamsOffset + 0x20, filehash, 0x10); *(sfoData+sfoDataParamsOffset) |= 0x01; /* If new encryption mode, compute and insert the 1220 hash. */ if (encryptmode & 2) { /* Enable the hash bit first */ *(sfoData+sfoDataParamsOffset) |= 0x20; if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, 3, 0)) < 0) { return ret - 500; } memcpy(sfoData+sfoDataParamsOffset + 0x70, filehash, 0x10); } /* Compute and insert the 11C0 hash. */ if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, 1, 0)) < 0) { return ret - 600; } memcpy(sfoData+sfoDataParamsOffset + 0x10, filehash, 0x10); /* All done. */ return 0; }
/* Read, decrypt, and write a savedata file. See main.c for example usage. */ int decrypt_file(const char *decrypted_filename, const char *encrypted_filename, const unsigned char *gamekey) { FILE *in, *out; int len, aligned_len; unsigned char *data, *cryptkey; int retval; /* Open file and get size */ if ((in = fopen(encrypted_filename, "r")) == NULL) { retval = -1; goto out; } fseek(in, 0, SEEK_END); len = ftell(in); fseek(in, 0, SEEK_SET); if (len <= 0) { retval = -2; goto out1; } /* Allocate buffers */ aligned_len = align16(len); if ((data = (unsigned char *) memalign(0x10, aligned_len)) == NULL) { retval = -3; goto out1; } if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) { retval = -4; goto out2; } /* Fill buffers */ if (gamekey != NULL) memcpy(cryptkey, gamekey, 0x10); memset(data + len, 0, aligned_len - len); if (fread(data, 1, len, in) != len) { retval = -5; goto out3; } /* Do the decryption */ if ((retval = decrypt_data( gamekey ? 3 : 1, data, &len, &aligned_len, gamekey ? cryptkey : NULL)) < 0) { retval -= 100; goto out3; } /* Write the data out. decrypt_data has set len correctly. */ if ((out = fopen(decrypted_filename, "w")) == NULL) { retval = -6; goto out3; } if (fwrite(data, 1, len, out) != len) { retval = -7; goto out4; } /* All done. Return file length. */ retval = len; out4: fclose(out); out3: free(cryptkey); out2: free(data); out1: fclose(in); out: return retval; }
void parse_pe(struct aout *a, const char *buf, int len) { int ad, i; PIMAGE_FILE_HEADER ph1; PIMAGE_OPTIONAL_HEADER32 ph2; PIMAGE_SECTION_HEADER sh; if (len < 0x40) { printf("FILE IS TOO SHORT: %d < %d\n", len, 0x40); return; } if (buf[0] != 'M' || buf[1] != 'Z') { printf("%08x: BAD SIGNATURE: %02x %02x (must be %02x %02x)\n", 0, buf[0], buf[1], 'M', 'Z'); return; } ad = *(int *)&buf[0x3c]; if (ad < 0 || ad + 4 + sizeof(*ph1) + sizeof(*ph2) > len) { printf("FILE IS TOO SHORT: %08x < %08x\n", len, ad); return; } if (buf[ad] != 'P' || buf[ad + 1] != 'E') { printf("%08x: BAD SIGNATURE: %02x %02x (must be %02x %02x)\n", ad, buf[ad], buf[ad + 1], 'P', 'E'); return; } ad += 4; ph1 = (PIMAGE_FILE_HEADER)&buf[ad]; ad += sizeof(*ph1); ph2 = (PIMAGE_OPTIONAL_HEADER32)&buf[ad]; ad += sizeof(*ph2); for (i = 0; i < ph1->NumberOfSections; i++) { char name[9]; sh = (PIMAGE_SECTION_HEADER)&buf[ad]; strncpy(name, sh->Name, 8); if (strcmp(name, ".text") == 0) { if (sh->VirtualAddress > 0x1000) { printf(".TEXT IS TOO FAR: %08x > 00001000\n", sh->VirtualAddress); return; } a->textvad = sh->VirtualAddress; a->textpos = sh->PointerToRawData; a->textlen = sh->VirtualSize; a->header.a_entry = ph2->AddressOfEntryPoint; a->header.a_text = a->textvad + align16(a->textlen); } else if (strcmp(name, ".data") == 0) { a->datavad = sh->VirtualAddress; a->datapos = sh->PointerToRawData; a->datalen = sh->VirtualSize; a->header.a_text = a->datavad; a->header.a_data = align16(a->datalen); } else if (strcmp(name, ".rdata") == 0) { a->rdatavad = sh->VirtualAddress; a->rdatapos = sh->PointerToRawData; a->rdatalen = sh->VirtualSize; if (a->datalen == 0) { a->header.a_text = a->rdatavad; a->header.a_data = align16(a->rdatalen); } else a->header.a_data = align16((a->rdatavad - a->datavad) + a->rdatalen); } else if (strcmp(name, ".bss") == 0) { a->header.a_bss = align16(sh->VirtualSize); if (a->datalen == 0 && a->rdatalen == 0) a->header.a_text = sh->VirtualAddress; else if (a->datalen == 0) a->header.a_data = sh->VirtualAddress - a->rdatavad; else a->header.a_data = sh->VirtualAddress - a->datavad; } #if 0 else if (strcmp(name, ".idata") == 0) { printf("CAN NOT IMPORT DLL!\n"); a->header.a_text = 0; return; } #endif ad += sizeof(*sh); } a->header.a_total += A_SYMPOS(a->header) - a->header.a_hdrlen; }
SC_FUNC int assemble(FILE *fout,FILE *fin) { AMX_HEADER hdr; AMX_FUNCSTUB func; int numpublics,numnatives,numoverlays,numlibraries,numpubvars,numtags; int padding; long nametablesize,nameofs; char line[512]; char *instr,*params; int i,pass,size; int16_t count; symbol *sym; symbol **nativelist; constvalue *constptr; cell mainaddr; char nullchar; #if !defined NDEBUG /* verify that the opcode list is sorted (skip entry 1; it is reserved * for a non-existant opcode) */ { #define MAX_OPCODE 176 unsigned char opcodearray[MAX_OPCODE+1]; assert(opcodelist[1].name!=NULL); memset(opcodearray,0,sizeof opcodearray); for (i=2; i<(sizeof opcodelist / sizeof opcodelist[0]); i++) { assert(opcodelist[i].name!=NULL); assert(stricmp(opcodelist[i].name,opcodelist[i-1].name)>0); /* also verify that no opcode number appears twice */ assert((int)opcodelist[i].opcode<=MAX_OPCODE); assert(opcodelist[i].opcode==0 || opcodearray[(int)opcodelist[i].opcode]==0); opcodearray[(int)opcodelist[i].opcode] += 1; } /* for */ } #endif writeerror=FALSE; nametablesize=sizeof(int16_t); numpublics=0; numnatives=0; numpubvars=0; numoverlays=0; mainaddr=-1; /* count number of public and native functions and public variables */ for (sym=glbtab.next; sym!=NULL; sym=sym->next) { int match=0; if (sym->ident==iFUNCTN) { if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0) match=++numnatives; if ((sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0) match=++numpublics; if (pc_overlays>0 && (sym->usage & uNATIVE)==0 && (sym->usage & (uREAD | uPUBLIC))!=0 && (sym->usage & uDEFINE)!=0) { if (strcmp(sym->name,uENTRYFUNC)!=0) ++numoverlays; /* there is no stub function for state entry functions */ if (sym->states!=NULL) { /* for functions with states, write an overlay block for every implementation */ statelist *stlist; for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) ++numoverlays; } /* if */ } /* if */ if (strcmp(sym->name,uMAINFUNC)==0) { assert(sym->vclass==sGLOBAL); mainaddr=(pc_overlays>0) ? sym->index : sym->addr; } /* if */ } else if (sym->ident==iVARIABLE) { if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) match=++numpubvars; } /* if */ if (match) { char alias[sNAMEMAX+1]; assert(sym!=NULL); if ((sym->usage & uNATIVE)==0 || !lookup_alias(alias,sym->name)) { assert(strlen(sym->name)<=sNAMEMAX); strcpy(alias,sym->name); } /* if */ nametablesize+=(int)strlen(alias)+1; } /* if */ } /* for */ assert(numnatives==ntv_funcid); /* count number of libraries */ numlibraries=0; if (pc_addlibtable) { for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) { if (constptr->value>0) { assert(strlen(constptr->name)>0); numlibraries++; nametablesize+=(int)strlen(constptr->name)+1; } /* if */ } /* for */ } /* if */ /* count number of public tags */ numtags=0; for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { if ((constptr->value & PUBLICTAG)!=0) { assert(strlen(constptr->name)>0); numtags++; nametablesize+=(int)strlen(constptr->name)+1; } /* if */ } /* for */ /* adjust the number of overlays by the special overlays */ if (pc_overlays>0) for (i=0; i<ovlFIRST; i++) if (pc_ovl0size[i][1]!=0) numoverlays++; /* pad the header to sc_dataalign * => thereby the code segment is aligned * => since the code segment is padded to a sc_dataalign boundary, the data segment is aligned * => and thereby the stack top is aligned too */ assert(sc_dataalign!=0); padding= (int)(sc_dataalign - (sizeof hdr + nametablesize) % sc_dataalign); if (padding==sc_dataalign) padding=0; /* write the abstract machine header */ memset(&hdr, 0, sizeof hdr); if (pc_cellsize==2) hdr.magic=(unsigned short)AMX_MAGIC_16; else if (pc_cellsize==4) hdr.magic=(unsigned short)AMX_MAGIC_32; else if (pc_cellsize==8) hdr.magic=(unsigned short)AMX_MAGIC_64; hdr.file_version=CUR_FILE_VERSION; hdr.amx_version=MIN_AMX_VERSION; hdr.flags=(short)(sc_debug & sSYMBOLIC); if (sc_debug==0) hdr.flags|=AMX_FLAG_NOCHECKS; if (pc_memflags & suSLEEP_INSTR) hdr.flags|=AMX_FLAG_SLEEP; if (pc_overlays>0) hdr.flags|=AMX_FLAG_OVERLAY; if (pc_cryptkey!=0) hdr.flags|=AMX_FLAG_CRYPT; hdr.defsize=sizeof(AMX_FUNCSTUB); hdr.publics=sizeof hdr; /* public table starts right after the header */ hdr.natives=hdr.publics + numpublics*sizeof(AMX_FUNCSTUB); hdr.libraries=hdr.natives + numnatives*sizeof(AMX_FUNCSTUB); hdr.pubvars=hdr.libraries + numlibraries*sizeof(AMX_FUNCSTUB); hdr.tags=hdr.pubvars + numpubvars*sizeof(AMX_FUNCSTUB); hdr.overlays=hdr.tags + numtags*sizeof(AMX_FUNCSTUB); hdr.nametable=hdr.overlays + numoverlays*sizeof(AMX_OVERLAYINFO); hdr.cod=hdr.nametable + nametablesize + padding; hdr.dat=(int32_t)(hdr.cod + code_idx); hdr.hea=(int32_t)(hdr.dat + glb_declared*pc_cellsize); hdr.stp=(int32_t)(hdr.hea + pc_stksize*pc_cellsize); hdr.cip=(int32_t)(mainaddr); hdr.size=hdr.hea; pc_writebin(fout,&hdr,sizeof hdr); /* dump zeros up to the rest of the header, so that we can easily "seek" */ nullchar='\0'; for (nameofs=sizeof hdr; nameofs<hdr.cod; nameofs++) pc_writebin(fout,&nullchar,1); nameofs=hdr.nametable+sizeof(int16_t); /* write the public functions table */ count=0; for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0) { assert(sym->vclass==sGLOBAL); /* in the case of overlays, write the overlay index rather than the address */ func.address=(uint32_t)((pc_overlays>0) ? sym->index : sym->addr); func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.publics+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,sym->name,(int)strlen(sym->name)+1); nameofs+=(int)strlen(sym->name)+1; count++; } /* if */ } /* for */ /* write the natives table */ /* The native functions must be written in sorted order. (They are * sorted on their "id", not on their name). A nested loop to find * each successive function would be an O(n^2) operation. But we * do not really need to sort, because the native function id's * are sequential and there are no duplicates. So we first walk * through the complete symbol list and store a pointer to every * native function of interest in a temporary table, where its id * serves as the index in the table. Now we can walk the table and * have all native functions in sorted order. */ if (numnatives>0) { nativelist=(symbol **)malloc(numnatives*sizeof(symbol *)); if (nativelist==NULL) error(103); /* insufficient memory */ #if !defined NDEBUG memset(nativelist,0,numnatives*sizeof(symbol *)); /* for NULL checking */ #endif for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0) { assert(sym->index < numnatives); nativelist[(int)sym->index]=sym; } /* if */ } /* for */ count=0; for (i=0; i<numnatives; i++) { char alias[sNAMEMAX+1]; sym=nativelist[i]; assert(sym!=NULL); if (!lookup_alias(alias,sym->name)) { assert(strlen(sym->name)<=sNAMEMAX); strcpy(alias,sym->name); } /* if */ assert(sym->vclass==sGLOBAL); func.address=0; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.natives+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,alias,(int)strlen(alias)+1); nameofs+=(int)strlen(alias)+1; count++; } /* for */ free(nativelist); } /* if */ /* write the libraries table */ if (pc_addlibtable) { count=0; for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) { if (constptr->value>0) { assert(strlen(constptr->name)>0); func.address=0; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.libraries+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); nameofs+=(int)strlen(constptr->name)+1; count++; } /* if */ } /* for */ } /* if */ /* write the public variables table */ count=0; for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iVARIABLE && (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) { assert((sym->usage & uDEFINE)!=0); assert(sym->vclass==sGLOBAL); func.address=(uint32_t)sym->addr; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.pubvars+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,sym->name,(int)strlen(sym->name)+1); nameofs+=(int)strlen(sym->name)+1; count++; } /* if */ } /* for */ /* write the public tagnames table */ count=0; for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { if ((constptr->value & PUBLICTAG)!=0) { assert(strlen(constptr->name)>0); func.address=(uint32_t)(constptr->value & TAGMASK); func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.tags+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); nameofs+=(int)strlen(constptr->name)+1; count++; } /* if */ } /* for */ /* write the "maximum name length" field in the name table */ assert(nameofs==hdr.nametable+nametablesize); pc_resetbin(fout,hdr.nametable); count=sNAMEMAX; #if BYTE_ORDER==BIG_ENDIAN align16(&count); #endif pc_writebin(fout,&count,sizeof count); /* write the overlay table */ if (pc_overlays>0) { AMX_OVERLAYINFO info; #if !defined NDEBUG int count=0; #endif pc_resetbin(fout,hdr.overlays); /* first the special overlay(s) for the return point(s) */ for (i=0; i<ovlFIRST; i++) { if (pc_ovl0size[i][1]!=0) { info.offset=pc_ovl0size[i][0]; info.size=pc_ovl0size[i][1]; #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); #if !defined NDEBUG count++; #endif } /* if */ } /* for */ /* now all real overlay functions */ for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)==0 && (sym->usage & (uREAD | uPUBLIC))!=0 && (sym->usage & uDEFINE)!=0) { assert(sym->vclass==sGLOBAL); assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->index==count++);/* overlay indices must be in sequential order */ assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->addr<sym->codeaddr); /* write the overlay for the stub function first */ if (strcmp(sym->name,uENTRYFUNC)!=0) { /* there is no stub function for state entry functions */ info.offset=(int32_t)sym->addr; info.size=(uint32_t)(sym->codeaddr - sym->addr); #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); } /* if */ if (sym->states!=NULL) { /* for functions with states, write an overlay block for every implementation */ statelist *stlist; for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) { assert(stlist->label==count++); info.offset=(int32_t)stlist->addr; info.size=(int32_t)(stlist->endaddr - stlist->addr); #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); } /* for */ } /* if */ } /* if */ } /* for */ } /* if */ pc_resetbin(fout,hdr.cod); /* First pass: relocate all labels */ /* This pass is necessary because the code addresses of labels is only known * after the peephole optimization flag. Labels can occur inside expressions * (e.g. the conditional operator), which are optimized. */ lbltab=NULL; if (sc_labnum>0) { cell codeindex=0; /* address of the current opcode similar to "code_idx" */ /* only very short programs have zero labels; no first pass is needed * if there are no labels */ lbltab=(cell *)malloc(sc_labnum*sizeof(cell)); if (lbltab==NULL) error(103); /* insufficient memory */ memset(lbltab,0,sc_labnum*sizeof(cell)); pc_resetasm(fin); while (pc_readasm(fin,line,sizeof line)!=NULL) { stripcomment(line); instr=skipwhitespace(line); /* ignore empty lines */ if (*instr=='\0') continue; if (tolower(*instr)=='l' && *(instr+1)=='.') { int lindex=(int)hex2ucell(instr+2,NULL); assert(lindex>=0 && lindex<sc_labnum); assert(lbltab[lindex]==0); /* should not already be declared */ lbltab[lindex]=codeindex; } else { /* get to the end of the instruction (make use of the '\n' that fgets() * added at the end of the line; this way we will *always* drop on a * whitespace character) */ for (params=instr; *params!='\0' && !isspace(*params); params++) /* nothing */; assert(params>instr); i=findopcode(instr,(int)(params-instr)); assert(opcodelist[i].name!=NULL); assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1); if (opcodelist[i].segment==sIN_CSEG) codeindex+=opcodelist[i].func(NULL,skipwhitespace(params),opcodelist[i].opcode,codeindex); } /* if */ } /* while */ } /* if */ /* Second pass (actually 2 more passes, one for all code and one for all data) */ for (pass=sIN_CSEG; pass<=sIN_DSEG; pass++) { cell codeindex=0; /* address of the current opcode similar to "code_idx" */ pc_resetasm(fin); while (pc_readasm(fin,line,sizeof line)!=NULL) { stripcomment(line); instr=skipwhitespace(line); /* ignore empty lines and labels (labels have a special syntax, so these * must be parsed separately) */ if (*instr=='\0' || tolower(*instr)=='l' && *(instr+1)=='.') continue; /* get to the end of the instruction (make use of the '\n' that fgets() * added at the end of the line; this way we will *always* drop on a * whitespace character) */ for (params=instr; *params!='\0' && !isspace(*params); params++) /* nothing */; assert(params>instr); i=findopcode(instr,(int)(params-instr)); assert(opcodelist[i].name!=NULL); assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1); if (opcodelist[i].segment==pass) codeindex+=opcodelist[i].func(fout,skipwhitespace(params),opcodelist[i].opcode,codeindex); } /* while */ } /* for */ if (lbltab!=NULL) { free(lbltab); #if !defined NDEBUG lbltab=NULL; #endif } /* if */ assert(hdr.size==pc_lengthbin(fout)); if (!writeerror && (sc_debug & sSYMBOLIC)!=0) append_dbginfo(fout); /* optionally append debug file */ if (writeerror) error(101,"disk full"); /* adjust the header (for Big Endian architectures) */ size=(int)hdr.cod; /* save, the value in the header may need to be swapped */ #if BYTE_ORDER==BIG_ENDIAN align32(&hdr.size); align16(&hdr.magic); align16(&hdr.flags); align16(&hdr.defsize); align32(&hdr.publics); align32(&hdr.natives); align32(&hdr.libraries); align32(&hdr.pubvars); align32(&hdr.tags); align32(&hdr.nametable); align32(&hdr.cod); align32(&hdr.dat); align32(&hdr.hea); align32(&hdr.stp); align32(&hdr.cip); pc_resetbin(fout,0); pc_writebin(fout,&hdr,sizeof hdr); #endif /* return the size of the header (including name tables, but excluding code * or data sections) */ return size; }
static void append_dbginfo(FILE *fout) { AMX_DBG_HDR dbghdr; AMX_DBG_LINE dbgline; AMX_DBG_SYMBOL dbgsym; AMX_DBG_SYMDIM dbgidxtag[sDIMEN_MAX]; int index,dim,dbgsymdim; const char *str,*prevstr,*name,*prevname; ucell codeidx,previdx; constvalue *constptr; char symname[2*sNAMEMAX+16]; int16_t id1,id2; ucell address; /* header with general information */ memset(&dbghdr, 0, sizeof dbghdr); dbghdr.size=sizeof dbghdr; dbghdr.magic=AMX_DBG_MAGIC; dbghdr.file_version=CUR_FILE_VERSION; dbghdr.amx_version=MIN_AMX_VERSION; /* first pass: collect the number of items in various tables */ /* file table */ previdx=0; prevstr=NULL; prevname=NULL; for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='F') { codeidx=hex2ucell(str+2,&name); if (codeidx!=previdx) { if (prevstr!=NULL) { assert(prevname!=NULL); dbghdr.files++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname)); } /* if */ previdx=codeidx; } /* if */ prevstr=str; prevname=skipwhitespace(name); } /* if */ } /* for */ if (prevstr!=NULL) { assert(prevname!=NULL); dbghdr.files++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname)); } /* if */ /* line number table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='L') { dbghdr.lines++; dbghdr.size+=sizeof(AMX_DBG_LINE); } /* if */ } /* for */ /* symbol table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='S') { dbghdr.symbols++; str=strchr(str+2,':'); assert(str!=NULL); name=skipwhitespace(str+1); str=strchr(name,' '); assert(str!=NULL); assert((int)(str-name)<sizeof symname); strlcpy(symname,name,(int)(str-name)+1); dbghdr.size+=(int32_t)(sizeof(AMX_DBG_SYMBOL)+strlen(symname)); if ((prevstr=strchr(name,'['))!=NULL) while ((prevstr=strchr(prevstr+1,':'))!=NULL) dbghdr.size+=sizeof(AMX_DBG_SYMDIM); } /* if */ } /* for */ /* tag table */ for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); dbghdr.tags++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_TAG)+strlen(constptr->name)); } /* for */ /* automaton table */ for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) { assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0); dbghdr.automatons++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_MACHINE)+strlen(constptr->name)); } /* for */ /* state table */ for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); dbghdr.states++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_STATE)+strlen(constptr->name)); } /* for */ /* pass 2: generate the tables */ #if BYTE_ORDER==BIG_ENDIAN align32((uint32_t*)&dbghdr.size); align16(&dbghdr.magic); align16(&dbghdr.flags); align16(&dbghdr.files); align16(&dbghdr.lines); align16(&dbghdr.symbols); align16(&dbghdr.tags); align16(&dbghdr.automatons); align16(&dbghdr.states); #endif writeerror |= !pc_writebin(fout,&dbghdr,sizeof dbghdr); /* file table */ previdx=0; prevstr=NULL; prevname=NULL; for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='F') { codeidx=hex2ucell(str+2,&name); if (codeidx!=previdx) { if (prevstr!=NULL) { assert(prevname!=NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&previdx); #endif writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1); } /* if */ previdx=codeidx; } /* if */ prevstr=str; prevname=skipwhitespace(name); } /* if */ } /* for */ if (prevstr!=NULL) { assert(prevname!=NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&previdx); #endif writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1); } /* if */ /* line number table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='L') { dbgline.address=(uint32_t)hex2ucell(str+2,&str); dbgline.line=(int32_t)hex2ucell(str,NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&dbgline.address); align32(&dbgline.line); #endif writeerror |= !pc_writebin(fout,&dbgline,sizeof dbgline); } /* if */ } /* for */ /* symbol table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='S') { dbgsym.address=(uint32_t)hex2ucell(str+2,&str); dbgsym.tag=(int16_t)hex2ucell(str,&str); str=skipwhitespace(str); assert(*str==':'); name=skipwhitespace(str+1); str=strchr(name,' '); assert(str!=NULL); assert((int)(str-name)<sizeof symname); strlcpy(symname,name,(int)(str-name)+1); dbgsym.codestart=(uint32_t)hex2ucell(str,&str); dbgsym.codeend=(uint32_t)hex2ucell(str,&str); dbgsym.ident=(char)hex2ucell(str,&str); dbgsym.vclass=(char)hex2ucell(str,&str); dbgsym.dim=0; str=skipwhitespace(str); if (*str=='[') { while (*(str=skipwhitespace(str+1))!=']') { dbgidxtag[dbgsym.dim].size=(uint32_t)hex2ucell(str,&str); dbgsym.dim++; } /* while */ } /* if */ dbgsymdim = dbgsym.dim; #if BYTE_ORDER==BIG_ENDIAN align32(&dbgsym.address); align16(&dbgsym.tag); align32(&dbgsym.codestart); align32(&dbgsym.codeend); align16(&dbgsym.dim); #endif writeerror |= !pc_writebin(fout,&dbgsym.address,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.tag,sizeof dbgsym.tag); writeerror |= !pc_writebin(fout,&dbgsym.codestart,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.codeend,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.ident,sizeof dbgsym.ident); writeerror |= !pc_writebin(fout,&dbgsym.vclass,sizeof dbgsym.vclass); writeerror |= !pc_writebin(fout,&dbgsym.dim,sizeof dbgsym.dim); writeerror |= !pc_writebin(fout,symname,(int)strlen(symname)+1); for (dim=0; dim<dbgsymdim; dim++) { #if BYTE_ORDER==BIG_ENDIAN align16(&dbgidxtag[dim].tag); align32(&dbgidxtag[dim].size); #endif writeerror |= !pc_writebin(fout,&dbgidxtag[dim].tag,sizeof dbgidxtag[dim].tag); writeerror |= !pc_writebin(fout,&dbgidxtag[dim].size,sizeof dbgidxtag[dim].size); } /* for */ } /* if */ } /* for */ /* tag table */ for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); id1=(int16_t)(constptr->value & TAGMASK); #if BYTE_ORDER==BIG_ENDIAN align16(&id1); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ /* automaton table */ for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) { assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0); id1=(int16_t)constptr->index; address=(ucell)constptr->value; #if BYTE_ORDER==BIG_ENDIAN align16(&id1); align32(&address); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,&address,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ /* state table */ for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); id1=(int16_t)constptr->value; id2=(int16_t)constptr->index; address=(ucell)constptr->value; #if BYTE_ORDER==BIG_ENDIAN align16(&id1); align16(&id2); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,&id2,sizeof id2); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ delete_dbgstringtable(); }
bool SavedataParam::Load(SceUtilitySavedataParam *param, int saveId) { if (!param) { return false; } u8 *data_ = (u8*)Memory::GetPointer(param->dataBuf); std::string dirPath = GetSaveFilePath(param, saveId); if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it { if (saveDataList[saveId].size == 0) // don't read no existing file { return false; } } std::string filePath = dirPath+"/"+GetFileName(param); s64 readSize; INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str()); u8* saveData = 0; int saveSize = -1; if (!ReadPSPFile(filePath, &saveData, saveSize, &readSize)) { ERROR_LOG(HLE,"Error reading file %s",filePath.c_str()); return false; } saveSize = (int)readSize; // copy back save name in request strncpy(param->saveName,GetSaveDirName(param, saveId).c_str(),20); ParamSFOData sfoFile; std::string sfopath = dirPath+"/"+sfoName; PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath); if(sfoInfo.exists) // Read sfo { u8 *sfoData = new u8[(size_t)sfoInfo.size]; size_t sfoSize = (size_t)sfoInfo.size; if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL)) { sfoFile.ReadSFO(sfoData,sfoSize); // copy back info in request strncpy(param->sfoParam.title,sfoFile.GetValueString("TITLE").c_str(),128); strncpy(param->sfoParam.savedataTitle,sfoFile.GetValueString("SAVEDATA_TITLE").c_str(),128); strncpy(param->sfoParam.detail,sfoFile.GetValueString("SAVEDATA_DETAIL").c_str(),1024); param->sfoParam.parentalLevel = sfoFile.GetValueInt("PARENTAL_LEVEL"); } delete[] sfoData; } // Don't know what it is, but PSP always respond this and this unlock some game param->bind = 1021; bool isCrypted = IsSaveEncrypted(param,saveId); bool saveDone = false; if(isCrypted)// Try to decrypt { int align_len = align16(saveSize); u8* data_base = new u8[align_len]; u8* cryptKey = new u8[0x10]; memset(cryptKey,0,0x10); if(param->key[0] != 0) { memcpy(cryptKey, param->key, 0x10); } memset(data_base + saveSize, 0, align_len - saveSize); memcpy(data_base, saveData, saveSize); int decryptMode = 1; if(param->key[0] != 0) { decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3); } if(DecryptSave(decryptMode, data_base, &saveSize, &align_len, ((param->key[0] != 0)?cryptKey:0)) == 0) { memcpy(data_, data_base, saveSize); saveDone = true; } delete[] data_base; delete[] cryptKey; } if(!saveDone) // not crypted or decrypt fail { memcpy(data_, saveData, saveSize); } param->dataSize = (SceSize)saveSize; delete[] saveData; return true; }
bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) { if (!param) { return false; } std::string dirPath = GetSaveFilePath(param, saveId); if (!pspFileSystem.GetFileInfo(dirPath).exists) pspFileSystem.MkDir(dirPath); u8* cryptedData = 0; int cryptedSize = 0; u8 cryptedHash[0x10]; memset(cryptedHash,0,0x10); // Encrypt save. if(param->dataBuf != 0 && g_Config.bEncryptSave) { cryptedSize = param->dataSize; if(cryptedSize == 0 || (SceSize)cryptedSize > param->dataBufSize) cryptedSize = param->dataBufSize; // fallback, should never use this u8* data_ = (u8*)Memory::GetPointer(param->dataBuf); int aligned_len = align16(cryptedSize); cryptedData = new u8[aligned_len + 0x10]; memcpy(cryptedData, data_, cryptedSize); int decryptMode = 1; if(param->key[0] != 0) { decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3); } if(EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, ((param->key[0] != 0)?param->key:0)) == 0) { } else { ERROR_LOG(HLE,"Save encryption failed. This save won't work on real PSP"); delete[] cryptedData; cryptedData = 0; } } // SAVE PARAM.SFO ParamSFOData sfoFile; std::string sfopath = dirPath+"/"+sfoName; PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath); if(sfoInfo.exists) // Read old sfo if exist { u8 *sfoData = new u8[(size_t)sfoInfo.size]; size_t sfoSize = (size_t)sfoInfo.size; if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL)) { sfoFile.ReadSFO(sfoData,sfoSize); delete[] sfoData; } } // Update values sfoFile.SetValue("TITLE",param->sfoParam.title,128); sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128); sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024); sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4); sfoFile.SetValue("CATEGORY","MS",4); sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64); // For each file, 13 bytes for filename, 16 bytes for file hash (0 in PPSSPP), 3 byte for padding const int FILE_LIST_ITEM_SIZE = 13 + 16 + 3; const int FILE_LIST_COUNT_MAX = 99; const int FILE_LIST_TOTAL_SIZE = FILE_LIST_ITEM_SIZE * FILE_LIST_COUNT_MAX; u32 tmpDataSize = 0; u8* tmpDataOrig = sfoFile.GetValueData("SAVEDATA_FILE_LIST", &tmpDataSize); u8* tmpData = new u8[FILE_LIST_TOTAL_SIZE]; if (tmpDataOrig != NULL) memcpy(tmpData, tmpDataOrig, tmpDataSize > FILE_LIST_TOTAL_SIZE ? FILE_LIST_TOTAL_SIZE : tmpDataSize); else memset(tmpData, 0, FILE_LIST_TOTAL_SIZE); if (param->dataBuf != 0) { char *fName = (char*)tmpData; for(int i = 0; i < FILE_LIST_COUNT_MAX; i++) { if(fName[0] == 0) break; // End of list if(strncmp(fName,GetFileName(param).c_str(),20) == 0) break; fName += FILE_LIST_ITEM_SIZE; } if (fName + 13 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE) snprintf(fName, 13, "%s",GetFileName(param).c_str()); if (fName + 13 + 16 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE) memcpy(fName+13, cryptedHash, 16); } sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, FILE_LIST_TOTAL_SIZE, FILE_LIST_TOTAL_SIZE); delete[] tmpData; // Init param with 0. This will be used to detect crypted save or not on loading tmpData = new u8[128]; memset(tmpData, 0, 128); sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128); delete[] tmpData; u8 *sfoData; size_t sfoSize; sfoFile.WriteSFO(&sfoData,&sfoSize); // Calc SFO hash for PSP. if(cryptedData != 0) { int offset = sfoFile.GetDataOffset(sfoData,"SAVEDATA_PARAMS"); if(offset >= 0) UpdateHash(sfoData, sfoSize, offset, (param->key[0]?3:1)); } WritePSPFile(sfopath, sfoData, (SceSize)sfoSize); delete[] sfoData; if(param->dataBuf != 0) // Can launch save without save data in mode 13 { std::string filePath = dirPath+"/"+GetFileName(param); u8* data_ = 0; SceSize saveSize = 0; if(cryptedData == 0) // Save decrypted data { saveSize = param->dataSize; if(saveSize == 0 || saveSize > param->dataBufSize) saveSize = param->dataBufSize; // fallback, should never use this data_ = (u8*)Memory::GetPointer(param->dataBuf); } else { data_ = cryptedData; saveSize = cryptedSize; } INFO_LOG(HLE,"Saving file with size %u in %s",saveSize,filePath.c_str()); // copy back save name in request strncpy(param->saveName,GetSaveDirName(param, saveId).c_str(),20); if (!WritePSPFile(filePath, data_, saveSize)) { ERROR_LOG(HLE,"Error writing file %s",filePath.c_str()); if(cryptedData != 0) { delete[] cryptedData; } return false; } delete[] cryptedData; } // SAVE ICON0 if (param->icon0FileData.buf) { u8* data_ = (u8*)Memory::GetPointer(param->icon0FileData.buf); std::string icon0path = dirPath+"/"+icon0Name; WritePSPFile(icon0path, data_, param->icon0FileData.bufSize); } // SAVE ICON1 if (param->icon1FileData.buf) { u8* data_ = (u8*)Memory::GetPointer(param->icon1FileData.buf); std::string icon1path = dirPath+"/"+icon1Name; WritePSPFile(icon1path, data_, param->icon1FileData.bufSize); } // SAVE PIC1 if (param->pic1FileData.buf) { u8* data_ = (u8*)Memory::GetPointer(param->pic1FileData.buf); std::string pic1path = dirPath+"/"+pic1Name; WritePSPFile(pic1path, data_, param->pic1FileData.bufSize); } // Save SND if (param->snd0FileData.buf) { u8* data_ = (u8*)Memory::GetPointer(param->snd0FileData.buf); std::string snd0path = dirPath+"/"+snd0Name; WritePSPFile(snd0path, data_, param->snd0FileData.bufSize); } // Save Encryption Data { EncryptFileInfo encryptInfo; SceSize dataSize = sizeof(encryptInfo); // version + key + sdkVersion memset(&encryptInfo,0,dataSize); encryptInfo.fileVersion = 1; encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion(); if(param->size > 1500) memcpy(encryptInfo.key,param->key,16); std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN"; WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize); } return true; }
static void pmc_show(struct ptp_message *msg, FILE *fp) { int action; struct TLV *tlv; struct management_tlv *mgt; struct management_tlv_datum *mtd; struct defaultDS *dds; struct currentDS *cds; struct parentDS *pds; struct timePropertiesDS *tp; struct time_status_np *tsn; struct grandmaster_settings_np *gsn; struct mgmt_clock_description *cd; struct tlv_extra *extra; struct portDS *p; struct port_ds_np *pnp; if (msg_type(msg) != MANAGEMENT) { return; } action = management_action(msg); if (action < GET || action > ACKNOWLEDGE) { return; } fprintf(fp, "\t%s seq %hu %s ", pid2str(&msg->header.sourcePortIdentity), msg->header.sequenceId, pmc_action_string(action)); if (msg_tlv_count(msg) != 1) { goto out; } extra = TAILQ_FIRST(&msg->tlv_list); tlv = (struct TLV *) msg->management.suffix; if (tlv->type == TLV_MANAGEMENT) { fprintf(fp, "MANAGEMENT "); } else if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) { fprintf(fp, "MANAGEMENT_ERROR_STATUS "); goto out; } else { fprintf(fp, "unknown-tlv "); goto out; } mgt = (struct management_tlv *) msg->management.suffix; if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT) { fprintf(fp, "empty-tlv "); goto out; } switch (mgt->id) { case TLV_CLOCK_DESCRIPTION: cd = &extra->cd; fprintf(fp, "CLOCK_DESCRIPTION " IFMT "clockType 0x%hx" IFMT "physicalLayerProtocol %s" IFMT "physicalAddress %s" IFMT "protocolAddress %hu %s", align16(cd->clockType), text2str(cd->physicalLayerProtocol), bin2str(cd->physicalAddress->address, align16(&cd->physicalAddress->length)), align16(&cd->protocolAddress->networkProtocol), portaddr2str(cd->protocolAddress)); fprintf(fp, IFMT "manufacturerId %s" IFMT "productDescription %s", bin2str(cd->manufacturerIdentity, OUI_LEN), text2str(cd->productDescription)); fprintf(fp, IFMT "revisionData %s", text2str(cd->revisionData)); fprintf(fp, IFMT "userDescription %s" IFMT "profileId %s", text2str(cd->userDescription), bin2str(cd->profileIdentity, PROFILE_ID_LEN)); break; case TLV_USER_DESCRIPTION: fprintf(fp, "USER_DESCRIPTION " IFMT "userDescription %s", text2str(extra->cd.userDescription)); break; case TLV_DEFAULT_DATA_SET: dds = (struct defaultDS *) mgt->data; fprintf(fp, "DEFAULT_DATA_SET " IFMT "twoStepFlag %d" IFMT "slaveOnly %d" IFMT "numberPorts %hu" IFMT "priority1 %hhu" IFMT "clockClass %hhu" IFMT "clockAccuracy 0x%02hhx" IFMT "offsetScaledLogVariance 0x%04hx" IFMT "priority2 %hhu" IFMT "clockIdentity %s" IFMT "domainNumber %hhu", dds->flags & DDS_TWO_STEP_FLAG ? 1 : 0, dds->flags & DDS_SLAVE_ONLY ? 1 : 0, dds->numberPorts, dds->priority1, dds->clockQuality.clockClass, dds->clockQuality.clockAccuracy, dds->clockQuality.offsetScaledLogVariance, dds->priority2, cid2str(&dds->clockIdentity), dds->domainNumber); break; case TLV_CURRENT_DATA_SET: cds = (struct currentDS *) mgt->data; fprintf(fp, "CURRENT_DATA_SET " IFMT "stepsRemoved %hd" IFMT "offsetFromMaster %.1f" IFMT "meanPathDelay %.1f", cds->stepsRemoved, cds->offsetFromMaster / 65536.0, cds->meanPathDelay / 65536.0); break; case TLV_PARENT_DATA_SET: pds = (struct parentDS *) mgt->data; fprintf(fp, "PARENT_DATA_SET " IFMT "parentPortIdentity %s" IFMT "parentStats %hhu" IFMT "observedParentOffsetScaledLogVariance 0x%04hx" IFMT "observedParentClockPhaseChangeRate 0x%08x" IFMT "grandmasterPriority1 %hhu" IFMT "gm.ClockClass %hhu" IFMT "gm.ClockAccuracy 0x%02hhx" IFMT "gm.OffsetScaledLogVariance 0x%04hx" IFMT "grandmasterPriority2 %hhu" IFMT "grandmasterIdentity %s", pid2str(&pds->parentPortIdentity), pds->parentStats, pds->observedParentOffsetScaledLogVariance, pds->observedParentClockPhaseChangeRate, pds->grandmasterPriority1, pds->grandmasterClockQuality.clockClass, pds->grandmasterClockQuality.clockAccuracy, pds->grandmasterClockQuality.offsetScaledLogVariance, pds->grandmasterPriority2, cid2str(&pds->grandmasterIdentity)); break; case TLV_TIME_PROPERTIES_DATA_SET: tp = (struct timePropertiesDS *) mgt->data; fprintf(fp, "TIME_PROPERTIES_DATA_SET " IFMT "currentUtcOffset %hd" IFMT "leap61 %d" IFMT "leap59 %d" IFMT "currentUtcOffsetValid %d" IFMT "ptpTimescale %d" IFMT "timeTraceable %d" IFMT "frequencyTraceable %d" IFMT "timeSource 0x%02hhx", tp->currentUtcOffset, tp->flags & LEAP_61 ? 1 : 0, tp->flags & LEAP_59 ? 1 : 0, tp->flags & UTC_OFF_VALID ? 1 : 0, tp->flags & PTP_TIMESCALE ? 1 : 0, tp->flags & TIME_TRACEABLE ? 1 : 0, tp->flags & FREQ_TRACEABLE ? 1 : 0, tp->timeSource); break; case TLV_PRIORITY1: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "PRIORITY1 " IFMT "priority1 %hhu", mtd->val); break; case TLV_PRIORITY2: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "PRIORITY2 " IFMT "priority2 %hhu", mtd->val); break; case TLV_DOMAIN: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "DOMAIN " IFMT "domainNumber %hhu", mtd->val); break; case TLV_SLAVE_ONLY: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "SLAVE_ONLY " IFMT "slaveOnly %d", mtd->val & DDS_SLAVE_ONLY ? 1 : 0); break; case TLV_CLOCK_ACCURACY: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "CLOCK_ACCURACY " IFMT "clockAccuracy 0x%02hhx", mtd->val); break; case TLV_TRACEABILITY_PROPERTIES: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "TRACEABILITY_PROPERTIES " IFMT "timeTraceable %d" IFMT "frequencyTraceable %d", mtd->val & TIME_TRACEABLE ? 1 : 0, mtd->val & FREQ_TRACEABLE ? 1 : 0); break; case TLV_TIMESCALE_PROPERTIES: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "TIMESCALE_PROPERTIES " IFMT "ptpTimescale %d", mtd->val & PTP_TIMESCALE ? 1 : 0); break; case TLV_TIME_STATUS_NP: tsn = (struct time_status_np *) mgt->data; fprintf(fp, "TIME_STATUS_NP " IFMT "master_offset %" PRId64 IFMT "ingress_time %" PRId64 IFMT "cumulativeScaledRateOffset %+.9f" IFMT "scaledLastGmPhaseChange %d" IFMT "gmTimeBaseIndicator %hu" IFMT "lastGmPhaseChange 0x%04hx'%016" PRIx64 ".%04hx" IFMT "gmPresent %s" IFMT "gmIdentity %s", tsn->master_offset, tsn->ingress_time, (tsn->cumulativeScaledRateOffset + 0.0) / P41, tsn->scaledLastGmPhaseChange, tsn->gmTimeBaseIndicator, tsn->lastGmPhaseChange.nanoseconds_msb, tsn->lastGmPhaseChange.nanoseconds_lsb, tsn->lastGmPhaseChange.fractional_nanoseconds, tsn->gmPresent ? "true" : "false", cid2str(&tsn->gmIdentity)); break; case TLV_GRANDMASTER_SETTINGS_NP: gsn = (struct grandmaster_settings_np *) mgt->data; fprintf(fp, "GRANDMASTER_SETTINGS_NP " IFMT "clockClass %hhu" IFMT "clockAccuracy 0x%02hhx" IFMT "offsetScaledLogVariance 0x%04hx" IFMT "currentUtcOffset %hd" IFMT "leap61 %d" IFMT "leap59 %d" IFMT "currentUtcOffsetValid %d" IFMT "ptpTimescale %d" IFMT "timeTraceable %d" IFMT "frequencyTraceable %d" IFMT "timeSource 0x%02hhx", gsn->clockQuality.clockClass, gsn->clockQuality.clockAccuracy, gsn->clockQuality.offsetScaledLogVariance, gsn->utc_offset, gsn->time_flags & LEAP_61 ? 1 : 0, gsn->time_flags & LEAP_59 ? 1 : 0, gsn->time_flags & UTC_OFF_VALID ? 1 : 0, gsn->time_flags & PTP_TIMESCALE ? 1 : 0, gsn->time_flags & TIME_TRACEABLE ? 1 : 0, gsn->time_flags & FREQ_TRACEABLE ? 1 : 0, gsn->time_source); break; case TLV_PORT_DATA_SET: p = (struct portDS *) mgt->data; if (p->portState > PS_SLAVE) { p->portState = 0; } fprintf(fp, "PORT_DATA_SET " IFMT "portIdentity %s" IFMT "portState %s" IFMT "logMinDelayReqInterval %hhd" IFMT "peerMeanPathDelay %" PRId64 IFMT "logAnnounceInterval %hhd" IFMT "announceReceiptTimeout %hhu" IFMT "logSyncInterval %hhd" IFMT "delayMechanism %hhu" IFMT "logMinPdelayReqInterval %hhd" IFMT "versionNumber %hhu", pid2str(&p->portIdentity), ps_str[p->portState], p->logMinDelayReqInterval, p->peerMeanPathDelay >> 16, p->logAnnounceInterval, p->announceReceiptTimeout, p->logSyncInterval, p->delayMechanism, p->logMinPdelayReqInterval, p->versionNumber); break; case TLV_PORT_DATA_SET_NP: pnp = (struct port_ds_np *) mgt->data; fprintf(fp, "PORT_DATA_SET_NP " IFMT "neighborPropDelayThresh %u" IFMT "asCapable %d", pnp->neighborPropDelayThresh, pnp->asCapable ? 1 : 0); break; case TLV_LOG_ANNOUNCE_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_ANNOUNCE_INTERVAL " IFMT "logAnnounceInterval %hhd", mtd->val); break; case TLV_ANNOUNCE_RECEIPT_TIMEOUT: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "ANNOUNCE_RECEIPT_TIMEOUT " IFMT "announceReceiptTimeout %hhu", mtd->val); break; case TLV_LOG_SYNC_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_SYNC_INTERVAL " IFMT "logSyncInterval %hhd", mtd->val); break; case TLV_VERSION_NUMBER: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "VERSION_NUMBER " IFMT "versionNumber %hhu", mtd->val); break; case TLV_DELAY_MECHANISM: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "DELAY_MECHANISM " IFMT "delayMechanism %hhu", mtd->val); break; case TLV_LOG_MIN_PDELAY_REQ_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL " IFMT "logMinPdelayReqInterval %hhd", mtd->val); break; } out: fprintf(fp, "\n"); fflush(fp); }