├── .gitignore ├── .travis.yml ├── AUTHORS ├── COPYING ├── ChangeLog ├── LICENSE ├── Makefile.am ├── NEWS ├── README ├── autogen.sh ├── compat.h ├── compat ├── Makefile.am └── jansson │ ├── .gitignore │ ├── LICENSE │ ├── Makefile.am │ ├── config.h │ ├── dump.c │ ├── hashtable.c │ ├── hashtable.h │ ├── jansson.h │ ├── jansson_private.h │ ├── load.c │ ├── strbuffer.c │ ├── strbuffer.h │ ├── utf.c │ ├── utf.h │ ├── util.h │ └── value.c ├── configure.ac ├── cpu-miner.c ├── elist.h ├── example-cfg.json ├── miner.h ├── mknsis.sh ├── sha256_4way.c ├── sha256_cryptopp.c ├── sha256_generic.c ├── sha256_sse2_amd64.c ├── sha256_via.c ├── util.c └── x86_64 ├── .gitignore ├── Makefile.am └── sha256_xmm_amd64.asm /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | minerd 3 | minerd.exe 4 | *.o 5 | 6 | autom4te.cache 7 | .deps 8 | 9 | Makefile 10 | Makefile.in 11 | INSTALL 12 | aclocal.m4 13 | configure 14 | depcomp 15 | missing 16 | install-sh 17 | stamp-h1 18 | cpuminer-config.h* 19 | compile 20 | config.log 21 | config.status 22 | config.guess 23 | config.sub 24 | 25 | mingw32-config.cache 26 | 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: c 3 | 4 | compiler: 5 | - clang 6 | - gcc 7 | 8 | os: 9 | - linux 10 | 11 | sudo: false 12 | 13 | env: 14 | global: 15 | - MAKEJOBS=-j3 16 | - RUN_TESTS=true 17 | - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out 18 | 19 | cache: 20 | apt: true 21 | 22 | addons: 23 | apt: 24 | packages: 25 | - libssl-dev 26 | - libcurl4-openssl-dev 27 | - libjansson-dev 28 | - pkg-config 29 | 30 | before_script: 31 | - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi 32 | - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh 33 | 34 | script: 35 | - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST 36 | - CPUMINER_CONFIG_ALL="--prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" 37 | - ./configure --cache-file=config.cache $CPUMINER_CONFIG_ALL $CPUMINER_CONFIG || ( cat config.log && false) 38 | - make -s $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL ; false ) 39 | - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib 40 | - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS distcheck; fi 41 | 42 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Jeff Garzik 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | See git repository ('git log') for full changelog. 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | cpuminer is available under the terms of the GNU Public License version 2. 2 | 3 | See COPYING for details. 4 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | if WANT_JANSSON 3 | JANSSON_INCLUDES= -I$(top_srcdir)/compat/jansson 4 | else 5 | JANSSON_INCLUDES= 6 | endif 7 | 8 | EXTRA_DIST = example-cfg.json 9 | 10 | SUBDIRS = compat 11 | 12 | INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES) 13 | 14 | bin_PROGRAMS = minerd 15 | 16 | minerd_SOURCES = elist.h miner.h compat.h \ 17 | cpu-miner.c util.c \ 18 | sha256_generic.c sha256_4way.c sha256_via.c \ 19 | sha256_cryptopp.c sha256_sse2_amd64.c 20 | minerd_LDFLAGS = $(PTHREAD_FLAGS) 21 | minerd_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ 22 | minerd_CPPFLAGS = @LIBCURL_CPPFLAGS@ 23 | 24 | if HAVE_x86_64 25 | if HAS_YASM 26 | SUBDIRS += x86_64 27 | minerd_LDADD += x86_64/libx8664.a 28 | AM_CFLAGS = -DHAS_YASM 29 | endif 30 | endif 31 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | - Linux x86_64 optimisations - Con Kolivas 2 | - Optimise for x86_64 by default by using sse2_64 algo 3 | - Detects CPUs and sets number of threads accordingly 4 | - Uses CPU affinity for each thread where appropriate 5 | - Sets scheduling policy to lowest possible 6 | - Minor performance tweaks 7 | 8 | Version 1.0.1 - May 14, 2011 9 | 10 | - OSX support in development 11 | 12 | Version 1.0 - May 9, 2011 13 | 14 | - jansson 2.0 compatibility 15 | - correct off-by-one in date (month) display output 16 | - fix platform detection 17 | - improve yasm configure bits 18 | - support full URL, in X-Long-Polling header 19 | 20 | Version 0.8.1 - March 22, 2011 21 | 22 | - Make --user, --pass actually work 23 | 24 | - Add User-Agent HTTP header to requests, so that server operators may 25 | more easily identify the miner client. 26 | 27 | - Fix minor bug in example JSON config file 28 | 29 | Version 0.8 - March 21, 2011 30 | 31 | - Support long polling: http://deepbit.net/longpolling.php 32 | 33 | - Adjust max workload based on scantime (default 5 seconds, 34 | or 60 seconds for longpoll) 35 | 36 | - Standardize program output, and support syslog on Unix platforms 37 | 38 | - Suport --user/--pass options (and "user" and "pass" in config file), 39 | as an alternative to the current --userpass 40 | 41 | Version 0.7.2 - March 14, 2011 42 | 43 | - Add port of ufasoft's sse2 assembly implementation (Linux only) 44 | This is a substantial speed improvement on Intel CPUs. 45 | 46 | - Move all JSON-RPC I/O to separate thread. This reduces the 47 | number of HTTP connections from one-per-thread to one, reducing resource 48 | usage on upstream bitcoind / pool server. 49 | 50 | Version 0.7.1 - March 2, 2011 51 | 52 | - Add support for JSON-format configuration file. See example 53 | file example-cfg.json. Any long argument on the command line 54 | may be stored in the config file. 55 | - Timestamp each solution found 56 | - Improve sha256_4way performance. NOTE: This optimization makes 57 | the 'hash' debug-print output for sha256_way incorrect. 58 | - Use __builtin_expect() intrinsic as compiler micro-optimization 59 | - Build on Intel compiler 60 | - HTTP library now follows HTTP redirects 61 | 62 | Version 0.7 - February 12, 2011 63 | 64 | - Re-use CURL object, thereby reuseing DNS cache and HTTP connections 65 | - Use bswap_32, if compiler intrinsic is not available 66 | - Disable full target validation (as opposed to simply H==0) for now 67 | 68 | Version 0.6.1 - February 4, 2011 69 | 70 | - Fully validate "hash < target", rather than simply stopping our scan 71 | if the high 32 bits are 00000000. 72 | - Add --retry-pause, to set length of pause time between failure retries 73 | - Display proof-of-work hash and target, if -D (debug mode) enabled 74 | - Fix max-nonce auto-adjustment to actually work. This means if your 75 | scan takes longer than 5 seconds (--scantime), the miner will slowly 76 | reduce the number of hashes you work on, before fetching a new work unit. 77 | 78 | Version 0.6 - January 29, 2011 79 | 80 | - Fetch new work unit, if scanhash takes longer than 5 seconds (--scantime) 81 | - BeeCee1's sha256 4way optimizations 82 | - lfm's byte swap optimization (improves via, cryptopp) 83 | - Fix non-working short options -q, -r 84 | 85 | Version 0.5 - December 28, 2010 86 | 87 | - Exit program, when all threads have exited 88 | - Improve JSON-RPC failure diagnostics and resilience 89 | - Add --quiet option, to disable hashmeter output. 90 | 91 | Version 0.3.3 - December 27, 2010 92 | 93 | - Critical fix for sha256_cryptopp 'cryptopp_asm' algo 94 | 95 | Version 0.3.2 - December 23, 2010 96 | 97 | - Critical fix for sha256_via 98 | 99 | Version 0.3.1 - December 19, 2010 100 | 101 | - Critical fix for sha256_via 102 | - Retry JSON-RPC failures (see --retry, under "minerd --help" output) 103 | 104 | Version 0.3 - December 18, 2010 105 | 106 | - Add crypto++ 32bit assembly implementation 107 | - show version upon 'minerd --help' 108 | - work around gcc 4.5.x bug that killed 4way performance 109 | 110 | Version 0.2.2 - December 6, 2010 111 | 112 | - VIA padlock implementation works now 113 | - Minor build and runtime fixes 114 | 115 | Version 0.2.1 - November 29, 2010 116 | 117 | - avoid buffer overflow when submitting solutions 118 | - add Crypto++ sha256 implementation (C only, ASM elided for now) 119 | - minor internal optimizations and cleanups 120 | 121 | Version 0.2 - November 27, 2010 122 | 123 | - Add script for building a Windows installer 124 | - improve hash performance (hashmeter) statistics 125 | - add tcatm 4way sha256 implementation 126 | - Add experimental VIA Padlock sha256 implementation 127 | 128 | Version 0.1.2 - November 26, 2010 129 | 130 | - many small cleanups and micro-optimizations 131 | - build win32 exe using mingw 132 | - RPC URL, username/password become command line arguments 133 | - remove unused OpenSSL dependency 134 | 135 | Version 0.1.1 - November 24, 2010 136 | 137 | - Do not build sha256_generic module separately from cpuminer. 138 | 139 | Version 0.1 - November 24, 2010 140 | 141 | - Initial release. 142 | 143 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | This is a multi-threaded CPU miner for bitcoin. 3 | 4 | License: See COPYING for details. 5 | 6 | Dependencies: 7 | libcurl http://curl.haxx.se/libcurl/ 8 | jansson http://www.digip.org/jansson/ 9 | (jansson is optional, and is included in-tree) 10 | 11 | Basic *nix build instructions: 12 | ./autogen.sh # only needed if building from git repo 13 | CFLAGS="-O3 -Wall -msse2" ./configure 14 | make 15 | 16 | Basic WIN32 build instructions (on Fedora 13; requires mingw32): 17 | ./autogen.sh # only needed if building from git repo 18 | rm -f mingw32-config.cache 19 | MINGW32_CFLAGS="-O3 -Wall -msse2" mingw32-configure 20 | make 21 | ./mknsis.sh 22 | 23 | Usage instructions: Run "minerd --help" to see options. 24 | 25 | Also many issues and FAQs are covered in the forum thread 26 | dedicated to this program, 27 | https://bitcointalk.org/?topic=1925.0;all 28 | 29 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # You need autoconf 2.5x, preferably 2.57 or later 4 | # You need automake 1.7 or later. 1.6 might work. 5 | 6 | set -e 7 | 8 | aclocal 9 | autoheader 10 | automake --gnu --add-missing --copy 11 | autoconf 12 | autoreconf -i 13 | 14 | -------------------------------------------------------------------------------- /compat.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPAT_H__ 2 | #define __COMPAT_H__ 3 | 4 | #ifdef WIN32 5 | 6 | #include 7 | 8 | static inline void sleep(int secs) 9 | { 10 | Sleep(secs * 1000); 11 | } 12 | 13 | enum { 14 | PRIO_PROCESS = 0, 15 | }; 16 | 17 | static inline int setpriority(int which, int who, int prio) 18 | { 19 | /* FIXME - actually do something */ 20 | return 0; 21 | } 22 | 23 | #endif /* WIN32 */ 24 | 25 | #endif /* __COMPAT_H__ */ 26 | -------------------------------------------------------------------------------- /compat/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | if WANT_JANSSON 3 | SUBDIRS = jansson 4 | else 5 | SUBDIRS = 6 | endif 7 | 8 | -------------------------------------------------------------------------------- /compat/jansson/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | libjansson.a 3 | 4 | -------------------------------------------------------------------------------- /compat/jansson/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, 2010 Petri Lehtinen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /compat/jansson/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_LIBRARIES = libjansson.a 3 | 4 | libjansson_a_SOURCES = \ 5 | config.h \ 6 | dump.c \ 7 | hashtable.c \ 8 | hashtable.h \ 9 | jansson.h \ 10 | jansson_private.h \ 11 | load.c \ 12 | strbuffer.c \ 13 | strbuffer.h \ 14 | utf.c \ 15 | utf.h \ 16 | util.h \ 17 | value.c 18 | 19 | -------------------------------------------------------------------------------- /compat/jansson/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the header file. */ 5 | #define HAVE_DLFCN_H 1 6 | 7 | /* Define to 1 if you have the header file. */ 8 | #define HAVE_INTTYPES_H 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_MEMORY_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_STDINT_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_STDLIB_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #define HAVE_STRINGS_H 1 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_STRING_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_SYS_STAT_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_SYS_TYPES_H 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_UNISTD_H 1 33 | 34 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 35 | */ 36 | #define LT_OBJDIR ".libs/" 37 | 38 | /* Name of package */ 39 | #define PACKAGE "jansson" 40 | 41 | /* Define to the address where bug reports for this package should be sent. */ 42 | #define PACKAGE_BUGREPORT "petri@digip.org" 43 | 44 | /* Define to the full name of this package. */ 45 | #define PACKAGE_NAME "jansson" 46 | 47 | /* Define to the full name and version of this package. */ 48 | #define PACKAGE_STRING "jansson 1.3" 49 | 50 | /* Define to the one symbol short name of this package. */ 51 | #define PACKAGE_TARNAME "jansson" 52 | 53 | /* Define to the home page for this package. */ 54 | #define PACKAGE_URL "" 55 | 56 | /* Define to the version of this package. */ 57 | #define PACKAGE_VERSION "1.3" 58 | 59 | /* Define to 1 if you have the ANSI C header files. */ 60 | #define STDC_HEADERS 1 61 | 62 | /* Version number of package */ 63 | #define VERSION "1.3" 64 | 65 | /* Define to `__inline__' or `__inline' if that's what the C compiler 66 | calls it, or to nothing if 'inline' is not supported under any name. */ 67 | #ifndef __cplusplus 68 | /* #undef inline */ 69 | #endif 70 | 71 | /* Define to the type of a signed integer type of width exactly 32 bits if 72 | such a type exists and the standard includes do not define it. */ 73 | /* #undef int32_t */ 74 | -------------------------------------------------------------------------------- /compat/jansson/dump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include "jansson_private.h" 16 | #include "strbuffer.h" 17 | #include "utf.h" 18 | 19 | #define MAX_INTEGER_STR_LENGTH 100 20 | #define MAX_REAL_STR_LENGTH 100 21 | 22 | typedef int (*dump_func)(const char *buffer, int size, void *data); 23 | 24 | struct string 25 | { 26 | char *buffer; 27 | int length; 28 | int size; 29 | }; 30 | 31 | static int dump_to_strbuffer(const char *buffer, int size, void *data) 32 | { 33 | return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); 34 | } 35 | 36 | static int dump_to_file(const char *buffer, int size, void *data) 37 | { 38 | FILE *dest = (FILE *)data; 39 | if(fwrite(buffer, size, 1, dest) != 1) 40 | return -1; 41 | return 0; 42 | } 43 | 44 | /* 256 spaces (the maximum indentation size) */ 45 | static char whitespace[] = " "; 46 | 47 | static int dump_indent(unsigned long flags, int depth, int space, dump_func dump, void *data) 48 | { 49 | if(JSON_INDENT(flags) > 0) 50 | { 51 | int i, ws_count = JSON_INDENT(flags); 52 | 53 | if(dump("\n", 1, data)) 54 | return -1; 55 | 56 | for(i = 0; i < depth; i++) 57 | { 58 | if(dump(whitespace, ws_count, data)) 59 | return -1; 60 | } 61 | } 62 | else if(space && !(flags & JSON_COMPACT)) 63 | { 64 | return dump(" ", 1, data); 65 | } 66 | return 0; 67 | } 68 | 69 | static int dump_string(const char *str, int ascii, dump_func dump, void *data) 70 | { 71 | const char *pos, *end; 72 | int32_t codepoint; 73 | 74 | if(dump("\"", 1, data)) 75 | return -1; 76 | 77 | end = pos = str; 78 | while(1) 79 | { 80 | const char *text; 81 | char seq[13]; 82 | int length; 83 | 84 | while(*end) 85 | { 86 | end = utf8_iterate(pos, &codepoint); 87 | if(!end) 88 | return -1; 89 | 90 | /* mandatory escape or control char */ 91 | if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20) 92 | break; 93 | 94 | /* non-ASCII */ 95 | if(ascii && codepoint > 0x7F) 96 | break; 97 | 98 | pos = end; 99 | } 100 | 101 | if(pos != str) { 102 | if(dump(str, pos - str, data)) 103 | return -1; 104 | } 105 | 106 | if(end == pos) 107 | break; 108 | 109 | /* handle \, ", and control codes */ 110 | length = 2; 111 | switch(codepoint) 112 | { 113 | case '\\': text = "\\\\"; break; 114 | case '\"': text = "\\\""; break; 115 | case '\b': text = "\\b"; break; 116 | case '\f': text = "\\f"; break; 117 | case '\n': text = "\\n"; break; 118 | case '\r': text = "\\r"; break; 119 | case '\t': text = "\\t"; break; 120 | default: 121 | { 122 | /* codepoint is in BMP */ 123 | if(codepoint < 0x10000) 124 | { 125 | sprintf(seq, "\\u%04x", codepoint); 126 | length = 6; 127 | } 128 | 129 | /* not in BMP -> construct a UTF-16 surrogate pair */ 130 | else 131 | { 132 | int32_t first, last; 133 | 134 | codepoint -= 0x10000; 135 | first = 0xD800 | ((codepoint & 0xffc00) >> 10); 136 | last = 0xDC00 | (codepoint & 0x003ff); 137 | 138 | sprintf(seq, "\\u%04x\\u%04x", first, last); 139 | length = 12; 140 | } 141 | 142 | text = seq; 143 | break; 144 | } 145 | } 146 | 147 | if(dump(text, length, data)) 148 | return -1; 149 | 150 | str = pos = end; 151 | } 152 | 153 | return dump("\"", 1, data); 154 | } 155 | 156 | static int object_key_compare_keys(const void *key1, const void *key2) 157 | { 158 | return strcmp((*(const object_key_t **)key1)->key, 159 | (*(const object_key_t **)key2)->key); 160 | } 161 | 162 | static int object_key_compare_serials(const void *key1, const void *key2) 163 | { 164 | return (*(const object_key_t **)key1)->serial - 165 | (*(const object_key_t **)key2)->serial; 166 | } 167 | 168 | static int do_dump(const json_t *json, unsigned long flags, int depth, 169 | dump_func dump, void *data) 170 | { 171 | int ascii = flags & JSON_ENSURE_ASCII ? 1 : 0; 172 | 173 | switch(json_typeof(json)) { 174 | case JSON_NULL: 175 | return dump("null", 4, data); 176 | 177 | case JSON_TRUE: 178 | return dump("true", 4, data); 179 | 180 | case JSON_FALSE: 181 | return dump("false", 5, data); 182 | 183 | case JSON_INTEGER: 184 | { 185 | char buffer[MAX_INTEGER_STR_LENGTH]; 186 | int size; 187 | 188 | size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, "%d", json_integer_value(json)); 189 | if(size >= MAX_INTEGER_STR_LENGTH) 190 | return -1; 191 | 192 | return dump(buffer, size, data); 193 | } 194 | 195 | case JSON_REAL: 196 | { 197 | char buffer[MAX_REAL_STR_LENGTH]; 198 | int size; 199 | 200 | size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%.17g", 201 | json_real_value(json)); 202 | if(size >= MAX_REAL_STR_LENGTH) 203 | return -1; 204 | 205 | /* Make sure there's a dot or 'e' in the output. Otherwise 206 | a real is converted to an integer when decoding */ 207 | if(strchr(buffer, '.') == NULL && 208 | strchr(buffer, 'e') == NULL) 209 | { 210 | if(size + 2 >= MAX_REAL_STR_LENGTH) { 211 | /* No space to append ".0" */ 212 | return -1; 213 | } 214 | buffer[size] = '.'; 215 | buffer[size + 1] = '0'; 216 | size += 2; 217 | } 218 | 219 | return dump(buffer, size, data); 220 | } 221 | 222 | case JSON_STRING: 223 | return dump_string(json_string_value(json), ascii, dump, data); 224 | 225 | case JSON_ARRAY: 226 | { 227 | int i; 228 | int n; 229 | json_array_t *array; 230 | 231 | /* detect circular references */ 232 | array = json_to_array(json); 233 | if(array->visited) 234 | goto array_error; 235 | array->visited = 1; 236 | 237 | n = json_array_size(json); 238 | 239 | if(dump("[", 1, data)) 240 | goto array_error; 241 | if(n == 0) { 242 | array->visited = 0; 243 | return dump("]", 1, data); 244 | } 245 | if(dump_indent(flags, depth + 1, 0, dump, data)) 246 | goto array_error; 247 | 248 | for(i = 0; i < n; ++i) { 249 | if(do_dump(json_array_get(json, i), flags, depth + 1, 250 | dump, data)) 251 | goto array_error; 252 | 253 | if(i < n - 1) 254 | { 255 | if(dump(",", 1, data) || 256 | dump_indent(flags, depth + 1, 1, dump, data)) 257 | goto array_error; 258 | } 259 | else 260 | { 261 | if(dump_indent(flags, depth, 0, dump, data)) 262 | goto array_error; 263 | } 264 | } 265 | 266 | array->visited = 0; 267 | return dump("]", 1, data); 268 | 269 | array_error: 270 | array->visited = 0; 271 | return -1; 272 | } 273 | 274 | case JSON_OBJECT: 275 | { 276 | json_object_t *object; 277 | void *iter; 278 | const char *separator; 279 | int separator_length; 280 | 281 | if(flags & JSON_COMPACT) { 282 | separator = ":"; 283 | separator_length = 1; 284 | } 285 | else { 286 | separator = ": "; 287 | separator_length = 2; 288 | } 289 | 290 | /* detect circular references */ 291 | object = json_to_object(json); 292 | if(object->visited) 293 | goto object_error; 294 | object->visited = 1; 295 | 296 | iter = json_object_iter((json_t *)json); 297 | 298 | if(dump("{", 1, data)) 299 | goto object_error; 300 | if(!iter) { 301 | object->visited = 0; 302 | return dump("}", 1, data); 303 | } 304 | if(dump_indent(flags, depth + 1, 0, dump, data)) 305 | goto object_error; 306 | 307 | if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER) 308 | { 309 | const object_key_t **keys; 310 | unsigned int size; 311 | unsigned int i; 312 | int (*cmp_func)(const void *, const void *); 313 | 314 | size = json_object_size(json); 315 | keys = malloc(size * sizeof(object_key_t *)); 316 | if(!keys) 317 | goto object_error; 318 | 319 | i = 0; 320 | while(iter) 321 | { 322 | keys[i] = jsonp_object_iter_fullkey(iter); 323 | iter = json_object_iter_next((json_t *)json, iter); 324 | i++; 325 | } 326 | assert(i == size); 327 | 328 | if(flags & JSON_SORT_KEYS) 329 | cmp_func = object_key_compare_keys; 330 | else 331 | cmp_func = object_key_compare_serials; 332 | 333 | qsort(keys, size, sizeof(object_key_t *), cmp_func); 334 | 335 | for(i = 0; i < size; i++) 336 | { 337 | const char *key; 338 | json_t *value; 339 | 340 | key = keys[i]->key; 341 | value = json_object_get(json, key); 342 | assert(value); 343 | 344 | dump_string(key, ascii, dump, data); 345 | if(dump(separator, separator_length, data) || 346 | do_dump(value, flags, depth + 1, dump, data)) 347 | { 348 | free(keys); 349 | goto object_error; 350 | } 351 | 352 | if(i < size - 1) 353 | { 354 | if(dump(",", 1, data) || 355 | dump_indent(flags, depth + 1, 1, dump, data)) 356 | { 357 | free(keys); 358 | goto object_error; 359 | } 360 | } 361 | else 362 | { 363 | if(dump_indent(flags, depth, 0, dump, data)) 364 | { 365 | free(keys); 366 | goto object_error; 367 | } 368 | } 369 | } 370 | 371 | free(keys); 372 | } 373 | else 374 | { 375 | /* Don't sort keys */ 376 | 377 | while(iter) 378 | { 379 | void *next = json_object_iter_next((json_t *)json, iter); 380 | 381 | dump_string(json_object_iter_key(iter), ascii, dump, data); 382 | if(dump(separator, separator_length, data) || 383 | do_dump(json_object_iter_value(iter), flags, depth + 1, 384 | dump, data)) 385 | goto object_error; 386 | 387 | if(next) 388 | { 389 | if(dump(",", 1, data) || 390 | dump_indent(flags, depth + 1, 1, dump, data)) 391 | goto object_error; 392 | } 393 | else 394 | { 395 | if(dump_indent(flags, depth, 0, dump, data)) 396 | goto object_error; 397 | } 398 | 399 | iter = next; 400 | } 401 | } 402 | 403 | object->visited = 0; 404 | return dump("}", 1, data); 405 | 406 | object_error: 407 | object->visited = 0; 408 | return -1; 409 | } 410 | 411 | default: 412 | /* not reached */ 413 | return -1; 414 | } 415 | } 416 | 417 | 418 | char *json_dumps(const json_t *json, unsigned long flags) 419 | { 420 | strbuffer_t strbuff; 421 | char *result; 422 | 423 | if(!json_is_array(json) && !json_is_object(json)) 424 | return NULL; 425 | 426 | if(strbuffer_init(&strbuff)) 427 | return NULL; 428 | 429 | if(do_dump(json, flags, 0, dump_to_strbuffer, (void *)&strbuff)) { 430 | strbuffer_close(&strbuff); 431 | return NULL; 432 | } 433 | 434 | result = strdup(strbuffer_value(&strbuff)); 435 | strbuffer_close(&strbuff); 436 | 437 | return result; 438 | } 439 | 440 | int json_dumpf(const json_t *json, FILE *output, unsigned long flags) 441 | { 442 | if(!json_is_array(json) && !json_is_object(json)) 443 | return -1; 444 | 445 | return do_dump(json, flags, 0, dump_to_file, (void *)output); 446 | } 447 | 448 | int json_dump_file(const json_t *json, const char *path, unsigned long flags) 449 | { 450 | int result; 451 | 452 | FILE *output = fopen(path, "w"); 453 | if(!output) 454 | return -1; 455 | 456 | result = json_dumpf(json, output, flags); 457 | 458 | fclose(output); 459 | return result; 460 | } 461 | -------------------------------------------------------------------------------- /compat/jansson/hashtable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include "hashtable.h" 12 | 13 | typedef struct hashtable_list list_t; 14 | typedef struct hashtable_pair pair_t; 15 | typedef struct hashtable_bucket bucket_t; 16 | 17 | #define container_of(ptr_, type_, member_) \ 18 | ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) 19 | 20 | #define list_to_pair(list_) container_of(list_, pair_t, list) 21 | 22 | static inline void list_init(list_t *list) 23 | { 24 | list->next = list; 25 | list->prev = list; 26 | } 27 | 28 | static inline void list_insert(list_t *list, list_t *node) 29 | { 30 | node->next = list; 31 | node->prev = list->prev; 32 | list->prev->next = node; 33 | list->prev = node; 34 | } 35 | 36 | static inline void list_remove(list_t *list) 37 | { 38 | list->prev->next = list->next; 39 | list->next->prev = list->prev; 40 | } 41 | 42 | static inline int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket) 43 | { 44 | return bucket->first == &hashtable->list && bucket->first == bucket->last; 45 | } 46 | 47 | static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket, 48 | list_t *list) 49 | { 50 | if(bucket_is_empty(hashtable, bucket)) 51 | { 52 | list_insert(&hashtable->list, list); 53 | bucket->first = bucket->last = list; 54 | } 55 | else 56 | { 57 | list_insert(bucket->first, list); 58 | bucket->first = list; 59 | } 60 | } 61 | 62 | static unsigned int primes[] = { 63 | 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 64 | 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 65 | 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 66 | 805306457, 1610612741 67 | }; 68 | static const unsigned int num_primes = sizeof(primes) / sizeof(unsigned int); 69 | 70 | static inline unsigned int num_buckets(hashtable_t *hashtable) 71 | { 72 | return primes[hashtable->num_buckets]; 73 | } 74 | 75 | 76 | static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket, 77 | const void *key, unsigned int hash) 78 | { 79 | list_t *list; 80 | pair_t *pair; 81 | 82 | if(bucket_is_empty(hashtable, bucket)) 83 | return NULL; 84 | 85 | list = bucket->first; 86 | while(1) 87 | { 88 | pair = list_to_pair(list); 89 | if(pair->hash == hash && hashtable->cmp_keys(pair->key, key)) 90 | return pair; 91 | 92 | if(list == bucket->last) 93 | break; 94 | 95 | list = list->next; 96 | } 97 | 98 | return NULL; 99 | } 100 | 101 | /* returns 0 on success, -1 if key was not found */ 102 | static int hashtable_do_del(hashtable_t *hashtable, 103 | const void *key, unsigned int hash) 104 | { 105 | pair_t *pair; 106 | bucket_t *bucket; 107 | unsigned int index; 108 | 109 | index = hash % num_buckets(hashtable); 110 | bucket = &hashtable->buckets[index]; 111 | 112 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 113 | if(!pair) 114 | return -1; 115 | 116 | if(&pair->list == bucket->first && &pair->list == bucket->last) 117 | bucket->first = bucket->last = &hashtable->list; 118 | 119 | else if(&pair->list == bucket->first) 120 | bucket->first = pair->list.next; 121 | 122 | else if(&pair->list == bucket->last) 123 | bucket->last = pair->list.prev; 124 | 125 | list_remove(&pair->list); 126 | 127 | if(hashtable->free_key) 128 | hashtable->free_key(pair->key); 129 | if(hashtable->free_value) 130 | hashtable->free_value(pair->value); 131 | 132 | free(pair); 133 | hashtable->size--; 134 | 135 | return 0; 136 | } 137 | 138 | static void hashtable_do_clear(hashtable_t *hashtable) 139 | { 140 | list_t *list, *next; 141 | pair_t *pair; 142 | 143 | for(list = hashtable->list.next; list != &hashtable->list; list = next) 144 | { 145 | next = list->next; 146 | pair = list_to_pair(list); 147 | if(hashtable->free_key) 148 | hashtable->free_key(pair->key); 149 | if(hashtable->free_value) 150 | hashtable->free_value(pair->value); 151 | free(pair); 152 | } 153 | } 154 | 155 | static int hashtable_do_rehash(hashtable_t *hashtable) 156 | { 157 | list_t *list, *next; 158 | pair_t *pair; 159 | unsigned int i, index, new_size; 160 | 161 | free(hashtable->buckets); 162 | 163 | hashtable->num_buckets++; 164 | new_size = num_buckets(hashtable); 165 | 166 | hashtable->buckets = malloc(new_size * sizeof(bucket_t)); 167 | if(!hashtable->buckets) 168 | return -1; 169 | 170 | for(i = 0; i < num_buckets(hashtable); i++) 171 | { 172 | hashtable->buckets[i].first = hashtable->buckets[i].last = 173 | &hashtable->list; 174 | } 175 | 176 | list = hashtable->list.next; 177 | list_init(&hashtable->list); 178 | 179 | for(; list != &hashtable->list; list = next) { 180 | next = list->next; 181 | pair = list_to_pair(list); 182 | index = pair->hash % new_size; 183 | insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list); 184 | } 185 | 186 | return 0; 187 | } 188 | 189 | 190 | hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, 191 | free_fn free_key, free_fn free_value) 192 | { 193 | hashtable_t *hashtable = malloc(sizeof(hashtable_t)); 194 | if(!hashtable) 195 | return NULL; 196 | 197 | if(hashtable_init(hashtable, hash_key, cmp_keys, free_key, free_value)) 198 | { 199 | free(hashtable); 200 | return NULL; 201 | } 202 | 203 | return hashtable; 204 | } 205 | 206 | void hashtable_destroy(hashtable_t *hashtable) 207 | { 208 | hashtable_close(hashtable); 209 | free(hashtable); 210 | } 211 | 212 | int hashtable_init(hashtable_t *hashtable, 213 | key_hash_fn hash_key, key_cmp_fn cmp_keys, 214 | free_fn free_key, free_fn free_value) 215 | { 216 | unsigned int i; 217 | 218 | hashtable->size = 0; 219 | hashtable->num_buckets = 0; /* index to primes[] */ 220 | hashtable->buckets = malloc(num_buckets(hashtable) * sizeof(bucket_t)); 221 | if(!hashtable->buckets) 222 | return -1; 223 | 224 | list_init(&hashtable->list); 225 | 226 | hashtable->hash_key = hash_key; 227 | hashtable->cmp_keys = cmp_keys; 228 | hashtable->free_key = free_key; 229 | hashtable->free_value = free_value; 230 | 231 | for(i = 0; i < num_buckets(hashtable); i++) 232 | { 233 | hashtable->buckets[i].first = hashtable->buckets[i].last = 234 | &hashtable->list; 235 | } 236 | 237 | return 0; 238 | } 239 | 240 | void hashtable_close(hashtable_t *hashtable) 241 | { 242 | hashtable_do_clear(hashtable); 243 | free(hashtable->buckets); 244 | } 245 | 246 | int hashtable_set(hashtable_t *hashtable, void *key, void *value) 247 | { 248 | pair_t *pair; 249 | bucket_t *bucket; 250 | unsigned int hash, index; 251 | 252 | /* rehash if the load ratio exceeds 1 */ 253 | if(hashtable->size >= num_buckets(hashtable)) 254 | if(hashtable_do_rehash(hashtable)) 255 | return -1; 256 | 257 | hash = hashtable->hash_key(key); 258 | index = hash % num_buckets(hashtable); 259 | bucket = &hashtable->buckets[index]; 260 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 261 | 262 | if(pair) 263 | { 264 | if(hashtable->free_key) 265 | hashtable->free_key(key); 266 | if(hashtable->free_value) 267 | hashtable->free_value(pair->value); 268 | pair->value = value; 269 | } 270 | else 271 | { 272 | pair = malloc(sizeof(pair_t)); 273 | if(!pair) 274 | return -1; 275 | 276 | pair->key = key; 277 | pair->value = value; 278 | pair->hash = hash; 279 | list_init(&pair->list); 280 | 281 | insert_to_bucket(hashtable, bucket, &pair->list); 282 | 283 | hashtable->size++; 284 | } 285 | return 0; 286 | } 287 | 288 | void *hashtable_get(hashtable_t *hashtable, const void *key) 289 | { 290 | pair_t *pair; 291 | unsigned int hash; 292 | bucket_t *bucket; 293 | 294 | hash = hashtable->hash_key(key); 295 | bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; 296 | 297 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 298 | if(!pair) 299 | return NULL; 300 | 301 | return pair->value; 302 | } 303 | 304 | int hashtable_del(hashtable_t *hashtable, const void *key) 305 | { 306 | unsigned int hash = hashtable->hash_key(key); 307 | return hashtable_do_del(hashtable, key, hash); 308 | } 309 | 310 | void hashtable_clear(hashtable_t *hashtable) 311 | { 312 | unsigned int i; 313 | 314 | hashtable_do_clear(hashtable); 315 | 316 | for(i = 0; i < num_buckets(hashtable); i++) 317 | { 318 | hashtable->buckets[i].first = hashtable->buckets[i].last = 319 | &hashtable->list; 320 | } 321 | 322 | list_init(&hashtable->list); 323 | hashtable->size = 0; 324 | } 325 | 326 | void *hashtable_iter(hashtable_t *hashtable) 327 | { 328 | return hashtable_iter_next(hashtable, &hashtable->list); 329 | } 330 | 331 | void *hashtable_iter_at(hashtable_t *hashtable, const void *key) 332 | { 333 | pair_t *pair; 334 | unsigned int hash; 335 | bucket_t *bucket; 336 | 337 | hash = hashtable->hash_key(key); 338 | bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; 339 | 340 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 341 | if(!pair) 342 | return NULL; 343 | 344 | return &pair->list; 345 | } 346 | 347 | void *hashtable_iter_next(hashtable_t *hashtable, void *iter) 348 | { 349 | list_t *list = (list_t *)iter; 350 | if(list->next == &hashtable->list) 351 | return NULL; 352 | return list->next; 353 | } 354 | 355 | void *hashtable_iter_key(void *iter) 356 | { 357 | pair_t *pair = list_to_pair((list_t *)iter); 358 | return pair->key; 359 | } 360 | 361 | void *hashtable_iter_value(void *iter) 362 | { 363 | pair_t *pair = list_to_pair((list_t *)iter); 364 | return pair->value; 365 | } 366 | 367 | void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value) 368 | { 369 | pair_t *pair = list_to_pair((list_t *)iter); 370 | 371 | if(hashtable->free_value) 372 | hashtable->free_value(pair->value); 373 | 374 | pair->value = value; 375 | } 376 | -------------------------------------------------------------------------------- /compat/jansson/hashtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef HASHTABLE_H 9 | #define HASHTABLE_H 10 | 11 | typedef unsigned int (*key_hash_fn)(const void *key); 12 | typedef int (*key_cmp_fn)(const void *key1, const void *key2); 13 | typedef void (*free_fn)(void *key); 14 | 15 | struct hashtable_list { 16 | struct hashtable_list *prev; 17 | struct hashtable_list *next; 18 | }; 19 | 20 | struct hashtable_pair { 21 | void *key; 22 | void *value; 23 | unsigned int hash; 24 | struct hashtable_list list; 25 | }; 26 | 27 | struct hashtable_bucket { 28 | struct hashtable_list *first; 29 | struct hashtable_list *last; 30 | }; 31 | 32 | typedef struct hashtable { 33 | unsigned int size; 34 | struct hashtable_bucket *buckets; 35 | unsigned int num_buckets; /* index to primes[] */ 36 | struct hashtable_list list; 37 | 38 | key_hash_fn hash_key; 39 | key_cmp_fn cmp_keys; /* returns non-zero for equal keys */ 40 | free_fn free_key; 41 | free_fn free_value; 42 | } hashtable_t; 43 | 44 | /** 45 | * hashtable_create - Create a hashtable object 46 | * 47 | * @hash_key: The key hashing function 48 | * @cmp_keys: The key compare function. Returns non-zero for equal and 49 | * zero for unequal unequal keys 50 | * @free_key: If non-NULL, called for a key that is no longer referenced. 51 | * @free_value: If non-NULL, called for a value that is no longer referenced. 52 | * 53 | * Returns a new hashtable object that should be freed with 54 | * hashtable_destroy when it's no longer used, or NULL on failure (out 55 | * of memory). 56 | */ 57 | hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, 58 | free_fn free_key, free_fn free_value); 59 | 60 | /** 61 | * hashtable_destroy - Destroy a hashtable object 62 | * 63 | * @hashtable: The hashtable 64 | * 65 | * Destroys a hashtable created with hashtable_create(). 66 | */ 67 | void hashtable_destroy(hashtable_t *hashtable); 68 | 69 | /** 70 | * hashtable_init - Initialize a hashtable object 71 | * 72 | * @hashtable: The (statically allocated) hashtable object 73 | * @hash_key: The key hashing function 74 | * @cmp_keys: The key compare function. Returns non-zero for equal and 75 | * zero for unequal unequal keys 76 | * @free_key: If non-NULL, called for a key that is no longer referenced. 77 | * @free_value: If non-NULL, called for a value that is no longer referenced. 78 | * 79 | * Initializes a statically allocated hashtable object. The object 80 | * should be cleared with hashtable_close when it's no longer used. 81 | * 82 | * Returns 0 on success, -1 on error (out of memory). 83 | */ 84 | int hashtable_init(hashtable_t *hashtable, 85 | key_hash_fn hash_key, key_cmp_fn cmp_keys, 86 | free_fn free_key, free_fn free_value); 87 | 88 | /** 89 | * hashtable_close - Release all resources used by a hashtable object 90 | * 91 | * @hashtable: The hashtable 92 | * 93 | * Destroys a statically allocated hashtable object. 94 | */ 95 | void hashtable_close(hashtable_t *hashtable); 96 | 97 | /** 98 | * hashtable_set - Add/modify value in hashtable 99 | * 100 | * @hashtable: The hashtable object 101 | * @key: The key 102 | * @value: The value 103 | * 104 | * If a value with the given key already exists, its value is replaced 105 | * with the new value. 106 | * 107 | * Key and value are "stealed" in the sense that hashtable frees them 108 | * automatically when they are no longer used. The freeing is 109 | * accomplished by calling free_key and free_value functions that were 110 | * supplied to hashtable_new. In case one or both of the free 111 | * functions is NULL, the corresponding item is not "stealed". 112 | * 113 | * Returns 0 on success, -1 on failure (out of memory). 114 | */ 115 | int hashtable_set(hashtable_t *hashtable, void *key, void *value); 116 | 117 | /** 118 | * hashtable_get - Get a value associated with a key 119 | * 120 | * @hashtable: The hashtable object 121 | * @key: The key 122 | * 123 | * Returns value if it is found, or NULL otherwise. 124 | */ 125 | void *hashtable_get(hashtable_t *hashtable, const void *key); 126 | 127 | /** 128 | * hashtable_del - Remove a value from the hashtable 129 | * 130 | * @hashtable: The hashtable object 131 | * @key: The key 132 | * 133 | * Returns 0 on success, or -1 if the key was not found. 134 | */ 135 | int hashtable_del(hashtable_t *hashtable, const void *key); 136 | 137 | /** 138 | * hashtable_clear - Clear hashtable 139 | * 140 | * @hashtable: The hashtable object 141 | * 142 | * Removes all items from the hashtable. 143 | */ 144 | void hashtable_clear(hashtable_t *hashtable); 145 | 146 | /** 147 | * hashtable_iter - Iterate over hashtable 148 | * 149 | * @hashtable: The hashtable object 150 | * 151 | * Returns an opaque iterator to the first element in the hashtable. 152 | * The iterator should be passed to hashtable_iter_* functions. 153 | * The hashtable items are not iterated over in any particular order. 154 | * 155 | * There's no need to free the iterator in any way. The iterator is 156 | * valid as long as the item that is referenced by the iterator is not 157 | * deleted. Other values may be added or deleted. In particular, 158 | * hashtable_iter_next() may be called on an iterator, and after that 159 | * the key/value pair pointed by the old iterator may be deleted. 160 | */ 161 | void *hashtable_iter(hashtable_t *hashtable); 162 | 163 | /** 164 | * hashtable_iter_at - Return an iterator at a specific key 165 | * 166 | * @hashtable: The hashtable object 167 | * @key: The key that the iterator should point to 168 | * 169 | * Like hashtable_iter() but returns an iterator pointing to a 170 | * specific key. 171 | */ 172 | void *hashtable_iter_at(hashtable_t *hashtable, const void *key); 173 | 174 | /** 175 | * hashtable_iter_next - Advance an iterator 176 | * 177 | * @hashtable: The hashtable object 178 | * @iter: The iterator 179 | * 180 | * Returns a new iterator pointing to the next element in the 181 | * hashtable or NULL if the whole hastable has been iterated over. 182 | */ 183 | void *hashtable_iter_next(hashtable_t *hashtable, void *iter); 184 | 185 | /** 186 | * hashtable_iter_key - Retrieve the key pointed by an iterator 187 | * 188 | * @iter: The iterator 189 | */ 190 | void *hashtable_iter_key(void *iter); 191 | 192 | /** 193 | * hashtable_iter_value - Retrieve the value pointed by an iterator 194 | * 195 | * @iter: The iterator 196 | */ 197 | void *hashtable_iter_value(void *iter); 198 | 199 | /** 200 | * hashtable_iter_set - Set the value pointed by an iterator 201 | * 202 | * @iter: The iterator 203 | * @value: The value to set 204 | */ 205 | void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value); 206 | 207 | #endif 208 | -------------------------------------------------------------------------------- /compat/jansson/jansson.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef JANSSON_H 9 | #define JANSSON_H 10 | 11 | #include 12 | 13 | #ifndef __cplusplus 14 | #define JSON_INLINE inline 15 | #else 16 | #define JSON_INLINE inline 17 | extern "C" { 18 | #endif 19 | 20 | /* types */ 21 | 22 | typedef enum { 23 | JSON_OBJECT, 24 | JSON_ARRAY, 25 | JSON_STRING, 26 | JSON_INTEGER, 27 | JSON_REAL, 28 | JSON_TRUE, 29 | JSON_FALSE, 30 | JSON_NULL 31 | } json_type; 32 | 33 | typedef struct { 34 | json_type type; 35 | unsigned long refcount; 36 | } json_t; 37 | 38 | #define json_typeof(json) ((json)->type) 39 | #define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT) 40 | #define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY) 41 | #define json_is_string(json) (json && json_typeof(json) == JSON_STRING) 42 | #define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER) 43 | #define json_is_real(json) (json && json_typeof(json) == JSON_REAL) 44 | #define json_is_number(json) (json_is_integer(json) || json_is_real(json)) 45 | #define json_is_true(json) (json && json_typeof(json) == JSON_TRUE) 46 | #define json_is_false(json) (json && json_typeof(json) == JSON_FALSE) 47 | #define json_is_boolean(json) (json_is_true(json) || json_is_false(json)) 48 | #define json_is_null(json) (json && json_typeof(json) == JSON_NULL) 49 | 50 | /* construction, destruction, reference counting */ 51 | 52 | json_t *json_object(void); 53 | json_t *json_array(void); 54 | json_t *json_string(const char *value); 55 | json_t *json_string_nocheck(const char *value); 56 | json_t *json_integer(int value); 57 | json_t *json_real(double value); 58 | json_t *json_true(void); 59 | json_t *json_false(void); 60 | json_t *json_null(void); 61 | 62 | static JSON_INLINE 63 | json_t *json_incref(json_t *json) 64 | { 65 | if(json && json->refcount != (unsigned int)-1) 66 | ++json->refcount; 67 | return json; 68 | } 69 | 70 | /* do not call json_delete directly */ 71 | void json_delete(json_t *json); 72 | 73 | static JSON_INLINE 74 | void json_decref(json_t *json) 75 | { 76 | if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0) 77 | json_delete(json); 78 | } 79 | 80 | 81 | /* getters, setters, manipulation */ 82 | 83 | unsigned int json_object_size(const json_t *object); 84 | json_t *json_object_get(const json_t *object, const char *key); 85 | int json_object_set_new(json_t *object, const char *key, json_t *value); 86 | int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); 87 | int json_object_del(json_t *object, const char *key); 88 | int json_object_clear(json_t *object); 89 | int json_object_update(json_t *object, json_t *other); 90 | void *json_object_iter(json_t *object); 91 | void *json_object_iter_at(json_t *object, const char *key); 92 | void *json_object_iter_next(json_t *object, void *iter); 93 | const char *json_object_iter_key(void *iter); 94 | json_t *json_object_iter_value(void *iter); 95 | int json_object_iter_set_new(json_t *object, void *iter, json_t *value); 96 | 97 | static JSON_INLINE 98 | int json_object_set(json_t *object, const char *key, json_t *value) 99 | { 100 | return json_object_set_new(object, key, json_incref(value)); 101 | } 102 | 103 | static JSON_INLINE 104 | int json_object_set_nocheck(json_t *object, const char *key, json_t *value) 105 | { 106 | return json_object_set_new_nocheck(object, key, json_incref(value)); 107 | } 108 | 109 | static inline 110 | int json_object_iter_set(json_t *object, void *iter, json_t *value) 111 | { 112 | return json_object_iter_set_new(object, iter, json_incref(value)); 113 | } 114 | 115 | unsigned int json_array_size(const json_t *array); 116 | json_t *json_array_get(const json_t *array, unsigned int index); 117 | int json_array_set_new(json_t *array, unsigned int index, json_t *value); 118 | int json_array_append_new(json_t *array, json_t *value); 119 | int json_array_insert_new(json_t *array, unsigned int index, json_t *value); 120 | int json_array_remove(json_t *array, unsigned int index); 121 | int json_array_clear(json_t *array); 122 | int json_array_extend(json_t *array, json_t *other); 123 | 124 | static JSON_INLINE 125 | int json_array_set(json_t *array, unsigned int index, json_t *value) 126 | { 127 | return json_array_set_new(array, index, json_incref(value)); 128 | } 129 | 130 | static JSON_INLINE 131 | int json_array_append(json_t *array, json_t *value) 132 | { 133 | return json_array_append_new(array, json_incref(value)); 134 | } 135 | 136 | static JSON_INLINE 137 | int json_array_insert(json_t *array, unsigned int index, json_t *value) 138 | { 139 | return json_array_insert_new(array, index, json_incref(value)); 140 | } 141 | 142 | const char *json_string_value(const json_t *string); 143 | int json_integer_value(const json_t *integer); 144 | double json_real_value(const json_t *real); 145 | double json_number_value(const json_t *json); 146 | 147 | int json_string_set(json_t *string, const char *value); 148 | int json_string_set_nocheck(json_t *string, const char *value); 149 | int json_integer_set(json_t *integer, int value); 150 | int json_real_set(json_t *real, double value); 151 | 152 | 153 | /* equality */ 154 | 155 | int json_equal(json_t *value1, json_t *value2); 156 | 157 | 158 | /* copying */ 159 | 160 | json_t *json_copy(json_t *value); 161 | json_t *json_deep_copy(json_t *value); 162 | 163 | 164 | /* loading, printing */ 165 | 166 | #define JSON_ERROR_TEXT_LENGTH 160 167 | 168 | typedef struct { 169 | char text[JSON_ERROR_TEXT_LENGTH]; 170 | int line; 171 | } json_error_t; 172 | 173 | json_t *json_loads(const char *input, json_error_t *error); 174 | json_t *json_loadf(FILE *input, json_error_t *error); 175 | json_t *json_load_file(const char *path, json_error_t *error); 176 | 177 | #define JSON_INDENT(n) (n & 0xFF) 178 | #define JSON_COMPACT 0x100 179 | #define JSON_ENSURE_ASCII 0x200 180 | #define JSON_SORT_KEYS 0x400 181 | #define JSON_PRESERVE_ORDER 0x800 182 | 183 | char *json_dumps(const json_t *json, unsigned long flags); 184 | int json_dumpf(const json_t *json, FILE *output, unsigned long flags); 185 | int json_dump_file(const json_t *json, const char *path, unsigned long flags); 186 | 187 | #ifdef __cplusplus 188 | } 189 | #endif 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /compat/jansson/jansson_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef JANSSON_PRIVATE_H 9 | #define JANSSON_PRIVATE_H 10 | 11 | #include "jansson.h" 12 | #include "hashtable.h" 13 | 14 | #define container_of(ptr_, type_, member_) \ 15 | ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) 16 | 17 | typedef struct { 18 | json_t json; 19 | hashtable_t hashtable; 20 | unsigned long serial; 21 | int visited; 22 | } json_object_t; 23 | 24 | typedef struct { 25 | json_t json; 26 | unsigned int size; 27 | unsigned int entries; 28 | json_t **table; 29 | int visited; 30 | } json_array_t; 31 | 32 | typedef struct { 33 | json_t json; 34 | char *value; 35 | } json_string_t; 36 | 37 | typedef struct { 38 | json_t json; 39 | double value; 40 | } json_real_t; 41 | 42 | typedef struct { 43 | json_t json; 44 | int value; 45 | } json_integer_t; 46 | 47 | #define json_to_object(json_) container_of(json_, json_object_t, json) 48 | #define json_to_array(json_) container_of(json_, json_array_t, json) 49 | #define json_to_string(json_) container_of(json_, json_string_t, json) 50 | #define json_to_real(json_) container_of(json_, json_real_t, json) 51 | #define json_to_integer(json_) container_of(json_, json_integer_t, json) 52 | 53 | typedef struct { 54 | unsigned long serial; 55 | char key[]; 56 | } object_key_t; 57 | 58 | const object_key_t *jsonp_object_iter_fullkey(void *iter); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /compat/jansson/load.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include "jansson_private.h" 20 | #include "strbuffer.h" 21 | #include "utf.h" 22 | 23 | #define TOKEN_INVALID -1 24 | #define TOKEN_EOF 0 25 | #define TOKEN_STRING 256 26 | #define TOKEN_INTEGER 257 27 | #define TOKEN_REAL 258 28 | #define TOKEN_TRUE 259 29 | #define TOKEN_FALSE 260 30 | #define TOKEN_NULL 261 31 | 32 | /* read one byte from stream, return EOF on end of file */ 33 | typedef int (*get_func)(void *data); 34 | 35 | /* return non-zero if end of file has been reached */ 36 | typedef int (*eof_func)(void *data); 37 | 38 | typedef struct { 39 | get_func get; 40 | eof_func eof; 41 | void *data; 42 | int stream_pos; 43 | char buffer[5]; 44 | int buffer_pos; 45 | } stream_t; 46 | 47 | 48 | typedef struct { 49 | stream_t stream; 50 | strbuffer_t saved_text; 51 | int token; 52 | int line, column; 53 | union { 54 | char *string; 55 | int integer; 56 | double real; 57 | } value; 58 | } lex_t; 59 | 60 | 61 | /*** error reporting ***/ 62 | 63 | static void error_init(json_error_t *error) 64 | { 65 | if(error) 66 | { 67 | error->text[0] = '\0'; 68 | error->line = -1; 69 | } 70 | } 71 | 72 | static void error_set(json_error_t *error, const lex_t *lex, 73 | const char *msg, ...) 74 | { 75 | va_list ap; 76 | char text[JSON_ERROR_TEXT_LENGTH]; 77 | 78 | if(!error || error->text[0] != '\0') { 79 | /* error already set */ 80 | return; 81 | } 82 | 83 | va_start(ap, msg); 84 | vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap); 85 | va_end(ap); 86 | 87 | if(lex) 88 | { 89 | const char *saved_text = strbuffer_value(&lex->saved_text); 90 | error->line = lex->line; 91 | if(saved_text && saved_text[0]) 92 | { 93 | if(lex->saved_text.length <= 20) { 94 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, 95 | "%s near '%s'", text, saved_text); 96 | } 97 | else 98 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); 99 | } 100 | else 101 | { 102 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, 103 | "%s near end of file", text); 104 | } 105 | } 106 | else 107 | { 108 | error->line = -1; 109 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); 110 | } 111 | } 112 | 113 | 114 | /*** lexical analyzer ***/ 115 | 116 | static void 117 | stream_init(stream_t *stream, get_func get, eof_func eof, void *data) 118 | { 119 | stream->get = get; 120 | stream->eof = eof; 121 | stream->data = data; 122 | stream->stream_pos = 0; 123 | stream->buffer[0] = '\0'; 124 | stream->buffer_pos = 0; 125 | } 126 | 127 | static char stream_get(stream_t *stream, json_error_t *error) 128 | { 129 | char c; 130 | 131 | if(!stream->buffer[stream->buffer_pos]) 132 | { 133 | stream->buffer[0] = stream->get(stream->data); 134 | stream->buffer_pos = 0; 135 | 136 | c = stream->buffer[0]; 137 | 138 | if((unsigned char)c >= 0x80 && c != (char)EOF) 139 | { 140 | /* multi-byte UTF-8 sequence */ 141 | int i, count; 142 | 143 | count = utf8_check_first(c); 144 | if(!count) 145 | goto out; 146 | 147 | assert(count >= 2); 148 | 149 | for(i = 1; i < count; i++) 150 | stream->buffer[i] = stream->get(stream->data); 151 | 152 | if(!utf8_check_full(stream->buffer, count, NULL)) 153 | goto out; 154 | 155 | stream->stream_pos += count; 156 | stream->buffer[count] = '\0'; 157 | } 158 | else { 159 | stream->buffer[1] = '\0'; 160 | stream->stream_pos++; 161 | } 162 | } 163 | 164 | return stream->buffer[stream->buffer_pos++]; 165 | 166 | out: 167 | error_set(error, NULL, "unable to decode byte 0x%x at position %d", 168 | (unsigned char)c, stream->stream_pos); 169 | 170 | stream->buffer[0] = EOF; 171 | stream->buffer[1] = '\0'; 172 | stream->buffer_pos = 1; 173 | 174 | return EOF; 175 | } 176 | 177 | static void stream_unget(stream_t *stream, char c) 178 | { 179 | assert(stream->buffer_pos > 0); 180 | stream->buffer_pos--; 181 | assert(stream->buffer[stream->buffer_pos] == c); 182 | } 183 | 184 | 185 | static int lex_get(lex_t *lex, json_error_t *error) 186 | { 187 | return stream_get(&lex->stream, error); 188 | } 189 | 190 | static int lex_eof(lex_t *lex) 191 | { 192 | return lex->stream.eof(lex->stream.data); 193 | } 194 | 195 | static void lex_save(lex_t *lex, char c) 196 | { 197 | strbuffer_append_byte(&lex->saved_text, c); 198 | } 199 | 200 | static int lex_get_save(lex_t *lex, json_error_t *error) 201 | { 202 | char c = stream_get(&lex->stream, error); 203 | lex_save(lex, c); 204 | return c; 205 | } 206 | 207 | static void lex_unget_unsave(lex_t *lex, char c) 208 | { 209 | char d; 210 | stream_unget(&lex->stream, c); 211 | d = strbuffer_pop(&lex->saved_text); 212 | assert(c == d); 213 | } 214 | 215 | static void lex_save_cached(lex_t *lex) 216 | { 217 | while(lex->stream.buffer[lex->stream.buffer_pos] != '\0') 218 | { 219 | lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); 220 | lex->stream.buffer_pos++; 221 | } 222 | } 223 | 224 | /* assumes that str points to 'u' plus at least 4 valid hex digits */ 225 | static int32_t decode_unicode_escape(const char *str) 226 | { 227 | int i; 228 | int32_t value = 0; 229 | 230 | assert(str[0] == 'u'); 231 | 232 | for(i = 1; i <= 4; i++) { 233 | char c = str[i]; 234 | value <<= 4; 235 | if(isdigit(c)) 236 | value += c - '0'; 237 | else if(islower(c)) 238 | value += c - 'a' + 10; 239 | else if(isupper(c)) 240 | value += c - 'A' + 10; 241 | else 242 | assert(0); 243 | } 244 | 245 | return value; 246 | } 247 | 248 | static void lex_scan_string(lex_t *lex, json_error_t *error) 249 | { 250 | char c; 251 | const char *p; 252 | char *t; 253 | int i; 254 | 255 | lex->value.string = NULL; 256 | lex->token = TOKEN_INVALID; 257 | 258 | c = lex_get_save(lex, error); 259 | 260 | while(c != '"') { 261 | if(c == (char)EOF) { 262 | lex_unget_unsave(lex, c); 263 | if(lex_eof(lex)) 264 | error_set(error, lex, "premature end of input"); 265 | goto out; 266 | } 267 | 268 | else if((unsigned char)c <= 0x1F) { 269 | /* control character */ 270 | lex_unget_unsave(lex, c); 271 | if(c == '\n') 272 | error_set(error, lex, "unexpected newline", c); 273 | else 274 | error_set(error, lex, "control character 0x%x", c); 275 | goto out; 276 | } 277 | 278 | else if(c == '\\') { 279 | c = lex_get_save(lex, error); 280 | if(c == 'u') { 281 | c = lex_get_save(lex, error); 282 | for(i = 0; i < 4; i++) { 283 | if(!isxdigit(c)) { 284 | lex_unget_unsave(lex, c); 285 | error_set(error, lex, "invalid escape"); 286 | goto out; 287 | } 288 | c = lex_get_save(lex, error); 289 | } 290 | } 291 | else if(c == '"' || c == '\\' || c == '/' || c == 'b' || 292 | c == 'f' || c == 'n' || c == 'r' || c == 't') 293 | c = lex_get_save(lex, error); 294 | else { 295 | lex_unget_unsave(lex, c); 296 | error_set(error, lex, "invalid escape"); 297 | goto out; 298 | } 299 | } 300 | else 301 | c = lex_get_save(lex, error); 302 | } 303 | 304 | /* the actual value is at most of the same length as the source 305 | string, because: 306 | - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte 307 | - a single \uXXXX escape (length 6) is converted to at most 3 bytes 308 | - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair 309 | are converted to 4 bytes 310 | */ 311 | lex->value.string = malloc(lex->saved_text.length + 1); 312 | if(!lex->value.string) { 313 | /* this is not very nice, since TOKEN_INVALID is returned */ 314 | goto out; 315 | } 316 | 317 | /* the target */ 318 | t = lex->value.string; 319 | 320 | /* + 1 to skip the " */ 321 | p = strbuffer_value(&lex->saved_text) + 1; 322 | 323 | while(*p != '"') { 324 | if(*p == '\\') { 325 | p++; 326 | if(*p == 'u') { 327 | char buffer[4]; 328 | int length; 329 | int32_t value; 330 | 331 | value = decode_unicode_escape(p); 332 | p += 5; 333 | 334 | if(0xD800 <= value && value <= 0xDBFF) { 335 | /* surrogate pair */ 336 | if(*p == '\\' && *(p + 1) == 'u') { 337 | int32_t value2 = decode_unicode_escape(++p); 338 | p += 5; 339 | 340 | if(0xDC00 <= value2 && value2 <= 0xDFFF) { 341 | /* valid second surrogate */ 342 | value = 343 | ((value - 0xD800) << 10) + 344 | (value2 - 0xDC00) + 345 | 0x10000; 346 | } 347 | else { 348 | /* invalid second surrogate */ 349 | error_set(error, lex, 350 | "invalid Unicode '\\u%04X\\u%04X'", 351 | value, value2); 352 | goto out; 353 | } 354 | } 355 | else { 356 | /* no second surrogate */ 357 | error_set(error, lex, "invalid Unicode '\\u%04X'", 358 | value); 359 | goto out; 360 | } 361 | } 362 | else if(0xDC00 <= value && value <= 0xDFFF) { 363 | error_set(error, lex, "invalid Unicode '\\u%04X'", value); 364 | goto out; 365 | } 366 | else if(value == 0) 367 | { 368 | error_set(error, lex, "\\u0000 is not allowed"); 369 | goto out; 370 | } 371 | 372 | if(utf8_encode(value, buffer, &length)) 373 | assert(0); 374 | 375 | memcpy(t, buffer, length); 376 | t += length; 377 | } 378 | else { 379 | switch(*p) { 380 | case '"': case '\\': case '/': 381 | *t = *p; break; 382 | case 'b': *t = '\b'; break; 383 | case 'f': *t = '\f'; break; 384 | case 'n': *t = '\n'; break; 385 | case 'r': *t = '\r'; break; 386 | case 't': *t = '\t'; break; 387 | default: assert(0); 388 | } 389 | t++; 390 | p++; 391 | } 392 | } 393 | else 394 | *(t++) = *(p++); 395 | } 396 | *t = '\0'; 397 | lex->token = TOKEN_STRING; 398 | return; 399 | 400 | out: 401 | free(lex->value.string); 402 | } 403 | 404 | static int lex_scan_number(lex_t *lex, char c, json_error_t *error) 405 | { 406 | const char *saved_text; 407 | char *end; 408 | double value; 409 | 410 | lex->token = TOKEN_INVALID; 411 | 412 | if(c == '-') 413 | c = lex_get_save(lex, error); 414 | 415 | if(c == '0') { 416 | c = lex_get_save(lex, error); 417 | if(isdigit(c)) { 418 | lex_unget_unsave(lex, c); 419 | goto out; 420 | } 421 | } 422 | else if(isdigit(c)) { 423 | c = lex_get_save(lex, error); 424 | while(isdigit(c)) 425 | c = lex_get_save(lex, error); 426 | } 427 | else { 428 | lex_unget_unsave(lex, c); 429 | goto out; 430 | } 431 | 432 | if(c != '.' && c != 'E' && c != 'e') { 433 | long value; 434 | 435 | lex_unget_unsave(lex, c); 436 | 437 | saved_text = strbuffer_value(&lex->saved_text); 438 | value = strtol(saved_text, &end, 10); 439 | assert(end == saved_text + lex->saved_text.length); 440 | 441 | if((value == LONG_MAX && errno == ERANGE) || value > INT_MAX) { 442 | error_set(error, lex, "too big integer"); 443 | goto out; 444 | } 445 | else if((value == LONG_MIN && errno == ERANGE) || value < INT_MIN) { 446 | error_set(error, lex, "too big negative integer"); 447 | goto out; 448 | } 449 | 450 | lex->token = TOKEN_INTEGER; 451 | lex->value.integer = (int)value; 452 | return 0; 453 | } 454 | 455 | if(c == '.') { 456 | c = lex_get(lex, error); 457 | if(!isdigit(c)) 458 | goto out; 459 | lex_save(lex, c); 460 | 461 | c = lex_get_save(lex, error); 462 | while(isdigit(c)) 463 | c = lex_get_save(lex, error); 464 | } 465 | 466 | if(c == 'E' || c == 'e') { 467 | c = lex_get_save(lex, error); 468 | if(c == '+' || c == '-') 469 | c = lex_get_save(lex, error); 470 | 471 | if(!isdigit(c)) { 472 | lex_unget_unsave(lex, c); 473 | goto out; 474 | } 475 | 476 | c = lex_get_save(lex, error); 477 | while(isdigit(c)) 478 | c = lex_get_save(lex, error); 479 | } 480 | 481 | lex_unget_unsave(lex, c); 482 | 483 | saved_text = strbuffer_value(&lex->saved_text); 484 | value = strtod(saved_text, &end); 485 | assert(end == saved_text + lex->saved_text.length); 486 | 487 | if(errno == ERANGE && value != 0) { 488 | error_set(error, lex, "real number overflow"); 489 | goto out; 490 | } 491 | 492 | lex->token = TOKEN_REAL; 493 | lex->value.real = value; 494 | return 0; 495 | 496 | out: 497 | return -1; 498 | } 499 | 500 | static int lex_scan(lex_t *lex, json_error_t *error) 501 | { 502 | char c; 503 | 504 | strbuffer_clear(&lex->saved_text); 505 | 506 | if(lex->token == TOKEN_STRING) { 507 | free(lex->value.string); 508 | lex->value.string = NULL; 509 | } 510 | 511 | c = lex_get(lex, error); 512 | while(c == ' ' || c == '\t' || c == '\n' || c == '\r') 513 | { 514 | if(c == '\n') 515 | lex->line++; 516 | 517 | c = lex_get(lex, error); 518 | } 519 | 520 | if(c == (char)EOF) { 521 | if(lex_eof(lex)) 522 | lex->token = TOKEN_EOF; 523 | else 524 | lex->token = TOKEN_INVALID; 525 | goto out; 526 | } 527 | 528 | lex_save(lex, c); 529 | 530 | if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') 531 | lex->token = c; 532 | 533 | else if(c == '"') 534 | lex_scan_string(lex, error); 535 | 536 | else if(isdigit(c) || c == '-') { 537 | if(lex_scan_number(lex, c, error)) 538 | goto out; 539 | } 540 | 541 | else if(isupper(c) || islower(c)) { 542 | /* eat up the whole identifier for clearer error messages */ 543 | const char *saved_text; 544 | 545 | c = lex_get_save(lex, error); 546 | while(isupper(c) || islower(c)) 547 | c = lex_get_save(lex, error); 548 | lex_unget_unsave(lex, c); 549 | 550 | saved_text = strbuffer_value(&lex->saved_text); 551 | 552 | if(strcmp(saved_text, "true") == 0) 553 | lex->token = TOKEN_TRUE; 554 | else if(strcmp(saved_text, "false") == 0) 555 | lex->token = TOKEN_FALSE; 556 | else if(strcmp(saved_text, "null") == 0) 557 | lex->token = TOKEN_NULL; 558 | else 559 | lex->token = TOKEN_INVALID; 560 | } 561 | 562 | else { 563 | /* save the rest of the input UTF-8 sequence to get an error 564 | message of valid UTF-8 */ 565 | lex_save_cached(lex); 566 | lex->token = TOKEN_INVALID; 567 | } 568 | 569 | out: 570 | return lex->token; 571 | } 572 | 573 | static char *lex_steal_string(lex_t *lex) 574 | { 575 | char *result = NULL; 576 | if(lex->token == TOKEN_STRING) 577 | { 578 | result = lex->value.string; 579 | lex->value.string = NULL; 580 | } 581 | return result; 582 | } 583 | 584 | static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data) 585 | { 586 | stream_init(&lex->stream, get, eof, data); 587 | if(strbuffer_init(&lex->saved_text)) 588 | return -1; 589 | 590 | lex->token = TOKEN_INVALID; 591 | lex->line = 1; 592 | 593 | return 0; 594 | } 595 | 596 | static void lex_close(lex_t *lex) 597 | { 598 | if(lex->token == TOKEN_STRING) 599 | free(lex->value.string); 600 | strbuffer_close(&lex->saved_text); 601 | } 602 | 603 | 604 | /*** parser ***/ 605 | 606 | static json_t *parse_value(lex_t *lex, json_error_t *error); 607 | 608 | static json_t *parse_object(lex_t *lex, json_error_t *error) 609 | { 610 | json_t *object = json_object(); 611 | if(!object) 612 | return NULL; 613 | 614 | lex_scan(lex, error); 615 | if(lex->token == '}') 616 | return object; 617 | 618 | while(1) { 619 | char *key; 620 | json_t *value; 621 | 622 | if(lex->token != TOKEN_STRING) { 623 | error_set(error, lex, "string or '}' expected"); 624 | goto error; 625 | } 626 | 627 | key = lex_steal_string(lex); 628 | if(!key) 629 | return NULL; 630 | 631 | lex_scan(lex, error); 632 | if(lex->token != ':') { 633 | free(key); 634 | error_set(error, lex, "':' expected"); 635 | goto error; 636 | } 637 | 638 | lex_scan(lex, error); 639 | value = parse_value(lex, error); 640 | if(!value) { 641 | free(key); 642 | goto error; 643 | } 644 | 645 | if(json_object_set_nocheck(object, key, value)) { 646 | free(key); 647 | json_decref(value); 648 | goto error; 649 | } 650 | 651 | json_decref(value); 652 | free(key); 653 | 654 | lex_scan(lex, error); 655 | if(lex->token != ',') 656 | break; 657 | 658 | lex_scan(lex, error); 659 | } 660 | 661 | if(lex->token != '}') { 662 | error_set(error, lex, "'}' expected"); 663 | goto error; 664 | } 665 | 666 | return object; 667 | 668 | error: 669 | json_decref(object); 670 | return NULL; 671 | } 672 | 673 | static json_t *parse_array(lex_t *lex, json_error_t *error) 674 | { 675 | json_t *array = json_array(); 676 | if(!array) 677 | return NULL; 678 | 679 | lex_scan(lex, error); 680 | if(lex->token == ']') 681 | return array; 682 | 683 | while(lex->token) { 684 | json_t *elem = parse_value(lex, error); 685 | if(!elem) 686 | goto error; 687 | 688 | if(json_array_append(array, elem)) { 689 | json_decref(elem); 690 | goto error; 691 | } 692 | json_decref(elem); 693 | 694 | lex_scan(lex, error); 695 | if(lex->token != ',') 696 | break; 697 | 698 | lex_scan(lex, error); 699 | } 700 | 701 | if(lex->token != ']') { 702 | error_set(error, lex, "']' expected"); 703 | goto error; 704 | } 705 | 706 | return array; 707 | 708 | error: 709 | json_decref(array); 710 | return NULL; 711 | } 712 | 713 | static json_t *parse_value(lex_t *lex, json_error_t *error) 714 | { 715 | json_t *json; 716 | 717 | switch(lex->token) { 718 | case TOKEN_STRING: { 719 | json = json_string_nocheck(lex->value.string); 720 | break; 721 | } 722 | 723 | case TOKEN_INTEGER: { 724 | json = json_integer(lex->value.integer); 725 | break; 726 | } 727 | 728 | case TOKEN_REAL: { 729 | json = json_real(lex->value.real); 730 | break; 731 | } 732 | 733 | case TOKEN_TRUE: 734 | json = json_true(); 735 | break; 736 | 737 | case TOKEN_FALSE: 738 | json = json_false(); 739 | break; 740 | 741 | case TOKEN_NULL: 742 | json = json_null(); 743 | break; 744 | 745 | case '{': 746 | json = parse_object(lex, error); 747 | break; 748 | 749 | case '[': 750 | json = parse_array(lex, error); 751 | break; 752 | 753 | case TOKEN_INVALID: 754 | error_set(error, lex, "invalid token"); 755 | return NULL; 756 | 757 | default: 758 | error_set(error, lex, "unexpected token"); 759 | return NULL; 760 | } 761 | 762 | if(!json) 763 | return NULL; 764 | 765 | return json; 766 | } 767 | 768 | static json_t *parse_json(lex_t *lex, json_error_t *error) 769 | { 770 | error_init(error); 771 | 772 | lex_scan(lex, error); 773 | if(lex->token != '[' && lex->token != '{') { 774 | error_set(error, lex, "'[' or '{' expected"); 775 | return NULL; 776 | } 777 | 778 | return parse_value(lex, error); 779 | } 780 | 781 | typedef struct 782 | { 783 | const char *data; 784 | int pos; 785 | } string_data_t; 786 | 787 | static int string_get(void *data) 788 | { 789 | char c; 790 | string_data_t *stream = (string_data_t *)data; 791 | c = stream->data[stream->pos]; 792 | if(c == '\0') 793 | return EOF; 794 | else 795 | { 796 | stream->pos++; 797 | return c; 798 | } 799 | } 800 | 801 | static int string_eof(void *data) 802 | { 803 | string_data_t *stream = (string_data_t *)data; 804 | return (stream->data[stream->pos] == '\0'); 805 | } 806 | 807 | json_t *json_loads(const char *string, json_error_t *error) 808 | { 809 | lex_t lex; 810 | json_t *result; 811 | 812 | string_data_t stream_data = { 813 | .data = string, 814 | .pos = 0 815 | }; 816 | 817 | if(lex_init(&lex, string_get, string_eof, (void *)&stream_data)) 818 | return NULL; 819 | 820 | result = parse_json(&lex, error); 821 | if(!result) 822 | goto out; 823 | 824 | lex_scan(&lex, error); 825 | if(lex.token != TOKEN_EOF) { 826 | error_set(error, &lex, "end of file expected"); 827 | json_decref(result); 828 | result = NULL; 829 | } 830 | 831 | out: 832 | lex_close(&lex); 833 | return result; 834 | } 835 | 836 | json_t *json_loadf(FILE *input, json_error_t *error) 837 | { 838 | lex_t lex; 839 | json_t *result; 840 | 841 | if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input)) 842 | return NULL; 843 | 844 | result = parse_json(&lex, error); 845 | if(!result) 846 | goto out; 847 | 848 | lex_scan(&lex, error); 849 | if(lex.token != TOKEN_EOF) { 850 | error_set(error, &lex, "end of file expected"); 851 | json_decref(result); 852 | result = NULL; 853 | } 854 | 855 | out: 856 | lex_close(&lex); 857 | return result; 858 | } 859 | 860 | json_t *json_load_file(const char *path, json_error_t *error) 861 | { 862 | json_t *result; 863 | FILE *fp; 864 | 865 | error_init(error); 866 | 867 | fp = fopen(path, "r"); 868 | if(!fp) 869 | { 870 | error_set(error, NULL, "unable to open %s: %s", 871 | path, strerror(errno)); 872 | return NULL; 873 | } 874 | 875 | result = json_loadf(fp, error); 876 | 877 | fclose(fp); 878 | return result; 879 | } 880 | -------------------------------------------------------------------------------- /compat/jansson/strbuffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include "strbuffer.h" 12 | #include "util.h" 13 | 14 | #define STRBUFFER_MIN_SIZE 16 15 | #define STRBUFFER_FACTOR 2 16 | 17 | int strbuffer_init(strbuffer_t *strbuff) 18 | { 19 | strbuff->size = STRBUFFER_MIN_SIZE; 20 | strbuff->length = 0; 21 | 22 | strbuff->value = malloc(strbuff->size); 23 | if(!strbuff->value) 24 | return -1; 25 | 26 | /* initialize to empty */ 27 | strbuff->value[0] = '\0'; 28 | return 0; 29 | } 30 | 31 | void strbuffer_close(strbuffer_t *strbuff) 32 | { 33 | free(strbuff->value); 34 | strbuff->size = 0; 35 | strbuff->length = 0; 36 | strbuff->value = NULL; 37 | } 38 | 39 | void strbuffer_clear(strbuffer_t *strbuff) 40 | { 41 | strbuff->length = 0; 42 | strbuff->value[0] = '\0'; 43 | } 44 | 45 | const char *strbuffer_value(const strbuffer_t *strbuff) 46 | { 47 | return strbuff->value; 48 | } 49 | 50 | char *strbuffer_steal_value(strbuffer_t *strbuff) 51 | { 52 | char *result = strbuff->value; 53 | strbuffer_init(strbuff); 54 | return result; 55 | } 56 | 57 | int strbuffer_append(strbuffer_t *strbuff, const char *string) 58 | { 59 | return strbuffer_append_bytes(strbuff, string, strlen(string)); 60 | } 61 | 62 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte) 63 | { 64 | return strbuffer_append_bytes(strbuff, &byte, 1); 65 | } 66 | 67 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size) 68 | { 69 | if(strbuff->length + size >= strbuff->size) 70 | { 71 | strbuff->size = max(strbuff->size * STRBUFFER_FACTOR, 72 | strbuff->length + size + 1); 73 | 74 | strbuff->value = realloc(strbuff->value, strbuff->size); 75 | if(!strbuff->value) 76 | return -1; 77 | } 78 | 79 | memcpy(strbuff->value + strbuff->length, data, size); 80 | strbuff->length += size; 81 | strbuff->value[strbuff->length] = '\0'; 82 | 83 | return 0; 84 | } 85 | 86 | char strbuffer_pop(strbuffer_t *strbuff) 87 | { 88 | if(strbuff->length > 0) { 89 | char c = strbuff->value[--strbuff->length]; 90 | strbuff->value[strbuff->length] = '\0'; 91 | return c; 92 | } 93 | else 94 | return '\0'; 95 | } 96 | -------------------------------------------------------------------------------- /compat/jansson/strbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef STRBUFFER_H 9 | #define STRBUFFER_H 10 | 11 | typedef struct { 12 | char *value; 13 | int length; /* bytes used */ 14 | int size; /* bytes allocated */ 15 | } strbuffer_t; 16 | 17 | int strbuffer_init(strbuffer_t *strbuff); 18 | void strbuffer_close(strbuffer_t *strbuff); 19 | 20 | void strbuffer_clear(strbuffer_t *strbuff); 21 | 22 | const char *strbuffer_value(const strbuffer_t *strbuff); 23 | char *strbuffer_steal_value(strbuffer_t *strbuff); 24 | 25 | int strbuffer_append(strbuffer_t *strbuff, const char *string); 26 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte); 27 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size); 28 | 29 | char strbuffer_pop(strbuffer_t *strbuff); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /compat/jansson/utf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include 9 | #include "utf.h" 10 | 11 | int utf8_encode(int32_t codepoint, char *buffer, int *size) 12 | { 13 | if(codepoint < 0) 14 | return -1; 15 | else if(codepoint < 0x80) 16 | { 17 | buffer[0] = (char)codepoint; 18 | *size = 1; 19 | } 20 | else if(codepoint < 0x800) 21 | { 22 | buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6); 23 | buffer[1] = 0x80 + ((codepoint & 0x03F)); 24 | *size = 2; 25 | } 26 | else if(codepoint < 0x10000) 27 | { 28 | buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12); 29 | buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6); 30 | buffer[2] = 0x80 + ((codepoint & 0x003F)); 31 | *size = 3; 32 | } 33 | else if(codepoint <= 0x10FFFF) 34 | { 35 | buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18); 36 | buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12); 37 | buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6); 38 | buffer[3] = 0x80 + ((codepoint & 0x00003F)); 39 | *size = 4; 40 | } 41 | else 42 | return -1; 43 | 44 | return 0; 45 | } 46 | 47 | int utf8_check_first(char byte) 48 | { 49 | unsigned char u = (unsigned char)byte; 50 | 51 | if(u < 0x80) 52 | return 1; 53 | 54 | if(0x80 <= u && u <= 0xBF) { 55 | /* second, third or fourth byte of a multi-byte 56 | sequence, i.e. a "continuation byte" */ 57 | return 0; 58 | } 59 | else if(u == 0xC0 || u == 0xC1) { 60 | /* overlong encoding of an ASCII byte */ 61 | return 0; 62 | } 63 | else if(0xC2 <= u && u <= 0xDF) { 64 | /* 2-byte sequence */ 65 | return 2; 66 | } 67 | 68 | else if(0xE0 <= u && u <= 0xEF) { 69 | /* 3-byte sequence */ 70 | return 3; 71 | } 72 | else if(0xF0 <= u && u <= 0xF4) { 73 | /* 4-byte sequence */ 74 | return 4; 75 | } 76 | else { /* u >= 0xF5 */ 77 | /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid 78 | UTF-8 */ 79 | return 0; 80 | } 81 | } 82 | 83 | int utf8_check_full(const char *buffer, int size, int32_t *codepoint) 84 | { 85 | int i; 86 | int32_t value = 0; 87 | unsigned char u = (unsigned char)buffer[0]; 88 | 89 | if(size == 2) 90 | { 91 | value = u & 0x1F; 92 | } 93 | else if(size == 3) 94 | { 95 | value = u & 0xF; 96 | } 97 | else if(size == 4) 98 | { 99 | value = u & 0x7; 100 | } 101 | else 102 | return 0; 103 | 104 | for(i = 1; i < size; i++) 105 | { 106 | u = (unsigned char)buffer[i]; 107 | 108 | if(u < 0x80 || u > 0xBF) { 109 | /* not a continuation byte */ 110 | return 0; 111 | } 112 | 113 | value = (value << 6) + (u & 0x3F); 114 | } 115 | 116 | if(value > 0x10FFFF) { 117 | /* not in Unicode range */ 118 | return 0; 119 | } 120 | 121 | else if(0xD800 <= value && value <= 0xDFFF) { 122 | /* invalid code point (UTF-16 surrogate halves) */ 123 | return 0; 124 | } 125 | 126 | else if((size == 2 && value < 0x80) || 127 | (size == 3 && value < 0x800) || 128 | (size == 4 && value < 0x10000)) { 129 | /* overlong encoding */ 130 | return 0; 131 | } 132 | 133 | if(codepoint) 134 | *codepoint = value; 135 | 136 | return 1; 137 | } 138 | 139 | const char *utf8_iterate(const char *buffer, int32_t *codepoint) 140 | { 141 | int count; 142 | int32_t value; 143 | 144 | if(!*buffer) 145 | return buffer; 146 | 147 | count = utf8_check_first(buffer[0]); 148 | if(count <= 0) 149 | return NULL; 150 | 151 | if(count == 1) 152 | value = (unsigned char)buffer[0]; 153 | else 154 | { 155 | if(!utf8_check_full(buffer, count, &value)) 156 | return NULL; 157 | } 158 | 159 | if(codepoint) 160 | *codepoint = value; 161 | 162 | return buffer + count; 163 | } 164 | 165 | int utf8_check_string(const char *string, int length) 166 | { 167 | int i; 168 | 169 | if(length == -1) 170 | length = strlen(string); 171 | 172 | for(i = 0; i < length; i++) 173 | { 174 | int count = utf8_check_first(string[i]); 175 | if(count == 0) 176 | return 0; 177 | else if(count > 1) 178 | { 179 | if(i + count > length) 180 | return 0; 181 | 182 | if(!utf8_check_full(&string[i], count, NULL)) 183 | return 0; 184 | 185 | i += count - 1; 186 | } 187 | } 188 | 189 | return 1; 190 | } 191 | -------------------------------------------------------------------------------- /compat/jansson/utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef UTF_H 9 | #define UTF_H 10 | 11 | #include 12 | 13 | #ifdef HAVE_INTTYPES_H 14 | /* inttypes.h includes stdint.h in a standard environment, so there's 15 | no need to include stdint.h separately. If inttypes.h doesn't define 16 | int32_t, it's defined in config.h. */ 17 | #include 18 | #endif 19 | 20 | int utf8_encode(int codepoint, char *buffer, int *size); 21 | 22 | int utf8_check_first(char byte); 23 | int utf8_check_full(const char *buffer, int size, int32_t *codepoint); 24 | const char *utf8_iterate(const char *buffer, int32_t *codepoint); 25 | 26 | int utf8_check_string(const char *string, int length); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /compat/jansson/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef UTIL_H 9 | #define UTIL_H 10 | 11 | #define max(a, b) ((a) > (b) ? (a) : (b)) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /compat/jansson/value.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include "hashtable.h" 17 | #include "jansson_private.h" 18 | #include "utf.h" 19 | #include "util.h" 20 | 21 | 22 | static inline void json_init(json_t *json, json_type type) 23 | { 24 | json->type = type; 25 | json->refcount = 1; 26 | } 27 | 28 | 29 | /*** object ***/ 30 | 31 | /* This macro just returns a pointer that's a few bytes backwards from 32 | string. This makes it possible to pass a pointer to object_key_t 33 | when only the string inside it is used, without actually creating 34 | an object_key_t instance. */ 35 | #define string_to_key(string) container_of(string, object_key_t, key) 36 | 37 | static unsigned int hash_key(const void *ptr) 38 | { 39 | const char *str = ((const object_key_t *)ptr)->key; 40 | 41 | unsigned int hash = 5381; 42 | unsigned int c; 43 | 44 | while((c = (unsigned int)*str)) 45 | { 46 | hash = ((hash << 5) + hash) + c; 47 | str++; 48 | } 49 | 50 | return hash; 51 | } 52 | 53 | static int key_equal(const void *ptr1, const void *ptr2) 54 | { 55 | return strcmp(((const object_key_t *)ptr1)->key, 56 | ((const object_key_t *)ptr2)->key) == 0; 57 | } 58 | 59 | static void value_decref(void *value) 60 | { 61 | json_decref((json_t *)value); 62 | } 63 | 64 | json_t *json_object(void) 65 | { 66 | json_object_t *object = malloc(sizeof(json_object_t)); 67 | if(!object) 68 | return NULL; 69 | json_init(&object->json, JSON_OBJECT); 70 | 71 | if(hashtable_init(&object->hashtable, hash_key, key_equal, 72 | free, value_decref)) 73 | { 74 | free(object); 75 | return NULL; 76 | } 77 | 78 | object->serial = 0; 79 | object->visited = 0; 80 | 81 | return &object->json; 82 | } 83 | 84 | static void json_delete_object(json_object_t *object) 85 | { 86 | hashtable_close(&object->hashtable); 87 | free(object); 88 | } 89 | 90 | unsigned int json_object_size(const json_t *json) 91 | { 92 | json_object_t *object; 93 | 94 | if(!json_is_object(json)) 95 | return -1; 96 | 97 | object = json_to_object(json); 98 | return object->hashtable.size; 99 | } 100 | 101 | json_t *json_object_get(const json_t *json, const char *key) 102 | { 103 | json_object_t *object; 104 | 105 | if(!json_is_object(json)) 106 | return NULL; 107 | 108 | object = json_to_object(json); 109 | return hashtable_get(&object->hashtable, string_to_key(key)); 110 | } 111 | 112 | int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) 113 | { 114 | json_object_t *object; 115 | object_key_t *k; 116 | 117 | if(!key || !value) 118 | return -1; 119 | 120 | if(!json_is_object(json) || json == value) 121 | { 122 | json_decref(value); 123 | return -1; 124 | } 125 | object = json_to_object(json); 126 | 127 | k = malloc(sizeof(object_key_t) + strlen(key) + 1); 128 | if(!k) 129 | return -1; 130 | 131 | k->serial = object->serial++; 132 | strcpy(k->key, key); 133 | 134 | if(hashtable_set(&object->hashtable, k, value)) 135 | { 136 | json_decref(value); 137 | return -1; 138 | } 139 | 140 | return 0; 141 | } 142 | 143 | int json_object_set_new(json_t *json, const char *key, json_t *value) 144 | { 145 | if(!key || !utf8_check_string(key, -1)) 146 | { 147 | json_decref(value); 148 | return -1; 149 | } 150 | 151 | return json_object_set_new_nocheck(json, key, value); 152 | } 153 | 154 | int json_object_del(json_t *json, const char *key) 155 | { 156 | json_object_t *object; 157 | 158 | if(!json_is_object(json)) 159 | return -1; 160 | 161 | object = json_to_object(json); 162 | return hashtable_del(&object->hashtable, string_to_key(key)); 163 | } 164 | 165 | int json_object_clear(json_t *json) 166 | { 167 | json_object_t *object; 168 | 169 | if(!json_is_object(json)) 170 | return -1; 171 | 172 | object = json_to_object(json); 173 | hashtable_clear(&object->hashtable); 174 | 175 | return 0; 176 | } 177 | 178 | int json_object_update(json_t *object, json_t *other) 179 | { 180 | void *iter; 181 | 182 | if(!json_is_object(object) || !json_is_object(other)) 183 | return -1; 184 | 185 | iter = json_object_iter(other); 186 | while(iter) { 187 | const char *key; 188 | json_t *value; 189 | 190 | key = json_object_iter_key(iter); 191 | value = json_object_iter_value(iter); 192 | 193 | if(json_object_set_nocheck(object, key, value)) 194 | return -1; 195 | 196 | iter = json_object_iter_next(other, iter); 197 | } 198 | 199 | return 0; 200 | } 201 | 202 | void *json_object_iter(json_t *json) 203 | { 204 | json_object_t *object; 205 | 206 | if(!json_is_object(json)) 207 | return NULL; 208 | 209 | object = json_to_object(json); 210 | return hashtable_iter(&object->hashtable); 211 | } 212 | 213 | void *json_object_iter_at(json_t *json, const char *key) 214 | { 215 | json_object_t *object; 216 | 217 | if(!key || !json_is_object(json)) 218 | return NULL; 219 | 220 | object = json_to_object(json); 221 | return hashtable_iter_at(&object->hashtable, string_to_key(key)); 222 | } 223 | 224 | void *json_object_iter_next(json_t *json, void *iter) 225 | { 226 | json_object_t *object; 227 | 228 | if(!json_is_object(json) || iter == NULL) 229 | return NULL; 230 | 231 | object = json_to_object(json); 232 | return hashtable_iter_next(&object->hashtable, iter); 233 | } 234 | 235 | const object_key_t *jsonp_object_iter_fullkey(void *iter) 236 | { 237 | if(!iter) 238 | return NULL; 239 | 240 | return hashtable_iter_key(iter); 241 | } 242 | 243 | const char *json_object_iter_key(void *iter) 244 | { 245 | if(!iter) 246 | return NULL; 247 | 248 | return jsonp_object_iter_fullkey(iter)->key; 249 | } 250 | 251 | json_t *json_object_iter_value(void *iter) 252 | { 253 | if(!iter) 254 | return NULL; 255 | 256 | return (json_t *)hashtable_iter_value(iter); 257 | } 258 | 259 | int json_object_iter_set_new(json_t *json, void *iter, json_t *value) 260 | { 261 | json_object_t *object; 262 | 263 | if(!json_is_object(json) || !iter || !value) 264 | return -1; 265 | 266 | object = json_to_object(json); 267 | hashtable_iter_set(&object->hashtable, iter, value); 268 | 269 | return 0; 270 | } 271 | 272 | static int json_object_equal(json_t *object1, json_t *object2) 273 | { 274 | void *iter; 275 | 276 | if(json_object_size(object1) != json_object_size(object2)) 277 | return 0; 278 | 279 | iter = json_object_iter(object1); 280 | while(iter) 281 | { 282 | const char *key; 283 | json_t *value1, *value2; 284 | 285 | key = json_object_iter_key(iter); 286 | value1 = json_object_iter_value(iter); 287 | value2 = json_object_get(object2, key); 288 | 289 | if(!json_equal(value1, value2)) 290 | return 0; 291 | 292 | iter = json_object_iter_next(object1, iter); 293 | } 294 | 295 | return 1; 296 | } 297 | 298 | static json_t *json_object_copy(json_t *object) 299 | { 300 | json_t *result; 301 | void *iter; 302 | 303 | result = json_object(); 304 | if(!result) 305 | return NULL; 306 | 307 | iter = json_object_iter(object); 308 | while(iter) 309 | { 310 | const char *key; 311 | json_t *value; 312 | 313 | key = json_object_iter_key(iter); 314 | value = json_object_iter_value(iter); 315 | json_object_set_nocheck(result, key, value); 316 | 317 | iter = json_object_iter_next(object, iter); 318 | } 319 | 320 | return result; 321 | } 322 | 323 | static json_t *json_object_deep_copy(json_t *object) 324 | { 325 | json_t *result; 326 | void *iter; 327 | 328 | result = json_object(); 329 | if(!result) 330 | return NULL; 331 | 332 | iter = json_object_iter(object); 333 | while(iter) 334 | { 335 | const char *key; 336 | json_t *value; 337 | 338 | key = json_object_iter_key(iter); 339 | value = json_object_iter_value(iter); 340 | json_object_set_new_nocheck(result, key, json_deep_copy(value)); 341 | 342 | iter = json_object_iter_next(object, iter); 343 | } 344 | 345 | return result; 346 | } 347 | 348 | 349 | /*** array ***/ 350 | 351 | json_t *json_array(void) 352 | { 353 | json_array_t *array = malloc(sizeof(json_array_t)); 354 | if(!array) 355 | return NULL; 356 | json_init(&array->json, JSON_ARRAY); 357 | 358 | array->entries = 0; 359 | array->size = 8; 360 | 361 | array->table = malloc(array->size * sizeof(json_t *)); 362 | if(!array->table) { 363 | free(array); 364 | return NULL; 365 | } 366 | 367 | array->visited = 0; 368 | 369 | return &array->json; 370 | } 371 | 372 | static void json_delete_array(json_array_t *array) 373 | { 374 | unsigned int i; 375 | 376 | for(i = 0; i < array->entries; i++) 377 | json_decref(array->table[i]); 378 | 379 | free(array->table); 380 | free(array); 381 | } 382 | 383 | unsigned int json_array_size(const json_t *json) 384 | { 385 | if(!json_is_array(json)) 386 | return 0; 387 | 388 | return json_to_array(json)->entries; 389 | } 390 | 391 | json_t *json_array_get(const json_t *json, unsigned int index) 392 | { 393 | json_array_t *array; 394 | if(!json_is_array(json)) 395 | return NULL; 396 | array = json_to_array(json); 397 | 398 | if(index >= array->entries) 399 | return NULL; 400 | 401 | return array->table[index]; 402 | } 403 | 404 | int json_array_set_new(json_t *json, unsigned int index, json_t *value) 405 | { 406 | json_array_t *array; 407 | 408 | if(!value) 409 | return -1; 410 | 411 | if(!json_is_array(json) || json == value) 412 | { 413 | json_decref(value); 414 | return -1; 415 | } 416 | array = json_to_array(json); 417 | 418 | if(index >= array->entries) 419 | { 420 | json_decref(value); 421 | return -1; 422 | } 423 | 424 | json_decref(array->table[index]); 425 | array->table[index] = value; 426 | 427 | return 0; 428 | } 429 | 430 | static void array_move(json_array_t *array, unsigned int dest, 431 | unsigned int src, unsigned int count) 432 | { 433 | memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *)); 434 | } 435 | 436 | static void array_copy(json_t **dest, unsigned int dpos, 437 | json_t **src, unsigned int spos, 438 | unsigned int count) 439 | { 440 | memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); 441 | } 442 | 443 | static json_t **json_array_grow(json_array_t *array, 444 | unsigned int amount, 445 | int copy) 446 | { 447 | unsigned int new_size; 448 | json_t **old_table, **new_table; 449 | 450 | if(array->entries + amount <= array->size) 451 | return array->table; 452 | 453 | old_table = array->table; 454 | 455 | new_size = max(array->size + amount, array->size * 2); 456 | new_table = malloc(new_size * sizeof(json_t *)); 457 | if(!new_table) 458 | return NULL; 459 | 460 | array->size = new_size; 461 | array->table = new_table; 462 | 463 | if(copy) { 464 | array_copy(array->table, 0, old_table, 0, array->entries); 465 | free(old_table); 466 | return array->table; 467 | } 468 | 469 | return old_table; 470 | } 471 | 472 | int json_array_append_new(json_t *json, json_t *value) 473 | { 474 | json_array_t *array; 475 | 476 | if(!value) 477 | return -1; 478 | 479 | if(!json_is_array(json) || json == value) 480 | { 481 | json_decref(value); 482 | return -1; 483 | } 484 | array = json_to_array(json); 485 | 486 | if(!json_array_grow(array, 1, 1)) { 487 | json_decref(value); 488 | return -1; 489 | } 490 | 491 | array->table[array->entries] = value; 492 | array->entries++; 493 | 494 | return 0; 495 | } 496 | 497 | int json_array_insert_new(json_t *json, unsigned int index, json_t *value) 498 | { 499 | json_array_t *array; 500 | json_t **old_table; 501 | 502 | if(!value) 503 | return -1; 504 | 505 | if(!json_is_array(json) || json == value) { 506 | json_decref(value); 507 | return -1; 508 | } 509 | array = json_to_array(json); 510 | 511 | if(index > array->entries) { 512 | json_decref(value); 513 | return -1; 514 | } 515 | 516 | old_table = json_array_grow(array, 1, 0); 517 | if(!old_table) { 518 | json_decref(value); 519 | return -1; 520 | } 521 | 522 | if(old_table != array->table) { 523 | array_copy(array->table, 0, old_table, 0, index); 524 | array_copy(array->table, index + 1, old_table, index, 525 | array->entries - index); 526 | free(old_table); 527 | } 528 | else 529 | array_move(array, index + 1, index, array->entries - index); 530 | 531 | array->table[index] = value; 532 | array->entries++; 533 | 534 | return 0; 535 | } 536 | 537 | int json_array_remove(json_t *json, unsigned int index) 538 | { 539 | json_array_t *array; 540 | 541 | if(!json_is_array(json)) 542 | return -1; 543 | array = json_to_array(json); 544 | 545 | if(index >= array->entries) 546 | return -1; 547 | 548 | json_decref(array->table[index]); 549 | 550 | array_move(array, index, index + 1, array->entries - index); 551 | array->entries--; 552 | 553 | return 0; 554 | } 555 | 556 | int json_array_clear(json_t *json) 557 | { 558 | json_array_t *array; 559 | unsigned int i; 560 | 561 | if(!json_is_array(json)) 562 | return -1; 563 | array = json_to_array(json); 564 | 565 | for(i = 0; i < array->entries; i++) 566 | json_decref(array->table[i]); 567 | 568 | array->entries = 0; 569 | return 0; 570 | } 571 | 572 | int json_array_extend(json_t *json, json_t *other_json) 573 | { 574 | json_array_t *array, *other; 575 | unsigned int i; 576 | 577 | if(!json_is_array(json) || !json_is_array(other_json)) 578 | return -1; 579 | array = json_to_array(json); 580 | other = json_to_array(other_json); 581 | 582 | if(!json_array_grow(array, other->entries, 1)) 583 | return -1; 584 | 585 | for(i = 0; i < other->entries; i++) 586 | json_incref(other->table[i]); 587 | 588 | array_copy(array->table, array->entries, other->table, 0, other->entries); 589 | 590 | array->entries += other->entries; 591 | return 0; 592 | } 593 | 594 | static int json_array_equal(json_t *array1, json_t *array2) 595 | { 596 | unsigned int i, size; 597 | 598 | size = json_array_size(array1); 599 | if(size != json_array_size(array2)) 600 | return 0; 601 | 602 | for(i = 0; i < size; i++) 603 | { 604 | json_t *value1, *value2; 605 | 606 | value1 = json_array_get(array1, i); 607 | value2 = json_array_get(array2, i); 608 | 609 | if(!json_equal(value1, value2)) 610 | return 0; 611 | } 612 | 613 | return 1; 614 | } 615 | 616 | static json_t *json_array_copy(json_t *array) 617 | { 618 | json_t *result; 619 | unsigned int i; 620 | 621 | result = json_array(); 622 | if(!result) 623 | return NULL; 624 | 625 | for(i = 0; i < json_array_size(array); i++) 626 | json_array_append(result, json_array_get(array, i)); 627 | 628 | return result; 629 | } 630 | 631 | static json_t *json_array_deep_copy(json_t *array) 632 | { 633 | json_t *result; 634 | unsigned int i; 635 | 636 | result = json_array(); 637 | if(!result) 638 | return NULL; 639 | 640 | for(i = 0; i < json_array_size(array); i++) 641 | json_array_append_new(result, json_deep_copy(json_array_get(array, i))); 642 | 643 | return result; 644 | } 645 | 646 | /*** string ***/ 647 | 648 | json_t *json_string_nocheck(const char *value) 649 | { 650 | json_string_t *string; 651 | 652 | if(!value) 653 | return NULL; 654 | 655 | string = malloc(sizeof(json_string_t)); 656 | if(!string) 657 | return NULL; 658 | json_init(&string->json, JSON_STRING); 659 | 660 | string->value = strdup(value); 661 | if(!string->value) { 662 | free(string); 663 | return NULL; 664 | } 665 | 666 | return &string->json; 667 | } 668 | 669 | json_t *json_string(const char *value) 670 | { 671 | if(!value || !utf8_check_string(value, -1)) 672 | return NULL; 673 | 674 | return json_string_nocheck(value); 675 | } 676 | 677 | const char *json_string_value(const json_t *json) 678 | { 679 | if(!json_is_string(json)) 680 | return NULL; 681 | 682 | return json_to_string(json)->value; 683 | } 684 | 685 | int json_string_set_nocheck(json_t *json, const char *value) 686 | { 687 | char *dup; 688 | json_string_t *string; 689 | 690 | dup = strdup(value); 691 | if(!dup) 692 | return -1; 693 | 694 | string = json_to_string(json); 695 | free(string->value); 696 | string->value = dup; 697 | 698 | return 0; 699 | } 700 | 701 | int json_string_set(json_t *json, const char *value) 702 | { 703 | if(!value || !utf8_check_string(value, -1)) 704 | return -1; 705 | 706 | return json_string_set_nocheck(json, value); 707 | } 708 | 709 | static void json_delete_string(json_string_t *string) 710 | { 711 | free(string->value); 712 | free(string); 713 | } 714 | 715 | static int json_string_equal(json_t *string1, json_t *string2) 716 | { 717 | return strcmp(json_string_value(string1), json_string_value(string2)) == 0; 718 | } 719 | 720 | static json_t *json_string_copy(json_t *string) 721 | { 722 | return json_string_nocheck(json_string_value(string)); 723 | } 724 | 725 | 726 | /*** integer ***/ 727 | 728 | json_t *json_integer(int value) 729 | { 730 | json_integer_t *integer = malloc(sizeof(json_integer_t)); 731 | if(!integer) 732 | return NULL; 733 | json_init(&integer->json, JSON_INTEGER); 734 | 735 | integer->value = value; 736 | return &integer->json; 737 | } 738 | 739 | int json_integer_value(const json_t *json) 740 | { 741 | if(!json_is_integer(json)) 742 | return 0; 743 | 744 | return json_to_integer(json)->value; 745 | } 746 | 747 | int json_integer_set(json_t *json, int value) 748 | { 749 | if(!json_is_integer(json)) 750 | return -1; 751 | 752 | json_to_integer(json)->value = value; 753 | 754 | return 0; 755 | } 756 | 757 | static void json_delete_integer(json_integer_t *integer) 758 | { 759 | free(integer); 760 | } 761 | 762 | static int json_integer_equal(json_t *integer1, json_t *integer2) 763 | { 764 | return json_integer_value(integer1) == json_integer_value(integer2); 765 | } 766 | 767 | static json_t *json_integer_copy(json_t *integer) 768 | { 769 | return json_integer(json_integer_value(integer)); 770 | } 771 | 772 | 773 | /*** real ***/ 774 | 775 | json_t *json_real(double value) 776 | { 777 | json_real_t *real = malloc(sizeof(json_real_t)); 778 | if(!real) 779 | return NULL; 780 | json_init(&real->json, JSON_REAL); 781 | 782 | real->value = value; 783 | return &real->json; 784 | } 785 | 786 | double json_real_value(const json_t *json) 787 | { 788 | if(!json_is_real(json)) 789 | return 0; 790 | 791 | return json_to_real(json)->value; 792 | } 793 | 794 | int json_real_set(json_t *json, double value) 795 | { 796 | if(!json_is_real(json)) 797 | return 0; 798 | 799 | json_to_real(json)->value = value; 800 | 801 | return 0; 802 | } 803 | 804 | static void json_delete_real(json_real_t *real) 805 | { 806 | free(real); 807 | } 808 | 809 | static int json_real_equal(json_t *real1, json_t *real2) 810 | { 811 | return json_real_value(real1) == json_real_value(real2); 812 | } 813 | 814 | static json_t *json_real_copy(json_t *real) 815 | { 816 | return json_real(json_real_value(real)); 817 | } 818 | 819 | 820 | /*** number ***/ 821 | 822 | double json_number_value(const json_t *json) 823 | { 824 | if(json_is_integer(json)) 825 | return json_integer_value(json); 826 | else if(json_is_real(json)) 827 | return json_real_value(json); 828 | else 829 | return 0.0; 830 | } 831 | 832 | 833 | /*** simple values ***/ 834 | 835 | json_t *json_true(void) 836 | { 837 | static json_t the_true = { 838 | .type = JSON_TRUE, 839 | .refcount = (unsigned int)-1 840 | }; 841 | return &the_true; 842 | } 843 | 844 | 845 | json_t *json_false(void) 846 | { 847 | static json_t the_false = { 848 | .type = JSON_FALSE, 849 | .refcount = (unsigned int)-1 850 | }; 851 | return &the_false; 852 | } 853 | 854 | 855 | json_t *json_null(void) 856 | { 857 | static json_t the_null = { 858 | .type = JSON_NULL, 859 | .refcount = (unsigned int)-1 860 | }; 861 | return &the_null; 862 | } 863 | 864 | 865 | /*** deletion ***/ 866 | 867 | void json_delete(json_t *json) 868 | { 869 | if(json_is_object(json)) 870 | json_delete_object(json_to_object(json)); 871 | 872 | else if(json_is_array(json)) 873 | json_delete_array(json_to_array(json)); 874 | 875 | else if(json_is_string(json)) 876 | json_delete_string(json_to_string(json)); 877 | 878 | else if(json_is_integer(json)) 879 | json_delete_integer(json_to_integer(json)); 880 | 881 | else if(json_is_real(json)) 882 | json_delete_real(json_to_real(json)); 883 | 884 | /* json_delete is not called for true, false or null */ 885 | } 886 | 887 | 888 | /*** equality ***/ 889 | 890 | int json_equal(json_t *json1, json_t *json2) 891 | { 892 | if(!json1 || !json2) 893 | return 0; 894 | 895 | if(json_typeof(json1) != json_typeof(json2)) 896 | return 0; 897 | 898 | /* this covers true, false and null as they are singletons */ 899 | if(json1 == json2) 900 | return 1; 901 | 902 | if(json_is_object(json1)) 903 | return json_object_equal(json1, json2); 904 | 905 | if(json_is_array(json1)) 906 | return json_array_equal(json1, json2); 907 | 908 | if(json_is_string(json1)) 909 | return json_string_equal(json1, json2); 910 | 911 | if(json_is_integer(json1)) 912 | return json_integer_equal(json1, json2); 913 | 914 | if(json_is_real(json1)) 915 | return json_real_equal(json1, json2); 916 | 917 | return 0; 918 | } 919 | 920 | 921 | /*** copying ***/ 922 | 923 | json_t *json_copy(json_t *json) 924 | { 925 | if(!json) 926 | return NULL; 927 | 928 | if(json_is_object(json)) 929 | return json_object_copy(json); 930 | 931 | if(json_is_array(json)) 932 | return json_array_copy(json); 933 | 934 | if(json_is_string(json)) 935 | return json_string_copy(json); 936 | 937 | if(json_is_integer(json)) 938 | return json_integer_copy(json); 939 | 940 | if(json_is_real(json)) 941 | return json_real_copy(json); 942 | 943 | if(json_is_true(json) || json_is_false(json) || json_is_null(json)) 944 | return json; 945 | 946 | return NULL; 947 | } 948 | 949 | json_t *json_deep_copy(json_t *json) 950 | { 951 | if(!json) 952 | return NULL; 953 | 954 | if(json_is_object(json)) 955 | return json_object_deep_copy(json); 956 | 957 | if(json_is_array(json)) 958 | return json_array_deep_copy(json); 959 | 960 | /* for the rest of the types, deep copying doesn't differ from 961 | shallow copying */ 962 | 963 | if(json_is_string(json)) 964 | return json_string_copy(json); 965 | 966 | if(json_is_integer(json)) 967 | return json_integer_copy(json); 968 | 969 | if(json_is_real(json)) 970 | return json_real_copy(json); 971 | 972 | if(json_is_true(json) || json_is_false(json) || json_is_null(json)) 973 | return json; 974 | 975 | return NULL; 976 | } 977 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([cpuminer], [1.0.2]) 2 | 3 | AC_PREREQ(2.52) 4 | AC_CANONICAL_SYSTEM 5 | AC_CONFIG_SRCDIR([cpu-miner.c]) 6 | AM_INIT_AUTOMAKE([gnu]) 7 | AC_CONFIG_HEADERS([cpuminer-config.h]) 8 | 9 | dnl Make sure anyone changing configure.ac/Makefile.am has a clue 10 | AM_MAINTAINER_MODE 11 | 12 | dnl Checks for programs 13 | AC_PROG_CC 14 | AC_PROG_GCC_TRADITIONAL 15 | AM_PROG_CC_C_O 16 | AC_PROG_RANLIB 17 | 18 | dnl Checks for header files. 19 | AC_HEADER_STDC 20 | AC_CHECK_HEADERS(syslog.h) 21 | 22 | AC_FUNC_ALLOCA 23 | 24 | case $target in 25 | *-*-mingw*) 26 | have_x86_64=false 27 | have_win32=true 28 | PTHREAD_FLAGS="" 29 | ;; 30 | x86_64-*) 31 | have_x86_64=true 32 | have_win32=false 33 | PTHREAD_FLAGS="-pthread" 34 | ;; 35 | *) 36 | have_x86_64=false 37 | have_win32=false 38 | PTHREAD_FLAGS="-pthread" 39 | ;; 40 | esac 41 | 42 | 43 | AC_CHECK_LIB(jansson, json_loads, request_jansson=false, request_jansson=true) 44 | AC_CHECK_LIB(pthread, pthread_create, PTHREAD_LIBS=-lpthread) 45 | 46 | AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue]) 47 | AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue]) 48 | AM_CONDITIONAL([HAVE_x86_64], [test x$have_x86_64 = xtrue]) 49 | 50 | if test x$request_jansson = xtrue 51 | then 52 | JANSSON_LIBS="compat/jansson/libjansson.a" 53 | else 54 | JANSSON_LIBS=-ljansson 55 | fi 56 | 57 | dnl Find YASM 58 | has_yasm=false 59 | AC_PATH_PROG([YASM],[yasm],[false]) 60 | if test "x$YASM" != "xfalse" ; then 61 | AC_MSG_CHECKING([if yasm version is greater than 1.0.1]) 62 | yasmver=`yasm --version | head -1 | cut -d\ -f2` 63 | yamajor=`echo $yasmver | cut -d. -f1` 64 | yaminor=`echo $yasmver | cut -d. -f2` 65 | yamini=`echo $yasmver | cut -d. -f3` 66 | if test "$yamajor" -ge "1" ; then 67 | if test "$yamajor" -eq "1" ; then 68 | if test "$yaminor" -ge "0" ; then 69 | if test "$yaminor" -eq "0"; then 70 | if test "$yamini" -ge "1"; then 71 | has_yasm=true 72 | fi 73 | else 74 | has_yasm=true 75 | fi 76 | fi 77 | fi 78 | else 79 | has_yasm=false 80 | fi 81 | if test "x$has_yasm" = "xtrue" ; then 82 | AC_MSG_RESULT([yes]) 83 | else 84 | AC_MSG_RESULT([no]) 85 | fi 86 | fi 87 | if test "x$has_yasm" = "xfalse" ; then 88 | AC_MSG_NOTICE([yasm is required for the sse2_64 algorithm. It will be skipped.]) 89 | fi 90 | 91 | AM_CONDITIONAL([HAS_YASM], [test x$has_yasm = xtrue]) 92 | 93 | PKG_PROG_PKG_CONFIG() 94 | 95 | LIBCURL_CHECK_CONFIG(, 7.10.1, , 96 | [AC_MSG_ERROR([Missing required libcurl >= 7.10.1])]) 97 | 98 | AC_SUBST(JANSSON_LIBS) 99 | AC_SUBST(PTHREAD_FLAGS) 100 | AC_SUBST(PTHREAD_LIBS) 101 | 102 | AC_CONFIG_FILES([ 103 | Makefile 104 | compat/Makefile 105 | compat/jansson/Makefile 106 | x86_64/Makefile 107 | ]) 108 | AC_OUTPUT 109 | 110 | -------------------------------------------------------------------------------- /elist.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_LIST_H 2 | #define _LINUX_LIST_H 3 | 4 | /* 5 | * Simple doubly linked list implementation. 6 | * 7 | * Some of the internal functions ("__xxx") are useful when 8 | * manipulating whole lists rather than single entries, as 9 | * sometimes we already know the next/prev entries and we can 10 | * generate better code by using them directly rather than 11 | * using the generic single-entry routines. 12 | */ 13 | 14 | struct list_head { 15 | struct list_head *next, *prev; 16 | }; 17 | 18 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 19 | 20 | #define LIST_HEAD(name) \ 21 | struct list_head name = LIST_HEAD_INIT(name) 22 | 23 | #define INIT_LIST_HEAD(ptr) do { \ 24 | (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 25 | } while (0) 26 | 27 | /* 28 | * Insert a new entry between two known consecutive entries. 29 | * 30 | * This is only for internal list manipulation where we know 31 | * the prev/next entries already! 32 | */ 33 | static inline void __list_add(struct list_head *new, 34 | struct list_head *prev, 35 | struct list_head *next) 36 | { 37 | next->prev = new; 38 | new->next = next; 39 | new->prev = prev; 40 | prev->next = new; 41 | } 42 | 43 | /** 44 | * list_add - add a new entry 45 | * @new: new entry to be added 46 | * @head: list head to add it after 47 | * 48 | * Insert a new entry after the specified head. 49 | * This is good for implementing stacks. 50 | */ 51 | static inline void list_add(struct list_head *new, struct list_head *head) 52 | { 53 | __list_add(new, head, head->next); 54 | } 55 | 56 | /** 57 | * list_add_tail - add a new entry 58 | * @new: new entry to be added 59 | * @head: list head to add it before 60 | * 61 | * Insert a new entry before the specified head. 62 | * This is useful for implementing queues. 63 | */ 64 | static inline void list_add_tail(struct list_head *new, struct list_head *head) 65 | { 66 | __list_add(new, head->prev, head); 67 | } 68 | 69 | /* 70 | * Delete a list entry by making the prev/next entries 71 | * point to each other. 72 | * 73 | * This is only for internal list manipulation where we know 74 | * the prev/next entries already! 75 | */ 76 | static inline void __list_del(struct list_head *prev, struct list_head *next) 77 | { 78 | next->prev = prev; 79 | prev->next = next; 80 | } 81 | 82 | /** 83 | * list_del - deletes entry from list. 84 | * @entry: the element to delete from the list. 85 | * Note: list_empty on entry does not return true after this, the entry is in an undefined state. 86 | */ 87 | static inline void list_del(struct list_head *entry) 88 | { 89 | __list_del(entry->prev, entry->next); 90 | entry->next = (void *) 0; 91 | entry->prev = (void *) 0; 92 | } 93 | 94 | /** 95 | * list_del_init - deletes entry from list and reinitialize it. 96 | * @entry: the element to delete from the list. 97 | */ 98 | static inline void list_del_init(struct list_head *entry) 99 | { 100 | __list_del(entry->prev, entry->next); 101 | INIT_LIST_HEAD(entry); 102 | } 103 | 104 | /** 105 | * list_move - delete from one list and add as another's head 106 | * @list: the entry to move 107 | * @head: the head that will precede our entry 108 | */ 109 | static inline void list_move(struct list_head *list, struct list_head *head) 110 | { 111 | __list_del(list->prev, list->next); 112 | list_add(list, head); 113 | } 114 | 115 | /** 116 | * list_move_tail - delete from one list and add as another's tail 117 | * @list: the entry to move 118 | * @head: the head that will follow our entry 119 | */ 120 | static inline void list_move_tail(struct list_head *list, 121 | struct list_head *head) 122 | { 123 | __list_del(list->prev, list->next); 124 | list_add_tail(list, head); 125 | } 126 | 127 | /** 128 | * list_empty - tests whether a list is empty 129 | * @head: the list to test. 130 | */ 131 | static inline int list_empty(struct list_head *head) 132 | { 133 | return head->next == head; 134 | } 135 | 136 | static inline void __list_splice(struct list_head *list, 137 | struct list_head *head) 138 | { 139 | struct list_head *first = list->next; 140 | struct list_head *last = list->prev; 141 | struct list_head *at = head->next; 142 | 143 | first->prev = head; 144 | head->next = first; 145 | 146 | last->next = at; 147 | at->prev = last; 148 | } 149 | 150 | /** 151 | * list_splice - join two lists 152 | * @list: the new list to add. 153 | * @head: the place to add it in the first list. 154 | */ 155 | static inline void list_splice(struct list_head *list, struct list_head *head) 156 | { 157 | if (!list_empty(list)) 158 | __list_splice(list, head); 159 | } 160 | 161 | /** 162 | * list_splice_init - join two lists and reinitialise the emptied list. 163 | * @list: the new list to add. 164 | * @head: the place to add it in the first list. 165 | * 166 | * The list at @list is reinitialised 167 | */ 168 | static inline void list_splice_init(struct list_head *list, 169 | struct list_head *head) 170 | { 171 | if (!list_empty(list)) { 172 | __list_splice(list, head); 173 | INIT_LIST_HEAD(list); 174 | } 175 | } 176 | 177 | /** 178 | * list_entry - get the struct for this entry 179 | * @ptr: the &struct list_head pointer. 180 | * @type: the type of the struct this is embedded in. 181 | * @member: the name of the list_struct within the struct. 182 | */ 183 | #define list_entry(ptr, type, member) \ 184 | ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 185 | 186 | /** 187 | * list_for_each - iterate over a list 188 | * @pos: the &struct list_head to use as a loop counter. 189 | * @head: the head for your list. 190 | */ 191 | #define list_for_each(pos, head) \ 192 | for (pos = (head)->next; pos != (head); \ 193 | pos = pos->next) 194 | /** 195 | * list_for_each_prev - iterate over a list backwards 196 | * @pos: the &struct list_head to use as a loop counter. 197 | * @head: the head for your list. 198 | */ 199 | #define list_for_each_prev(pos, head) \ 200 | for (pos = (head)->prev; pos != (head); \ 201 | pos = pos->prev) 202 | 203 | /** 204 | * list_for_each_safe - iterate over a list safe against removal of list entry 205 | * @pos: the &struct list_head to use as a loop counter. 206 | * @n: another &struct list_head to use as temporary storage 207 | * @head: the head for your list. 208 | */ 209 | #define list_for_each_safe(pos, n, head) \ 210 | for (pos = (head)->next, n = pos->next; pos != (head); \ 211 | pos = n, n = pos->next) 212 | 213 | /** 214 | * list_for_each_entry - iterate over list of given type 215 | * @pos: the type * to use as a loop counter. 216 | * @head: the head for your list. 217 | * @member: the name of the list_struct within the struct. 218 | */ 219 | #define list_for_each_entry(pos, head, member) \ 220 | for (pos = list_entry((head)->next, typeof(*pos), member); \ 221 | &pos->member != (head); \ 222 | pos = list_entry(pos->member.next, typeof(*pos), member)) 223 | 224 | /** 225 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 226 | * @pos: the type * to use as a loop counter. 227 | * @n: another type * to use as temporary storage 228 | * @head: the head for your list. 229 | * @member: the name of the list_struct within the struct. 230 | */ 231 | #define list_for_each_entry_safe(pos, n, head, member) \ 232 | for (pos = list_entry((head)->next, typeof(*pos), member), \ 233 | n = list_entry(pos->member.next, typeof(*pos), member); \ 234 | &pos->member != (head); \ 235 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) 236 | 237 | /** 238 | * list_for_each_entry_continue - iterate over list of given type 239 | * continuing after existing point 240 | * @pos: the type * to use as a loop counter. 241 | * @head: the head for your list. 242 | * @member: the name of the list_struct within the struct. 243 | */ 244 | #define list_for_each_entry_continue(pos, head, member) \ 245 | for (pos = list_entry(pos->member.next, typeof(*pos), member), \ 246 | prefetch(pos->member.next); \ 247 | &pos->member != (head); \ 248 | pos = list_entry(pos->member.next, typeof(*pos), member), \ 249 | prefetch(pos->member.next)) 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /example-cfg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment1" : "Any long-format command line argument ", 3 | "_comment2" : "may be used in this JSON configuration file", 4 | 5 | "url" : "http://127.0.0.1:8332", 6 | "user" : "rpcuser", 7 | "pass" : "rpcpass", 8 | 9 | "algo" : "sse2_64", 10 | "threads" : "4", 11 | 12 | "quiet" : true 13 | } 14 | -------------------------------------------------------------------------------- /miner.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINER_H__ 2 | #define __MINER_H__ 3 | 4 | /* 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the Free 7 | * Software Foundation; either version 2 of the License, or (at your option) 8 | * any later version. See COPYING for more details. 9 | */ 10 | 11 | #include "cpuminer-config.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #ifdef STDC_HEADERS 21 | # include 22 | # include 23 | #else 24 | # ifdef HAVE_STDLIB_H 25 | # include 26 | # endif 27 | #endif 28 | #ifdef HAVE_ALLOCA_H 29 | # include 30 | #elif defined __GNUC__ 31 | # define alloca __builtin_alloca 32 | #elif defined _AIX 33 | # define alloca __alloca 34 | #elif defined _MSC_VER 35 | # include 36 | # define alloca _alloca 37 | #else 38 | # ifndef HAVE_ALLOCA 39 | # ifdef __cplusplus 40 | extern "C" 41 | # endif 42 | void *alloca (size_t); 43 | # endif 44 | #endif 45 | 46 | 47 | #ifdef __SSE2__ 48 | #define WANT_SSE2_4WAY 1 49 | #endif 50 | 51 | #if defined(__i386__) || defined(__x86_64__) 52 | #define WANT_VIA_PADLOCK 1 53 | #endif 54 | 55 | #if defined(__x86_64__) && defined(__SSE2__) && defined(HAS_YASM) 56 | #define WANT_X8664_SSE2 1 57 | #endif 58 | 59 | #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) 60 | #define WANT_BUILTIN_BSWAP 61 | #else 62 | #if HAVE_BYTESWAP_H 63 | #include 64 | #elif defined(USE_SYS_ENDIAN_H) 65 | #include 66 | #elif defined(__APPLE__) 67 | #include 68 | #define bswap_16 OSSwapInt16 69 | #define bswap_32 OSSwapInt32 70 | #define bswap_64 OSSwapInt64 71 | #else 72 | #define bswap_16(value) \ 73 | ((((value) & 0xff) << 8) | ((value) >> 8)) 74 | 75 | #define bswap_32(value) \ 76 | (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \ 77 | (uint32_t)bswap_16((uint16_t)((value) >> 16))) 78 | 79 | #define bswap_64(value) \ 80 | (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \ 81 | << 32) | \ 82 | (uint64_t)bswap_32((uint32_t)((value) >> 32))) 83 | #endif 84 | #endif /* !defined(__GLXBYTEORDER_H__) */ 85 | 86 | #ifdef HAVE_SYSLOG_H 87 | #include 88 | #else 89 | enum { 90 | LOG_ERR, 91 | LOG_WARNING, 92 | LOG_INFO, 93 | LOG_DEBUG, 94 | }; 95 | #endif 96 | 97 | #undef unlikely 98 | #undef likely 99 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) 100 | #define unlikely(expr) (__builtin_expect(!!(expr), 0)) 101 | #define likely(expr) (__builtin_expect(!!(expr), 1)) 102 | #else 103 | #define unlikely(expr) (expr) 104 | #define likely(expr) (expr) 105 | #endif 106 | 107 | #if defined(__i386__) 108 | #define WANT_CRYPTOPP_ASM32 109 | #endif 110 | 111 | #ifndef ARRAY_SIZE 112 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 113 | #endif 114 | 115 | struct thr_info { 116 | int id; 117 | pthread_t pth; 118 | struct thread_q *q; 119 | }; 120 | 121 | static inline uint32_t swab32(uint32_t v) 122 | { 123 | #ifdef WANT_BUILTIN_BSWAP 124 | return __builtin_bswap32(v); 125 | #else 126 | return bswap_32(v); 127 | #endif 128 | } 129 | 130 | static inline void swap256(void *dest_p, const void *src_p) 131 | { 132 | uint32_t *dest = dest_p; 133 | const uint32_t *src = src_p; 134 | 135 | dest[0] = src[7]; 136 | dest[1] = src[6]; 137 | dest[2] = src[5]; 138 | dest[3] = src[4]; 139 | dest[4] = src[3]; 140 | dest[5] = src[2]; 141 | dest[6] = src[1]; 142 | dest[7] = src[0]; 143 | } 144 | 145 | extern bool opt_debug; 146 | extern bool opt_protocol; 147 | extern const uint32_t sha256_init_state[]; 148 | extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, 149 | const char *rpc_req, bool, bool); 150 | extern char *bin2hex(const unsigned char *p, size_t len); 151 | extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); 152 | 153 | extern unsigned int ScanHash_4WaySSE2(int, const unsigned char *pmidstate, 154 | unsigned char *pdata, unsigned char *phash1, unsigned char *phash, 155 | const unsigned char *ptarget, 156 | uint32_t max_nonce, unsigned long *nHashesDone); 157 | 158 | extern unsigned int scanhash_sse2_amd64(int, const unsigned char *pmidstate, 159 | unsigned char *pdata, unsigned char *phash1, unsigned char *phash, 160 | const unsigned char *ptarget, 161 | uint32_t max_nonce, unsigned long *nHashesDone); 162 | 163 | extern bool scanhash_via(int, unsigned char *data_inout, 164 | const unsigned char *target, 165 | uint32_t max_nonce, unsigned long *hashes_done); 166 | 167 | extern bool scanhash_c(int, const unsigned char *midstate, unsigned char *data, 168 | unsigned char *hash, const unsigned char *target, 169 | uint32_t max_nonce, unsigned long *hashes_done); 170 | extern bool scanhash_cryptopp(int, const unsigned char *midstate,unsigned char *data, 171 | unsigned char *hash, const unsigned char *target, 172 | uint32_t max_nonce, unsigned long *hashes_done); 173 | extern bool scanhash_asm32(int, const unsigned char *midstate,unsigned char *data, 174 | unsigned char *hash, 175 | const unsigned char *target, 176 | uint32_t max_nonce, unsigned long *hashes_done); 177 | extern int scanhash_sse2_64(int, const unsigned char *pmidstate, unsigned char *pdata, 178 | unsigned char *phash1, unsigned char *phash, 179 | const unsigned char *ptarget, 180 | uint32_t max_nonce, unsigned long *nHashesDone); 181 | 182 | extern int 183 | timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y); 184 | 185 | extern bool fulltest(const unsigned char *hash, const unsigned char *target); 186 | 187 | extern int opt_scantime; 188 | extern bool want_longpoll; 189 | extern bool have_longpoll; 190 | struct thread_q; 191 | 192 | struct work_restart { 193 | volatile unsigned long restart; 194 | char padding[128 - sizeof(unsigned long)]; 195 | }; 196 | 197 | extern pthread_mutex_t time_lock; 198 | extern bool use_syslog; 199 | extern struct thr_info *thr_info; 200 | extern int longpoll_thr_id; 201 | extern struct work_restart *work_restart; 202 | 203 | extern void applog(int prio, const char *fmt, ...); 204 | extern struct thread_q *tq_new(void); 205 | extern void tq_free(struct thread_q *tq); 206 | extern bool tq_push(struct thread_q *tq, void *data); 207 | extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime); 208 | extern void tq_freeze(struct thread_q *tq); 209 | extern void tq_thaw(struct thread_q *tq); 210 | 211 | #endif /* __MINER_H__ */ 212 | -------------------------------------------------------------------------------- /mknsis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MINGW_PATH=/usr/i686-pc-mingw32/sys-root/mingw/bin 4 | 5 | OUT_BASE="cpuminer-installer" 6 | OUT_EXE="$OUT_BASE.exe" 7 | 8 | PATH=$PATH:$MINGW_PATH \ 9 | nsiswrapper --run \ 10 | --name "CPU miner" \ 11 | --outfile "$OUT_EXE" \ 12 | minerd.exe \ 13 | $MINGW_PATH/libcurl-4.dll=libcurl-4.dll \ 14 | $MINGW_PATH/pthreadgc2.dll=pthreadgc2.dll \ 15 | $MINGW_PATH/libidn-11.dll=libidn-11.dll \ 16 | $MINGW_PATH/libssh2-1.dll=libssh2-1.dll \ 17 | $MINGW_PATH/libssl-10.dll=libssl-10.dll \ 18 | $MINGW_PATH/zlib1.dll=zlib1.dll \ 19 | $MINGW_PATH/libcrypto-10.dll=libcrypto-10.dll \ 20 | $MINGW_PATH/libiconv-2.dll=libiconv-2.dll \ 21 | $MINGW_PATH/libintl-8.dll=libintl-8.dll 22 | 23 | chmod 0755 "$OUT_EXE" 24 | zip -9 "$OUT_BASE" "$OUT_EXE" 25 | rm -f "$OUT_EXE" 26 | 27 | chmod 0644 "$OUT_BASE.zip" 28 | 29 | echo -n "SHA1: " 30 | sha1sum "$OUT_BASE.zip" 31 | 32 | echo -n "MD5: " 33 | md5sum "$OUT_BASE.zip" 34 | 35 | -------------------------------------------------------------------------------- /sha256_4way.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 Satoshi Nakamoto 2 | // Distributed under the MIT/X11 software license, see the accompanying 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | // tcatm's 4-way 128-bit SSE2 SHA-256 6 | 7 | #include "cpuminer-config.h" 8 | #include "miner.h" 9 | 10 | #ifdef WANT_SSE2_4WAY 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #define NPAR 32 20 | 21 | static void DoubleBlockSHA256(const void* pin, void* pout, const void* pinit, unsigned int hash[8][NPAR], const void* init2); 22 | 23 | static const unsigned int sha256_consts[] = { 24 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, /* 0 */ 25 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 26 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, /* 8 */ 27 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 28 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, /* 16 */ 29 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 30 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, /* 24 */ 31 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 32 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, /* 32 */ 33 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 34 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, /* 40 */ 35 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 36 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, /* 48 */ 37 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 38 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, /* 56 */ 39 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 40 | }; 41 | 42 | 43 | static inline __m128i Ch(const __m128i b, const __m128i c, const __m128i d) { 44 | return _mm_xor_si128(_mm_and_si128(b,c),_mm_andnot_si128(b,d)); 45 | } 46 | 47 | static inline __m128i Maj(const __m128i b, const __m128i c, const __m128i d) { 48 | return _mm_xor_si128(_mm_and_si128(b,_mm_xor_si128(c,d)),_mm_and_si128(c,d)); 49 | } 50 | 51 | static __attribute__((always_inline)) __m128i ROTR(__m128i x, const int n) { 52 | return _mm_or_si128(_mm_srli_epi32(x, n),_mm_slli_epi32(x, 32 - n)); 53 | } 54 | 55 | static __attribute__((always_inline)) __m128i SHR(__m128i x, const int n) { 56 | return _mm_srli_epi32(x, n); 57 | } 58 | 59 | /* SHA256 Functions */ 60 | #define BIGSIGMA0_256(x) (_mm_xor_si128(_mm_xor_si128(ROTR((x), 2),ROTR((x), 13)),ROTR((x), 22))) 61 | #define BIGSIGMA1_256(x) (_mm_xor_si128(_mm_xor_si128(ROTR((x), 6),ROTR((x), 11)),ROTR((x), 25))) 62 | 63 | 64 | #define SIGMA0_256(x) (_mm_xor_si128(_mm_xor_si128(ROTR((x), 7),ROTR((x), 18)), SHR((x), 3 ))) 65 | #define SIGMA1_256(x) (_mm_xor_si128(_mm_xor_si128(ROTR((x),17),ROTR((x), 19)), SHR((x), 10))) 66 | 67 | static inline unsigned int store32(const __m128i x, int i) { 68 | union { unsigned int ret[4]; __m128i x; } box; 69 | box.x = x; 70 | return box.ret[i]; 71 | } 72 | 73 | static inline void store_epi32(const __m128i x, unsigned int *x0, unsigned int *x1, unsigned int *x2, unsigned int *x3) { 74 | union { unsigned int ret[4]; __m128i x; } box; 75 | box.x = x; 76 | *x0 = box.ret[3]; *x1 = box.ret[2]; *x2 = box.ret[1]; *x3 = box.ret[0]; 77 | } 78 | 79 | #define add4(x0, x1, x2, x3) _mm_add_epi32(_mm_add_epi32(x0, x1),_mm_add_epi32( x2,x3)) 80 | #define add5(x0, x1, x2, x3, x4) _mm_add_epi32(add4(x0, x1, x2, x3), x4) 81 | 82 | #define SHA256ROUND(a, b, c, d, e, f, g, h, i, w) \ 83 | T1 = add5(h, BIGSIGMA1_256(e), Ch(e, f, g), _mm_set1_epi32(sha256_consts[i]), w); \ 84 | d = _mm_add_epi32(d, T1); \ 85 | h = _mm_add_epi32(T1, _mm_add_epi32(BIGSIGMA0_256(a), Maj(a, b, c))); 86 | 87 | static inline void dumpreg(__m128i x, char *msg) { 88 | union { unsigned int ret[4]; __m128i x; } box; 89 | box.x = x ; 90 | printf("%s %08x %08x %08x %08x\n", msg, box.ret[0], box.ret[1], box.ret[2], box.ret[3]); 91 | } 92 | 93 | #if 1 94 | #define dumpstate(i) printf("%s: %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", \ 95 | __func__, store32(w0, i), store32(a, i), store32(b, i), store32(c, i), store32(d, i), store32(e, i), store32(f, i), store32(g, i), store32(h, i)); 96 | #else 97 | #define dumpstate() 98 | #endif 99 | 100 | static const unsigned int pSHA256InitState[8] = 101 | {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; 102 | 103 | 104 | unsigned int ScanHash_4WaySSE2(int thr_id, const unsigned char *pmidstate, 105 | unsigned char *pdata, 106 | unsigned char *phash1, unsigned char *phash, 107 | const unsigned char *ptarget, 108 | uint32_t max_nonce, unsigned long *nHashesDone) 109 | { 110 | unsigned int *nNonce_p = (unsigned int*)(pdata + 12); 111 | unsigned int nonce = 0; 112 | 113 | work_restart[thr_id].restart = 0; 114 | 115 | for (;;) 116 | { 117 | unsigned int thash[9][NPAR] __attribute__((aligned(128))); 118 | int j; 119 | 120 | nonce += NPAR; 121 | *nNonce_p = nonce; 122 | 123 | DoubleBlockSHA256(pdata, phash1, pmidstate, thash, pSHA256InitState); 124 | 125 | for (j = 0; j < NPAR; j++) 126 | { 127 | if (unlikely(thash[7][j] == 0)) 128 | { 129 | int i; 130 | 131 | for (i = 0; i < 32/4; i++) 132 | ((unsigned int*)phash)[i] = thash[i][j]; 133 | 134 | if (fulltest(phash, ptarget)) { 135 | *nHashesDone = nonce; 136 | *nNonce_p = nonce + j; 137 | return nonce + j; 138 | } 139 | } 140 | } 141 | 142 | if ((nonce >= max_nonce) || work_restart[thr_id].restart) 143 | { 144 | *nHashesDone = nonce; 145 | return -1; 146 | } 147 | } 148 | } 149 | 150 | 151 | static void DoubleBlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init) 152 | { 153 | unsigned int* In = (unsigned int*)pin; 154 | unsigned int* Pad = (unsigned int*)pad; 155 | unsigned int* hPre = (unsigned int*)pre; 156 | unsigned int* hInit = (unsigned int*)init; 157 | unsigned int /* i, j, */ k; 158 | 159 | /* vectors used in calculation */ 160 | __m128i w0, w1, w2, w3, w4, w5, w6, w7; 161 | __m128i w8, w9, w10, w11, w12, w13, w14, w15; 162 | __m128i T1; 163 | __m128i a, b, c, d, e, f, g, h; 164 | __m128i nonce, preNonce; 165 | 166 | /* nonce offset for vector */ 167 | __m128i offset = _mm_set_epi32(0x00000003, 0x00000002, 0x00000001, 0x00000000); 168 | 169 | 170 | preNonce = _mm_add_epi32(_mm_set1_epi32(In[3]), offset); 171 | 172 | for(k = 0; k 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "miner.h" 10 | 11 | typedef uint32_t word32; 12 | 13 | static word32 rotrFixed(word32 word, unsigned int shift) 14 | { 15 | return (word >> shift) | (word << (32 - shift)); 16 | } 17 | 18 | #define blk0(i) (W[i] = data[i]) 19 | 20 | static const word32 SHA256_K[64] = { 21 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 22 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 23 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 24 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 25 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 26 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 27 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 28 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 29 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 30 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 31 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 32 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 33 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 34 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 35 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 36 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 37 | }; 38 | 39 | #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) 40 | 41 | #define Ch(x,y,z) (z^(x&(y^z))) 42 | #define Maj(x,y,z) (y^((x^y)&(y^z))) 43 | 44 | #define a(i) T[(0-i)&7] 45 | #define b(i) T[(1-i)&7] 46 | #define c(i) T[(2-i)&7] 47 | #define d(i) T[(3-i)&7] 48 | #define e(i) T[(4-i)&7] 49 | #define f(i) T[(5-i)&7] 50 | #define g(i) T[(6-i)&7] 51 | #define h(i) T[(7-i)&7] 52 | 53 | #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ 54 | d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) 55 | 56 | // for SHA256 57 | #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) 58 | #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) 59 | #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) 60 | #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) 61 | 62 | static void SHA256_Transform(word32 *state, const word32 *data) 63 | { 64 | word32 W[16] = { }; 65 | word32 T[8]; 66 | unsigned int j; 67 | 68 | /* Copy context->state[] to working vars */ 69 | memcpy(T, state, sizeof(T)); 70 | /* 64 operations, partially loop unrolled */ 71 | for (j=0; j<64; j+=16) 72 | { 73 | R( 0); R( 1); R( 2); R( 3); 74 | R( 4); R( 5); R( 6); R( 7); 75 | R( 8); R( 9); R(10); R(11); 76 | R(12); R(13); R(14); R(15); 77 | } 78 | /* Add the working vars back into context.state[] */ 79 | state[0] += a(0); 80 | state[1] += b(0); 81 | state[2] += c(0); 82 | state[3] += d(0); 83 | state[4] += e(0); 84 | state[5] += f(0); 85 | state[6] += g(0); 86 | state[7] += h(0); 87 | } 88 | 89 | static void runhash(void *state, const void *input, const void *init) 90 | { 91 | memcpy(state, init, 32); 92 | SHA256_Transform(state, input); 93 | } 94 | 95 | /* suspiciously similar to ScanHash* from bitcoin */ 96 | bool scanhash_cryptopp(int thr_id, const unsigned char *midstate, 97 | unsigned char *data, unsigned char *hash, 98 | const unsigned char *target, 99 | uint32_t max_nonce, unsigned long *hashes_done) 100 | { 101 | uint32_t *hash32 = (uint32_t *) hash; 102 | uint32_t *nonce = (uint32_t *)(data + 12); 103 | uint32_t n = 0; 104 | unsigned long stat_ctr = 0; 105 | 106 | work_restart[thr_id].restart = 0; 107 | 108 | while (1) { 109 | unsigned char hash1[32]; 110 | 111 | n++; 112 | *nonce = n; 113 | 114 | runhash(hash1, data, midstate); 115 | runhash(hash, hash1, sha256_init_state); 116 | 117 | stat_ctr++; 118 | 119 | if (unlikely((hash32[7] == 0) && fulltest(hash, target))) { 120 | *hashes_done = stat_ctr; 121 | return true; 122 | } 123 | 124 | if ((n >= max_nonce) || work_restart[thr_id].restart) { 125 | *hashes_done = stat_ctr; 126 | return false; 127 | } 128 | } 129 | } 130 | 131 | #if defined(WANT_CRYPTOPP_ASM32) 132 | 133 | #define CRYPTOPP_FASTCALL 134 | #define CRYPTOPP_BOOL_X86 1 135 | #define CRYPTOPP_BOOL_X64 0 136 | #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0 137 | 138 | #ifdef CRYPTOPP_GENERATE_X64_MASM 139 | #define AS1(x) x*newline* 140 | #define AS2(x, y) x, y*newline* 141 | #define AS3(x, y, z) x, y, z*newline* 142 | #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline* 143 | #define ASL(x) label##x:*newline* 144 | #define ASJ(x, y, z) x label##y*newline* 145 | #define ASC(x, y) x label##y*newline* 146 | #define AS_HEX(y) 0##y##h 147 | #elif defined(_MSC_VER) || defined(__BORLANDC__) 148 | #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 149 | #define AS1(x) __asm {x} 150 | #define AS2(x, y) __asm {x, y} 151 | #define AS3(x, y, z) __asm {x, y, z} 152 | #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)} 153 | #define ASL(x) __asm {label##x:} 154 | #define ASJ(x, y, z) __asm {x label##y} 155 | #define ASC(x, y) __asm {x label##y} 156 | #define CRYPTOPP_NAKED __declspec(naked) 157 | #define AS_HEX(y) 0x##y 158 | #else 159 | #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY 160 | // define these in two steps to allow arguments to be expanded 161 | #define GNU_AS1(x) #x ";" 162 | #define GNU_AS2(x, y) #x ", " #y ";" 163 | #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" 164 | #define GNU_ASL(x) "\n" #x ":" 165 | #define GNU_ASJ(x, y, z) #x " " #y #z ";" 166 | #define AS1(x) GNU_AS1(x) 167 | #define AS2(x, y) GNU_AS2(x, y) 168 | #define AS3(x, y, z) GNU_AS3(x, y, z) 169 | #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" 170 | #define ASL(x) GNU_ASL(x) 171 | #define ASJ(x, y, z) GNU_ASJ(x, y, z) 172 | #define ASC(x, y) #x " " #y ";" 173 | #define CRYPTOPP_NAKED 174 | #define AS_HEX(y) 0x##y 175 | #endif 176 | 177 | #define IF0(y) 178 | #define IF1(y) y 179 | 180 | #ifdef CRYPTOPP_GENERATE_X64_MASM 181 | #define ASM_MOD(x, y) ((x) MOD (y)) 182 | #define XMMWORD_PTR XMMWORD PTR 183 | #else 184 | // GNU assembler doesn't seem to have mod operator 185 | #define ASM_MOD(x, y) ((x)-((x)/(y))*(y)) 186 | // GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM 187 | #define XMMWORD_PTR 188 | #endif 189 | 190 | #if CRYPTOPP_BOOL_X86 191 | #define AS_REG_1 ecx 192 | #define AS_REG_2 edx 193 | #define AS_REG_3 esi 194 | #define AS_REG_4 edi 195 | #define AS_REG_5 eax 196 | #define AS_REG_6 ebx 197 | #define AS_REG_7 ebp 198 | #define AS_REG_1d ecx 199 | #define AS_REG_2d edx 200 | #define AS_REG_3d esi 201 | #define AS_REG_4d edi 202 | #define AS_REG_5d eax 203 | #define AS_REG_6d ebx 204 | #define AS_REG_7d ebp 205 | #define WORD_SZ 4 206 | #define WORD_REG(x) e##x 207 | #define WORD_PTR DWORD PTR 208 | #define AS_PUSH_IF86(x) AS1(push e##x) 209 | #define AS_POP_IF86(x) AS1(pop e##x) 210 | #define AS_JCXZ jecxz 211 | #elif CRYPTOPP_BOOL_X64 212 | #ifdef CRYPTOPP_GENERATE_X64_MASM 213 | #define AS_REG_1 rcx 214 | #define AS_REG_2 rdx 215 | #define AS_REG_3 r8 216 | #define AS_REG_4 r9 217 | #define AS_REG_5 rax 218 | #define AS_REG_6 r10 219 | #define AS_REG_7 r11 220 | #define AS_REG_1d ecx 221 | #define AS_REG_2d edx 222 | #define AS_REG_3d r8d 223 | #define AS_REG_4d r9d 224 | #define AS_REG_5d eax 225 | #define AS_REG_6d r10d 226 | #define AS_REG_7d r11d 227 | #else 228 | #define AS_REG_1 rdi 229 | #define AS_REG_2 rsi 230 | #define AS_REG_3 rdx 231 | #define AS_REG_4 rcx 232 | #define AS_REG_5 r8 233 | #define AS_REG_6 r9 234 | #define AS_REG_7 r10 235 | #define AS_REG_1d edi 236 | #define AS_REG_2d esi 237 | #define AS_REG_3d edx 238 | #define AS_REG_4d ecx 239 | #define AS_REG_5d r8d 240 | #define AS_REG_6d r9d 241 | #define AS_REG_7d r10d 242 | #endif 243 | #define WORD_SZ 8 244 | #define WORD_REG(x) r##x 245 | #define WORD_PTR QWORD PTR 246 | #define AS_PUSH_IF86(x) 247 | #define AS_POP_IF86(x) 248 | #define AS_JCXZ jrcxz 249 | #endif 250 | 251 | static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len 252 | #if defined(_MSC_VER) && (_MSC_VER == 1200) 253 | , ... // VC60 workaround: prevent VC 6 from inlining this function 254 | #endif 255 | ) 256 | { 257 | #if defined(_MSC_VER) && (_MSC_VER == 1200) 258 | AS2(mov ecx, [state]) 259 | AS2(mov edx, [data]) 260 | #endif 261 | 262 | #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ 263 | #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4] 264 | #define G(i) H(i+1) 265 | #define F(i) H(i+2) 266 | #define E(i) H(i+3) 267 | #define D(i) H(i+4) 268 | #define C(i) H(i+5) 269 | #define B(i) H(i+6) 270 | #define A(i) H(i+7) 271 | #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4 272 | #define Wt_2(i) Wt((i)-2) 273 | #define Wt_15(i) Wt((i)-15) 274 | #define Wt_7(i) Wt((i)-7) 275 | #define K_END [BASE+8*4+16*4+0*WORD_SZ] 276 | #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ] 277 | #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ] 278 | #define DATA_END [BASE+8*4+16*4+3*WORD_SZ] 279 | #define Kt(i) WORD_REG(si)+(i)*4 280 | #if CRYPTOPP_BOOL_X86 281 | #define BASE esp+4 282 | #elif defined(__GNUC__) 283 | #define BASE r8 284 | #else 285 | #define BASE rsp 286 | #endif 287 | 288 | #define RA0(i, edx, edi) \ 289 | AS2( add edx, [Kt(i)] )\ 290 | AS2( add edx, [Wt(i)] )\ 291 | AS2( add edx, H(i) )\ 292 | 293 | #define RA1(i, edx, edi) 294 | 295 | #define RB0(i, edx, edi) 296 | 297 | #define RB1(i, edx, edi) \ 298 | AS2( mov AS_REG_7d, [Wt_2(i)] )\ 299 | AS2( mov edi, [Wt_15(i)])\ 300 | AS2( mov ebx, AS_REG_7d )\ 301 | AS2( shr AS_REG_7d, 10 )\ 302 | AS2( ror ebx, 17 )\ 303 | AS2( xor AS_REG_7d, ebx )\ 304 | AS2( ror ebx, 2 )\ 305 | AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\ 306 | AS2( add ebx, [Wt_7(i)])\ 307 | AS2( mov AS_REG_7d, edi )\ 308 | AS2( shr AS_REG_7d, 3 )\ 309 | AS2( ror edi, 7 )\ 310 | AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\ 311 | AS2( xor AS_REG_7d, edi )\ 312 | AS2( add edx, [Kt(i)])\ 313 | AS2( ror edi, 11 )\ 314 | AS2( add edx, H(i) )\ 315 | AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\ 316 | AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\ 317 | AS2( mov [Wt(i)], AS_REG_7d)\ 318 | AS2( add edx, AS_REG_7d )\ 319 | 320 | #define ROUND(i, r, eax, ecx, edi, edx)\ 321 | /* in: edi = E */\ 322 | /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\ 323 | AS2( mov edx, F(i) )\ 324 | AS2( xor edx, G(i) )\ 325 | AS2( and edx, edi )\ 326 | AS2( xor edx, G(i) )/* Ch(E,F,G) = (G^(E&(F^G))) */\ 327 | AS2( mov AS_REG_7d, edi )\ 328 | AS2( ror edi, 6 )\ 329 | AS2( ror AS_REG_7d, 25 )\ 330 | RA##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ 331 | AS2( xor AS_REG_7d, edi )\ 332 | AS2( ror edi, 5 )\ 333 | AS2( xor AS_REG_7d, edi )/* S1(E) */\ 334 | AS2( add edx, AS_REG_7d )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\ 335 | RB##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ 336 | /* in: ecx = A, eax = B^C, edx = T1 */\ 337 | /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\ 338 | AS2( mov ebx, ecx )\ 339 | AS2( xor ecx, B(i) )/* A^B */\ 340 | AS2( and eax, ecx )\ 341 | AS2( xor eax, B(i) )/* Maj(A,B,C) = B^((A^B)&(B^C) */\ 342 | AS2( mov AS_REG_7d, ebx )\ 343 | AS2( ror ebx, 2 )\ 344 | AS2( add eax, edx )/* T1 + Maj(A,B,C) */\ 345 | AS2( add edx, D(i) )\ 346 | AS2( mov D(i), edx )\ 347 | AS2( ror AS_REG_7d, 22 )\ 348 | AS2( xor AS_REG_7d, ebx )\ 349 | AS2( ror ebx, 11 )\ 350 | AS2( xor AS_REG_7d, ebx )\ 351 | AS2( add eax, AS_REG_7d )/* T1 + S0(A) + Maj(A,B,C) */\ 352 | AS2( mov H(i), eax )\ 353 | 354 | #define SWAP_COPY(i) \ 355 | AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\ 356 | AS1( bswap WORD_REG(bx))\ 357 | AS2( mov [Wt(i*(1+CRYPTOPP_BOOL_X64)+CRYPTOPP_BOOL_X64)], WORD_REG(bx)) 358 | 359 | #if defined(__GNUC__) 360 | #if CRYPTOPP_BOOL_X64 361 | FixedSizeAlignedSecBlock workspace; 362 | #endif 363 | __asm__ __volatile__ 364 | ( 365 | #if CRYPTOPP_BOOL_X64 366 | "lea %4, %%r8;" 367 | #endif 368 | ".intel_syntax noprefix;" 369 | #elif defined(CRYPTOPP_GENERATE_X64_MASM) 370 | ALIGN 8 371 | X86_SHA256_HashBlocks PROC FRAME 372 | rex_push_reg rsi 373 | push_reg rdi 374 | push_reg rbx 375 | push_reg rbp 376 | alloc_stack(LOCALS_SIZE+8) 377 | .endprolog 378 | mov rdi, r8 379 | lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4] 380 | #endif 381 | 382 | #if CRYPTOPP_BOOL_X86 383 | #ifndef __GNUC__ 384 | AS2( mov edi, [len]) 385 | AS2( lea WORD_REG(si), [SHA256_K+48*4]) 386 | #endif 387 | #if !defined(_MSC_VER) || (_MSC_VER < 1400) 388 | AS_PUSH_IF86(bx) 389 | #endif 390 | 391 | AS_PUSH_IF86(bp) 392 | AS2( mov ebx, esp) 393 | AS2( and esp, -16) 394 | AS2( sub WORD_REG(sp), LOCALS_SIZE) 395 | AS_PUSH_IF86(bx) 396 | #endif 397 | AS2( mov STATE_SAVE, WORD_REG(cx)) 398 | AS2( mov DATA_SAVE, WORD_REG(dx)) 399 | AS2( lea WORD_REG(ax), [WORD_REG(di) + WORD_REG(dx)]) 400 | AS2( mov DATA_END, WORD_REG(ax)) 401 | AS2( mov K_END, WORD_REG(si)) 402 | 403 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 404 | #if CRYPTOPP_BOOL_X86 405 | AS2( test edi, 1) 406 | ASJ( jnz, 2, f) 407 | AS1( dec DWORD PTR K_END) 408 | #endif 409 | AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16]) 410 | AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16]) 411 | #endif 412 | 413 | #if CRYPTOPP_BOOL_X86 414 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 415 | ASJ( jmp, 0, f) 416 | #endif 417 | ASL(2) // non-SSE2 418 | AS2( mov esi, ecx) 419 | AS2( lea edi, A(0)) 420 | AS2( mov ecx, 8) 421 | AS1( rep movsd) 422 | AS2( mov esi, K_END) 423 | ASJ( jmp, 3, f) 424 | #endif 425 | 426 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 427 | ASL(0) 428 | AS2( movdqa E(0), xmm1) 429 | AS2( movdqa A(0), xmm0) 430 | #endif 431 | #if CRYPTOPP_BOOL_X86 432 | ASL(3) 433 | #endif 434 | AS2( sub WORD_REG(si), 48*4) 435 | SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3) 436 | SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7) 437 | #if CRYPTOPP_BOOL_X86 438 | SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11) 439 | SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15) 440 | #endif 441 | AS2( mov edi, E(0)) // E 442 | AS2( mov eax, B(0)) // B 443 | AS2( xor eax, C(0)) // B^C 444 | AS2( mov ecx, A(0)) // A 445 | 446 | ROUND(0, 0, eax, ecx, edi, edx) 447 | ROUND(1, 0, ecx, eax, edx, edi) 448 | ROUND(2, 0, eax, ecx, edi, edx) 449 | ROUND(3, 0, ecx, eax, edx, edi) 450 | ROUND(4, 0, eax, ecx, edi, edx) 451 | ROUND(5, 0, ecx, eax, edx, edi) 452 | ROUND(6, 0, eax, ecx, edi, edx) 453 | ROUND(7, 0, ecx, eax, edx, edi) 454 | ROUND(8, 0, eax, ecx, edi, edx) 455 | ROUND(9, 0, ecx, eax, edx, edi) 456 | ROUND(10, 0, eax, ecx, edi, edx) 457 | ROUND(11, 0, ecx, eax, edx, edi) 458 | ROUND(12, 0, eax, ecx, edi, edx) 459 | ROUND(13, 0, ecx, eax, edx, edi) 460 | ROUND(14, 0, eax, ecx, edi, edx) 461 | ROUND(15, 0, ecx, eax, edx, edi) 462 | 463 | ASL(1) 464 | AS2(add WORD_REG(si), 4*16) 465 | ROUND(0, 1, eax, ecx, edi, edx) 466 | ROUND(1, 1, ecx, eax, edx, edi) 467 | ROUND(2, 1, eax, ecx, edi, edx) 468 | ROUND(3, 1, ecx, eax, edx, edi) 469 | ROUND(4, 1, eax, ecx, edi, edx) 470 | ROUND(5, 1, ecx, eax, edx, edi) 471 | ROUND(6, 1, eax, ecx, edi, edx) 472 | ROUND(7, 1, ecx, eax, edx, edi) 473 | ROUND(8, 1, eax, ecx, edi, edx) 474 | ROUND(9, 1, ecx, eax, edx, edi) 475 | ROUND(10, 1, eax, ecx, edi, edx) 476 | ROUND(11, 1, ecx, eax, edx, edi) 477 | ROUND(12, 1, eax, ecx, edi, edx) 478 | ROUND(13, 1, ecx, eax, edx, edi) 479 | ROUND(14, 1, eax, ecx, edi, edx) 480 | ROUND(15, 1, ecx, eax, edx, edi) 481 | AS2( cmp WORD_REG(si), K_END) 482 | ASJ( jb, 1, b) 483 | 484 | AS2( mov WORD_REG(dx), DATA_SAVE) 485 | AS2( add WORD_REG(dx), 64) 486 | AS2( mov AS_REG_7, STATE_SAVE) 487 | AS2( mov DATA_SAVE, WORD_REG(dx)) 488 | 489 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 490 | #if CRYPTOPP_BOOL_X86 491 | AS2( test DWORD PTR K_END, 1) 492 | ASJ( jz, 4, f) 493 | #endif 494 | AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16]) 495 | AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16]) 496 | AS2( paddd xmm1, E(0)) 497 | AS2( paddd xmm0, A(0)) 498 | AS2( movdqa [AS_REG_7+1*16], xmm1) 499 | AS2( movdqa [AS_REG_7+0*16], xmm0) 500 | AS2( cmp WORD_REG(dx), DATA_END) 501 | ASJ( jb, 0, b) 502 | #endif 503 | 504 | #if CRYPTOPP_BOOL_X86 505 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 506 | ASJ( jmp, 5, f) 507 | ASL(4) // non-SSE2 508 | #endif 509 | AS2( add [AS_REG_7+0*4], ecx) // A 510 | AS2( add [AS_REG_7+4*4], edi) // E 511 | AS2( mov eax, B(0)) 512 | AS2( mov ebx, C(0)) 513 | AS2( mov ecx, D(0)) 514 | AS2( add [AS_REG_7+1*4], eax) 515 | AS2( add [AS_REG_7+2*4], ebx) 516 | AS2( add [AS_REG_7+3*4], ecx) 517 | AS2( mov eax, F(0)) 518 | AS2( mov ebx, G(0)) 519 | AS2( mov ecx, H(0)) 520 | AS2( add [AS_REG_7+5*4], eax) 521 | AS2( add [AS_REG_7+6*4], ebx) 522 | AS2( add [AS_REG_7+7*4], ecx) 523 | AS2( mov ecx, AS_REG_7d) 524 | AS2( cmp WORD_REG(dx), DATA_END) 525 | ASJ( jb, 2, b) 526 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 527 | ASL(5) 528 | #endif 529 | #endif 530 | 531 | AS_POP_IF86(sp) 532 | AS_POP_IF86(bp) 533 | #if !defined(_MSC_VER) || (_MSC_VER < 1400) 534 | AS_POP_IF86(bx) 535 | #endif 536 | 537 | #ifdef CRYPTOPP_GENERATE_X64_MASM 538 | add rsp, LOCALS_SIZE+8 539 | pop rbp 540 | pop rbx 541 | pop rdi 542 | pop rsi 543 | ret 544 | X86_SHA256_HashBlocks ENDP 545 | #endif 546 | 547 | #ifdef __GNUC__ 548 | ".att_syntax prefix;" 549 | : 550 | : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len) 551 | #if CRYPTOPP_BOOL_X64 552 | , "m" (workspace[0]) 553 | #endif 554 | : "memory", "cc", "%eax" 555 | #if CRYPTOPP_BOOL_X64 556 | , "%rbx", "%r8", "%r10" 557 | #endif 558 | ); 559 | #endif 560 | } 561 | 562 | static inline bool HasSSE2(void) { return false; } 563 | 564 | static void SHA256_Transform32(word32 *state, const word32 *data) 565 | { 566 | word32 W[16]; 567 | int i; 568 | 569 | for (i = 0; i < 16; i++) 570 | W[i] = swab32(((word32 *)(data))[i]); 571 | 572 | X86_SHA256_HashBlocks(state, W, 16 * 4); 573 | } 574 | 575 | static void runhash32(void *state, const void *input, const void *init) 576 | { 577 | memcpy(state, init, 32); 578 | SHA256_Transform32(state, input); 579 | } 580 | 581 | /* suspiciously similar to ScanHash* from bitcoin */ 582 | bool scanhash_asm32(int thr_id, const unsigned char *midstate, 583 | unsigned char *data, unsigned char *hash, 584 | const unsigned char *target, 585 | uint32_t max_nonce, unsigned long *hashes_done) 586 | { 587 | uint32_t *hash32 = (uint32_t *) hash; 588 | uint32_t *nonce = (uint32_t *)(data + 12); 589 | uint32_t n = 0; 590 | unsigned long stat_ctr = 0; 591 | 592 | work_restart[thr_id].restart = 0; 593 | 594 | while (1) { 595 | unsigned char hash1[32]; 596 | 597 | n++; 598 | *nonce = n; 599 | 600 | runhash32(hash1, data, midstate); 601 | runhash32(hash, hash1, sha256_init_state); 602 | 603 | stat_ctr++; 604 | 605 | if (unlikely((hash32[7] == 0) && fulltest(hash, target))) { 606 | *hashes_done = stat_ctr; 607 | return true; 608 | } 609 | 610 | if ((n >= max_nonce) || work_restart[thr_id].restart) { 611 | *hashes_done = stat_ctr; 612 | return false; 613 | } 614 | } 615 | } 616 | 617 | #endif // #if defined(WANT_CRYPTOPP_ASM32) 618 | -------------------------------------------------------------------------------- /sha256_generic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cryptographic API. 3 | * 4 | * SHA-256, as specified in 5 | * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf 6 | * 7 | * SHA-256 code by Jean-Luc Cooke . 8 | * 9 | * Copyright (c) Jean-Luc Cooke 10 | * Copyright (c) Andrew McDonald 11 | * Copyright (c) 2002 James Morris 12 | * SHA224 Support Copyright 2007 Intel Corporation 13 | * 14 | * This program is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU General Public License as published by the Free 16 | * Software Foundation; either version 2 of the License, or (at your option) 17 | * any later version. 18 | * 19 | */ 20 | 21 | #include "cpuminer-config.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "miner.h" 28 | 29 | typedef uint32_t u32; 30 | typedef uint8_t u8; 31 | 32 | static inline u32 ror32(u32 word, unsigned int shift) 33 | { 34 | return (word >> shift) | (word << (32 - shift)); 35 | } 36 | 37 | static inline u32 Ch(u32 x, u32 y, u32 z) 38 | { 39 | return z ^ (x & (y ^ z)); 40 | } 41 | 42 | static inline u32 Maj(u32 x, u32 y, u32 z) 43 | { 44 | return (x & y) | (z & (x | y)); 45 | } 46 | 47 | #define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22)) 48 | #define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25)) 49 | #define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3)) 50 | #define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10)) 51 | 52 | static inline void LOAD_OP(int I, u32 *W, const u8 *input) 53 | { 54 | /* byteswap is commented out, because bitcoin input 55 | * is already big-endian 56 | */ 57 | W[I] = /* ntohl */ ( ((u32*)(input))[I] ); 58 | } 59 | 60 | static inline void BLEND_OP(int I, u32 *W) 61 | { 62 | W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; 63 | } 64 | 65 | static void sha256_transform(u32 *state, const u8 *input) 66 | { 67 | u32 a, b, c, d, e, f, g, h, t1, t2; 68 | u32 W[64]; 69 | int i; 70 | 71 | /* load the input */ 72 | for (i = 0; i < 16; i++) 73 | LOAD_OP(i, W, input); 74 | 75 | /* now blend */ 76 | for (i = 16; i < 64; i++) 77 | BLEND_OP(i, W); 78 | 79 | /* load the state into our registers */ 80 | a=state[0]; b=state[1]; c=state[2]; d=state[3]; 81 | e=state[4]; f=state[5]; g=state[6]; h=state[7]; 82 | 83 | /* now iterate */ 84 | t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0]; 85 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 86 | t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1]; 87 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 88 | t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2]; 89 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 90 | t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3]; 91 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 92 | t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4]; 93 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 94 | t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5]; 95 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 96 | t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6]; 97 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 98 | t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7]; 99 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 100 | 101 | t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8]; 102 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 103 | t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9]; 104 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 105 | t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10]; 106 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 107 | t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11]; 108 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 109 | t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12]; 110 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 111 | t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13]; 112 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 113 | t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14]; 114 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 115 | t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15]; 116 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 117 | 118 | t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16]; 119 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 120 | t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17]; 121 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 122 | t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18]; 123 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 124 | t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19]; 125 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 126 | t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20]; 127 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 128 | t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21]; 129 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 130 | t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22]; 131 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 132 | t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23]; 133 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 134 | 135 | t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24]; 136 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 137 | t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25]; 138 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 139 | t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26]; 140 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 141 | t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27]; 142 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 143 | t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28]; 144 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 145 | t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29]; 146 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 147 | t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30]; 148 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 149 | t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31]; 150 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 151 | 152 | t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32]; 153 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 154 | t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33]; 155 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 156 | t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34]; 157 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 158 | t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35]; 159 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 160 | t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36]; 161 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 162 | t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37]; 163 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 164 | t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38]; 165 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 166 | t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39]; 167 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 168 | 169 | t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40]; 170 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 171 | t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41]; 172 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 173 | t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42]; 174 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 175 | t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43]; 176 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 177 | t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44]; 178 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 179 | t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45]; 180 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 181 | t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46]; 182 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 183 | t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47]; 184 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 185 | 186 | t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48]; 187 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 188 | t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49]; 189 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 190 | t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50]; 191 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 192 | t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51]; 193 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 194 | t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52]; 195 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 196 | t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53]; 197 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 198 | t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54]; 199 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 200 | t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55]; 201 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 202 | 203 | t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56]; 204 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; 205 | t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57]; 206 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; 207 | t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58]; 208 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; 209 | t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59]; 210 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; 211 | t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60]; 212 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; 213 | t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61]; 214 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; 215 | t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62]; 216 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; 217 | t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63]; 218 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; 219 | 220 | state[0] += a; state[1] += b; state[2] += c; state[3] += d; 221 | state[4] += e; state[5] += f; state[6] += g; state[7] += h; 222 | 223 | #if 0 224 | /* clear any sensitive info... */ 225 | a = b = c = d = e = f = g = h = t1 = t2 = 0; 226 | memset(W, 0, 64 * sizeof(u32)); 227 | #endif 228 | } 229 | 230 | static void runhash(void *state, const void *input, const void *init) 231 | { 232 | memcpy(state, init, 32); 233 | sha256_transform(state, input); 234 | } 235 | 236 | const uint32_t sha256_init_state[8] = { 237 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 238 | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 239 | }; 240 | 241 | /* suspiciously similar to ScanHash* from bitcoin */ 242 | bool scanhash_c(int thr_id, const unsigned char *midstate, unsigned char *data, 243 | unsigned char *hash, const unsigned char *target, 244 | uint32_t max_nonce, unsigned long *hashes_done) 245 | { 246 | uint32_t *hash32 = (uint32_t *) hash; 247 | uint32_t *nonce = (uint32_t *)(data + 12); 248 | uint32_t n = 0; 249 | unsigned long stat_ctr = 0; 250 | 251 | work_restart[thr_id].restart = 0; 252 | 253 | while (1) { 254 | unsigned char hash1[32]; 255 | 256 | n++; 257 | *nonce = n; 258 | 259 | runhash(hash1, data, midstate); 260 | runhash(hash, hash1, sha256_init_state); 261 | 262 | stat_ctr++; 263 | 264 | if (unlikely((hash32[7] == 0) && fulltest(hash, target))) { 265 | *hashes_done = stat_ctr; 266 | return true; 267 | } 268 | 269 | if ((n >= max_nonce) || work_restart[thr_id].restart) { 270 | *hashes_done = stat_ctr; 271 | return false; 272 | } 273 | } 274 | } 275 | 276 | -------------------------------------------------------------------------------- /sha256_sse2_amd64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SHA-256 driver for ASM routine for x86_64 on Linux 3 | * Copyright (c) Mark Crichton 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the Free 7 | * Software Foundation; either version 2 of the License, or (at your option) 8 | * any later version. 9 | * 10 | */ 11 | 12 | #include "cpuminer-config.h" 13 | 14 | #include "miner.h" 15 | 16 | #ifdef WANT_X8664_SSE2 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | extern void CalcSha256_x64(__m128i *res, __m128i *data, uint32_t init[8]); 26 | 27 | uint32_t g_sha256_k[] = { 28 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, /* 0 */ 29 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 30 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, /* 8 */ 31 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 32 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, /* 16 */ 33 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 34 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, /* 24 */ 35 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 36 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, /* 32 */ 37 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 38 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, /* 40 */ 39 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 40 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, /* 48 */ 41 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 42 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, /* 56 */ 43 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 44 | }; 45 | 46 | 47 | uint32_t g_sha256_hinit[8] = 48 | {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; 49 | 50 | __m128i g_4sha256_k[64]; 51 | 52 | int scanhash_sse2_64(int thr_id, const unsigned char *pmidstate, 53 | unsigned char *pdata, 54 | unsigned char *phash1, unsigned char *phash, 55 | const unsigned char *ptarget, 56 | uint32_t max_nonce, unsigned long *nHashesDone) 57 | { 58 | uint32_t *nNonce_p = (uint32_t *)(pdata + 12); 59 | uint32_t nonce = 0; 60 | uint32_t m_midstate[8], m_w[16], m_w1[16]; 61 | __m128i m_4w[64], m_4hash[64], m_4hash1[64]; 62 | __m128i offset; 63 | int i; 64 | 65 | work_restart[thr_id].restart = 0; 66 | 67 | /* For debugging */ 68 | union { 69 | __m128i m; 70 | uint32_t i[4]; 71 | } mi; 72 | 73 | /* Message expansion */ 74 | memcpy(m_midstate, pmidstate, sizeof(m_midstate)); 75 | memcpy(m_w, pdata, sizeof(m_w)); /* The 2nd half of the data */ 76 | memcpy(m_w1, phash1, sizeof(m_w1)); 77 | memset(m_4hash, 0, sizeof(m_4hash)); 78 | 79 | /* Transmongrify */ 80 | for (i = 0; i < 16; i++) 81 | m_4w[i] = _mm_set1_epi32(m_w[i]); 82 | 83 | for (i = 0; i < 16; i++) 84 | m_4hash1[i] = _mm_set1_epi32(m_w1[i]); 85 | 86 | for (i = 0; i < 64; i++) 87 | g_4sha256_k[i] = _mm_set1_epi32(g_sha256_k[i]); 88 | 89 | offset = _mm_set_epi32(0x3, 0x2, 0x1, 0x0); 90 | 91 | for (;;) 92 | { 93 | int j; 94 | 95 | m_4w[3] = _mm_add_epi32(offset, _mm_set1_epi32(nonce)); 96 | 97 | /* Some optimization can be done here W.R.T. precalculating some hash */ 98 | CalcSha256_x64(m_4hash1, m_4w, m_midstate); 99 | CalcSha256_x64(m_4hash, m_4hash1, g_sha256_hinit); 100 | 101 | for (j = 0; j < 4; j++) { 102 | mi.m = m_4hash[7]; 103 | if (unlikely(mi.i[j] == 0)) 104 | break; 105 | } 106 | 107 | /* If j = true, we found a hit...so check it */ 108 | /* Use the C version for a check... */ 109 | if (unlikely(j != 4)) { 110 | for (i = 0; i < 8; i++) { 111 | mi.m = m_4hash[i]; 112 | *(uint32_t *)&(phash)[i*4] = mi.i[j]; 113 | } 114 | 115 | if (fulltest(phash, ptarget)) { 116 | *nHashesDone = nonce; 117 | *nNonce_p = nonce + j; 118 | return nonce + j; 119 | } 120 | } 121 | 122 | nonce += 4; 123 | 124 | if (unlikely((nonce >= max_nonce) || work_restart[thr_id].restart)) 125 | { 126 | *nHashesDone = nonce; 127 | return -1; 128 | } 129 | } 130 | } 131 | 132 | #endif /* WANT_X8664_SSE2 */ 133 | 134 | -------------------------------------------------------------------------------- /sha256_via.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * This program is free software; you can redistribute it and/or modify it 4 | * under the terms of the GNU General Public License as published by the Free 5 | * Software Foundation; either version 2 of the License, or (at your option) 6 | * any later version. See COPYING for more details. 7 | */ 8 | 9 | #include "cpuminer-config.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "miner.h" 17 | 18 | #ifdef WANT_VIA_PADLOCK 19 | 20 | static void via_sha256(void *hash, void *buf, unsigned len) 21 | { 22 | unsigned stat = 0; 23 | asm volatile(".byte 0xf3, 0x0f, 0xa6, 0xd0" 24 | :"+S"(buf), "+a"(stat) 25 | :"c"(len), "D" (hash) 26 | :"memory"); 27 | } 28 | 29 | bool scanhash_via(int thr_id, unsigned char *data_inout, 30 | const unsigned char *target, 31 | uint32_t max_nonce, unsigned long *hashes_done) 32 | { 33 | unsigned char data[128] __attribute__((aligned(128))); 34 | unsigned char tmp_hash[32] __attribute__((aligned(128))); 35 | unsigned char tmp_hash1[32] __attribute__((aligned(128))); 36 | uint32_t *data32 = (uint32_t *) data; 37 | uint32_t *hash32 = (uint32_t *) tmp_hash; 38 | uint32_t *nonce = (uint32_t *)(data + 64 + 12); 39 | uint32_t n = 0; 40 | unsigned long stat_ctr = 0; 41 | int i; 42 | 43 | work_restart[thr_id].restart = 0; 44 | 45 | /* bitcoin gives us big endian input, but via wants LE, 46 | * so we reverse the swapping bitcoin has already done (extra work) 47 | * in order to permit the hardware to swap everything 48 | * back to BE again (extra work). 49 | */ 50 | for (i = 0; i < 128/4; i++) 51 | data32[i] = swab32(((uint32_t *)data_inout)[i]); 52 | 53 | while (1) { 54 | n++; 55 | *nonce = n; 56 | 57 | /* first SHA256 transform */ 58 | memcpy(tmp_hash1, sha256_init_state, 32); 59 | via_sha256(tmp_hash1, data, 80); /* or maybe 128? */ 60 | 61 | for (i = 0; i < 32/4; i++) 62 | ((uint32_t *)tmp_hash1)[i] = 63 | swab32(((uint32_t *)tmp_hash1)[i]); 64 | 65 | /* second SHA256 transform */ 66 | memcpy(tmp_hash, sha256_init_state, 32); 67 | via_sha256(tmp_hash, tmp_hash1, 32); 68 | 69 | stat_ctr++; 70 | 71 | if (unlikely((hash32[7] == 0) && fulltest(tmp_hash, target))) { 72 | /* swap nonce'd data back into original storage area; 73 | * TODO: only swap back the nonce, rather than all data 74 | */ 75 | for (i = 0; i < 128/4; i++) { 76 | uint32_t *dout32 = (uint32_t *) data_inout; 77 | dout32[i] = swab32(data32[i]); 78 | } 79 | 80 | *hashes_done = stat_ctr; 81 | return true; 82 | } 83 | 84 | if ((n >= max_nonce) || work_restart[thr_id].restart) { 85 | *hashes_done = stat_ctr; 86 | return false; 87 | } 88 | } 89 | } 90 | 91 | #endif /* WANT_VIA_PADLOCK */ 92 | 93 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2010 Jeff Garzik 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the Free 7 | * Software Foundation; either version 2 of the License, or (at your option) 8 | * any later version. See COPYING for more details. 9 | */ 10 | 11 | #define _GNU_SOURCE 12 | #include "cpuminer-config.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "miner.h" 23 | #include "elist.h" 24 | 25 | #if JANSSON_MAJOR_VERSION >= 2 26 | #define JSON_LOADS(str, err_ptr) json_loads((str), 0, (err_ptr)) 27 | #else 28 | #define JSON_LOADS(str, err_ptr) json_loads((str), (err_ptr)) 29 | #endif 30 | 31 | struct data_buffer { 32 | void *buf; 33 | size_t len; 34 | }; 35 | 36 | struct upload_buffer { 37 | const void *buf; 38 | size_t len; 39 | }; 40 | 41 | struct header_info { 42 | char *lp_path; 43 | }; 44 | 45 | struct tq_ent { 46 | void *data; 47 | struct list_head q_node; 48 | }; 49 | 50 | struct thread_q { 51 | struct list_head q; 52 | 53 | bool frozen; 54 | 55 | pthread_mutex_t mutex; 56 | pthread_cond_t cond; 57 | }; 58 | 59 | void applog(int prio, const char *fmt, ...) 60 | { 61 | va_list ap; 62 | 63 | va_start(ap, fmt); 64 | 65 | #ifdef HAVE_SYSLOG_H 66 | if (use_syslog) { 67 | vsyslog(prio, fmt, ap); 68 | } 69 | #else 70 | if (0) {} 71 | #endif 72 | else { 73 | char *f; 74 | int len; 75 | struct timeval tv = { }; 76 | struct tm tm, *tm_p; 77 | 78 | gettimeofday(&tv, NULL); 79 | 80 | pthread_mutex_lock(&time_lock); 81 | tm_p = localtime(&tv.tv_sec); 82 | memcpy(&tm, tm_p, sizeof(tm)); 83 | pthread_mutex_unlock(&time_lock); 84 | 85 | len = 40 + strlen(fmt) + 2; 86 | f = alloca(len); 87 | sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n", 88 | tm.tm_year + 1900, 89 | tm.tm_mon + 1, 90 | tm.tm_mday, 91 | tm.tm_hour, 92 | tm.tm_min, 93 | tm.tm_sec, 94 | fmt); 95 | vfprintf(stderr, f, ap); /* atomic write to stderr */ 96 | } 97 | va_end(ap); 98 | } 99 | 100 | static void databuf_free(struct data_buffer *db) 101 | { 102 | if (!db) 103 | return; 104 | 105 | free(db->buf); 106 | 107 | memset(db, 0, sizeof(*db)); 108 | } 109 | 110 | static size_t all_data_cb(const void *ptr, size_t size, size_t nmemb, 111 | void *user_data) 112 | { 113 | struct data_buffer *db = user_data; 114 | size_t len = size * nmemb; 115 | size_t oldlen, newlen; 116 | void *newmem; 117 | static const unsigned char zero; 118 | 119 | oldlen = db->len; 120 | newlen = oldlen + len; 121 | 122 | newmem = realloc(db->buf, newlen + 1); 123 | if (!newmem) 124 | return 0; 125 | 126 | db->buf = newmem; 127 | db->len = newlen; 128 | memcpy(db->buf + oldlen, ptr, len); 129 | memcpy(db->buf + newlen, &zero, 1); /* null terminate */ 130 | 131 | return len; 132 | } 133 | 134 | static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb, 135 | void *user_data) 136 | { 137 | struct upload_buffer *ub = user_data; 138 | int len = size * nmemb; 139 | 140 | if (len > ub->len) 141 | len = ub->len; 142 | 143 | if (len) { 144 | memcpy(ptr, ub->buf, len); 145 | ub->buf += len; 146 | ub->len -= len; 147 | } 148 | 149 | return len; 150 | } 151 | 152 | static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data) 153 | { 154 | struct header_info *hi = user_data; 155 | size_t remlen, slen, ptrlen = size * nmemb; 156 | char *rem, *val = NULL, *key = NULL; 157 | void *tmp; 158 | 159 | val = calloc(1, ptrlen); 160 | key = calloc(1, ptrlen); 161 | if (!key || !val) 162 | goto out; 163 | 164 | tmp = memchr(ptr, ':', ptrlen); 165 | if (!tmp || (tmp == ptr)) /* skip empty keys / blanks */ 166 | goto out; 167 | slen = tmp - ptr; 168 | if ((slen + 1) == ptrlen) /* skip key w/ no value */ 169 | goto out; 170 | memcpy(key, ptr, slen); /* store & nul term key */ 171 | key[slen] = 0; 172 | 173 | rem = ptr + slen + 1; /* trim value's leading whitespace */ 174 | remlen = ptrlen - slen - 1; 175 | while ((remlen > 0) && (isspace(*rem))) { 176 | remlen--; 177 | rem++; 178 | } 179 | 180 | memcpy(val, rem, remlen); /* store value, trim trailing ws */ 181 | val[remlen] = 0; 182 | while ((*val) && (isspace(val[strlen(val) - 1]))) { 183 | val[strlen(val) - 1] = 0; 184 | } 185 | if (!*val) /* skip blank value */ 186 | goto out; 187 | 188 | if (opt_protocol) 189 | applog(LOG_DEBUG, "HTTP hdr(%s): %s", key, val); 190 | 191 | if (!strcasecmp("X-Long-Polling", key)) { 192 | hi->lp_path = val; /* steal memory reference */ 193 | val = NULL; 194 | } 195 | 196 | out: 197 | free(key); 198 | free(val); 199 | return ptrlen; 200 | } 201 | 202 | json_t *json_rpc_call(CURL *curl, const char *url, 203 | const char *userpass, const char *rpc_req, 204 | bool longpoll_scan, bool longpoll) 205 | { 206 | json_t *val, *err_val, *res_val; 207 | int rc; 208 | struct data_buffer all_data = { }; 209 | struct upload_buffer upload_data; 210 | json_error_t err = { }; 211 | struct curl_slist *headers = NULL; 212 | char len_hdr[64], user_agent_hdr[128]; 213 | char curl_err_str[CURL_ERROR_SIZE]; 214 | long timeout = longpoll ? (60 * 60) : (60 * 10); 215 | struct header_info hi = { }; 216 | bool lp_scanning = false; 217 | 218 | /* it is assumed that 'curl' is freshly [re]initialized at this pt */ 219 | 220 | if (longpoll_scan) 221 | lp_scanning = want_longpoll && !have_longpoll; 222 | 223 | if (opt_protocol) 224 | curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); 225 | curl_easy_setopt(curl, CURLOPT_URL, url); 226 | curl_easy_setopt(curl, CURLOPT_ENCODING, ""); 227 | curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); 228 | curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); 229 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb); 230 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data); 231 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb); 232 | curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data); 233 | curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); 234 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 235 | curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); 236 | if (lp_scanning) { 237 | curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb); 238 | curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi); 239 | } 240 | if (userpass) { 241 | curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); 242 | curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 243 | } 244 | curl_easy_setopt(curl, CURLOPT_POST, 1); 245 | 246 | if (opt_protocol) 247 | applog(LOG_DEBUG, "JSON protocol request:\n%s\n", rpc_req); 248 | 249 | upload_data.buf = rpc_req; 250 | upload_data.len = strlen(rpc_req); 251 | sprintf(len_hdr, "Content-Length: %lu", 252 | (unsigned long) upload_data.len); 253 | sprintf(user_agent_hdr, "User-Agent: %s", PACKAGE_STRING); 254 | 255 | headers = curl_slist_append(headers, 256 | "Content-type: application/json"); 257 | headers = curl_slist_append(headers, len_hdr); 258 | headers = curl_slist_append(headers, user_agent_hdr); 259 | headers = curl_slist_append(headers, "Expect:"); /* disable Expect hdr*/ 260 | 261 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 262 | 263 | rc = curl_easy_perform(curl); 264 | if (rc) { 265 | applog(LOG_ERR, "HTTP request failed: %s", curl_err_str); 266 | goto err_out; 267 | } 268 | 269 | /* If X-Long-Polling was found, activate long polling */ 270 | if (hi.lp_path) { 271 | have_longpoll = true; 272 | opt_scantime = 60; 273 | tq_push(thr_info[longpoll_thr_id].q, hi.lp_path); 274 | } else 275 | free(hi.lp_path); 276 | hi.lp_path = NULL; 277 | 278 | val = JSON_LOADS(all_data.buf, &err); 279 | if (!val) { 280 | applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text); 281 | goto err_out; 282 | } 283 | 284 | if (opt_protocol) { 285 | char *s = json_dumps(val, JSON_INDENT(3)); 286 | applog(LOG_DEBUG, "JSON protocol response:\n%s", s); 287 | free(s); 288 | } 289 | 290 | /* JSON-RPC valid response returns a non-null 'result', 291 | * and a null 'error'. 292 | */ 293 | res_val = json_object_get(val, "result"); 294 | err_val = json_object_get(val, "error"); 295 | 296 | if (!res_val || json_is_null(res_val) || 297 | (err_val && !json_is_null(err_val))) { 298 | char *s; 299 | 300 | if (err_val) 301 | s = json_dumps(err_val, JSON_INDENT(3)); 302 | else 303 | s = strdup("(unknown reason)"); 304 | 305 | applog(LOG_ERR, "JSON-RPC call failed: %s", s); 306 | 307 | free(s); 308 | 309 | goto err_out; 310 | } 311 | 312 | databuf_free(&all_data); 313 | curl_slist_free_all(headers); 314 | curl_easy_reset(curl); 315 | return val; 316 | 317 | err_out: 318 | databuf_free(&all_data); 319 | curl_slist_free_all(headers); 320 | curl_easy_reset(curl); 321 | return NULL; 322 | } 323 | 324 | char *bin2hex(const unsigned char *p, size_t len) 325 | { 326 | int i; 327 | char *s = malloc((len * 2) + 1); 328 | if (!s) 329 | return NULL; 330 | 331 | for (i = 0; i < len; i++) 332 | sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); 333 | 334 | return s; 335 | } 336 | 337 | bool hex2bin(unsigned char *p, const char *hexstr, size_t len) 338 | { 339 | while (*hexstr && len) { 340 | char hex_byte[3]; 341 | unsigned int v; 342 | 343 | if (!hexstr[1]) { 344 | applog(LOG_ERR, "hex2bin str truncated"); 345 | return false; 346 | } 347 | 348 | hex_byte[0] = hexstr[0]; 349 | hex_byte[1] = hexstr[1]; 350 | hex_byte[2] = 0; 351 | 352 | if (sscanf(hex_byte, "%x", &v) != 1) { 353 | applog(LOG_ERR, "hex2bin sscanf '%s' failed", hex_byte); 354 | return false; 355 | } 356 | 357 | *p = (unsigned char) v; 358 | 359 | p++; 360 | hexstr += 2; 361 | len--; 362 | } 363 | 364 | return (len == 0 && *hexstr == 0) ? true : false; 365 | } 366 | 367 | /* Subtract the `struct timeval' values X and Y, 368 | storing the result in RESULT. 369 | Return 1 if the difference is negative, otherwise 0. */ 370 | 371 | int 372 | timeval_subtract ( 373 | struct timeval *result, struct timeval *x, struct timeval *y) 374 | { 375 | /* Perform the carry for the later subtraction by updating Y. */ 376 | if (x->tv_usec < y->tv_usec) { 377 | int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; 378 | y->tv_usec -= 1000000 * nsec; 379 | y->tv_sec += nsec; 380 | } 381 | if (x->tv_usec - y->tv_usec > 1000000) { 382 | int nsec = (x->tv_usec - y->tv_usec) / 1000000; 383 | y->tv_usec += 1000000 * nsec; 384 | y->tv_sec -= nsec; 385 | } 386 | 387 | /* Compute the time remaining to wait. 388 | `tv_usec' is certainly positive. */ 389 | result->tv_sec = x->tv_sec - y->tv_sec; 390 | result->tv_usec = x->tv_usec - y->tv_usec; 391 | 392 | /* Return 1 if result is negative. */ 393 | return x->tv_sec < y->tv_sec; 394 | } 395 | 396 | bool fulltest(const unsigned char *hash, const unsigned char *target) 397 | { 398 | unsigned char hash_swap[32], target_swap[32]; 399 | uint32_t *hash32 = (uint32_t *) hash_swap; 400 | uint32_t *target32 = (uint32_t *) target_swap; 401 | int i; 402 | bool rc = true; 403 | char *hash_str, *target_str; 404 | 405 | swap256(hash_swap, hash); 406 | swap256(target_swap, target); 407 | 408 | for (i = 0; i < 32/4; i++) { 409 | uint32_t h32tmp = swab32(hash32[i]); 410 | uint32_t t32tmp = target32[i]; 411 | 412 | target32[i] = swab32(target32[i]); /* for printing */ 413 | 414 | if (h32tmp > t32tmp) { 415 | rc = false; 416 | break; 417 | } 418 | if (h32tmp < t32tmp) { 419 | rc = true; 420 | break; 421 | } 422 | } 423 | 424 | if (opt_debug) { 425 | hash_str = bin2hex(hash_swap, 32); 426 | target_str = bin2hex(target_swap, 32); 427 | 428 | applog(LOG_DEBUG, " Proof: %s\nTarget: %s\nTrgVal? %s", 429 | hash_str, 430 | target_str, 431 | rc ? "YES (hash < target)" : 432 | "no (false positive; hash > target)"); 433 | 434 | free(hash_str); 435 | free(target_str); 436 | } 437 | 438 | return true; /* FIXME: return rc; */ 439 | } 440 | 441 | struct thread_q *tq_new(void) 442 | { 443 | struct thread_q *tq; 444 | 445 | tq = calloc(1, sizeof(*tq)); 446 | if (!tq) 447 | return NULL; 448 | 449 | INIT_LIST_HEAD(&tq->q); 450 | pthread_mutex_init(&tq->mutex, NULL); 451 | pthread_cond_init(&tq->cond, NULL); 452 | 453 | return tq; 454 | } 455 | 456 | void tq_free(struct thread_q *tq) 457 | { 458 | struct tq_ent *ent, *iter; 459 | 460 | if (!tq) 461 | return; 462 | 463 | list_for_each_entry_safe(ent, iter, &tq->q, q_node) { 464 | list_del(&ent->q_node); 465 | free(ent); 466 | } 467 | 468 | pthread_cond_destroy(&tq->cond); 469 | pthread_mutex_destroy(&tq->mutex); 470 | 471 | memset(tq, 0, sizeof(*tq)); /* poison */ 472 | free(tq); 473 | } 474 | 475 | static void tq_freezethaw(struct thread_q *tq, bool frozen) 476 | { 477 | pthread_mutex_lock(&tq->mutex); 478 | 479 | tq->frozen = frozen; 480 | 481 | pthread_cond_signal(&tq->cond); 482 | pthread_mutex_unlock(&tq->mutex); 483 | } 484 | 485 | void tq_freeze(struct thread_q *tq) 486 | { 487 | tq_freezethaw(tq, true); 488 | } 489 | 490 | void tq_thaw(struct thread_q *tq) 491 | { 492 | tq_freezethaw(tq, false); 493 | } 494 | 495 | bool tq_push(struct thread_q *tq, void *data) 496 | { 497 | struct tq_ent *ent; 498 | bool rc = true; 499 | 500 | ent = calloc(1, sizeof(*ent)); 501 | if (!ent) 502 | return false; 503 | 504 | ent->data = data; 505 | INIT_LIST_HEAD(&ent->q_node); 506 | 507 | pthread_mutex_lock(&tq->mutex); 508 | 509 | if (!tq->frozen) { 510 | list_add_tail(&ent->q_node, &tq->q); 511 | } else { 512 | free(ent); 513 | rc = false; 514 | } 515 | 516 | pthread_cond_signal(&tq->cond); 517 | pthread_mutex_unlock(&tq->mutex); 518 | 519 | return rc; 520 | } 521 | 522 | void *tq_pop(struct thread_q *tq, const struct timespec *abstime) 523 | { 524 | struct tq_ent *ent; 525 | void *rval = NULL; 526 | int rc; 527 | 528 | pthread_mutex_lock(&tq->mutex); 529 | 530 | if (!list_empty(&tq->q)) 531 | goto pop; 532 | 533 | if (abstime) 534 | rc = pthread_cond_timedwait(&tq->cond, &tq->mutex, abstime); 535 | else 536 | rc = pthread_cond_wait(&tq->cond, &tq->mutex); 537 | if (rc) 538 | goto out; 539 | if (list_empty(&tq->q)) 540 | goto out; 541 | 542 | pop: 543 | ent = list_entry(tq->q.next, struct tq_ent, q_node); 544 | rval = ent->data; 545 | 546 | list_del(&ent->q_node); 547 | free(ent); 548 | 549 | out: 550 | pthread_mutex_unlock(&tq->mutex); 551 | return rval; 552 | } 553 | 554 | -------------------------------------------------------------------------------- /x86_64/.gitignore: -------------------------------------------------------------------------------- 1 | libx8664.a 2 | -------------------------------------------------------------------------------- /x86_64/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LIBRARIES = libx8664.a 2 | 3 | SUFFIXES = .asm 4 | 5 | libx8664_a_SOURCES = sha256_xmm_amd64.asm 6 | 7 | .asm.o: 8 | $(YASM) -f elf64 $< 9 | -------------------------------------------------------------------------------- /x86_64/sha256_xmm_amd64.asm: -------------------------------------------------------------------------------- 1 | ;; SHA-256 for X86-64 for Linux, based off of: 2 | 3 | ; (c) Ufasoft 2011 http://ufasoft.com mailto:support@ufasoft.com 4 | ; Version 2011 5 | ; This software is Public Domain 6 | 7 | ; SHA-256 CPU SSE cruncher for Bitcoin Miner 8 | 9 | ALIGN 32 10 | BITS 64 11 | 12 | %define hash rdi 13 | %define data rsi 14 | %define init rdx 15 | 16 | extern g_4sha256_k 17 | 18 | global CalcSha256_x64 19 | ; CalcSha256 hash(rdi), data(rsi), init(rdx) 20 | CalcSha256_x64: 21 | 22 | push rbx 23 | 24 | LAB_NEXT_NONCE: 25 | mov r11, data 26 | ; mov rax, pnonce 27 | ; mov eax, [rax] 28 | ; mov [rbx+3*16], eax 29 | ; inc eax 30 | ; mov [rbx+3*16+4], eax 31 | ; inc eax 32 | ; mov [rbx+3*16+8], eax 33 | ; inc eax 34 | ; mov [rbx+3*16+12], eax 35 | 36 | mov rcx, 64*4 ;rcx is # of SHA-2 rounds 37 | mov rax, 16*4 ;rax is where we expand to 38 | 39 | LAB_SHA: 40 | push rcx 41 | lea rcx, qword [r11+rcx*4] 42 | lea r11, qword [r11+rax*4] 43 | LAB_CALC: 44 | movdqa xmm0, [r11-15*16] 45 | movdqa xmm2, xmm0 ; (Rotr32(w_15, 7) ^ Rotr32(w_15, 18) ^ (w_15 >> 3)) 46 | psrld xmm0, 3 47 | movdqa xmm1, xmm0 48 | pslld xmm2, 14 49 | psrld xmm1, 4 50 | pxor xmm0, xmm1 51 | pxor xmm0, xmm2 52 | pslld xmm2, 11 53 | psrld xmm1, 11 54 | pxor xmm0, xmm1 55 | pxor xmm0, xmm2 56 | 57 | paddd xmm0, [r11-16*16] 58 | 59 | movdqa xmm3, [r11-2*16] 60 | movdqa xmm2, xmm3 ; (Rotr32(w_2, 17) ^ Rotr32(w_2, 19) ^ (w_2 >> 10)) 61 | psrld xmm3, 10 62 | movdqa xmm1, xmm3 63 | pslld xmm2, 13 64 | psrld xmm1, 7 65 | pxor xmm3, xmm1 66 | pxor xmm3, xmm2 67 | pslld xmm2, 2 68 | psrld xmm1, 2 69 | pxor xmm3, xmm1 70 | pxor xmm3, xmm2 71 | paddd xmm0, xmm3 72 | 73 | paddd xmm0, [r11-7*16] 74 | movdqa [r11], xmm0 75 | add r11, 16 76 | cmp r11, rcx 77 | jb LAB_CALC 78 | pop rcx 79 | 80 | mov rax, 0 81 | 82 | ; Load the init values of the message into the hash. 83 | 84 | movd xmm0, dword [rdx+4*4] ; xmm0 == e 85 | pshufd xmm0, xmm0, 0 86 | movd xmm3, dword [rdx+3*4] ; xmm3 == d 87 | pshufd xmm3, xmm3, 0 88 | movd xmm4, dword [rdx+2*4] ; xmm4 == c 89 | pshufd xmm4, xmm4, 0 90 | movd xmm5, dword [rdx+1*4] ; xmm5 == b 91 | pshufd xmm5, xmm5, 0 92 | movd xmm7, dword [rdx+0*4] ; xmm7 == a 93 | pshufd xmm7, xmm7, 0 94 | movd xmm8, dword [rdx+5*4] ; xmm8 == f 95 | pshufd xmm8, xmm8, 0 96 | movd xmm9, dword [rdx+6*4] ; xmm9 == g 97 | pshufd xmm9, xmm9, 0 98 | movd xmm10, dword [rdx+7*4] ; xmm10 == h 99 | pshufd xmm10, xmm10, 0 100 | 101 | LAB_LOOP: 102 | 103 | ;; T t1 = h + (Rotr32(e, 6) ^ Rotr32(e, 11) ^ Rotr32(e, 25)) + ((e & f) ^ AndNot(e, g)) + Expand32(g_sha256_k[j]) + w[j] 104 | 105 | movdqa xmm6, [rsi+rax*4] 106 | paddd xmm6, g_4sha256_k[rax*4] 107 | add rax, 4 108 | 109 | paddd xmm6, xmm10 ; +h 110 | 111 | movdqa xmm1, xmm0 112 | movdqa xmm2, xmm9 113 | pandn xmm1, xmm2 ; ~e & g 114 | 115 | movdqa xmm10, xmm2 ; h = g 116 | movdqa xmm2, xmm8 ; f 117 | movdqa xmm9, xmm2 ; g = f 118 | 119 | pand xmm2, xmm0 ; e & f 120 | pxor xmm1, xmm2 ; (e & f) ^ (~e & g) 121 | movdqa xmm8, xmm0 ; f = e 122 | 123 | paddd xmm6, xmm1 ; Ch + h + w[i] + k[i] 124 | 125 | movdqa xmm1, xmm0 126 | psrld xmm0, 6 127 | movdqa xmm2, xmm0 128 | pslld xmm1, 7 129 | psrld xmm2, 5 130 | pxor xmm0, xmm1 131 | pxor xmm0, xmm2 132 | pslld xmm1, 14 133 | psrld xmm2, 14 134 | pxor xmm0, xmm1 135 | pxor xmm0, xmm2 136 | pslld xmm1, 5 137 | pxor xmm0, xmm1 ; Rotr32(e, 6) ^ Rotr32(e, 11) ^ Rotr32(e, 25) 138 | paddd xmm6, xmm0 ; xmm6 = t1 139 | 140 | movdqa xmm0, xmm3 ; d 141 | paddd xmm0, xmm6 ; e = d+t1 142 | 143 | movdqa xmm1, xmm5 ; =b 144 | movdqa xmm3, xmm4 ; d = c 145 | movdqa xmm2, xmm4 ; c 146 | pand xmm2, xmm5 ; b & c 147 | pxor xmm1, xmm4 ; b ^ c 148 | pand xmm1, xmm7 ; a & (b ^ c) 149 | pxor xmm1, xmm2 ; (a & (b ^ c)) ^ (b & c) 150 | movdqa xmm4, xmm5 ; c = b 151 | movdqa xmm5, xmm7 ; b = a 152 | paddd xmm6, xmm1 ; t1 + ((a & c) ^ (a & d) ^ (c & d)) 153 | 154 | movdqa xmm2, xmm7 155 | psrld xmm7, 2 156 | movdqa xmm1, xmm7 157 | pslld xmm2, 10 158 | psrld xmm1, 11 159 | pxor xmm7, xmm2 160 | pxor xmm7, xmm1 161 | pslld xmm2, 9 162 | psrld xmm1, 9 163 | pxor xmm7, xmm2 164 | pxor xmm7, xmm1 165 | pslld xmm2, 11 166 | pxor xmm7, xmm2 167 | paddd xmm7, xmm6 ; a = t1 + (Rotr32(a, 2) ^ Rotr32(a, 13) ^ Rotr32(a, 22)) + ((a & c) ^ (a & d) ^ (c & d)); 168 | 169 | cmp rax, rcx 170 | jb LAB_LOOP 171 | 172 | ; Finished the 64 rounds, calculate hash and save 173 | 174 | movd xmm1, dword [rdx+0*4] 175 | pshufd xmm1, xmm1, 0 176 | paddd xmm7, xmm1 177 | 178 | movd xmm1, dword [rdx+1*4] 179 | pshufd xmm1, xmm1, 0 180 | paddd xmm5, xmm1 181 | 182 | movd xmm1, dword [rdx+2*4] 183 | pshufd xmm1, xmm1, 0 184 | paddd xmm4, xmm1 185 | 186 | movd xmm1, dword [rdx+3*4] 187 | pshufd xmm1, xmm1, 0 188 | paddd xmm3, xmm1 189 | 190 | movd xmm1, dword [rdx+4*4] 191 | pshufd xmm1, xmm1, 0 192 | paddd xmm0, xmm1 193 | 194 | movd xmm1, dword [rdx+5*4] 195 | pshufd xmm1, xmm1, 0 196 | paddd xmm8, xmm1 197 | 198 | movd xmm1, dword [rdx+6*4] 199 | pshufd xmm1, xmm1, 0 200 | paddd xmm9, xmm1 201 | 202 | movd xmm1, dword [rdx+7*4] 203 | pshufd xmm1, xmm1, 0 204 | paddd xmm10, xmm1 205 | 206 | debug_me: 207 | movdqa [rdi+0*16], xmm7 208 | movdqa [rdi+1*16], xmm5 209 | movdqa [rdi+2*16], xmm4 210 | movdqa [rdi+3*16], xmm3 211 | movdqa [rdi+4*16], xmm0 212 | movdqa [rdi+5*16], xmm8 213 | movdqa [rdi+6*16], xmm9 214 | movdqa [rdi+7*16], xmm10 215 | 216 | LAB_RET: 217 | pop rbx 218 | ret 219 | --------------------------------------------------------------------------------