diff --git a/c2rust-analyze/src/borrowck/type_check.rs b/c2rust-analyze/src/borrowck/type_check.rs index 3121664275..859cc1b801 100644 --- a/c2rust-analyze/src/borrowck/type_check.rs +++ b/c2rust-analyze/src/borrowck/type_check.rs @@ -583,6 +583,19 @@ impl<'tcx> TypeChecker<'tcx, '_> { self.visit_operand(p) }); } + Callee::Memcpy => { + let _pl_lty = self.visit_place(destination); + let _rv_lty = assert_matches!(&args[..], [dest, src, _] => { + self.visit_operand(dest); + self.visit_operand(src); + }); + } + Callee::Memset => { + let _pl_lty = self.visit_place(destination); + let _rv_lty = assert_matches!(&args[..], [dest, ..] => { + self.visit_operand(dest) + }); + } Callee::IsNull => { let _rv_lty = assert_matches!(&args[..], [p] => { self.visit_operand(p) diff --git a/c2rust-analyze/src/c_void_casts.rs b/c2rust-analyze/src/c_void_casts.rs index 7a1e4a003b..7b9795c576 100644 --- a/c2rust-analyze/src/c_void_casts.rs +++ b/c2rust-analyze/src/c_void_casts.rs @@ -1,16 +1,15 @@ use std::borrow::Borrow; use std::collections::{HashMap, HashSet}; +use rustc_middle::mir::{BasicBlock, LocalKind}; use rustc_middle::{ mir::{ - Body, LocalDecls, Location, Place, Rvalue, Statement, StatementKind, Terminator, + BasicBlockData, Body, LocalDecls, Location, Place, Rvalue, Statement, StatementKind, TerminatorKind, }, ty::{TyCtxt, TyKind}, }; -use assert_matches::assert_matches; - use crate::util::{get_assign_sides, get_cast_place, terminator_location, ty_callee, Callee}; /// The direction of a [`*c_void`](core::ffi::c_void) cast. @@ -48,6 +47,7 @@ impl CVoidCastDirection { Malloc | Calloc => &[From][..], Realloc => &[To, From][..], Free => &[To][..], + Memcpy | Memset => &[To][..], _ => &[], } } @@ -69,18 +69,25 @@ impl<'tcx> CVoidPtr<'tcx> { /// /// This panics on failure. pub fn checked(place: Place<'tcx>, local_decls: &LocalDecls<'tcx>, tcx: TyCtxt<'tcx>) -> Self { - let deref_ty = place - .ty(local_decls, tcx) - .ty - .builtin_deref(true) - .unwrap() - .ty - .kind(); - assert_matches!(deref_ty, TyKind::Adt(adt, _) => { - assert_eq!(tcx.def_path(adt.did()).data[0].to_string(), "ffi"); - assert_eq!(tcx.item_name(adt.did()).as_str(), "c_void"); - }); - Self { place } + Self::checked_optional(place, local_decls, tcx).unwrap() + } + + pub fn checked_optional( + place: Place<'tcx>, + local_decls: &LocalDecls<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> Option { + let deref_ty = place.ty(local_decls, tcx).ty.builtin_deref(true)?; + + if let TyKind::Adt(adt, _) = deref_ty.ty.kind() { + if tcx.def_path(adt.did()).data[0].to_string() == "ffi" + && tcx.item_name(adt.did()).as_str() == "c_void" + { + return Some(Self { place }); + } + } + + None } /// Check another [`Place`] for being a [`*c_void`](core::ffi::c_void) @@ -137,7 +144,7 @@ impl<'tcx> Borrow> for CVoidPtr<'tcx> { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq, Hash)] /// A cast to/from a [`*c_void`](core::ffi::c_void) to/from a properly typed pointer. pub struct CVoidCast<'tcx> { /// The [`*c_void`](core::ffi::c_void) side of the cast. @@ -162,14 +169,14 @@ pub struct CVoidCast<'tcx> { pub struct CVoidCastsUniDirectional<'tcx> { /// Mapping from location of a call that either /// produces or consumes a [`CVoidPtr`] to its - /// succeeding or preceding [`CVoidCast`] - calls: HashMap>, + /// succeeding or preceding [`CVoidCast`]s + calls: HashMap>>, /// Set of locations where [`CVoidCast`]s occur. casts: HashSet, } impl<'tcx> CVoidCastsUniDirectional<'tcx> { - /// Get the adjusted [`Place`] from a cast at a particulat [`Location`]. + /// Get the adjusted [`Place`] from a cast at a particular [`Location`]. /// /// Otherwise, the same `place` is returned, as no adjustments are necessary. pub fn get_adjusted_place_or_default_to( @@ -177,20 +184,22 @@ impl<'tcx> CVoidCastsUniDirectional<'tcx> { loc: Location, place: Place<'tcx>, ) -> Place<'tcx> { - *self - .calls - .get(&loc) - .map(|cast| { - assert_eq!(cast.c_void_ptr.place, place); - &cast.other_ptr - }) - .unwrap_or(&place) + // If there are multiple CVoidCasts for a Location, this logic may need to be adjusted + // depending on the intended behavior. + if let Some(casts) = self.calls.get(&loc) { + for cast in casts { + if cast.c_void_ptr.place == place { + return cast.other_ptr; + } + } + } + place } /// Tracks the [Location] of the use of a casted pointer in a [TerminatorKind::Call] pub fn insert_call(&mut self, loc: Location, cast: CVoidCast<'tcx>) { - assert!(!self.calls.contains_key(&loc)); - self.calls.insert(loc, cast); + let entry = self.calls.entry(loc).or_insert_with(HashSet::new); + entry.insert(cast); } /// Tracks the [Location] of void pointer [Rvalue::Cast] @@ -346,8 +355,10 @@ impl<'tcx> CVoidCasts<'tcx> { /// in a sequence of [Statement]s. We expect that the /// cast is the first non-[StatementKind::StorageDead] /// statement in the block, a special case for - /// [Terminator]s whose destination is casted from a + /// [`Terminator`]s whose destination is casted from a /// void pointer to some other pointer type. + /// + /// [`Terminator`]: rustc_middle::mir::Terminator fn find_first_cast( statements: &[Statement<'tcx>], c_void_ptr: CVoidPtr<'tcx>, @@ -377,7 +388,9 @@ impl<'tcx> CVoidCasts<'tcx> { for (sidx, stmt) in statements.iter().enumerate().rev() { let cast = c_void_ptr.get_cast_from_stmt(CVoidCastDirection::To, stmt); if let Some(cast) = cast { - return Some((sidx, cast)); + if cast.c_void_ptr == c_void_ptr { + return Some((sidx, cast)); + } } else if Self::is_place_modified_by_statement(&c_void_ptr.place, stmt) { return None; } @@ -403,62 +416,134 @@ impl<'tcx> CVoidCasts<'tcx> { /// [`*c_void`]: core::ffi::c_void fn insert_all_from_body(&mut self, body: &Body<'tcx>, tcx: TyCtxt<'tcx>) { for (block, bb_data) in body.basic_blocks().iter_enumerated() { - let term: &Terminator = match &bb_data.terminator { - Some(term) => term, - None => continue, - }; - let (func, args, destination, target) = match term.kind { - TerminatorKind::Call { - ref func, - ref args, + if let Some(term) = &bb_data.terminator { + if let TerminatorKind::Call { + func, + args, destination, target, .. - } => (func, args, destination, target), - _ => continue, - }; - let func_ty = func.ty(&body.local_decls, tcx); - - for direction in CVoidCastDirection::from_callee(ty_callee(tcx, func_ty)) - .iter() - .copied() + } = &term.kind + { + let func_ty = func.ty(&body.local_decls, tcx); + let directions = CVoidCastDirection::from_callee(ty_callee(tcx, func_ty)); + + for direction in directions.iter().copied() { + use CVoidCastDirection::*; + + match direction { + From => { + let c_void_ptr = + CVoidPtr::checked(*destination, &body.local_decls, tcx); + if let Some((statement_index, cast)) = Self::find_first_cast( + &body.basic_blocks()[target.unwrap()].statements, + c_void_ptr, + ) { + self.insert_cast( + direction, + Location { + statement_index, + block: target.unwrap(), + }, + ); + self.insert_call( + direction, + terminator_location(block, bb_data), + cast, + ); + } + } + To => { + for arg in args { + if let Some(place) = arg.place() { + if let Some(c_void_ptr) = CVoidPtr::checked_optional( + place, + &body.local_decls, + tcx, + ) { + self.find_and_insert_pred_cast( + body, c_void_ptr, direction, bb_data, + ); + } + } + } + } + } + } + } + } + } + } + + fn find_modifying_assignments( + current_block: BasicBlock, + current_block_data: &BasicBlockData<'tcx>, + c_void_ptr: &CVoidPtr<'tcx>, + ) -> Vec<(BasicBlock, usize)> { + let mut modifying_statements = current_block_data + .statements + .iter() + .enumerate() + .filter(|(_, stmt)| { + matches!(stmt.kind, StatementKind::Assign(..)) + && Self::is_place_modified_by_statement(&c_void_ptr.place, stmt) + }) + .map(|(index, _stmt)| (current_block, index)) + .collect::>(); + + if let Some(terminator) = ¤t_block_data.terminator { + if matches!(terminator.kind, TerminatorKind::Call { destination, .. } if destination == c_void_ptr.place) { - use CVoidCastDirection::*; - let c_void_ptr = match direction { - From => destination, - To => args[0] - .place() - .expect("Casts to/from null pointer are not yet supported"), - }; - let c_void_ptr = CVoidPtr::checked(c_void_ptr, &body.local_decls, tcx); - let cast = match direction { - // For [`CVoidCastDirection::From`], we only count - // a cast from `*c_void` to an arbitrary type in the subsequent block, - // searching forward. - From => Self::find_first_cast( - &body.basic_blocks()[target.unwrap()].statements, - c_void_ptr, - ), - // For [`CVoidCastDirection::To`], we only count - // a cast to `*c_void` from an arbitrary type in the same block, - // searching backwards. - To => Self::find_last_cast(&bb_data.statements, c_void_ptr), + modifying_statements.push((current_block, usize::MAX)); + } + } + + modifying_statements + } + + fn find_and_insert_pred_cast( + &mut self, + body: &Body<'tcx>, + c_void_ptr: CVoidPtr<'tcx>, + direction: CVoidCastDirection, + bb_data: &BasicBlockData<'tcx>, + ) { + let mut inserted_places = HashSet::new(); + let mut modifying_statements = Vec::new(); + + for (current_block, current_block_data) in body.basic_blocks().iter_enumerated() { + modifying_statements.extend(Self::find_modifying_assignments( + current_block, + current_block_data, + &c_void_ptr, + )); + + if let Some((statement_index, cast)) = + Self::find_last_cast(¤t_block_data.statements, c_void_ptr) + { + assert!( + inserted_places.insert(c_void_ptr.place), + "Duplicate c_void_ptr.place found: {:?}", + c_void_ptr.place + ); + assert!( + body.local_kind(c_void_ptr.place.local) == LocalKind::Temp, + "Unsupported cast into non-temporary local" + ); + let location = Location { + statement_index, + block: current_block, }; - if let Some((statement_index, cast)) = cast { - self.insert_cast( - direction, - Location { - statement_index, - block: match direction { - To => block, - From => target.unwrap(), - }, - }, - ); - self.insert_call(direction, terminator_location(block, bb_data), cast); - } + self.insert_cast(direction, location); + self.insert_call(direction, terminator_location(current_block, bb_data), cast); } } + + assert!( + modifying_statements.len() == 1, + "c_void_ptr.place modified multiple times: {:?}", + modifying_statements + ); } pub fn new(body: &Body<'tcx>, tcx: TyCtxt<'tcx>) -> Self { diff --git a/c2rust-analyze/src/dataflow/type_check.rs b/c2rust-analyze/src/dataflow/type_check.rs index 7f888df42b..3b7ae89b03 100644 --- a/c2rust-analyze/src/dataflow/type_check.rs +++ b/c2rust-analyze/src/dataflow/type_check.rs @@ -494,7 +494,73 @@ impl<'tcx> TypeChecker<'tcx, '_> { let perms = PermissionSet::FREE; self.constraints.add_all_perms(rv_lty.label, perms); } + Callee::Memcpy => { + let out_ptr = self.acx.c_void_casts.get_adjusted_place_or_default_to( + loc, + CVoidCastDirection::From, + destination, + ); + let dest_ptr = args[0] + .place() + .expect("Casts to/from null pointer are not yet supported"); + let dest_ptr = self.acx.c_void_casts.get_adjusted_place_or_default_to( + loc, + CVoidCastDirection::To, + dest_ptr, + ); + self.visit_place(out_ptr, Mutability::Mut); + assert!(args.len() == 3); + self.visit_place(dest_ptr, Mutability::Mut); + let rv_lty = self.acx.type_of(dest_ptr); + + // input needs WRITE permission + let perms = PermissionSet::WRITE; + self.constraints.add_all_perms(rv_lty.label, perms); + + let src_ptr = args[1] + .place() + .expect("Casts to/from null pointer are not yet supported"); + let src_ptr = self.acx.c_void_casts.get_adjusted_place_or_default_to( + loc, + CVoidCastDirection::To, + src_ptr, + ); + self.visit_place(out_ptr, Mutability::Mut); + let dest_ptr_lty = self.acx.type_of(out_ptr); + assert!(args.len() == 3); + self.visit_place(src_ptr, Mutability::Not); + let src_ptr_lty = self.acx.type_of(src_ptr); + + // input needs READ permission + let perms = PermissionSet::READ; + self.constraints.add_all_perms(src_ptr_lty.label, perms); + + // Perform a pseudo-assignment for *dest = *src + self.do_equivalence_nested(dest_ptr_lty.args[0], src_ptr_lty.args[0]); + } + Callee::Memset => { + let dest_ptr = args[0] + .place() + .expect("Casts to/from null pointer are not yet supported"); + let dest_ptr = self.acx.c_void_casts.get_adjusted_place_or_default_to( + loc, + CVoidCastDirection::To, + dest_ptr, + ); + self.visit_place(destination, Mutability::Mut); + assert!(args.len() == 3); + + let rv_lty = self.acx.type_of(dest_ptr); + let perms = PermissionSet::WRITE; + self.constraints.add_all_perms(rv_lty.label, perms); + + // TODO: the return values of `memcpy` are rarely used + // and may not always be casted to a non-void-pointer, + // so avoid unifying for now + // let pl_lty = self.acx.type_of(out_ptr); + // self.do_equivalence_nested(pl_lty, rv_lty); + } Callee::IsNull => { assert!(args.len() == 1); self.visit_operand(&args[0]); diff --git a/c2rust-analyze/src/rewrite/expr/unlower.rs b/c2rust-analyze/src/rewrite/expr/unlower.rs index 45f608c00a..00cee0aa26 100644 --- a/c2rust-analyze/src/rewrite/expr/unlower.rs +++ b/c2rust-analyze/src/rewrite/expr/unlower.rs @@ -155,17 +155,20 @@ impl<'a, 'tcx> UnlowerVisitor<'a, 'tcx> { &'a mir::Operand<'tcx>, &'a [mir::Operand<'tcx>], )> { - let loc = *locs.last()?; - let term = self.mir.stmt_at(loc).right()?; - match term.kind { - mir::TerminatorKind::Call { - ref func, - ref args, - destination, - .. - } => Some((loc, destination, func, args)), - _ => None, + for &loc in locs.iter().rev() { + if let Some(term) = self.mir.stmt_at(loc).right() { + match term.kind { + mir::TerminatorKind::Call { + ref func, + ref args, + destination, + .. + } => return Some((loc, destination, func, args)), + _ => {} + } + } } + None } fn should_ignore_statement(&self, loc: Location) -> bool { diff --git a/c2rust-analyze/src/util.rs b/c2rust-analyze/src/util.rs index 4a9c15bf38..01c1b7efa3 100644 --- a/c2rust-analyze/src/util.rs +++ b/c2rust-analyze/src/util.rs @@ -177,6 +177,12 @@ pub enum Callee<'tcx> { /// libc::calloc Calloc, + /// libc::memset + Memset, + + /// libc::memcpy + Memcpy, + /// libc::free Free, @@ -303,6 +309,20 @@ fn builtin_callee<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, substs: SubstsRef<'tcx>) None } + "memset" => { + if matches!(tcx.def_kind(tcx.parent(did)), DefKind::ForeignMod) { + return Some(Callee::Memset); + } + None + } + + "memcpy" => { + if matches!(tcx.def_kind(tcx.parent(did)), DefKind::ForeignMod) { + return Some(Callee::Memcpy); + } + None + } + "is_null" => { // The `offset` inherent method of `*const T` and `*mut T`. let parent_did = tcx.parent(did); diff --git a/c2rust-analyze/tests/filecheck.rs b/c2rust-analyze/tests/filecheck.rs index afdfa6a9c2..f3cdfc2ede 100644 --- a/c2rust-analyze/tests/filecheck.rs +++ b/c2rust-analyze/tests/filecheck.rs @@ -33,6 +33,7 @@ macro_rules! define_tests { define_tests! { addr_of, aggregate1, + algo_md5, alias1, alias2, alias3, diff --git a/c2rust-analyze/tests/filecheck/algo_md5.rs b/c2rust-analyze/tests/filecheck/algo_md5.rs new file mode 100644 index 0000000000..d04a2fd53c --- /dev/null +++ b/c2rust-analyze/tests/filecheck/algo_md5.rs @@ -0,0 +1,698 @@ +#![feature(rustc_private)] + +extern crate libc; + +extern "C" { + fn memcpy(_: *mut libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> *mut libc::c_void; + fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void; +} +pub type __uint32_t = libc::c_uint; +pub type uint32_t = __uint32_t; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct MD5_CTX { + pub state: [uint32_t; 4], + pub count: [uint32_t; 2], + pub buffer: [libc::c_uchar; 64], +} +static mut PADDING: [libc::c_uchar; 64] = [ + 0x80 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, + 0 as libc::c_int as libc::c_uchar, +]; + +// CHECK-LABEL: MD5_Init +#[no_mangle] +pub unsafe extern "C" fn MD5_Init(mut context: *mut MD5_CTX) { + (*context).count[1 as libc::c_int as usize] = 0 as libc::c_int as uint32_t; + (*context).count[0 as libc::c_int as usize] = (*context).count[1 as libc::c_int as usize]; + (*context).state[0 as libc::c_int as usize] = 0x67452301 as libc::c_int as uint32_t; + (*context).state[1 as libc::c_int as usize] = 0xefcdab89 as libc::c_uint; + (*context).state[2 as libc::c_int as usize] = 0x98badcfe as libc::c_uint; + (*context).state[3 as libc::c_int as usize] = 0x10325476 as libc::c_int as uint32_t; +} +#[no_mangle] +pub unsafe extern "C" fn MD5_Update( + mut context: *mut MD5_CTX, + mut input: *const libc::c_void, + mut inputLen: libc::c_uint, +) { + let mut i: libc::c_uint = 0; + let mut ndx: libc::c_uint = 0; + let mut partLen: libc::c_uint = 0; + // let mut input: *const libc::c_uchar = _input as *const libc::c_uchar; + ndx = (*context).count[0 as libc::c_int as usize] >> 3 as libc::c_int + & 0x3f as libc::c_int as libc::c_uint; + (*context).count[0 as libc::c_int as usize] = + ((*context).count[0 as libc::c_int as usize] as libc::c_uint) + .wrapping_add(inputLen << 3 as libc::c_int) as uint32_t as uint32_t; + if (*context).count[0 as libc::c_int as usize] < inputLen << 3 as libc::c_int { + (*context).count[1 as libc::c_int as usize] = + ((*context).count[1 as libc::c_int as usize]).wrapping_add(1); + } + (*context).count[1 as libc::c_int as usize] = + ((*context).count[1 as libc::c_int as usize] as libc::c_uint) + .wrapping_add(inputLen >> 29 as libc::c_int) as uint32_t as uint32_t; + partLen = (64 as libc::c_int as libc::c_uint).wrapping_sub(ndx); + if inputLen >= partLen { + memcpy( + &mut *((*context).buffer).as_mut_ptr().offset(ndx as isize) as *mut libc::c_uchar + as *mut libc::c_void, + input /* as *mut libc::c_uchar */ as *const libc::c_void, + partLen as libc::c_ulong, + ); + li_MD5Transform( + ((*context).state).as_mut_ptr(), + ((*context).buffer).as_mut_ptr() as *const libc::c_uchar, + ); + i = partLen; + while i.wrapping_add(63 as libc::c_int as libc::c_uint) < inputLen { + // li_MD5Transform(((*context).state).as_mut_ptr(), &*input.offset(i as isize)); + i = i.wrapping_add(64 as libc::c_int as libc::c_uint); + } + ndx = 0 as libc::c_int as libc::c_uint; + } else { + i = 0 as libc::c_int as libc::c_uint; + } + // memcpy( + // &mut *((*context).buffer).as_mut_ptr().offset(ndx as isize) as *mut libc::c_uchar + // as *mut libc::c_void, + // &*input.offset(i as isize) as *const libc::c_uchar as *mut libc::c_uchar + // as *const libc::c_void, + // inputLen.wrapping_sub(i) as libc::c_ulong, + // ); +} +#[no_mangle] +pub unsafe extern "C" fn MD5_Final(mut digest: *mut libc::c_uchar, mut context: *mut MD5_CTX) { + let mut bits: [libc::c_uchar; 8] = [0; 8]; + let mut ndx: libc::c_uint = 0; + let mut padLen: libc::c_uint = 0; + // Encode( + // bits.as_mut_ptr(), + // ((*context).count).as_mut_ptr(), + // 8 as libc::c_int as libc::c_uint, + // ); + ndx = (*context).count[0 as libc::c_int as usize] >> 3 as libc::c_int + & 0x3f as libc::c_int as libc::c_uint; + padLen = if ndx < 56 as libc::c_int as libc::c_uint { + (56 as libc::c_int as libc::c_uint).wrapping_sub(ndx) + } else { + (120 as libc::c_int as libc::c_uint).wrapping_sub(ndx) + }; + // MD5_Update(context, PADDING.as_mut_ptr(),// as *const libc::c_void, + // padLen); + // MD5_Update( + // context, + // bits.as_mut_ptr(), // as *const libc::c_void, + // 8 as libc::c_int as libc::c_uint, + // ); + // Encode( + // digest, + // ((*context).state).as_mut_ptr(), + // 16 as libc::c_int as libc::c_uint, + // ); + memset( + context /* as *mut libc::c_uchar */ as *mut libc::c_void, + 0 as libc::c_int, + ::std::mem::size_of::() as libc::c_ulong, + ); +} +unsafe extern "C" fn li_MD5Transform(mut state: *mut uint32_t, mut block: *const libc::c_uchar) { + let mut a: uint32_t = *state.offset(0 as libc::c_int as isize); + let mut b: uint32_t = *state.offset(1 as libc::c_int as isize); + let mut c: uint32_t = *state.offset(2 as libc::c_int as isize); + let mut d: uint32_t = *state.offset(3 as libc::c_int as isize); + let mut x: [uint32_t; 16] = [0; 16]; + // Decode(x.as_mut_ptr(), block, 64 as libc::c_int as libc::c_uint); + a = (a as libc::c_uint).wrapping_add( + (b & c | !b & d) + .wrapping_add(x[0 as libc::c_int as usize]) + .wrapping_add(0xd76aa478 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 7 as libc::c_int | a >> 32 as libc::c_int - 7 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & b | !a & c) + .wrapping_add(x[1 as libc::c_int as usize]) + .wrapping_add(0xe8c7b756 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 12 as libc::c_int | d >> 32 as libc::c_int - 12 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & a | !d & b) + .wrapping_add(x[2 as libc::c_int as usize]) + .wrapping_add(0x242070db as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 17 as libc::c_int | c >> 32 as libc::c_int - 17 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & d | !c & a) + .wrapping_add(x[3 as libc::c_int as usize]) + .wrapping_add(0xc1bdceee as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 22 as libc::c_int | b >> 32 as libc::c_int - 22 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & c | !b & d) + .wrapping_add(x[4 as libc::c_int as usize]) + .wrapping_add(0xf57c0faf as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 7 as libc::c_int | a >> 32 as libc::c_int - 7 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & b | !a & c) + .wrapping_add(x[5 as libc::c_int as usize]) + .wrapping_add(0x4787c62a as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + d = d << 12 as libc::c_int | d >> 32 as libc::c_int - 12 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & a | !d & b) + .wrapping_add(x[6 as libc::c_int as usize]) + .wrapping_add(0xa8304613 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 17 as libc::c_int | c >> 32 as libc::c_int - 17 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & d | !c & a) + .wrapping_add(x[7 as libc::c_int as usize]) + .wrapping_add(0xfd469501 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 22 as libc::c_int | b >> 32 as libc::c_int - 22 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & c | !b & d) + .wrapping_add(x[8 as libc::c_int as usize]) + .wrapping_add(0x698098d8 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 7 as libc::c_int | a >> 32 as libc::c_int - 7 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & b | !a & c) + .wrapping_add(x[9 as libc::c_int as usize]) + .wrapping_add(0x8b44f7af as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 12 as libc::c_int | d >> 32 as libc::c_int - 12 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & a | !d & b) + .wrapping_add(x[10 as libc::c_int as usize]) + .wrapping_add(0xffff5bb1 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 17 as libc::c_int | c >> 32 as libc::c_int - 17 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & d | !c & a) + .wrapping_add(x[11 as libc::c_int as usize]) + .wrapping_add(0x895cd7be as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 22 as libc::c_int | b >> 32 as libc::c_int - 22 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & c | !b & d) + .wrapping_add(x[12 as libc::c_int as usize]) + .wrapping_add(0x6b901122 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 7 as libc::c_int | a >> 32 as libc::c_int - 7 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & b | !a & c) + .wrapping_add(x[13 as libc::c_int as usize]) + .wrapping_add(0xfd987193 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 12 as libc::c_int | d >> 32 as libc::c_int - 12 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & a | !d & b) + .wrapping_add(x[14 as libc::c_int as usize]) + .wrapping_add(0xa679438e as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 17 as libc::c_int | c >> 32 as libc::c_int - 17 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & d | !c & a) + .wrapping_add(x[15 as libc::c_int as usize]) + .wrapping_add(0x49b40821 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + b = b << 22 as libc::c_int | b >> 32 as libc::c_int - 22 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & d | c & !d) + .wrapping_add(x[1 as libc::c_int as usize]) + .wrapping_add(0xf61e2562 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 5 as libc::c_int | a >> 32 as libc::c_int - 5 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & c | b & !c) + .wrapping_add(x[6 as libc::c_int as usize]) + .wrapping_add(0xc040b340 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 9 as libc::c_int | d >> 32 as libc::c_int - 9 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & b | a & !b) + .wrapping_add(x[11 as libc::c_int as usize]) + .wrapping_add(0x265e5a51 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 14 as libc::c_int | c >> 32 as libc::c_int - 14 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & a | d & !a) + .wrapping_add(x[0 as libc::c_int as usize]) + .wrapping_add(0xe9b6c7aa as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 20 as libc::c_int | b >> 32 as libc::c_int - 20 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & d | c & !d) + .wrapping_add(x[5 as libc::c_int as usize]) + .wrapping_add(0xd62f105d as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 5 as libc::c_int | a >> 32 as libc::c_int - 5 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & c | b & !c) + .wrapping_add(x[10 as libc::c_int as usize]) + .wrapping_add(0x2441453 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + d = d << 9 as libc::c_int | d >> 32 as libc::c_int - 9 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & b | a & !b) + .wrapping_add(x[15 as libc::c_int as usize]) + .wrapping_add(0xd8a1e681 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 14 as libc::c_int | c >> 32 as libc::c_int - 14 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & a | d & !a) + .wrapping_add(x[4 as libc::c_int as usize]) + .wrapping_add(0xe7d3fbc8 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 20 as libc::c_int | b >> 32 as libc::c_int - 20 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & d | c & !d) + .wrapping_add(x[9 as libc::c_int as usize]) + .wrapping_add(0x21e1cde6 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 5 as libc::c_int | a >> 32 as libc::c_int - 5 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & c | b & !c) + .wrapping_add(x[14 as libc::c_int as usize]) + .wrapping_add(0xc33707d6 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 9 as libc::c_int | d >> 32 as libc::c_int - 9 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & b | a & !b) + .wrapping_add(x[3 as libc::c_int as usize]) + .wrapping_add(0xf4d50d87 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 14 as libc::c_int | c >> 32 as libc::c_int - 14 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & a | d & !a) + .wrapping_add(x[8 as libc::c_int as usize]) + .wrapping_add(0x455a14ed as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + b = b << 20 as libc::c_int | b >> 32 as libc::c_int - 20 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b & d | c & !d) + .wrapping_add(x[13 as libc::c_int as usize]) + .wrapping_add(0xa9e3e905 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 5 as libc::c_int | a >> 32 as libc::c_int - 5 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a & c | b & !c) + .wrapping_add(x[2 as libc::c_int as usize]) + .wrapping_add(0xfcefa3f8 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 9 as libc::c_int | d >> 32 as libc::c_int - 9 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d & b | a & !b) + .wrapping_add(x[7 as libc::c_int as usize]) + .wrapping_add(0x676f02d9 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 14 as libc::c_int | c >> 32 as libc::c_int - 14 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c & a | d & !a) + .wrapping_add(x[12 as libc::c_int as usize]) + .wrapping_add(0x8d2a4c8a as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 20 as libc::c_int | b >> 32 as libc::c_int - 20 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b ^ c ^ d) + .wrapping_add(x[5 as libc::c_int as usize]) + .wrapping_add(0xfffa3942 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 4 as libc::c_int | a >> 32 as libc::c_int - 4 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a ^ b ^ c) + .wrapping_add(x[8 as libc::c_int as usize]) + .wrapping_add(0x8771f681 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 11 as libc::c_int | d >> 32 as libc::c_int - 11 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d ^ a ^ b) + .wrapping_add(x[11 as libc::c_int as usize]) + .wrapping_add(0x6d9d6122 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 16 as libc::c_int | c >> 32 as libc::c_int - 16 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c ^ d ^ a) + .wrapping_add(x[14 as libc::c_int as usize]) + .wrapping_add(0xfde5380c as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 23 as libc::c_int | b >> 32 as libc::c_int - 23 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b ^ c ^ d) + .wrapping_add(x[1 as libc::c_int as usize]) + .wrapping_add(0xa4beea44 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 4 as libc::c_int | a >> 32 as libc::c_int - 4 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a ^ b ^ c) + .wrapping_add(x[4 as libc::c_int as usize]) + .wrapping_add(0x4bdecfa9 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + d = d << 11 as libc::c_int | d >> 32 as libc::c_int - 11 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d ^ a ^ b) + .wrapping_add(x[7 as libc::c_int as usize]) + .wrapping_add(0xf6bb4b60 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 16 as libc::c_int | c >> 32 as libc::c_int - 16 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c ^ d ^ a) + .wrapping_add(x[10 as libc::c_int as usize]) + .wrapping_add(0xbebfbc70 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 23 as libc::c_int | b >> 32 as libc::c_int - 23 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b ^ c ^ d) + .wrapping_add(x[13 as libc::c_int as usize]) + .wrapping_add(0x289b7ec6 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 4 as libc::c_int | a >> 32 as libc::c_int - 4 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a ^ b ^ c) + .wrapping_add(x[0 as libc::c_int as usize]) + .wrapping_add(0xeaa127fa as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 11 as libc::c_int | d >> 32 as libc::c_int - 11 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d ^ a ^ b) + .wrapping_add(x[3 as libc::c_int as usize]) + .wrapping_add(0xd4ef3085 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 16 as libc::c_int | c >> 32 as libc::c_int - 16 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c ^ d ^ a) + .wrapping_add(x[6 as libc::c_int as usize]) + .wrapping_add(0x4881d05 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + b = b << 23 as libc::c_int | b >> 32 as libc::c_int - 23 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (b ^ c ^ d) + .wrapping_add(x[9 as libc::c_int as usize]) + .wrapping_add(0xd9d4d039 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 4 as libc::c_int | a >> 32 as libc::c_int - 4 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (a ^ b ^ c) + .wrapping_add(x[12 as libc::c_int as usize]) + .wrapping_add(0xe6db99e5 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 11 as libc::c_int | d >> 32 as libc::c_int - 11 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (d ^ a ^ b) + .wrapping_add(x[15 as libc::c_int as usize]) + .wrapping_add(0x1fa27cf8 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 16 as libc::c_int | c >> 32 as libc::c_int - 16 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (c ^ d ^ a) + .wrapping_add(x[2 as libc::c_int as usize]) + .wrapping_add(0xc4ac5665 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 23 as libc::c_int | b >> 32 as libc::c_int - 23 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (c ^ (b | !d)) + .wrapping_add(x[0 as libc::c_int as usize]) + .wrapping_add(0xf4292244 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 6 as libc::c_int | a >> 32 as libc::c_int - 6 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (b ^ (a | !c)) + .wrapping_add(x[7 as libc::c_int as usize]) + .wrapping_add(0x432aff97 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + d = d << 10 as libc::c_int | d >> 32 as libc::c_int - 10 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (a ^ (d | !b)) + .wrapping_add(x[14 as libc::c_int as usize]) + .wrapping_add(0xab9423a7 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 15 as libc::c_int | c >> 32 as libc::c_int - 15 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (d ^ (c | !a)) + .wrapping_add(x[5 as libc::c_int as usize]) + .wrapping_add(0xfc93a039 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 21 as libc::c_int | b >> 32 as libc::c_int - 21 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (c ^ (b | !d)) + .wrapping_add(x[12 as libc::c_int as usize]) + .wrapping_add(0x655b59c3 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 6 as libc::c_int | a >> 32 as libc::c_int - 6 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (b ^ (a | !c)) + .wrapping_add(x[3 as libc::c_int as usize]) + .wrapping_add(0x8f0ccc92 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 10 as libc::c_int | d >> 32 as libc::c_int - 10 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (a ^ (d | !b)) + .wrapping_add(x[10 as libc::c_int as usize]) + .wrapping_add(0xffeff47d as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 15 as libc::c_int | c >> 32 as libc::c_int - 15 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (d ^ (c | !a)) + .wrapping_add(x[1 as libc::c_int as usize]) + .wrapping_add(0x85845dd1 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 21 as libc::c_int | b >> 32 as libc::c_int - 21 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (c ^ (b | !d)) + .wrapping_add(x[8 as libc::c_int as usize]) + .wrapping_add(0x6fa87e4f as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + a = a << 6 as libc::c_int | a >> 32 as libc::c_int - 6 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (b ^ (a | !c)) + .wrapping_add(x[15 as libc::c_int as usize]) + .wrapping_add(0xfe2ce6e0 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 10 as libc::c_int | d >> 32 as libc::c_int - 10 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (a ^ (d | !b)) + .wrapping_add(x[6 as libc::c_int as usize]) + .wrapping_add(0xa3014314 as libc::c_uint), + ) as uint32_t as uint32_t; + c = c << 15 as libc::c_int | c >> 32 as libc::c_int - 15 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (d ^ (c | !a)) + .wrapping_add(x[13 as libc::c_int as usize]) + .wrapping_add(0x4e0811a1 as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + b = b << 21 as libc::c_int | b >> 32 as libc::c_int - 21 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + a = (a as libc::c_uint).wrapping_add( + (c ^ (b | !d)) + .wrapping_add(x[4 as libc::c_int as usize]) + .wrapping_add(0xf7537e82 as libc::c_uint), + ) as uint32_t as uint32_t; + a = a << 6 as libc::c_int | a >> 32 as libc::c_int - 6 as libc::c_int; + a = (a as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + d = (d as libc::c_uint).wrapping_add( + (b ^ (a | !c)) + .wrapping_add(x[11 as libc::c_int as usize]) + .wrapping_add(0xbd3af235 as libc::c_uint), + ) as uint32_t as uint32_t; + d = d << 10 as libc::c_int | d >> 32 as libc::c_int - 10 as libc::c_int; + d = (d as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + c = (c as libc::c_uint).wrapping_add( + (a ^ (d | !b)) + .wrapping_add(x[2 as libc::c_int as usize]) + .wrapping_add(0x2ad7d2bb as libc::c_int as uint32_t), + ) as uint32_t as uint32_t; + c = c << 15 as libc::c_int | c >> 32 as libc::c_int - 15 as libc::c_int; + c = (c as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + b = (b as libc::c_uint).wrapping_add( + (d ^ (c | !a)) + .wrapping_add(x[9 as libc::c_int as usize]) + .wrapping_add(0xeb86d391 as libc::c_uint), + ) as uint32_t as uint32_t; + b = b << 21 as libc::c_int | b >> 32 as libc::c_int - 21 as libc::c_int; + b = (b as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + let ref mut fresh0 = *state.offset(0 as libc::c_int as isize); + *fresh0 = (*fresh0 as libc::c_uint).wrapping_add(a) as uint32_t as uint32_t; + let ref mut fresh1 = *state.offset(1 as libc::c_int as isize); + *fresh1 = (*fresh1 as libc::c_uint).wrapping_add(b) as uint32_t as uint32_t; + let ref mut fresh2 = *state.offset(2 as libc::c_int as isize); + *fresh2 = (*fresh2 as libc::c_uint).wrapping_add(c) as uint32_t as uint32_t; + let ref mut fresh3 = *state.offset(3 as libc::c_int as isize); + *fresh3 = (*fresh3 as libc::c_uint).wrapping_add(d) as uint32_t as uint32_t; + memset( + x.as_mut_ptr() /* as *mut libc::c_uchar */ as *mut libc::c_void, + 0 as libc::c_int, + ::std::mem::size_of::<[uint32_t; 16]>() as libc::c_ulong, + ); +} +unsafe extern "C" fn Encode( + mut output: *mut libc::c_uchar, + mut input: *mut uint32_t, + mut len: libc::c_uint, +) { + let mut i: libc::c_uint = 0; + let mut j: libc::c_uint = 0; + i = 0 as libc::c_int as libc::c_uint; + j = 0 as libc::c_int as libc::c_uint; + while j < len { + *output.offset(j as isize) = + (*input.offset(i as isize) & 0xff as libc::c_int as libc::c_uint) as libc::c_uchar; + *output.offset(j.wrapping_add(1 as libc::c_int as libc::c_uint) as isize) = + (*input.offset(i as isize) >> 8 as libc::c_int & 0xff as libc::c_int as libc::c_uint) + as libc::c_uchar; + *output.offset(j.wrapping_add(2 as libc::c_int as libc::c_uint) as isize) = + (*input.offset(i as isize) >> 16 as libc::c_int & 0xff as libc::c_int as libc::c_uint) + as libc::c_uchar; + *output.offset(j.wrapping_add(3 as libc::c_int as libc::c_uint) as isize) = + (*input.offset(i as isize) >> 24 as libc::c_int & 0xff as libc::c_int as libc::c_uint) + as libc::c_uchar; + i = i.wrapping_add(1); + j = j.wrapping_add(4 as libc::c_int as libc::c_uint); + } +} +unsafe extern "C" fn Decode( + mut output: *mut uint32_t, + mut input: *const libc::c_uchar, + mut len: libc::c_uint, +) { + let mut i: libc::c_uint = 0; + let mut j: libc::c_uint = 0; + i = 0 as libc::c_int as libc::c_uint; + j = 0 as libc::c_int as libc::c_uint; + while j < len { + *output.offset(i as isize) = *input.offset(j as isize) as uint32_t + | (*input.offset(j.wrapping_add(1 as libc::c_int as libc::c_uint) as isize) + as uint32_t) + << 8 as libc::c_int + | (*input.offset(j.wrapping_add(2 as libc::c_int as libc::c_uint) as isize) + as uint32_t) + << 16 as libc::c_int + | (*input.offset(j.wrapping_add(3 as libc::c_int as libc::c_uint) as isize) + as uint32_t) + << 24 as libc::c_int; + i = i.wrapping_add(1); + j = j.wrapping_add(4 as libc::c_int as libc::c_uint); + } +}