static int ser_on_next(const cdsl_serializer_t* self, const cdsl_serializeNode_t* node, size_t nsz, const uint8_t* data){ if((self == NULL) || (node == NULL)) { return ERR_INV_PARAM; } const file_serializer_t* serializer = container_of(self, file_serializer_t, handle); if(serializer->fd < 0) { return ERR_INV_PARAM; } uint8_t has_next = HAS_NEXT; if(F_WRITE(serializer->fd, &has_next, sizeof(uint8_t)) < 0) { return ERR_WR_OP_FAIL; } if(F_WRITE(serializer->fd, node, nsz) < 0){ return ERR_WR_OP_FAIL; } struct serializer_delim node_term = {0}; if(node->d_size > 0) { node_term.node_chs = serializer_calcNodeChecksum(node, data); if (F_WRITE(serializer->fd, data, node->d_size) < 0) { return ERR_WR_OP_FAIL; } } node_term.delim = SERIALIZER_DELIM; if(F_WRITE(serializer->fd, &node_term, sizeof(struct serializer_delim)) < 0) { return ERR_WR_OP_FAIL; } return OK; }
/* =========================================================================== Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of bytes actually written (0 in case of error). */ size_t lib_gzwrite (gzFile file, const voidp buf, size_t len) { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; s->stream.next_in = (Bytef*)buf; s->stream.avail_in = (uInt)len; while (s->stream.avail_in != 0) { if (s->stream.avail_out == 0) { s->stream.next_out = s->outbuf; if (F_WRITE(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { s->z_err = Z_ERRNO; break; } s->stream.avail_out = Z_BUFSIZE; } s->z_err = deflate(&(s->stream), Z_NO_FLUSH); if (s->z_err != Z_OK) break; } s->crc = crc32(s->crc, (const Bytef *)buf, (uInt)len); return (int)(len - s->stream.avail_in); }
static InstTransResult doCmpxchgRR(InstPtr ip, BasicBlock *&b, const MCOperand &dstReg, const MCOperand &srcReg) { NASSERT(dstReg.isReg()); NASSERT(srcReg.isReg()); Value *acc; switch(width) { case 8: acc = R_READ<width>(b, X86::AL); break; case 16: acc = R_READ<width>(b, X86::AX); break; case 32: acc = R_READ<width>(b, X86::EAX); break; default: throw TErr(__LINE__, __FILE__, "Width not supported"); } Value *dstReg_v = R_READ<width>(b, dstReg.getReg()); Value *srcReg_v = R_READ<width>(b, srcReg.getReg()); doCmpVV<width>(ip, b, acc, dstReg_v); Value *Cmp = new ICmpInst(*b, CmpInst::ICMP_EQ, acc, dstReg_v); F_WRITE(b, ZF, Cmp); /// // ZF = Acc == DST // acc = select(ZF, acc, dst) // dst = select(ZF, src, dst) Value *new_acc = SelectInst::Create(Cmp, acc, dstReg_v, "", b); Value *new_dst = SelectInst::Create(Cmp, srcReg_v, dstReg_v, "", b); R_WRITE<width>(b, dstReg.getReg(), new_dst); switch(width) { case 8: R_WRITE<width>(b, X86::AL, new_acc); break; case 16: R_WRITE<width>(b, X86::AX, new_acc); break; case 32: R_WRITE<width>(b, X86::EAX, new_acc); break; default: throw TErr(__LINE__, __FILE__, "Width not supported"); } return ContinueBlock; }
static int ser_on_tail(const cdsl_serializer_t* self, const cdsl_serializeTail_t* tail) { if((self == NULL) || (tail == NULL)) { return ERR_INV_PARAM; } uint16_t eof = SERIALIZER_END_OF_FILE; const file_serializer_t* serializer = container_of(self, file_serializer_t, handle); uint8_t has_next = END_OF_ITEMS; if(F_WRITE(serializer->fd, &has_next, sizeof(uint8_t)) < 0) { return ERR_WR_OP_FAIL; } if(F_WRITE(serializer->fd, tail, sizeof(cdsl_serializeTail_t)) < 0) { return ERR_WR_OP_FAIL; } if(F_WRITE(serializer->fd, &eof, sizeof(uint16_t)) < 0) { return ERR_WR_OP_FAIL; } return OK; }
static int ser_on_head(const cdsl_serializer_t* self, const cdsl_serializeHeader_t* head) { if((self == NULL) || (head == NULL)) { return ERR_INV_PARAM; } uint16_t ser_starter = SERIALIZER_START_OF_FILE; const file_serializer_t* serializer = container_of(self, file_serializer_t, handle); if(serializer->fd < 0) { return ERR_INV_PARAM; } if(F_WRITE(serializer->fd, &ser_starter, sizeof(uint16_t)) < 0) { return ERR_WR_OP_FAIL; } if(F_WRITE(serializer->fd, head, sizeof(cdsl_serializeHeader_t)) < 0) { return ERR_WR_OP_FAIL; } return OK; }
/* =========================================================================== * Update the compression level and strategy */ int lib_gzsetparams ( gzFile file, int level, int strategy) { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; /* Make room to allow flushing */ if (s->stream.avail_out == 0) { s->stream.next_out = s->outbuf; if (F_WRITE(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { s->z_err = Z_ERRNO; } s->stream.avail_out = Z_BUFSIZE; } return deflateParams (&(s->stream), level, strategy); }
/* =========================================================================== Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. */ static int do_flush (gzFile file, int flush) { uInt len; int done = 0; gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; s->stream.avail_in = 0; /* should be zero already anyway */ for (;;) { len = Z_BUFSIZE - s->stream.avail_out; if (len != 0) { if ((uInt)F_WRITE(s->outbuf, 1, len, s->file) != len) { s->z_err = Z_ERRNO; return Z_ERRNO; } s->stream.next_out = s->outbuf; s->stream.avail_out = Z_BUFSIZE; } if (done) break; s->z_err = deflate(&(s->stream), flush); /* Ignore the second of two consecutive flushes: */ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; /* deflate has finished flushing only when it hasn't used up * all the available space in the output buffer: */ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; } return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; }
static InstTransResult doCmpxchgRM(InstPtr ip, BasicBlock *&b, Value *dstAddr, const MCOperand &srcReg) { NASSERT(dstAddr != NULL); NASSERT(srcReg.isReg()); Value *acc; switch(width) { case 8: acc = R_READ<width>(b, X86::AL); break; case 16: acc = R_READ<width>(b, X86::AX); break; case 32: acc = R_READ<width>(b, X86::EAX); break; default: throw TErr(__LINE__, __FILE__, "Width not supported"); } //Value *mem_v = M_READ<width>(ip, b, dstAddr); Value *m_addr = NULL; unsigned addrspace = ip->get_addr_space(); if( dstAddr->getType()->isPointerTy() == false ) { llvm::Type *ptrTy = Type::getIntNPtrTy(b->getContext(), width, addrspace); m_addr = new llvm::IntToPtrInst(dstAddr, ptrTy, "", b); } else if( dstAddr->getType() != Type::getIntNPtrTy( b->getContext(), width, addrspace) ) { //we need to bitcast the pointer value to a pointer type of the appropriate width m_addr = CastInst::CreatePointerCast(dstAddr, Type::getIntNPtrTy(b->getContext(), width, addrspace), "", b); } else { m_addr = dstAddr; } Value *srcReg_v = R_READ<width>(b, srcReg.getReg()); AtomicCmpXchgInst *cmpx = new AtomicCmpXchgInst( m_addr, acc, srcReg_v, llvm::SequentiallyConsistent, llvm::SequentiallyConsistent, llvm::CrossThread, b); cmpx->setVolatile(true); Value *cmpx_val = ExtractValueInst::Create(cmpx, 0, "cmpxchg_cmpx_val", b); Value *was_eq = ExtractValueInst::Create(cmpx, 1, "cmpxchg_was_eq", b); doCmpVV<width>(ip, b, acc, cmpx_val); F_WRITE(b, ZF, was_eq); Value *new_acc = SelectInst::Create(was_eq, acc, cmpx_val, "", b); switch(width) { case 8: R_WRITE<width>(b, X86::AL, new_acc); break; case 16: R_WRITE<width>(b, X86::AX, new_acc); break; case 32: R_WRITE<width>(b, X86::EAX, new_acc); break; default: throw TErr(__LINE__, __FILE__, "Width not supported"); } return ContinueBlock; }
/* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The file is given either by file descriptor or path name (if fd == -1). lib_gz_open return NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ gzFile lib_gzfopen (SYS_FILEHANDLE fd, const char *mode) { int err; int level = Z_DEFAULT_COMPRESSION; /* compression level */ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ char *p = (char*)mode; gz_stream *s; char fmode[80]; /* copy of mode, without the compression level */ char *m = fmode; if (!mode) return Z_NULL; s = (gz_stream *)ALLOC(sizeof(gz_stream)); if (!s) return Z_NULL; s->stream.zalloc = (alloc_func)_zcalloc; s->stream.zfree = (free_func)_zcfree; s->stream.opaque = (voidpf)0; s->stream.next_in = s->inbuf = Z_NULL; s->stream.next_out = s->outbuf = Z_NULL; s->stream.avail_in = s->stream.avail_out = 0; s->file = fd; s->z_err = Z_OK; s->z_eof = 0; s->crc = crc32(0L, Z_NULL, 0); s->msg = NULL; s->transparent = 0; s->mode = '\0'; do { if (*p == 'r') s->mode = 'r'; if (*p == 'w' || *p == 'a') s->mode = 'w'; if (*p >= '0' && *p <= '9') { level = *p - '0'; } else if (*p == 'f') { strategy = Z_FILTERED; } else if (*p == 'h') { strategy = Z_HUFFMAN_ONLY; } else { *m++ = *p; /* copy the mode */ } } while (*p++ && m != fmode + sizeof(fmode)); if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == 'w') { #ifdef NO_DEFLATE err = Z_STREAM_ERROR; #else err = deflateInit2(&(s->stream), level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); /* windowBits is passed < 0 to suppress zlib header */ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); #endif if (err != Z_OK || s->outbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } else { s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); err = inflateInit2(&(s->stream), -MAX_WBITS); /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are * present after the compressed stream. */ if (err != Z_OK || s->inbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } s->stream.avail_out = Z_BUFSIZE; if (s->file == (SYS_FILEHANDLE )NULL) { return destroy(s), (gzFile)Z_NULL; } if (s->mode == 'w') { /* Write a very simple .gz header: */ char tx[16]; sprintf(tx, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); F_WRITE(tx, 1, 10, s->file); s->startpos = 10L; /* We use 10L instead of ftell(s->file) to because ftell causes an * fflush on some systems. This version of the library doesn't use * startpos anyway in write mode, so this initialization is not * necessary. */ } else { check_header(s); /* skip the .gz header */ s->startpos = (F_TELL(s->file) - s->stream.avail_in); } return (gzFile)s; }