├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── bootstrap ├── configure.ac ├── libdisarm.pc.in └── src ├── dacli └── dacli.c └── libdisarm ├── args.c ├── args.h ├── disarm.h ├── endian.h ├── macros.h ├── parser.c ├── parser.h ├── print.c ├── print.h └── types.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Authors: 2 | * Jon Lund Steffensen 3 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 | 2 | libdisarm-0.1 3 | ------------- 4 | 50 Jon Lund Steffensen 2008-03-13 5 | Update README. 6 | 7 | 49 Jon Lund Steffensen 2008-03-13 8 | Update INSTALL. 9 | 10 | 48 Jon Lund Steffensen 2008-01-18 11 | fix email in AUTHORS 12 | 13 | 47 Jon Lund Steffensen 2007-12-19 14 | Clean up naming; better use of args struct. 15 | 16 | 46 Jon Lund Steffensen 2007-12-14 17 | Make GCC detect unused enumeration codes in switch statements. 18 | 19 | 45 Jon Lund Steffensen 2007-12-13 20 | add a generic way to get instruction args. 21 | 22 | 44 Jon Lund Steffensen 2007-10-07 23 | Update README 24 | 25 | 43 Jon Lund Steffensen 2007-10-07 26 | Separate ARM disassembler out into libdisarm 27 | 28 | 29 | history from ARM disassembler source 30 | ------------------------------------ 31 | 32 | 42 Jon Lund Steffensen 2007-09-27 [merge] 33 | minor fixes; basic block stats 34 | 35 | 41 Jon Lund Steffensen 2007-08-24 36 | put basic info in AUTHORS and README files 37 | 38 | 40 Jon Lund Steffensen 2007-08-20 39 | fixes in fall-through references in basicblock.cpp 40 | 41 | 39 Jon Lund Steffensen 2007-08-20 42 | change format of printed address when symbol is found; assume (for now) that branch-and-links always return 43 | 44 | 38 Jon Lund Steffensen 2007-08-19 45 | do backtracking to find implicit branch-and-links 46 | 47 | 37 Jon Lund Steffensen 2007-08-19 48 | format data output like hexdump -C; clean up reference pass in basicblock.cpp; basic blocks start out as unknown type not code 49 | 50 | 36 Jon Lund Steffensen 2007-08-19 51 | do backtracking to find all jump destinations in switch statements 52 | 53 | 35 Jon Lund Steffensen 2007-08-19 54 | add _is_flag_changed and _is_flag_used functions 55 | 56 | 34 Jon Lund Steffensen 2007-08-18 57 | clean up basicblock.cpp; add adjacent block merge pass 58 | 59 | 33 Jon Lund Steffensen 2007-08-18 60 | add image_is_addr_mapped 61 | 62 | 32 Jon Lund Steffensen 2007-08-18 63 | use image_is_addr_mapped 64 | 65 | 31 Jon Lund Steffensen 2007-08-18 66 | minor fix in configure.ac 67 | 68 | 30 Jon Lund Steffensen 2007-08-18 69 | add reference pass in basic block analysis; loop through basic blocks in disarm.cpp instead of instructions 70 | 71 | 29 Jon Lund Steffensen 2007-08-17 72 | do late reference analysis in basicblock.cpp for added benefits from earlier analysis 73 | 74 | 28 Jon Lund Steffensen 2007-08-17 75 | output info about changed flags and flags depended on; flag blocks with undef'd instructions as data blocks 76 | 77 | 27 Jon Lund Steffensen 2007-08-16 78 | improve arm_instr_used_regs; add basic block register usage/change analysis in disarm.cpp 79 | 80 | 26 Jon Lund Steffensen 2007-08-16 81 | minor change in basicblock_find 82 | 83 | 25 Jon Lund Steffensen 2007-08-16 84 | use new image mapping and basic block features in disarm.cpp 85 | 86 | 24 Jon Lund Steffensen 2007-08-16 87 | add basic block related functions in basicblock.cpp 88 | 89 | 23 Jon Lund Steffensen 2007-08-16 90 | fix for previous updates to image handling 91 | 92 | 22 Jon Lund Steffensen 2007-08-16 93 | print value of referenced data in arm_instr_fprint 94 | 95 | 21 Jon Lund Steffensen 2007-08-16 96 | provide handling of multiple data files in image.cpp with image mappings 97 | 98 | 20 Jon Lund Steffensen 2007-08-15 99 | simplify code in codesep.cpp 100 | 101 | 19 Jon Lund Steffensen 2007-08-15 102 | minor improvements and simplified code in basic block analysis 103 | 104 | 18 Jon Lund Steffensen 2007-08-15 105 | arm fixes, add helper functions get_cond and get_type 106 | 107 | 17 Jon Lund Steffensen 2007-04-20 108 | collect data references in basic block analysis 109 | 110 | 16 Jon Lund Steffensen 2007-04-20 111 | use bool type in basicblock.cpp 112 | 113 | 15 Jon Lund Steffensen 2007-04-20 114 | use c++ stl list, stack and map; use c++ iostream 115 | 116 | 14 Jon Lund Steffensen 2007-04-19 117 | use iostream in disarm.cpp for output to stdout and stderr 118 | 119 | 13 Jon Lund Steffensen 2007-04-19 120 | use c++ include style when including c standard headers 121 | 122 | 12 Jon Lund Steffensen 2007-04-19 123 | initial conversion to c++ 124 | 125 | 11 Jon Lund Steffensen 2007-04-18 126 | add beginnings of a simulator 127 | 128 | 10 Jon Lund Steffensen 2007-01-06 129 | improvements in ouput format, improvements in basic block analysis, support little endian (dirty hack) 130 | 131 | 9 Jon Lund Steffensen 2006-12-21 132 | improve code/data separator 133 | 134 | 8 Jon Lund Steffensen 2006-12-20 135 | move basic block analysis and symbol table to individual files 136 | 137 | 7 Jon Lund Steffensen 2006-12-19 138 | separate code into more files; add initial code/data separation pass 139 | 140 | 6 Jon Lund Steffensen 2006-12-19 141 | updates 142 | 143 | 5 Jon Lund Steffensen 2006-12-14 144 | improve code structure; improve hashtable implementation 145 | 146 | 4 Jon Lund Steffensen 2006-12-13 147 | fix annotation order; simplify code for basic block analysis 148 | 149 | 3 Jon Lund Steffensen 2006-12-12 150 | trying to speed up hashtable lookup with a simpler list 151 | 152 | 2 Jon Lund Steffensen 2006-12-12 153 | updates; it's still a mess 154 | 155 | 1 Jon Lund Steffensen 2006-11-27 156 | initial import 157 | 158 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, 5 | Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell commands `./configure; make; make install' should 16 | configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | HP-UX `make' updates targets which have the same time stamps as 230 | their prerequisites, which makes it generally unusable when shipped 231 | generated files such as `configure' are involved. Use GNU `make' 232 | instead. 233 | 234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 235 | parse its `' header file. The option `-nodtk' can be used as 236 | a workaround. If GNU CC is not installed, it is therefore recommended 237 | to try 238 | 239 | ./configure CC="cc" 240 | 241 | and if that doesn't work, try 242 | 243 | ./configure CC="cc -nodtk" 244 | 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 246 | directory contains several dysfunctional programs; working variants of 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 248 | in your `PATH', put it _after_ `/usr/bin'. 249 | 250 | On Haiku, software installed for all users goes in `/boot/common', 251 | not `/usr/local'. It is recommended to use the following options: 252 | 253 | ./configure --prefix=/boot/common 254 | 255 | Specifying the System Type 256 | ========================== 257 | 258 | There may be some features `configure' cannot figure out 259 | automatically, but needs to determine by the type of machine the package 260 | will run on. Usually, assuming the package is built to be run on the 261 | _same_ architectures, `configure' can figure that out, but if it prints 262 | a message saying it cannot guess the machine type, give it the 263 | `--build=TYPE' option. TYPE can either be a short name for the system 264 | type, such as `sun4', or a canonical name which has the form: 265 | 266 | CPU-COMPANY-SYSTEM 267 | 268 | where SYSTEM can have one of these forms: 269 | 270 | OS 271 | KERNEL-OS 272 | 273 | See the file `config.sub' for the possible values of each field. If 274 | `config.sub' isn't included in this package, then this package doesn't 275 | need to know the machine type. 276 | 277 | If you are _building_ compiler tools for cross-compiling, you should 278 | use the option `--target=TYPE' to select the type of system they will 279 | produce code for. 280 | 281 | If you want to _use_ a cross compiler, that generates code for a 282 | platform different from the build platform, you should specify the 283 | "host" platform (i.e., that on which the generated programs will 284 | eventually be run) with `--host=TYPE'. 285 | 286 | Sharing Defaults 287 | ================ 288 | 289 | If you want to set default values for `configure' scripts to share, 290 | you can create a site shell script called `config.site' that gives 291 | default values for variables like `CC', `cache_file', and `prefix'. 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the 294 | `CONFIG_SITE' environment variable to the location of the site script. 295 | A warning: not all `configure' scripts look for a site script. 296 | 297 | Defining Variables 298 | ================== 299 | 300 | Variables not defined in a site shell script can be set in the 301 | environment passed to `configure'. However, some packages may run 302 | configure again during the build, and the customized values of these 303 | variables may be lost. In order to avoid this problem, you should set 304 | them in the `configure' command line, using `VAR=value'. For example: 305 | 306 | ./configure CC=/usr/local2/bin/gcc 307 | 308 | causes the specified `gcc' to be used as the C compiler (unless it is 309 | overridden in the site shell script). 310 | 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 312 | an Autoconf limitation. Until the limitation is lifted, you can use 313 | this workaround: 314 | 315 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 316 | 317 | `configure' Invocation 318 | ====================== 319 | 320 | `configure' recognizes the following options to control how it 321 | operates. 322 | 323 | `--help' 324 | `-h' 325 | Print a summary of all of the options to `configure', and exit. 326 | 327 | `--help=short' 328 | `--help=recursive' 329 | Print a summary of the options unique to this package's 330 | `configure', and exit. The `short' variant lists options used 331 | only in the top level, while the `recursive' variant lists options 332 | also present in any nested packages. 333 | 334 | `--version' 335 | `-V' 336 | Print the version of Autoconf used to generate the `configure' 337 | script, and exit. 338 | 339 | `--cache-file=FILE' 340 | Enable the cache: use and save the results of the tests in FILE, 341 | traditionally `config.cache'. FILE defaults to `/dev/null' to 342 | disable caching. 343 | 344 | `--config-cache' 345 | `-C' 346 | Alias for `--cache-file=config.cache'. 347 | 348 | `--quiet' 349 | `--silent' 350 | `-q' 351 | Do not print messages saying which checks are being made. To 352 | suppress all normal output, redirect it to `/dev/null' (any error 353 | messages will still be shown). 354 | 355 | `--srcdir=DIR' 356 | Look for the package's source code in directory DIR. Usually 357 | `configure' can determine that directory automatically. 358 | 359 | `--prefix=DIR' 360 | Use DIR as the installation prefix. *note Installation Names:: 361 | for more details, including other options available for fine-tuning 362 | the installation locations. 363 | 364 | `--no-create' 365 | `-n' 366 | Run the configure checks, but stop before creating any output 367 | files. 368 | 369 | `configure' also accepts some other, not widely useful, options. Run 370 | `configure --help' for more details. 371 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AM_CFLAGS=-I$(top_srcdir)/src 3 | 4 | # libdisarm.pc 5 | pkgconfigdir = $(libdir)/pkgconfig 6 | pkgconfig_DATA = libdisarm.pc 7 | 8 | 9 | # libdisarm.la 10 | LIBDISARMSOURCES = \ 11 | src/libdisarm/args.c \ 12 | src/libdisarm/parser.c \ 13 | src/libdisarm/print.c 14 | 15 | LIBDISARMHEADERS = \ 16 | src/libdisarm/args.h \ 17 | src/libdisarm/disarm.h \ 18 | src/libdisarm/macros.h \ 19 | src/libdisarm/parser.h \ 20 | src/libdisarm/print.h \ 21 | src/libdisarm/types.h 22 | 23 | LIBDISARMPRIVHEADERS = \ 24 | src/libdisarm/endian.h 25 | 26 | lib_LTLIBRARIES = libdisarm.la 27 | 28 | libdisarm_la_SOURCES = \ 29 | $(LIBDISARMSOURCES) \ 30 | $(LIBDISARMHEADERS) \ 31 | $(LIBDISARMPRIVHEADERS) 32 | pkginclude_HEADERS = $(LIBDISARMHEADERS) 33 | noinst_HEADERS = $(LIBDISARMPRIVHEADERS) 34 | libdisarm_la_LDFLAGS = -version-info $(LIBDISARM_VERSION_INFO) 35 | 36 | 37 | # dacli 38 | bin_PROGRAMS = dacli 39 | 40 | dacli_SOURCES = src/dacli/dacli.c 41 | dacli_LDADD = libdisarm.la 42 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 2 | libdisarm-0.1 3 | ------------- 4 | First release of libdisarm. It is pretty usable already, but expect some bugs. 5 | It has only really been tested on ARMv4 code, but should support instructions 6 | from ARMv5 and below. 7 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | Disassembler Library for ARM 3 | 4 | Disassembles ARM instructions to a data structure that makes it easy to access 5 | instruction parameters. The library also contains functions to print 6 | human-readable assembly code from instructions, and alongside the library 7 | a small disassembly tool is provided. Tested on ARMv4 code but should support 8 | instructions in ARMv5 and below. Thumb instructions are currently not 9 | supported. 10 | 11 | Documentation: 12 | 13 | 14 | Code repository: 15 | 16 | 17 | 18 | Compiling and installing: 19 | First, run the following command if you branched the code from 20 | the bzr repository: 21 | $ ./bootstrap 22 | 23 | Next, use the following steps to compile libdisarm: 24 | $ ./configure 25 | $ make 26 | 27 | If it succeded you should be able to run dacli directly from 28 | the build directory like this: 29 | $ ./dacli -h 30 | 31 | If you want to install (probably requires that you are root) run 32 | the following command: 33 | $ make install 34 | 35 | Please see the web sites mentioned above for further information. 36 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # change to root directory 4 | cd $(dirname "$0") 5 | 6 | # run auto.* tools 7 | libtoolize --automake --copy --force && \ 8 | aclocal --force -I m4 && \ 9 | autoheader --force && \ 10 | automake --gnu --add-missing --force-missing --copy && \ 11 | autoconf --force 12 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.69]) 5 | AC_INIT([libdisarm],[0.1],[jonlst@gmail.com]) 6 | AC_CONFIG_SRCDIR([src/libdisarm/disarm.h]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz -Wall]) 9 | 10 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 11 | 12 | AC_SUBST(LIBDISARM_VERSION_INFO, [0:0:0]) 13 | 14 | # Checks for programs. 15 | AC_PROG_CC 16 | AM_PROG_CC_C_O 17 | AM_PROG_AR 18 | AC_PROG_LIBTOOL 19 | 20 | # Checks for libraries. 21 | 22 | # Checks for header files. 23 | AC_HEADER_ASSERT 24 | AC_CHECK_HEADERS([byteswap.h endian.h stdint.h stdlib.h sys/endian.h]) 25 | 26 | # Checks for typedefs, structures, and compiler characteristics. 27 | AC_C_CONST 28 | AC_C_BIGENDIAN 29 | AC_SYS_LARGEFILE 30 | AC_TYPE_OFF_T 31 | AC_TYPE_SIZE_T 32 | AC_TYPE_UINT32_T 33 | 34 | # Checks for library functions. 35 | 36 | AC_CONFIG_FILES([ 37 | Makefile 38 | libdisarm.pc 39 | ]) 40 | AC_OUTPUT 41 | 42 | 43 | echo " 44 | $PACKAGE_NAME $VERSION 45 | 46 | prefix: ${prefix} 47 | compiler: ${CC} 48 | cflags: ${CFLAGS} 49 | " 50 | -------------------------------------------------------------------------------- /libdisarm.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=${prefix} 3 | libdir=@libdir@ 4 | includedir=${prefix}/include 5 | 6 | Name: @PACKAGE_NAME@ 7 | Description: @PACKAGE_STRING@ 8 | Version: @PACKAGE_VERSION@ 9 | Libs: -L${libdir} -ldisarm 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /src/dacli/dacli.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dacli.c - libdisarm command line interface 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | # include 23 | #endif 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | 34 | #define USAGE \ 35 | "Usage: %s [-EB|-EL] [-h] [-m OFFSET] [-s SKIP] [FILE]\n" 36 | #define HELP \ 37 | USAGE \ 38 | " Disassemble ARM machine code from FILE or standard input.\n" \ 39 | " -EB\t\tRead input as big endian data\n" \ 40 | " -EL\t\tRead input as little endian data\n" \ 41 | " -h\t\tDisplay this help message\n" \ 42 | " -m OFFSET\tUse OFFSET as memory address of input\n" \ 43 | " -s SKIP\tNumber of bytes to skip before disassembly\n" \ 44 | "Report bugs to <" PACKAGE_BUGREPORT ">.\n" 45 | 46 | /* Return -1 on error, 0 on EOF, 1 on succesful read. */ 47 | int 48 | read_hex_input(void *dest, size_t size, FILE *f) 49 | { 50 | int c = fgetc(f); 51 | if (c == EOF) return 0; 52 | 53 | int i; 54 | for (i = 0; i < size; i++) { 55 | while (isspace(c)) { 56 | c = fgetc(f); 57 | } 58 | 59 | if (c == EOF) return 0; 60 | 61 | int byte = 0; 62 | int j; 63 | for (j = 0; j < 2; j++) { 64 | int input; 65 | if (c >= '0' && c <= '9') { 66 | input = c - '0'; 67 | } else if (c >= 'a' && c <= 'f') { 68 | input = c - 'a' + 10; 69 | } else if (c >= 'A' && c <= 'F') { 70 | input = c - 'A' + 10; 71 | } else if (j > 0 && isspace(c)) { 72 | break; 73 | } else { 74 | return -1; 75 | } 76 | 77 | byte = (byte << 4) | input; 78 | 79 | c = fgetc(f); 80 | if (c == EOF) break; 81 | } 82 | 83 | ((unsigned char *)dest)[i] = byte; 84 | } 85 | 86 | return 1; 87 | } 88 | 89 | int 90 | main(int argc, char *argv[]) 91 | { 92 | int r; 93 | 94 | int hex_input = 0; 95 | da_addr_t mem_offset = 0; 96 | off_t file_offset = 0; 97 | ssize_t disasm_size = -1; 98 | int big_endian = 0; 99 | 100 | int opt; 101 | while ((opt = getopt(argc, argv, "c:E:hm:s:x")) != -1) { 102 | switch (opt) { 103 | case 'c': 104 | disasm_size = atoi(optarg); 105 | break; 106 | case 'E': 107 | if (optarg != NULL && 108 | (optarg[0] == 'B' || optarg[0] == 'L')) { 109 | big_endian = (optarg[0] == 'B'); 110 | } else { 111 | fprintf(stderr, USAGE, argv[0]); 112 | exit(EXIT_FAILURE); 113 | } 114 | break; 115 | case 'h': 116 | printf(HELP, argv[0]); 117 | exit(EXIT_SUCCESS); 118 | break; 119 | case 'm': 120 | mem_offset = atoi(optarg); 121 | break; 122 | case 's': 123 | file_offset = atoi(optarg); 124 | break; 125 | case 'x': 126 | hex_input = 1; 127 | break; 128 | default: 129 | fprintf(stderr, USAGE, argv[0]); 130 | exit(EXIT_FAILURE); 131 | } 132 | } 133 | 134 | FILE *f = stdin; 135 | 136 | if (optind < argc && strcmp(argv[optind], "-")) { 137 | f = fopen(argv[optind], "rb"); 138 | if (f == NULL) { 139 | perror("fopen"); 140 | exit(EXIT_FAILURE); 141 | } 142 | 143 | if (file_offset > 0) { 144 | r = fseek(f, file_offset, SEEK_SET); 145 | if (r < 0) { 146 | perror("fseek"); 147 | exit(EXIT_FAILURE); 148 | } 149 | } 150 | } 151 | 152 | da_addr_t addr = mem_offset; 153 | 154 | while (disasm_size < 0 || addr < mem_offset + disasm_size) { 155 | da_word_t data; 156 | 157 | if (!hex_input) { 158 | size_t read = fread(&data, sizeof(da_word_t), 1, f); 159 | if (read < 1) { 160 | if (feof(f)) break; 161 | else { 162 | perror("fread"); 163 | exit(EXIT_FAILURE); 164 | } 165 | } 166 | } else { 167 | r = read_hex_input(&data, sizeof(da_word_t), f); 168 | if (r < 0) { 169 | fprintf(stderr, "Unable to parse input.\n"); 170 | exit(EXIT_FAILURE); 171 | } else if (r == 0) { 172 | break; 173 | } 174 | } 175 | 176 | da_instr_t instr; 177 | da_instr_args_t args; 178 | da_instr_parse(&instr, data, big_endian); 179 | da_instr_parse_args(&args, &instr); 180 | 181 | printf("%08x\t", addr); 182 | printf("%08x\t", instr.data); 183 | da_instr_fprint(stdout, &instr, &args, addr); 184 | printf("\n"); 185 | 186 | addr += sizeof(da_word_t); 187 | } 188 | 189 | r = fclose(f); 190 | if (r < 0) { 191 | perror("fclose"); 192 | exit(EXIT_FAILURE); 193 | } 194 | 195 | return EXIT_SUCCESS; 196 | } 197 | -------------------------------------------------------------------------------- /src/libdisarm/args.c: -------------------------------------------------------------------------------- 1 | /* 2 | * args.c - Instruction argument functions 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | # include 23 | #endif 24 | 25 | #include 26 | 27 | #include "args.h" 28 | #include "macros.h" 29 | #include "types.h" 30 | 31 | 32 | /* Return true if instruction has a cond field. */ 33 | static int 34 | da_instr_has_cond(const da_instr_t *instr) 35 | { 36 | switch (instr->group) { 37 | case DA_GROUP_UNDEF_1: 38 | case DA_GROUP_UNDEF_2: 39 | case DA_GROUP_UNDEF_3: 40 | case DA_GROUP_UNDEF_4: 41 | case DA_GROUP_UNDEF_5: 42 | case DA_GROUP_BLX_IMM: 43 | return 0; 44 | default: 45 | return 1; 46 | } 47 | } 48 | 49 | DA_API da_cond_t 50 | da_instr_get_cond(const da_instr_t *instr) 51 | { 52 | if (da_instr_has_cond(instr)) return DA_ARG_COND(instr, 28); 53 | else return DA_COND_AL; 54 | } 55 | 56 | /* Return target address for branch instruction offset. */ 57 | DA_API da_addr_t 58 | da_instr_branch_target(da_uint_t offset, da_addr_t addr) 59 | { 60 | /* Sign-extend offset */ 61 | struct { signed int ext : 24; } off; 62 | off.ext = offset; 63 | 64 | return (off.ext << 2) + addr + 8; 65 | } 66 | 67 | /* Parse instruction arguments. */ 68 | DA_API void 69 | da_instr_parse_args(da_instr_args_t *args, const da_instr_t *instr) 70 | { 71 | switch (instr->group) { 72 | case DA_GROUP_BKPT: 73 | args->bkpt.cond = DA_ARG_COND(instr, 28); 74 | args->bkpt.imm = (DA_ARG(instr, 8, 0xfff) << 4) | 75 | DA_ARG(instr, 0, 0xf); 76 | break; 77 | case DA_GROUP_BL: 78 | args->bl.cond = DA_ARG_COND(instr, 28); 79 | args->bl.link = DA_ARG_BOOL(instr, 24); 80 | args->bl.off = DA_ARG(instr, 0, 0xffffff); 81 | break; 82 | case DA_GROUP_BLX_IMM: 83 | args->blx_imm.h = DA_ARG_BOOL(instr, 24); 84 | args->blx_imm.off = DA_ARG(instr, 0, 0xffffff); 85 | break; 86 | case DA_GROUP_BLX_REG: 87 | args->blx_reg.cond = DA_ARG_COND(instr, 28); 88 | args->blx_reg.link = DA_ARG_BOOL(instr, 5); 89 | args->blx_reg.rm = DA_ARG_REG(instr, 0); 90 | break; 91 | case DA_GROUP_CLZ: 92 | args->clz.cond = DA_ARG_COND(instr, 28); 93 | args->clz.rd = DA_ARG_REG(instr, 12); 94 | args->clz.rm = DA_ARG_REG(instr, 0); 95 | break; 96 | case DA_GROUP_CP_DATA: 97 | args->cp_data.cond = DA_ARG_COND(instr, 28); 98 | args->cp_data.op_1 = DA_ARG(instr, 20, 0xf); 99 | args->cp_data.crn = DA_ARG_CPREG(instr, 16); 100 | args->cp_data.crd = DA_ARG_CPREG(instr, 12); 101 | args->cp_data.cp_num = DA_ARG(instr, 8, 0xf); 102 | args->cp_data.op_2 = DA_ARG(instr, 5, 0x7); 103 | args->cp_data.crm = DA_ARG_CPREG(instr, 0); 104 | break; 105 | case DA_GROUP_CP_LS: 106 | args->cp_ls.cond = DA_ARG_COND(instr, 28); 107 | args->cp_ls.p = DA_ARG_BOOL(instr, 24); 108 | args->cp_ls.sign = DA_ARG_BOOL(instr, 23); 109 | args->cp_ls.n = DA_ARG_BOOL(instr, 22); 110 | args->cp_ls.write = DA_ARG_BOOL(instr, 21); 111 | args->cp_ls.load = DA_ARG_BOOL(instr, 20); 112 | args->cp_ls.rn = DA_ARG_REG(instr, 16); 113 | args->cp_ls.crd = DA_ARG_CPREG(instr, 12); 114 | args->cp_ls.cp_num = DA_ARG(instr, 8, 0xf); 115 | args->cp_ls.imm = DA_ARG(instr, 0, 0xff); 116 | break; 117 | case DA_GROUP_CP_REG: 118 | args->cp_reg.cond = DA_ARG_COND(instr, 28); 119 | args->cp_reg.op_1 = DA_ARG(instr, 21, 0x7); 120 | args->cp_reg.load = DA_ARG_BOOL(instr, 20); 121 | args->cp_reg.crn = DA_ARG_CPREG(instr, 16); 122 | args->cp_reg.rd = DA_ARG_REG(instr, 12); 123 | args->cp_reg.cp_num = DA_ARG(instr, 8, 0xf); 124 | args->cp_reg.op_2 = DA_ARG(instr, 5, 0x7); 125 | args->cp_reg.crm = DA_ARG_CPREG(instr, 0); 126 | break; 127 | case DA_GROUP_DATA_IMM: 128 | args->data_imm.cond = DA_ARG_COND(instr, 28); 129 | args->data_imm.op = DA_ARG_DATA_OP(instr, 21); 130 | args->data_imm.flags = DA_ARG_BOOL(instr, 20); 131 | args->data_imm.rn = DA_ARG_REG(instr, 16); 132 | args->data_imm.rd = DA_ARG_REG(instr, 12); 133 | args->data_imm.imm = (DA_ARG(instr, 0, 0xff) >> 134 | (DA_ARG(instr, 8, 0xf) << 1)) | 135 | (DA_ARG(instr, 0, 0xff) << 136 | (32 - (DA_ARG(instr, 8, 0xf) << 1))); 137 | break; 138 | case DA_GROUP_DATA_IMM_SH: 139 | args->data_imm_sh.cond = DA_ARG_COND(instr, 28); 140 | args->data_imm_sh.op = DA_ARG_DATA_OP(instr, 21); 141 | args->data_imm_sh.flags = DA_ARG_BOOL(instr, 20); 142 | args->data_imm_sh.rn = DA_ARG_REG(instr, 16); 143 | args->data_imm_sh.rd = DA_ARG_REG(instr, 12); 144 | args->data_imm_sh.sha = DA_ARG(instr, 7, 0x1f); 145 | args->data_imm_sh.sh = DA_ARG_SHIFT(instr, 5); 146 | args->data_imm_sh.rm = DA_ARG_REG(instr, 0); 147 | break; 148 | case DA_GROUP_DATA_REG_SH: 149 | args->data_reg_sh.cond = DA_ARG_COND(instr, 28); 150 | args->data_reg_sh.op = DA_ARG_DATA_OP(instr, 21); 151 | args->data_reg_sh.flags = DA_ARG_BOOL(instr, 20); 152 | args->data_reg_sh.rn = DA_ARG_REG(instr, 16); 153 | args->data_reg_sh.rd = DA_ARG_REG(instr, 12); 154 | args->data_reg_sh.rs = DA_ARG_REG(instr, 8); 155 | args->data_reg_sh.sh = DA_ARG_SHIFT(instr, 5); 156 | args->data_reg_sh.rm = DA_ARG_REG(instr, 0); 157 | break; 158 | case DA_GROUP_DSP_ADD_SUB: 159 | args->dsp_add_sub.cond = DA_ARG_COND(instr, 28); 160 | args->dsp_add_sub.op = DA_ARG(instr, 21, 0x3); 161 | args->dsp_add_sub.rn = DA_ARG_REG(instr, 16); 162 | args->dsp_add_sub.rd = DA_ARG_REG(instr, 12); 163 | args->dsp_add_sub.rm = DA_ARG_REG(instr, 0); 164 | break; 165 | case DA_GROUP_DSP_MUL: 166 | args->dsp_mul.cond = DA_ARG_COND(instr, 28); 167 | args->dsp_mul.op = DA_ARG(instr, 21, 0x3); 168 | args->dsp_mul.rd = DA_ARG_REG(instr, 16); 169 | args->dsp_mul.rn = DA_ARG_REG(instr, 12); 170 | args->dsp_mul.rs = DA_ARG_REG(instr, 8); 171 | args->dsp_mul.y = DA_ARG_BOOL(instr, 6); 172 | args->dsp_mul.x = DA_ARG_BOOL(instr, 5); 173 | args->dsp_mul.rm = DA_ARG_REG(instr, 0); 174 | break; 175 | case DA_GROUP_L_SIGN_IMM: 176 | args->l_sign_imm.cond = DA_ARG_COND(instr, 28); 177 | args->l_sign_imm.p = DA_ARG_BOOL(instr, 24); 178 | args->l_sign_imm.write = DA_ARG_BOOL(instr, 21); 179 | args->l_sign_imm.rn = DA_ARG_REG(instr, 16); 180 | args->l_sign_imm.rd = DA_ARG_REG(instr, 12); 181 | args->l_sign_imm.hword = DA_ARG_BOOL(instr, 5); 182 | args->l_sign_imm.off = (DA_ARG_BOOL(instr, 23) ? 1 : -1) * 183 | ((DA_ARG(instr, 8, 0xf) << 4) | DA_ARG(instr, 0, 0xf)); 184 | break; 185 | case DA_GROUP_L_SIGN_REG: 186 | args->l_sign_reg.cond = DA_ARG_COND(instr, 28); 187 | args->l_sign_reg.p = DA_ARG_BOOL(instr, 24); 188 | args->l_sign_reg.sign = DA_ARG_BOOL(instr, 23); 189 | args->l_sign_reg.write = DA_ARG_BOOL(instr, 21); 190 | args->l_sign_reg.rn = DA_ARG_REG(instr, 16); 191 | args->l_sign_reg.rd = DA_ARG_REG(instr, 12); 192 | args->l_sign_reg.hword = DA_ARG_BOOL(instr, 5); 193 | args->l_sign_reg.rm = DA_ARG_REG(instr, 0); 194 | break; 195 | case DA_GROUP_LS_HW_IMM: 196 | args->ls_hw_imm.cond = DA_ARG_COND(instr, 28); 197 | args->ls_hw_imm.p = DA_ARG_BOOL(instr, 24); 198 | args->ls_hw_imm.write = DA_ARG_BOOL(instr, 21); 199 | args->ls_hw_imm.load = DA_ARG_BOOL(instr, 20); 200 | args->ls_hw_imm.rn = DA_ARG_REG(instr, 16); 201 | args->ls_hw_imm.rd = DA_ARG_REG(instr, 12); 202 | args->ls_hw_imm.off = (DA_ARG_BOOL(instr, 23) ? 1 : -1) * 203 | ((DA_ARG(instr, 8, 0xf) << 4) | DA_ARG(instr, 0, 0xf)); 204 | break; 205 | case DA_GROUP_LS_HW_REG: 206 | args->ls_hw_reg.cond = DA_ARG_COND(instr, 28); 207 | args->ls_hw_reg.p = DA_ARG_BOOL(instr, 24); 208 | args->ls_hw_reg.sign = DA_ARG_BOOL(instr, 23); 209 | args->ls_hw_reg.write = DA_ARG_BOOL(instr, 21); 210 | args->ls_hw_reg.load = DA_ARG_BOOL(instr, 20); 211 | args->ls_hw_reg.rn = DA_ARG_REG(instr, 16); 212 | args->ls_hw_reg.rd = DA_ARG_REG(instr, 12); 213 | args->ls_hw_reg.rm = DA_ARG_REG(instr, 0); 214 | break; 215 | case DA_GROUP_LS_IMM: 216 | args->ls_imm.cond = DA_ARG_COND(instr, 28); 217 | args->ls_imm.p = DA_ARG_BOOL(instr, 24); 218 | args->ls_imm.byte = DA_ARG_BOOL(instr, 22); 219 | args->ls_imm.w = DA_ARG_BOOL(instr, 21); 220 | args->ls_imm.load = DA_ARG_BOOL(instr, 20); 221 | args->ls_imm.rn = DA_ARG_REG(instr, 16); 222 | args->ls_imm.rd = DA_ARG_REG(instr, 12); 223 | args->ls_imm.off = (DA_ARG_BOOL(instr, 23) ? 1 : -1) * 224 | DA_ARG(instr, 0, 0xfff); 225 | break; 226 | case DA_GROUP_LS_MULTI: 227 | args->ls_multi.cond = DA_ARG_COND(instr, 28); 228 | args->ls_multi.p = DA_ARG_BOOL(instr, 24); 229 | args->ls_multi.u = DA_ARG_BOOL(instr, 23); 230 | args->ls_multi.s = DA_ARG_BOOL(instr, 22); 231 | args->ls_multi.write = DA_ARG_BOOL(instr, 21); 232 | args->ls_multi.load = DA_ARG_BOOL(instr, 20); 233 | args->ls_multi.rn = DA_ARG_REG(instr, 16); 234 | args->ls_multi.reglist = DA_ARG(instr, 0, 0xffff); 235 | break; 236 | case DA_GROUP_LS_REG: 237 | args->ls_reg.cond = DA_ARG_COND(instr, 28); 238 | args->ls_reg.p = DA_ARG_BOOL(instr, 24); 239 | args->ls_reg.sign = DA_ARG_BOOL(instr, 23); 240 | args->ls_reg.byte = DA_ARG_BOOL(instr, 22); 241 | args->ls_reg.write = DA_ARG_BOOL(instr, 21); 242 | args->ls_reg.load = DA_ARG_BOOL(instr, 20); 243 | args->ls_reg.rn = DA_ARG_REG(instr, 16); 244 | args->ls_reg.rd = DA_ARG_REG(instr, 12); 245 | args->ls_reg.sha = DA_ARG(instr, 7, 0x1f); 246 | args->ls_reg.sh = DA_ARG_SHIFT(instr, 5); 247 | args->ls_reg.rm = DA_ARG_REG(instr, 0); 248 | break; 249 | case DA_GROUP_LS_TWO_IMM: 250 | args->ls_two_imm.cond = DA_ARG_COND(instr, 28); 251 | args->ls_two_imm.p = DA_ARG_BOOL(instr, 24); 252 | args->ls_two_imm.write = DA_ARG_BOOL(instr, 21); 253 | args->ls_two_imm.rn = DA_ARG_REG(instr, 16); 254 | args->ls_two_imm.rd = DA_ARG_REG(instr, 12); 255 | args->ls_two_imm.store = DA_ARG_BOOL(instr, 5); 256 | args->ls_two_imm.off = (DA_ARG_BOOL(instr, 23) ? 1 : -1) * 257 | ((DA_ARG(instr, 8, 0xf) << 4) | DA_ARG(instr, 0, 0xf)); 258 | break; 259 | case DA_GROUP_LS_TWO_REG: 260 | args->ls_two_reg.cond = DA_ARG_COND(instr, 28); 261 | args->ls_two_reg.p = DA_ARG_BOOL(instr, 24); 262 | args->ls_two_reg.sign = DA_ARG_BOOL(instr, 23); 263 | args->ls_two_reg.write = DA_ARG_BOOL(instr, 21); 264 | args->ls_two_reg.rn = DA_ARG_REG(instr, 16); 265 | args->ls_two_reg.rd = DA_ARG_REG(instr, 12); 266 | args->ls_two_reg.store = DA_ARG_BOOL(instr, 5); 267 | args->ls_two_reg.rm = DA_ARG_REG(instr, 0); 268 | break; 269 | case DA_GROUP_MRS: 270 | args->mrs.cond = DA_ARG_COND(instr, 28); 271 | args->mrs.r = DA_ARG_BOOL(instr, 22); 272 | args->mrs.rd = DA_ARG_REG(instr, 12); 273 | break; 274 | case DA_GROUP_MSR: 275 | args->msr.cond = DA_ARG_COND(instr, 28); 276 | args->msr.r = DA_ARG_BOOL(instr, 22); 277 | args->msr.mask = DA_ARG(instr, 16, 0xf); 278 | args->msr.rm = DA_ARG_REG(instr, 0); 279 | break; 280 | case DA_GROUP_MSR_IMM: 281 | args->msr_imm.cond = DA_ARG_COND(instr, 28); 282 | args->msr_imm.r = DA_ARG_BOOL(instr, 22); 283 | args->msr_imm.mask = DA_ARG(instr, 16, 0xf); 284 | args->msr_imm.imm = (DA_ARG(instr, 0, 0xff) >> 285 | (DA_ARG(instr, 8, 0xf) << 1)) | 286 | (DA_ARG(instr, 0, 0xff) << 287 | (32 - (DA_ARG(instr, 8, 0xf) << 1))); 288 | break; 289 | case DA_GROUP_MUL: 290 | args->mul.cond = DA_ARG_COND(instr, 28); 291 | args->mul.acc = DA_ARG_BOOL(instr, 21); 292 | args->mul.flags = DA_ARG_BOOL(instr, 20); 293 | args->mul.rd = DA_ARG_REG(instr, 16); 294 | args->mul.rn = DA_ARG_REG(instr, 12); 295 | args->mul.rs = DA_ARG_REG(instr, 8); 296 | args->mul.rm = DA_ARG_REG(instr, 0); 297 | break; 298 | case DA_GROUP_MULL: 299 | args->mull.cond = DA_ARG_COND(instr, 28); 300 | args->mull.sign = DA_ARG_BOOL(instr, 22); 301 | args->mull.acc = DA_ARG_BOOL(instr, 21); 302 | args->mull.flags = DA_ARG_BOOL(instr, 20); 303 | args->mull.rd_hi = DA_ARG_REG(instr, 16); 304 | args->mull.rd_lo = DA_ARG_REG(instr, 12); 305 | args->mull.rs = DA_ARG_REG(instr, 8); 306 | args->mull.rm = DA_ARG_REG(instr, 0); 307 | break; 308 | case DA_GROUP_SWI: 309 | args->swi.cond = DA_ARG_COND(instr, 28); 310 | args->swi.imm = DA_ARG(instr, 0, 0xffffff); 311 | break; 312 | case DA_GROUP_SWP: 313 | args->swp.cond = DA_ARG_COND(instr, 28); 314 | args->swp.byte = DA_ARG_BOOL(instr, 22); 315 | args->swp.rn = DA_ARG_REG(instr, 16); 316 | args->swp.rd = DA_ARG_REG(instr, 12); 317 | args->swp.rm = DA_ARG_REG(instr, 0); 318 | break; 319 | case DA_GROUP_UNDEF_1: 320 | case DA_GROUP_UNDEF_2: 321 | case DA_GROUP_UNDEF_3: 322 | case DA_GROUP_UNDEF_4: 323 | case DA_GROUP_UNDEF_5: 324 | break; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /src/libdisarm/args.h: -------------------------------------------------------------------------------- 1 | /* 2 | * args.h - Instruction argument header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_ARGS_H 22 | #define _LIBDISARM_ARGS_H 23 | 24 | #include 25 | #include 26 | 27 | #define DA_ARG(instr,shift,mask) (((instr)->data >> (shift)) & (mask)) 28 | #define DA_ARG_BOOL(instr,shift) DA_ARG(instr,shift,1) 29 | #define DA_ARG_COND(instr,shift) DA_ARG(instr,shift,DA_COND_MASK) 30 | #define DA_ARG_SHIFT(instr,shift) DA_ARG(instr,shift,DA_SHIFT_MASK) 31 | #define DA_ARG_DATA_OP(instr,shift) DA_ARG(instr,shift,DA_DATA_OP_MASK) 32 | #define DA_ARG_REG(instr,shift) DA_ARG(instr,shift,DA_REG_MASK) 33 | #define DA_ARG_CPREG(instr,shift) DA_ARG(instr,shift,DA_CPREG_MASK) 34 | 35 | DA_BEGIN_DECLS 36 | 37 | typedef struct { 38 | da_cond_t cond; 39 | da_uint_t imm; 40 | } da_args_bkpt_t; 41 | 42 | typedef struct { 43 | da_cond_t cond; 44 | da_uint_t link; 45 | da_uint_t off; 46 | } da_args_bl_t; 47 | 48 | typedef struct { 49 | da_cond_t cond; 50 | da_uint_t link; 51 | da_reg_t rm; 52 | } da_args_blx_reg_t; 53 | 54 | typedef struct { 55 | da_uint_t h; 56 | da_uint_t off; 57 | } da_args_blx_imm_t; 58 | 59 | typedef struct { 60 | da_cond_t cond; 61 | da_reg_t rd; 62 | da_reg_t rm; 63 | } da_args_clz_t; 64 | 65 | typedef struct { 66 | da_cond_t cond; 67 | da_uint_t op_1; 68 | da_cpreg_t crn; 69 | da_cpreg_t crd; 70 | da_uint_t cp_num; 71 | da_uint_t op_2; 72 | da_cpreg_t crm; 73 | } da_args_cp_data_t; 74 | 75 | typedef struct { 76 | da_cond_t cond; 77 | da_uint_t p; 78 | da_uint_t sign; 79 | da_uint_t n; 80 | da_uint_t write; 81 | da_uint_t load; 82 | da_reg_t rn; 83 | da_cpreg_t crd; 84 | da_uint_t cp_num; 85 | da_uint_t imm; 86 | } da_args_cp_ls_t; 87 | 88 | typedef struct { 89 | da_cond_t cond; 90 | da_uint_t op_1; 91 | da_uint_t load; 92 | da_cpreg_t crn; 93 | da_reg_t rd; 94 | da_uint_t cp_num; 95 | da_uint_t op_2; 96 | da_cpreg_t crm; 97 | } da_args_cp_reg_t; 98 | 99 | typedef struct { 100 | da_cond_t cond; 101 | da_data_op_t op; 102 | da_uint_t flags; 103 | da_reg_t rn; 104 | da_reg_t rd; 105 | da_uint_t imm; 106 | } da_args_data_imm_t; 107 | 108 | typedef struct { 109 | da_cond_t cond; 110 | da_data_op_t op; 111 | da_uint_t flags; 112 | da_reg_t rn; 113 | da_reg_t rd; 114 | da_uint_t sha; 115 | da_shift_t sh; 116 | da_reg_t rm; 117 | } da_args_data_imm_sh_t; 118 | 119 | typedef struct { 120 | da_cond_t cond; 121 | da_data_op_t op; 122 | da_uint_t flags; 123 | da_reg_t rn; 124 | da_reg_t rd; 125 | da_reg_t rs; 126 | da_shift_t sh; 127 | da_reg_t rm; 128 | } da_args_data_reg_sh_t; 129 | 130 | typedef struct { 131 | da_cond_t cond; 132 | da_uint_t op; 133 | da_reg_t rn; 134 | da_reg_t rd; 135 | da_reg_t rm; 136 | } da_args_dsp_add_sub_t; 137 | 138 | typedef struct { 139 | da_cond_t cond; 140 | da_uint_t op; 141 | da_reg_t rd; 142 | da_reg_t rn; 143 | da_reg_t rs; 144 | da_uint_t y; 145 | da_uint_t x; 146 | da_reg_t rm; 147 | } da_args_dsp_mul_t; 148 | 149 | typedef struct { 150 | da_cond_t cond; 151 | da_uint_t p; 152 | da_uint_t write; 153 | da_reg_t rn; 154 | da_reg_t rd; 155 | da_uint_t hword; 156 | int off; 157 | } da_args_l_sign_imm_t; 158 | 159 | typedef struct { 160 | da_cond_t cond; 161 | da_uint_t p; 162 | da_uint_t sign; 163 | da_uint_t write; 164 | da_reg_t rn; 165 | da_reg_t rd; 166 | da_uint_t hword; 167 | da_reg_t rm; 168 | } da_args_l_sign_reg_t; 169 | 170 | typedef struct { 171 | da_cond_t cond; 172 | da_uint_t p; 173 | da_uint_t write; 174 | da_uint_t load; 175 | da_reg_t rn; 176 | da_reg_t rd; 177 | int off; 178 | } da_args_ls_hw_imm_t; 179 | 180 | typedef struct { 181 | da_cond_t cond; 182 | da_uint_t p; 183 | da_uint_t sign; 184 | da_uint_t write; 185 | da_uint_t load; 186 | da_reg_t rn; 187 | da_reg_t rd; 188 | da_reg_t rm; 189 | } da_args_ls_hw_reg_t; 190 | 191 | typedef struct { 192 | da_cond_t cond; 193 | da_uint_t p; 194 | da_uint_t byte; 195 | da_uint_t w; 196 | da_uint_t load; 197 | da_reg_t rn; 198 | da_reg_t rd; 199 | int off; 200 | } da_args_ls_imm_t; 201 | 202 | typedef struct { 203 | da_cond_t cond; 204 | da_uint_t p; 205 | da_uint_t u; 206 | da_uint_t s; 207 | da_uint_t write; 208 | da_uint_t load; 209 | da_reg_t rn; 210 | da_uint_t reglist; 211 | } da_args_ls_multi_t; 212 | 213 | typedef struct { 214 | da_cond_t cond; 215 | da_uint_t p; 216 | da_uint_t sign; 217 | da_uint_t byte; 218 | da_uint_t write; 219 | da_uint_t load; 220 | da_reg_t rn; 221 | da_reg_t rd; 222 | da_uint_t sha; 223 | da_shift_t sh; 224 | da_reg_t rm; 225 | } da_args_ls_reg_t; 226 | 227 | typedef struct { 228 | da_cond_t cond; 229 | da_uint_t p; 230 | da_uint_t write; 231 | da_reg_t rn; 232 | da_reg_t rd; 233 | da_uint_t store; 234 | int off; 235 | } da_args_ls_two_imm_t; 236 | 237 | typedef struct { 238 | da_cond_t cond; 239 | da_uint_t p; 240 | da_uint_t sign; 241 | da_uint_t write; 242 | da_reg_t rn; 243 | da_reg_t rd; 244 | da_uint_t store; 245 | da_reg_t rm; 246 | } da_args_ls_two_reg_t; 247 | 248 | typedef struct { 249 | da_cond_t cond; 250 | da_uint_t r; 251 | da_reg_t rd; 252 | } da_args_mrs_t; 253 | 254 | typedef struct { 255 | da_cond_t cond; 256 | da_uint_t r; 257 | da_uint_t mask; 258 | da_reg_t rm; 259 | } da_args_msr_t; 260 | 261 | typedef struct { 262 | da_cond_t cond; 263 | da_uint_t r; 264 | da_uint_t mask; 265 | da_uint_t imm; 266 | } da_args_msr_imm_t; 267 | 268 | typedef struct { 269 | da_cond_t cond; 270 | da_uint_t acc; 271 | da_uint_t flags; 272 | da_reg_t rd; 273 | da_reg_t rn; 274 | da_reg_t rs; 275 | da_reg_t rm; 276 | } da_args_mul_t; 277 | 278 | typedef struct { 279 | da_cond_t cond; 280 | da_uint_t sign; 281 | da_uint_t acc; 282 | da_uint_t flags; 283 | da_reg_t rd_hi; 284 | da_reg_t rd_lo; 285 | da_reg_t rs; 286 | da_reg_t rm; 287 | } da_args_mull_t; 288 | 289 | typedef struct { 290 | da_cond_t cond; 291 | da_uint_t imm; 292 | } da_args_swi_t; 293 | 294 | typedef struct { 295 | da_cond_t cond; 296 | da_uint_t byte; 297 | da_reg_t rn; 298 | da_reg_t rd; 299 | da_reg_t rm; 300 | } da_args_swp_t; 301 | 302 | 303 | typedef struct { 304 | union { 305 | da_args_bkpt_t bkpt; 306 | da_args_bl_t bl; 307 | da_args_blx_imm_t blx_imm; 308 | da_args_blx_reg_t blx_reg; 309 | da_args_clz_t clz; 310 | da_args_cp_data_t cp_data; 311 | da_args_cp_ls_t cp_ls; 312 | da_args_cp_reg_t cp_reg; 313 | da_args_data_imm_t data_imm; 314 | da_args_data_imm_sh_t data_imm_sh; 315 | da_args_data_reg_sh_t data_reg_sh; 316 | da_args_dsp_add_sub_t dsp_add_sub; 317 | da_args_dsp_mul_t dsp_mul; 318 | da_args_l_sign_imm_t l_sign_imm; 319 | da_args_l_sign_reg_t l_sign_reg; 320 | da_args_ls_hw_imm_t ls_hw_imm; 321 | da_args_ls_hw_reg_t ls_hw_reg; 322 | da_args_ls_imm_t ls_imm; 323 | da_args_ls_multi_t ls_multi; 324 | da_args_ls_reg_t ls_reg; 325 | da_args_ls_two_imm_t ls_two_imm; 326 | da_args_ls_two_reg_t ls_two_reg; 327 | da_args_mrs_t mrs; 328 | da_args_msr_t msr; 329 | da_args_msr_imm_t msr_imm; 330 | da_args_mul_t mul; 331 | da_args_mull_t mull; 332 | da_args_swi_t swi; 333 | da_args_swp_t swp; 334 | }; 335 | } da_instr_args_t; 336 | 337 | 338 | da_cond_t da_instr_get_cond(const da_instr_t *instr); 339 | da_addr_t da_instr_branch_target(da_uint_t off, da_addr_t addr); 340 | 341 | void da_instr_parse_args(da_instr_args_t *args, const da_instr_t *instr); 342 | 343 | DA_END_DECLS 344 | 345 | #endif /* ! _LIBDISARM_ARGS_H */ 346 | -------------------------------------------------------------------------------- /src/libdisarm/disarm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * disarm.h - ARM disassembler header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_DISARM_H 22 | #define _LIBDISARM_DISARM_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | 31 | #endif /* ! _LIBDISARM_DISARM_H */ 32 | -------------------------------------------------------------------------------- /src/libdisarm/endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | * endian.h - Endianness conversion header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_ENDIAN_H 22 | #define _LIBDISARM_ENDIAN_H 23 | 24 | 25 | #ifdef HAVE_CONFIG_H 26 | # include 27 | #endif 28 | 29 | #if defined HAVE_SYS_ENDIAN_H 30 | # include 31 | #elif defined HAVE_ENDIAN_H 32 | # include 33 | #else 34 | 35 | # include 36 | # include 37 | # include 38 | 39 | # ifdef HAVE_BYTESWAP_H 40 | # include 41 | # define bswap16(x) (bswap_16((x))) 42 | # define bswap32(x) (bswap_32((x))) 43 | # define bswap64(x) (bswap_64((x))) 44 | # else /* ! HAVE_BYTESWAP_H */ 45 | # define bswap16(x) \ 46 | ((((x) & 0x00ff) << 8) | \ 47 | (((x) & 0xff00) >> 8)) 48 | # define bswap32(x) \ 49 | ((((x) & 0x000000ff) << 24) | \ 50 | (((x) & 0x0000ff00) << 8) | \ 51 | (((x) & 0x00ff0000) >> 8) | \ 52 | (((x) & 0xff000000) >> 24)) 53 | # define bswap64(x) \ 54 | ((((x) & 0x00000000000000ffull) << 56) | \ 55 | (((x) & 0x000000000000ff00ull) << 40) | \ 56 | (((x) & 0x0000000000ff0000ull) << 24) | \ 57 | (((x) & 0x00000000ff000000ull) << 8) | \ 58 | (((x) & 0x000000ff00000000ull) >> 8) | \ 59 | (((x) & 0x0000ff0000000000ull) >> 24) | \ 60 | (((x) & 0x00ff000000000000ull) >> 40) | \ 61 | (((x) & 0xff00000000000000ull) >> 56)) 62 | # endif /* HAVE_BYTESWAP_H */ 63 | 64 | # ifdef WORDS_BIGENDIAN 65 | # define be16toh(x) (x) 66 | # define be32toh(x) (x) 67 | # define be64toh(x) (x) 68 | # define le16toh(x) bswap16((uint16_t)(x)) 69 | # define le32toh(x) bswap32((uint32_t)(x)) 70 | # define le64toh(x) bswap64((uint64_t)(x)) 71 | # else /* ! WORDS_BIGENDIAN */ 72 | # define be16toh(x) bswap16((uint16_t)(x)) 73 | # define be32toh(x) bswap32((uint32_t)(x)) 74 | # define be64toh(x) bswap64((uint64_t)(x)) 75 | # define le16toh(x) (x) 76 | # define le32toh(x) (x) 77 | # define le64toh(x) (x) 78 | # endif /* WORDS_BIGENDIAN */ 79 | 80 | # define htobe16(x) be16toh(x) 81 | # define htobe32(x) be32toh(x) 82 | # define htobe64(x) be64toh(x) 83 | # define htole16(x) le16toh(x) 84 | # define htole32(x) le32toh(x) 85 | # define htole64(x) le32toh(x) 86 | 87 | #endif /* HAVE_SYS_ENDIAN_H */ 88 | 89 | 90 | #endif /* ! _LIBDISARM_ENDIAN_H */ 91 | -------------------------------------------------------------------------------- /src/libdisarm/macros.h: -------------------------------------------------------------------------------- 1 | /* macros.h */ 2 | 3 | #ifndef _LIBDISARM_MACROS_H 4 | #define _LIBDISARM_MACROS_H 5 | 6 | 7 | /* Declarations for header files */ 8 | #ifdef __cplusplus 9 | # define DA_BEGIN_DECLS extern "C" { 10 | # define DA_END_DECLS } 11 | #else 12 | # define DA_BEGIN_DECLS 13 | # define DA_END_DECLS 14 | #endif 15 | 16 | /* API macros */ 17 | #if __GNUC__ >= 4 18 | # define DA_API __attribute__ ((__visibility__("default"))) 19 | #else 20 | # define DA_API 21 | #endif 22 | 23 | 24 | #endif /* ! _LIBDISARM_MACROS_H */ 25 | -------------------------------------------------------------------------------- /src/libdisarm/parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * parser.c - ARM instruction parse functions 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | # include 23 | #endif 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "endian.h" 30 | #include "macros.h" 31 | #include "types.h" 32 | 33 | 34 | /* Figure 3-2 in ARM Architecture Reference */ 35 | static da_group_t 36 | da_parse_group_mul_ls(da_word_t data) 37 | { 38 | if ((data >> 6) & 1) { 39 | if ((data >> 20) & 1) { 40 | if ((data >> 22) & 1) { 41 | return DA_GROUP_L_SIGN_IMM; 42 | } else return DA_GROUP_L_SIGN_REG; 43 | } else if ((data >> 22) & 1) { 44 | return DA_GROUP_LS_TWO_IMM; 45 | } else return DA_GROUP_LS_TWO_REG; 46 | } else { 47 | if ((data >> 5) & 1) { 48 | if ((data >> 22) & 1) { 49 | return DA_GROUP_LS_HW_IMM; 50 | } else return DA_GROUP_LS_HW_REG; 51 | } else { 52 | if ((data >> 24) & 1) return DA_GROUP_SWP; 53 | else if ((data >> 23) & 1) { 54 | return DA_GROUP_MULL; 55 | } else return DA_GROUP_MUL; 56 | } 57 | } 58 | } 59 | 60 | static da_group_t 61 | da_parse_group_type_0(da_word_t data) 62 | { 63 | if ((data >> 4) & 1) { 64 | if ((data >> 7) & 1) return da_parse_group_mul_ls(data); 65 | else if ((((data >> 23) & 0x3) == 0x2) && 66 | (((data >> 20) & 1) == 0)) { 67 | if ((data >> 6) & 1) { 68 | if ((data >> 5) & 1) return DA_GROUP_BKPT; 69 | else return DA_GROUP_DSP_ADD_SUB; 70 | } else { 71 | if ((data >> 22) & 1) return DA_GROUP_CLZ; 72 | else return DA_GROUP_BLX_REG; 73 | } 74 | } else return DA_GROUP_DATA_REG_SH; 75 | } else { 76 | if ((((data >> 23) & 0x3) == 0x2) && 77 | (((data >> 20) & 1) == 0)) { 78 | if ((data >> 7) & 1) return DA_GROUP_DSP_MUL; 79 | else if ((data >> 21) & 1) return DA_GROUP_MSR; 80 | else return DA_GROUP_MRS; 81 | } else return DA_GROUP_DATA_IMM_SH; 82 | } 83 | } 84 | 85 | static da_group_t 86 | da_parse_group_cond(da_word_t data) 87 | { 88 | switch ((data >> 25) & 0x7) { 89 | case 0: return da_parse_group_type_0(data); 90 | case 1: 91 | if ((((data >> 23) & 0x3) == 0x2) && 92 | (((data >> 20) & 1) == 0)) { 93 | if ((data >> 21) & 1) { 94 | return DA_GROUP_MSR_IMM; 95 | } else return DA_GROUP_UNDEF_1; 96 | } else return DA_GROUP_DATA_IMM; 97 | case 2: return DA_GROUP_LS_IMM; 98 | case 3: 99 | if ((data >> 4) & 1) return DA_GROUP_UNDEF_2; 100 | else return DA_GROUP_LS_REG; 101 | case 4: return DA_GROUP_LS_MULTI; 102 | case 5: return DA_GROUP_BL; 103 | case 6: return DA_GROUP_CP_LS; 104 | case 7: 105 | if ((data >> 24) & 1) return DA_GROUP_SWI; 106 | else if ((data >> 4) & 1) return DA_GROUP_CP_REG; 107 | else return DA_GROUP_CP_DATA; 108 | default: 109 | assert(0); /* Control shouldn't reach here. */ 110 | } 111 | } 112 | 113 | static da_group_t 114 | da_parse_group(da_word_t data) 115 | { 116 | switch ((data >> 28) & 0xf) { 117 | case 0xf: 118 | switch ((data >> 25) & 0x7) { 119 | case 0: 120 | case 1: 121 | case 2: 122 | case 3: return DA_GROUP_UNDEF_3; 123 | case 4: return DA_GROUP_UNDEF_4; 124 | case 5: return DA_GROUP_BLX_IMM; 125 | case 6: 126 | case 7: return DA_GROUP_UNDEF_5; 127 | } 128 | default: return da_parse_group_cond(data); 129 | } 130 | } 131 | 132 | DA_API void 133 | da_instr_parse(da_instr_t *instr, da_word_t data, int big_endian) 134 | { 135 | instr->data = (big_endian ? be32toh(data) : le32toh(data)); 136 | instr->group = da_parse_group(instr->data); 137 | } 138 | -------------------------------------------------------------------------------- /src/libdisarm/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * parser.c - ARM instruction parser header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_PARSER_H 22 | #define _LIBDISARM_PARSER_H 23 | 24 | #include 25 | #include 26 | 27 | DA_BEGIN_DECLS 28 | 29 | void da_instr_parse(da_instr_t *instr, da_word_t data, int big_endian); 30 | 31 | DA_END_DECLS 32 | 33 | #endif /* ! _LIBDISARM_PARSER_H */ 34 | -------------------------------------------------------------------------------- /src/libdisarm/print.c: -------------------------------------------------------------------------------- 1 | /* 2 | * print.c - Instruction printer functions 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | # include 23 | #endif 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "args.h" 30 | #include "macros.h" 31 | #include "print.h" 32 | #include "types.h" 33 | 34 | 35 | static const char *const da_cond_map[] = { 36 | "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 37 | "hi", "ls", "ge", "lt", "gt", "le", "", "nv" 38 | }; 39 | 40 | static const char *const da_shift_map[] = { 41 | "lsl", "lsr", "asr", "ror" 42 | }; 43 | 44 | static const char *const da_data_op_map[] = { 45 | "and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc", 46 | "tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn" 47 | }; 48 | 49 | 50 | static void 51 | da_reglist_fprint(FILE *f, da_uint_t reglist) 52 | { 53 | int comma = 0; 54 | int range_start = -1; 55 | int i = 0; 56 | for (i = 0; reglist; i++) { 57 | if (reglist & 1 && range_start == -1) { 58 | range_start = i; 59 | } 60 | 61 | reglist >>= 1; 62 | 63 | if (!(reglist & 1)) { 64 | if (range_start == i) { 65 | if (comma) fprintf(f, ","); 66 | fprintf(f, " r%d", i); 67 | comma = 1; 68 | } else if (i > 0 && range_start == i-1) { 69 | if (comma) fprintf(f, ","); 70 | fprintf(f, " r%d, r%d", 71 | range_start, i); 72 | comma = 1; 73 | } else if (range_start >= 0) { 74 | if (comma) fprintf(f, ","); 75 | fprintf(f, " r%d-r%d", range_start, i); 76 | comma = 1; 77 | } 78 | range_start = -1; 79 | } 80 | } 81 | } 82 | 83 | 84 | static void 85 | da_instr_fprint_bkpt(FILE *f, const da_instr_t *instr, 86 | const da_args_bkpt_t *args, da_addr_t addr) 87 | { 88 | fprintf(f, "bkpt%s\t0x%x", da_cond_map[args->cond], args->imm); 89 | } 90 | 91 | static void 92 | da_instr_fprint_bl(FILE *f, const da_instr_t *instr, 93 | const da_args_bl_t *args, da_addr_t addr) 94 | { 95 | da_uint_t target = da_instr_branch_target(args->off, addr); 96 | fprintf(f, "b%s%s\t0x%x", (args->link ? "l" : ""), 97 | da_cond_map[args->cond], target); 98 | } 99 | 100 | static void 101 | da_instr_fprint_blx_imm(FILE *f, const da_instr_t *instr, 102 | const da_args_blx_imm_t *args, da_addr_t addr) 103 | { 104 | da_uint_t target = da_instr_branch_target(args->off, addr); 105 | fprintf(f, "blx\t0x%x", target | args->h); 106 | } 107 | 108 | static void 109 | da_instr_fprint_blx_reg(FILE *f, const da_instr_t *instr, 110 | const da_args_blx_reg_t *args, da_addr_t addr) 111 | { 112 | fprintf(f, "b%sx%s\tr%d", (args->link ? "l" : ""), 113 | da_cond_map[args->cond], args->rm); 114 | } 115 | 116 | static void 117 | da_instr_fprint_clz(FILE *f, const da_instr_t *instr, 118 | const da_args_clz_t *args, da_addr_t addr) 119 | { 120 | fprintf(f, "clz%s\tr%d, r%d", da_cond_map[args->cond], 121 | args->rd, args->rm); 122 | } 123 | 124 | static void 125 | da_instr_fprint_cp_data(FILE *f, const da_instr_t *instr, 126 | const da_args_cp_data_t *args, da_addr_t addr) 127 | { 128 | fprintf(f, "cdp%s\tp%d, %d, cr%d, cr%d, cr%d, %d", 129 | (args->cond != DA_COND_NV ? da_cond_map[args->cond] : "2"), 130 | args->cp_num, args->op_1, args->crd, args->crn, args->crm, 131 | args->op_2); 132 | } 133 | 134 | static void 135 | da_instr_fprint_cp_ls(FILE *f, const da_instr_t *instr, 136 | const da_args_cp_ls_t *args, da_addr_t addr) 137 | { 138 | fprintf(f, "%sc%s%s\tp%d, cr%d, [r%d", (args->load ? "ld" : "st"), 139 | (args->cond != DA_COND_NV ? da_cond_map[args->cond] : "2"), 140 | (args->n ? "l" : ""), args->cp_num, args->crd, args->rn); 141 | 142 | if (!args->p) fprintf(f, "]"); 143 | 144 | if (!(args->sign || args->p)) { 145 | fprintf(f, ", {%d}", args->imm); 146 | } else if (args->imm > 0) { 147 | fprintf(f, ", #%s0x%x", (args->sign ? "" : "-"), 148 | (args->imm << 2)); 149 | } 150 | 151 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 152 | } 153 | 154 | static void 155 | da_instr_fprint_cp_reg(FILE *f, const da_instr_t *instr, 156 | const da_args_cp_reg_t *args, da_addr_t addr) 157 | { 158 | fprintf(f, "m%s%s\tp%d, %d, r%d, cr%d, cr%d, %d", 159 | (args->load ? "rc" : "cr"), 160 | (args->cond != DA_COND_NV ? da_cond_map[args->cond] : "2"), 161 | args->cp_num, args->op_1, args->rd, args->crn, args->crm, 162 | args->op_2); 163 | } 164 | 165 | static void 166 | da_instr_fprint_data_imm(FILE *f, const da_instr_t *instr, 167 | const da_args_data_imm_t *args, da_addr_t addr) 168 | { 169 | fprintf(f, "%s%s%s\t", da_data_op_map[args->op], 170 | ((args->flags && (args->op < DA_DATA_OP_TST || 171 | args->op > DA_DATA_OP_CMN)) ? "s" : ""), 172 | da_cond_map[args->cond]); 173 | 174 | if (args->op >= DA_DATA_OP_TST && args->op <= DA_DATA_OP_CMN) { 175 | fprintf(f, "r%d", args->rn); 176 | } else if (args->op == DA_DATA_OP_MOV || args->op == DA_DATA_OP_MVN) { 177 | fprintf(f, "r%d", args->rd); 178 | } else { 179 | fprintf(f, "r%d, r%d", args->rd, args->rn); 180 | } 181 | 182 | fprintf(f, ", #0x%x", args->imm); 183 | 184 | if (args->rn == DA_REG_R15) { 185 | if (args->op == DA_DATA_OP_ADD) { 186 | fprintf(f, "\t; 0x%x", addr + 8 + args->imm); 187 | } else if (args->op == DA_DATA_OP_SUB) { 188 | fprintf(f, "\t; 0x%x", addr + 8 - args->imm); 189 | } 190 | } 191 | } 192 | 193 | static void 194 | da_instr_fprint_data_imm_sh(FILE *f, const da_instr_t *instr, 195 | const da_args_data_imm_sh_t *args, da_addr_t addr) 196 | { 197 | fprintf(f, "%s%s%s\t", da_data_op_map[args->op], 198 | ((args->flags && 199 | (args->op < DA_DATA_OP_TST || 200 | args->op > DA_DATA_OP_CMN)) ? "s" : ""), 201 | da_cond_map[args->cond]); 202 | 203 | if (args->op >= DA_DATA_OP_TST && args->op <= DA_DATA_OP_CMN) { 204 | fprintf(f, "r%d, r%d", args->rn, args->rm); 205 | } else if (args->op == DA_DATA_OP_MOV || args->op == DA_DATA_OP_MVN) { 206 | fprintf(f, "r%d, r%d", args->rd, args->rm); 207 | } else { 208 | fprintf(f, "r%d, r%d, r%d", args->rd, args->rn, args->rm); 209 | } 210 | 211 | da_uint_t sha = args->sha; 212 | 213 | if (args->sh == DA_SHIFT_LSR || args->sh == DA_SHIFT_ASR) { 214 | sha = ((sha > 0) ? sha : 32); 215 | } 216 | 217 | if (sha > 0) { 218 | fprintf(f, ", %s #0x%x", da_shift_map[args->sh], sha); 219 | } else if (args->sh == DA_SHIFT_ROR) { 220 | fprintf(f, ", rrx"); 221 | } 222 | } 223 | 224 | static void 225 | da_instr_fprint_data_reg_sh(FILE *f, const da_instr_t *instr, 226 | const da_args_data_reg_sh_t *args, da_addr_t addr) 227 | { 228 | fprintf(f, "%s%s%s\t", da_data_op_map[args->op], 229 | ((args->flags && 230 | (args->op < DA_DATA_OP_TST || 231 | args->op > DA_DATA_OP_CMN)) ? "s" : ""), 232 | da_cond_map[args->cond]); 233 | 234 | if (args->op >= DA_DATA_OP_TST && args->op <= DA_DATA_OP_CMN) { 235 | fprintf(f, "r%d, r%d", args->rn, args->rm); 236 | } else if (args->op == DA_DATA_OP_MOV || args->op == DA_DATA_OP_MVN) { 237 | fprintf(f, "r%d, r%d", args->rd, args->rm); 238 | } else { 239 | fprintf(f, "r%d, r%d, r%d", args->rd, args->rn, args->rm); 240 | } 241 | 242 | fprintf(f, ", %s r%d", da_shift_map[args->sh], args->rs); 243 | } 244 | 245 | static void 246 | da_instr_fprint_dsp_add_sub(FILE *f, const da_instr_t *instr, 247 | const da_args_dsp_add_sub_t *args, da_addr_t addr) 248 | { 249 | fprintf(f, "q%s%s%s\tr%d, r%d, r%d", ((args->op & 2) ? "d" : ""), 250 | ((args->op & 1) ? "sub" : "add"), da_cond_map[args->cond], 251 | args->rd, args->rm, args->rn); 252 | } 253 | 254 | static void 255 | da_instr_fprint_dsp_mul(FILE *f, const da_instr_t *instr, 256 | const da_args_dsp_mul_t *args, da_addr_t addr) 257 | { 258 | switch (args->op) { 259 | case 0: 260 | fprintf(f, "smla%s%s%s\tr%d, r%d, r%d, r%d", 261 | (args->x ? "t" : "b"), (args->y ? "t" : "b"), 262 | da_cond_map[args->cond], args->rd, args->rm, args->rs, 263 | args->rn); 264 | break; 265 | case 1: 266 | fprintf(f, "s%sw%s%s\tr%d, r%d, r%d", 267 | (args->x ? "mul" : "mla"), (args->y ? "t" : "b"), 268 | da_cond_map[args->cond], args->rd, args->rm, args->rs); 269 | if (!args->x) fprintf(f, ", r%d", args->rn); 270 | break; 271 | case 2: 272 | fprintf(f, "smlal%s%s%s\tr%d, r%d, r%d, r%d", 273 | (args->x ? "t" : "b"), (args->y ? "t" : "b"), 274 | da_cond_map[args->cond], args->rn, args->rd, args->rm, 275 | args->rs); 276 | break; 277 | case 3: 278 | fprintf(f, "smul%s%s%s\tr%d, r%d, r%d", 279 | (args->x ? "t" : "b"), (args->y ? "t" : "b"), 280 | da_cond_map[args->cond], args->rd, args->rm, args->rs); 281 | break; 282 | } 283 | } 284 | 285 | static void 286 | da_instr_fprint_l_sign_imm(FILE *f, const da_instr_t *instr, 287 | const da_args_l_sign_imm_t *args, da_addr_t addr) 288 | { 289 | fprintf(f, "ldrs%s%s\tr%d, [r%d", (args->hword ? "h" : "b"), 290 | da_cond_map[args->cond], args->rd, args->rn); 291 | 292 | if (!args->p) fprintf(f, "]"); 293 | 294 | if (args->off != 0) { 295 | fprintf(f, ", #%s0x%x", (args->off < 0 ? "-" : ""), 296 | abs(args->off)); 297 | } 298 | 299 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 300 | 301 | if (args->rn == DA_REG_R15) { 302 | fprintf(f, "\t; 0x%x", addr + 8 + args->off); 303 | } 304 | } 305 | 306 | static void 307 | da_instr_fprint_l_sign_reg(FILE *f, const da_instr_t *instr, 308 | const da_args_l_sign_reg_t *args, da_addr_t addr) 309 | { 310 | fprintf(f, "ldrs%s%s\tr%d, [r%d", (args->hword ? "h" : "b"), 311 | da_cond_map[args->cond], args->rd, args->rn); 312 | 313 | if (!args->p) fprintf(f, "]"); 314 | 315 | fprintf(f, ", %sr%d", (args->sign ? "" : "-"), args->rm); 316 | 317 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 318 | } 319 | 320 | static void 321 | da_instr_fprint_ls_hw_imm(FILE *f, const da_instr_t *instr, 322 | const da_args_ls_hw_imm_t *args, da_addr_t addr) 323 | { 324 | fprintf(f, "%srh%s\tr%d, [r%d", (args->load ? "ld" : "st"), 325 | da_cond_map[args->cond], args->rd, args->rn); 326 | 327 | if (!args->p) fprintf(f, "]"); 328 | 329 | if (args->off != 0) { 330 | fprintf(f, ", #%s0x%x", (args->off < 0 ? "-" : ""), 331 | abs(args->off)); 332 | } 333 | 334 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 335 | 336 | if (args->rn == DA_REG_R15) { 337 | fprintf(f, "\t; 0x%x", addr + 8 + args->off); 338 | } 339 | } 340 | 341 | static void 342 | da_instr_fprint_ls_hw_reg(FILE *f, const da_instr_t *instr, 343 | const da_args_ls_hw_reg_t *args, da_addr_t addr) 344 | { 345 | fprintf(f, "%srh%s\tr%d, [r%d", (args->load ? "ld" : "st"), 346 | da_cond_map[args->cond], args->rd, args->rn); 347 | 348 | if (!args->p) fprintf(f, "]"); 349 | 350 | fprintf(f, ", %sr%d", (args->sign ? "" : "-"), args->rm); 351 | 352 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 353 | } 354 | 355 | static void 356 | da_instr_fprint_ls_imm(FILE *f, const da_instr_t *instr, 357 | const da_args_ls_imm_t *args, da_addr_t addr) 358 | { 359 | fprintf(f, "%sr%s%s%s\tr%d, [r%d", (args->load ? "ld" : "st"), 360 | (args->byte ? "b" : ""), ((!args->p && args->w) ? "t" : ""), 361 | da_cond_map[args->cond], args->rd, args->rn); 362 | 363 | if (!args->p) fprintf(f, "]"); 364 | 365 | if (args->off != 0) { 366 | fprintf(f, ", #%s0x%x", (args->off < 0 ? "-" : ""), 367 | abs(args->off)); 368 | } 369 | 370 | if (args->p) fprintf(f, "]%s", (args->w ? "!" : "")); 371 | 372 | if (args->rn == DA_REG_R15) { 373 | fprintf(f, "\t; 0x%x", addr + 8 + args->off); 374 | } 375 | } 376 | 377 | static void 378 | da_instr_fprint_ls_multi(FILE *f, const da_instr_t *instr, 379 | const da_args_ls_multi_t *args, da_addr_t addr) 380 | { 381 | fprintf(f, "%sm%s%s%s\tr%d%s, {", (args->load ? "ld" : "st"), 382 | (args->u ? "i" : "d"), (args->p ? "b" : "a"), 383 | da_cond_map[args->cond], args->rn, (args->write ? "!" : "")); 384 | 385 | da_reglist_fprint(f, args->reglist); 386 | 387 | fprintf(f, " }%s", (args->s ? "^" : "")); 388 | } 389 | 390 | static void 391 | da_instr_fprint_ls_reg(FILE *f, const da_instr_t *instr, 392 | const da_args_ls_reg_t *args, da_addr_t addr) 393 | { 394 | fprintf(f, "%sr%s%s%s\tr%d, [r%d", (args->load ? "ld" : "st"), 395 | (args->byte ? "b" : ""), ((!args->p && args->write) ? "t" : ""), 396 | da_cond_map[args->cond], args->rd, args->rn); 397 | 398 | if (!args->p) fprintf(f, "]"); 399 | 400 | fprintf(f, ", %sr%d", (args->sign ? "" : "-"), args->rm); 401 | 402 | da_uint_t sha = args->sha; 403 | 404 | if (args->sh == DA_SHIFT_LSR || args->sh == DA_SHIFT_ASR) { 405 | sha = (sha ? sha : 32); 406 | } 407 | 408 | if (sha > 0) { 409 | fprintf(f, ", %s #0x%x", da_shift_map[args->sh], sha); 410 | } else if (args->sh == DA_SHIFT_ROR) { 411 | fprintf(f, ", rrx"); 412 | } 413 | 414 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 415 | } 416 | 417 | static void 418 | da_instr_fprint_ls_two_imm(FILE *f, const da_instr_t *instr, 419 | const da_args_ls_two_imm_t *args, da_addr_t addr) 420 | { 421 | fprintf(f, "%srd%s\tr%d, [r%d", (args->store ? "st" : "ld"), 422 | da_cond_map[args->cond], args->rd, args->rn); 423 | 424 | if (!args->p) fprintf(f, "]"); 425 | 426 | if (args->off != 0) { 427 | fprintf(f, ", #%s0x%x", (args->off < 0 ? "-" : ""), 428 | abs(args->off)); 429 | } 430 | 431 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 432 | 433 | if (args->rn == DA_REG_R15) { 434 | fprintf(f, "\t; 0x%x", addr + 8 + args->off); 435 | } 436 | } 437 | 438 | static void 439 | da_instr_fprint_ls_two_reg(FILE *f, const da_instr_t *instr, 440 | const da_args_ls_two_reg_t *args, da_addr_t addr) 441 | { 442 | fprintf(f, "%srd%s\tr%d, [r%d", (args->store ? "st" : "ld"), 443 | da_cond_map[args->cond], args->rd, args->rn); 444 | 445 | if (!args->p) fprintf(f, "]"); 446 | 447 | fprintf(f, ", %sr%d", (args->sign ? "" : "-"), args->rm); 448 | 449 | if (args->p) fprintf(f, "]%s", (args->write ? "!" : "")); 450 | } 451 | 452 | static void 453 | da_instr_fprint_mrs(FILE *f, const da_instr_t *instr, 454 | const da_args_mrs_t *args, da_addr_t addr) 455 | { 456 | fprintf(f, "mrs%s\tr%d, %s", da_cond_map[args->cond], 457 | args->rd, (args->r ? "SPSR" : "CPSR")); 458 | } 459 | 460 | static void 461 | da_instr_fprint_msr(FILE *f, const da_instr_t *instr, 462 | const da_args_msr_t *args, da_addr_t addr) 463 | { 464 | fprintf(f, "msr%s\t%s_%s%s%s%s", da_cond_map[args->cond], 465 | (args->r ? "SPSR" : "CPSR"), ((args->mask & 1) ? "c" : ""), 466 | ((args->mask & 2) ? "x" : ""), ((args->mask & 4) ? "s" : ""), 467 | ((args->mask & 8) ? "f" : "")); 468 | 469 | fprintf(f, ", r%d", args->rm); 470 | } 471 | 472 | static void 473 | da_instr_fprint_msr_imm(FILE *f, const da_instr_t *instr, 474 | const da_args_msr_imm_t *args, da_addr_t addr) 475 | { 476 | fprintf(f, "msr%s\t%s_%s%s%s%s, #0x%x", da_cond_map[args->cond], 477 | (args->r ? "SPSR" : "CPSR"), ((args->mask & 1) ? "c" : ""), 478 | ((args->mask & 2) ? "x" : ""), ((args->mask & 4) ? "s" : ""), 479 | ((args->mask & 8) ? "f" : ""), args->imm); 480 | } 481 | 482 | static void 483 | da_instr_fprint_mul(FILE *f, const da_instr_t *instr, 484 | const da_args_mul_t *args, da_addr_t addr) 485 | { 486 | fprintf(f, "m%s%s%s\tr%d, r%d, r%d", (args->acc ? "la" : "ul"), 487 | (args->flags ? "s" : ""), da_cond_map[args->cond], 488 | args->rd, args->rm, args->rs); 489 | 490 | if (args->acc) fprintf(f, ", r%d", args->rn); 491 | } 492 | 493 | static void 494 | da_instr_fprint_mull(FILE *f, const da_instr_t *instr, 495 | const da_args_mull_t *args, da_addr_t addr) 496 | { 497 | fprintf(f, "%sm%sl%s%s\tr%d, r%d, r%d, r%d", 498 | (args->sign ? "s" : "u"), (args->acc ? "la" : "ul"), 499 | (args->flags ? "s" : ""), da_cond_map[args->cond], 500 | args->rd_lo, args->rd_hi, args->rm, args->rs); 501 | } 502 | 503 | static void 504 | da_instr_fprint_swi(FILE *f, const da_instr_t *instr, 505 | const da_args_swi_t *args, da_addr_t addr) 506 | { 507 | fprintf(f, "swi%s\t0x%x", da_cond_map[args->cond], args->imm); 508 | } 509 | 510 | static void 511 | da_instr_fprint_swp(FILE *f, const da_instr_t *instr, 512 | const da_args_swp_t *args, da_addr_t addr) 513 | { 514 | fprintf(f, "swp%s%s\tr%d, r%d, [r%d]", da_cond_map[args->cond], 515 | (args->byte ? "b" : ""), args->rd, args->rm, args->rn); 516 | } 517 | 518 | DA_API void 519 | da_instr_fprint(FILE *f, const da_instr_t *instr, const da_instr_args_t *args, 520 | da_addr_t addr) 521 | { 522 | switch (instr->group) { 523 | case DA_GROUP_BKPT: 524 | da_instr_fprint_bkpt(f, instr, &args->bkpt, addr); 525 | break; 526 | case DA_GROUP_BL: 527 | da_instr_fprint_bl(f, instr, &args->bl, addr); 528 | break; 529 | case DA_GROUP_BLX_IMM: 530 | da_instr_fprint_blx_imm(f, instr, &args->blx_imm, addr); 531 | break; 532 | case DA_GROUP_BLX_REG: 533 | da_instr_fprint_blx_reg(f, instr, &args->blx_reg, addr); 534 | break; 535 | case DA_GROUP_CLZ: 536 | da_instr_fprint_clz(f, instr, &args->clz, addr); 537 | break; 538 | case DA_GROUP_CP_DATA: 539 | da_instr_fprint_cp_data(f, instr, &args->cp_data, addr); 540 | break; 541 | case DA_GROUP_CP_LS: 542 | da_instr_fprint_cp_ls(f, instr, &args->cp_ls, addr); 543 | break; 544 | case DA_GROUP_CP_REG: 545 | da_instr_fprint_cp_reg(f, instr, &args->cp_reg, addr); 546 | break; 547 | case DA_GROUP_DATA_IMM: 548 | da_instr_fprint_data_imm(f, instr, &args->data_imm, addr); 549 | break; 550 | case DA_GROUP_DATA_IMM_SH: 551 | da_instr_fprint_data_imm_sh(f, instr, &args->data_imm_sh, 552 | addr); 553 | break; 554 | case DA_GROUP_DATA_REG_SH: 555 | da_instr_fprint_data_reg_sh(f, instr, &args->data_reg_sh, 556 | addr); 557 | break; 558 | case DA_GROUP_DSP_ADD_SUB: 559 | da_instr_fprint_dsp_add_sub(f, instr, &args->dsp_add_sub, 560 | addr); 561 | break; 562 | case DA_GROUP_DSP_MUL: 563 | da_instr_fprint_dsp_mul(f, instr, &args->dsp_mul, addr); 564 | break; 565 | case DA_GROUP_L_SIGN_IMM: 566 | da_instr_fprint_l_sign_imm(f, instr, &args->l_sign_imm, addr); 567 | break; 568 | case DA_GROUP_L_SIGN_REG: 569 | da_instr_fprint_l_sign_reg(f, instr, &args->l_sign_reg, addr); 570 | break; 571 | case DA_GROUP_LS_HW_IMM: 572 | da_instr_fprint_ls_hw_imm(f, instr, &args->ls_hw_imm, addr); 573 | break; 574 | case DA_GROUP_LS_HW_REG: 575 | da_instr_fprint_ls_hw_reg(f, instr, &args->ls_hw_reg, addr); 576 | break; 577 | case DA_GROUP_LS_IMM: 578 | da_instr_fprint_ls_imm(f, instr, &args->ls_imm, addr); 579 | break; 580 | case DA_GROUP_LS_MULTI: 581 | da_instr_fprint_ls_multi(f, instr, &args->ls_multi, addr); 582 | break; 583 | case DA_GROUP_LS_REG: 584 | da_instr_fprint_ls_reg(f, instr, &args->ls_reg, addr); 585 | break; 586 | case DA_GROUP_LS_TWO_IMM: 587 | da_instr_fprint_ls_two_imm(f, instr, &args->ls_two_imm, addr); 588 | break; 589 | case DA_GROUP_LS_TWO_REG: 590 | da_instr_fprint_ls_two_reg(f, instr, &args->ls_two_reg, addr); 591 | break; 592 | case DA_GROUP_MRS: 593 | da_instr_fprint_mrs(f, instr, &args->mrs, addr); 594 | break; 595 | case DA_GROUP_MSR: 596 | da_instr_fprint_msr(f, instr, &args->msr, addr); 597 | break; 598 | case DA_GROUP_MSR_IMM: 599 | da_instr_fprint_msr_imm(f, instr, &args->msr_imm, addr); 600 | break; 601 | case DA_GROUP_MUL: 602 | da_instr_fprint_mul(f, instr, &args->mul, addr); 603 | break; 604 | case DA_GROUP_MULL: 605 | da_instr_fprint_mull(f, instr, &args->mull, addr); 606 | break; 607 | case DA_GROUP_SWI: 608 | da_instr_fprint_swi(f, instr, &args->swi, addr); 609 | break; 610 | case DA_GROUP_SWP: 611 | da_instr_fprint_swp(f, instr, &args->swp, addr); 612 | break; 613 | case DA_GROUP_UNDEF_1: 614 | case DA_GROUP_UNDEF_2: 615 | case DA_GROUP_UNDEF_3: 616 | case DA_GROUP_UNDEF_4: 617 | case DA_GROUP_UNDEF_5: 618 | fprintf(f, "undefined"); 619 | break; 620 | } 621 | } 622 | -------------------------------------------------------------------------------- /src/libdisarm/print.h: -------------------------------------------------------------------------------- 1 | /* 2 | * print.h - Instruction printer header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_PRINT_H 22 | #define _LIBDISARM_PRINT_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | DA_BEGIN_DECLS 29 | 30 | void da_instr_fprint(FILE *f, const da_instr_t *instr, 31 | const da_instr_args_t *args, da_addr_t addr); 32 | 33 | DA_END_DECLS 34 | 35 | #endif /* ! _LIBDISARM_PRINT_H */ 36 | -------------------------------------------------------------------------------- /src/libdisarm/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * types.h - Types header 3 | * 4 | * Copyright (C) 2007 Jon Lund Steffensen 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _LIBDISARM_TYPES_H 22 | #define _LIBDISARM_TYPES_H 23 | 24 | #include 25 | 26 | 27 | typedef uint32_t da_word_t; 28 | typedef da_word_t da_addr_t; 29 | typedef unsigned int da_uint_t; 30 | 31 | 32 | typedef enum { 33 | /* Software breakpoint */ 34 | DA_GROUP_BKPT = 0, 35 | 36 | /* Branch and branch with link */ 37 | DA_GROUP_BL, 38 | /* Branch and branch with link and possible change to Thumb */ 39 | DA_GROUP_BLX_IMM, 40 | /* Branch and link/exchange instruction set */ 41 | DA_GROUP_BLX_REG, 42 | 43 | /* Count leading zeros */ 44 | DA_GROUP_CLZ, 45 | 46 | /* Coprocessor data processing */ 47 | DA_GROUP_CP_DATA, 48 | /* Coprocessor load/store and double register transfers */ 49 | DA_GROUP_CP_LS, 50 | /* Coprocessor register transfers */ 51 | DA_GROUP_CP_REG, 52 | 53 | /* Data processing immediate */ 54 | DA_GROUP_DATA_IMM, 55 | /* Data processing immediate shift */ 56 | DA_GROUP_DATA_IMM_SH, 57 | /* Data processing register shift */ 58 | DA_GROUP_DATA_REG_SH, 59 | 60 | /* Enhanced DSP add/subtracts */ 61 | DA_GROUP_DSP_ADD_SUB, 62 | /* Enhanced DSP multiplies */ 63 | DA_GROUP_DSP_MUL, 64 | 65 | /* Load signed halfword/byte immediate offset */ 66 | DA_GROUP_L_SIGN_IMM, 67 | /* Load signed halfword/byte register offset */ 68 | DA_GROUP_L_SIGN_REG, 69 | /* Load/store halfword immediate offset */ 70 | DA_GROUP_LS_HW_IMM, 71 | /* Load/store halfword register offset */ 72 | DA_GROUP_LS_HW_REG, 73 | /* Load/store immediate offset */ 74 | DA_GROUP_LS_IMM, 75 | /* Load/store multiple */ 76 | DA_GROUP_LS_MULTI, 77 | /* Load/store register offset */ 78 | DA_GROUP_LS_REG, 79 | /* Load/store two words immediate offset */ 80 | DA_GROUP_LS_TWO_IMM, 81 | /* Load/store two words register offset */ 82 | DA_GROUP_LS_TWO_REG, 83 | 84 | /* Move status register to register */ 85 | DA_GROUP_MRS, 86 | /* Move register to status register */ 87 | DA_GROUP_MSR, 88 | /* Move immediate to status register */ 89 | DA_GROUP_MSR_IMM, 90 | 91 | /* Multiply (accumulate) */ 92 | DA_GROUP_MUL, 93 | /* Multiply (accumulate) long */ 94 | DA_GROUP_MULL, 95 | 96 | /* Software interrupt */ 97 | DA_GROUP_SWI, 98 | 99 | /* Swap/swap byte */ 100 | DA_GROUP_SWP, 101 | 102 | /* Undefined instruction group #1 */ 103 | DA_GROUP_UNDEF_1, 104 | /* Undefined instruction group #2 */ 105 | DA_GROUP_UNDEF_2, 106 | /* Undefined instruction group #3 */ 107 | DA_GROUP_UNDEF_3, 108 | /* Undefined instruction group #4 */ 109 | DA_GROUP_UNDEF_4, 110 | /* Undefined instruction group #5 */ 111 | DA_GROUP_UNDEF_5, 112 | 113 | DA_GROUP_MAX 114 | } da_group_t; 115 | 116 | 117 | typedef enum { 118 | DA_COND_EQ = 0, DA_COND_NE, 119 | DA_COND_CS, DA_COND_CC, 120 | DA_COND_MI, DA_COND_PL, 121 | DA_COND_VS, DA_COND_VC, 122 | DA_COND_HI, DA_COND_LS, 123 | DA_COND_GE, DA_COND_LT, 124 | DA_COND_GT, DA_COND_LE, 125 | DA_COND_AL, DA_COND_NV, 126 | DA_COND_MAX 127 | } da_cond_t; 128 | 129 | #define DA_COND_MASK (DA_COND_MAX - 1) 130 | 131 | 132 | typedef enum { 133 | DA_SHIFT_LSL = 0, DA_SHIFT_LSR, 134 | DA_SHIFT_ASR, DA_SHIFT_ROR, 135 | DA_SHIFT_MAX 136 | } da_shift_t; 137 | 138 | #define DA_SHIFT_MASK (DA_SHIFT_MAX - 1) 139 | 140 | typedef enum { 141 | DA_DATA_OP_AND = 0, DA_DATA_OP_EOR, 142 | DA_DATA_OP_SUB, DA_DATA_OP_RSB, 143 | DA_DATA_OP_ADD, DA_DATA_OP_ADC, 144 | DA_DATA_OP_SBC, DA_DATA_OP_RSC, 145 | DA_DATA_OP_TST, DA_DATA_OP_TEQ, 146 | DA_DATA_OP_CMP, DA_DATA_OP_CMN, 147 | DA_DATA_OP_ORR, DA_DATA_OP_MOV, 148 | DA_DATA_OP_BIC, DA_DATA_OP_MVN, 149 | DA_DATA_OP_MAX 150 | } da_data_op_t; 151 | 152 | #define DA_DATA_OP_MASK (DA_DATA_OP_MAX - 1) 153 | 154 | 155 | typedef enum { 156 | DA_REG_R0 = 0, DA_REG_R1, 157 | DA_REG_R2, DA_REG_R3, 158 | DA_REG_R4, DA_REG_R5, 159 | DA_REG_R6, DA_REG_R7, 160 | DA_REG_R8, DA_REG_R9, 161 | DA_REG_R10, DA_REG_R11, 162 | DA_REG_R12, DA_REG_R13, 163 | DA_REG_R14, DA_REG_R15, 164 | DA_REG_MAX 165 | } da_reg_t; 166 | 167 | #define DA_REG_SP DA_REG_13 168 | #define DA_REG_LR DA_REG_14 169 | #define DA_REG_PC DA_REG_15 170 | 171 | #define DA_REG_MASK (DA_REG_MAX - 1) 172 | 173 | 174 | typedef enum { 175 | DA_CPREG_CR0 = 0, DA_CPREG_CR1, 176 | DA_CPREG_CR2, DA_CPREG_CR3, 177 | DA_CPREG_CR4, DA_CPREG_CR5, 178 | DA_CPREG_CR6, DA_CPREG_CR7, 179 | DA_CPREG_CR8, DA_CPREG_CR9, 180 | DA_CPREG_CR10, DA_CPREG_CR11, 181 | DA_CPREG_CR12, DA_CPREG_CR13, 182 | DA_CPREG_CR14, DA_CPREG_CR15, 183 | DA_CPREG_MAX 184 | } da_cpreg_t; 185 | 186 | #define DA_CPREG_MASK (DA_CPREG_MAX - 1) 187 | 188 | 189 | typedef enum { 190 | DA_FLAG_N = 0, DA_FLAG_Z, 191 | DA_FLAG_C, DA_FLAG_V, 192 | DA_FLAG_MAX 193 | } da_flag_t; 194 | 195 | #define DA_FLAG_MASK (DA_FLAG_MAX - 1) 196 | 197 | 198 | typedef struct { 199 | da_word_t data; 200 | da_group_t group; 201 | } da_instr_t; 202 | 203 | 204 | #endif /* ! _LIBDISARM_TYPES_H */ 205 | --------------------------------------------------------------------------------